2 * HTML5 placeholder emulation for jQuery plugin
4 * This will automatically use the HTML5 placeholder attribute if supported, or emulate this behavior if not.
6 * This is a fork from Mathias Bynens' jquery.placeholder as of this commit
7 * https://github.com/mathiasbynens/jquery-placeholder/blob/47f05d400e2dd16b59d144141a2cf54a9a77c502/jquery.placeholder.js
9 * @author Mathias Bynens <http://mathiasbynens.be/>
10 * @author Trevor Parscal <tparscal@wikimedia.org>, 2012
11 * @author Krinkle <krinklemail@gmail.com>, 2012
12 * @author Alex Ivanov <alexivanov97@gmail.com>, 2013
19 var isInputSupported
= 'placeholder' in document
.createElement( 'input' ),
20 isTextareaSupported
= 'placeholder' in document
.createElement( 'textarea' ),
22 valHooks
= $.valHooks
,
23 propHooks
= $.propHooks
,
27 function safeActiveElement() {
28 // Avoid IE9 `document.activeElement` of death
29 // https://github.com/mathiasbynens/jquery-placeholder/pull/99
31 return document
.activeElement
;
35 function args( elem
) {
36 // Return an object of element attributes
38 rinlinejQuery
= /^jQuery\d+$/;
39 $.each( elem
.attributes
, function ( i
, attr
) {
40 if ( attr
.specified
&& !rinlinejQuery
.test( attr
.name
) ) {
41 newAttrs
[ attr
.name
] = attr
.value
;
47 function clearPlaceholder( event
, value
) {
50 if ( input
.value
=== $input
.attr( 'placeholder' ) && $input
.hasClass( 'placeholder' ) ) {
51 if ( $input
.data( 'placeholder-password' ) ) {
52 $input
= $input
.hide().next().show().attr( 'id', $input
.removeAttr( 'id' ).data( 'placeholder-id' ) );
53 // If `clearPlaceholder` was called from `$.valHooks.input.set`
54 if ( event
=== true ) {
55 $input
[ 0 ].value
= value
;
61 $input
.removeClass( 'placeholder' );
62 if ( input
=== safeActiveElement() ) {
69 function setPlaceholder() {
75 if ( input
.type
=== 'password' ) {
76 if ( !$input
.data( 'placeholder-textinput' ) ) {
78 $replacement
= $input
.clone().attr( { type
: 'text' } );
80 $replacement
= $( '<input>' ).attr( $.extend( args( this ), { type
: 'text' } ) );
85 'placeholder-password': $input
,
88 .on( 'focus.placeholder drop.placeholder', clearPlaceholder
);
91 'placeholder-textinput': $replacement
,
94 .before( $replacement
);
96 $input
= $input
.removeAttr( 'id' ).hide().prev().attr( 'id', id
).show();
97 // Note: `$input[0] != input` now!
99 $input
.addClass( 'placeholder' );
100 $input
[ 0 ].value
= $input
.attr( 'placeholder' );
102 $input
.removeClass( 'placeholder' );
106 function changePlaceholder( text
) {
107 var hasArgs
= arguments
.length
,
110 if ( $input
.attr( 'placeholder' ) !== text
) {
111 $input
.prop( 'placeholder', text
);
112 if ( $input
.hasClass( 'placeholder' ) ) {
113 $input
[ 0 ].value
= text
;
119 if ( isInputSupported
&& isTextareaSupported
) {
121 placeholder
= prototype.placeholder = function ( text
) {
122 var hasArgs
= arguments
.length
;
125 changePlaceholder
.call( this, text
);
131 placeholder
.input
= placeholder
.textarea
= true;
135 placeholder
= prototype.placeholder = function ( text
) {
137 hasArgs
= arguments
.length
;
140 changePlaceholder
.call( this, text
);
144 .filter( ( isInputSupported
? 'textarea' : ':input' ) + '[placeholder]' )
145 .filter( function () {
146 return !$( this ).data( 'placeholder-enabled' );
149 'focus.placeholder drop.placeholder': clearPlaceholder
,
150 'blur.placeholder': setPlaceholder
152 .data( 'placeholder-enabled', true )
153 .trigger( 'blur.placeholder' );
157 placeholder
.input
= isInputSupported
;
158 placeholder
.textarea
= isTextareaSupported
;
161 get: function ( element
) {
162 var $element
= $( element
),
163 $passwordInput
= $element
.data( 'placeholder-password' );
164 if ( $passwordInput
) {
165 return $passwordInput
[ 0 ].value
;
168 return $element
.data( 'placeholder-enabled' ) && $element
.hasClass( 'placeholder' ) ? '' : element
.value
;
170 set: function ( element
, value
) {
171 var $element
= $( element
),
172 $passwordInput
= $element
.data( 'placeholder-password' );
173 if ( $passwordInput
) {
174 $passwordInput
[ 0 ].value
= value
;
178 if ( !$element
.data( 'placeholder-enabled' ) ) {
179 element
.value
= value
;
183 element
.value
= value
;
184 // Issue #56: Setting the placeholder causes problems if the element continues to have focus.
185 if ( element
!== safeActiveElement() ) {
186 // We can't use `triggerHandler` here because of dummy text/password inputs :(
187 setPlaceholder
.call( element
);
189 } else if ( $element
.hasClass( 'placeholder' ) ) {
190 if ( !clearPlaceholder
.call( element
, true, value
) ) {
191 element
.value
= value
;
194 element
.value
= value
;
196 // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
201 if ( !isInputSupported
) {
202 valHooks
.input
= hooks
;
203 propHooks
.value
= hooks
;
205 if ( !isTextareaSupported
) {
206 valHooks
.textarea
= hooks
;
207 propHooks
.value
= hooks
;
212 $( document
).delegate( 'form', 'submit.placeholder', function () {
213 // Clear the placeholder values so they don't get submitted
214 var $inputs
= $( '.placeholder', this ).each( clearPlaceholder
);
215 setTimeout( function () {
216 $inputs
.each( setPlaceholder
);
221 // Clear placeholder values upon page reload
222 $( window
).on( 'beforeunload.placeholder', function () {
223 $( '.placeholder' ).each( function () {