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 () {