/*! * HTML5 placeholder emulation for jQuery plugin * * This will automatically use the HTML5 placeholder attribute if supported, or emulate this behavior if not. * * This is a fork from Mathias Bynens' jquery.placeholder as of this commit * https://github.com/mathiasbynens/jquery-placeholder/blob/47f05d400e2dd16b59d144141a2cf54a9a77c502/jquery.placeholder.js * * @author Mathias Bynens * @author Trevor Parscal , 2012 * @author Krinkle , 2012 * @author Alex Ivanov , 2013 * @version 2.1.0 * @license MIT */ ( function ( $ ) { var isInputSupported = 'placeholder' in document.createElement( 'input' ), isTextareaSupported = 'placeholder' in document.createElement( 'textarea' ), prototype = $.fn, valHooks = $.valHooks, propHooks = $.propHooks, hooks, placeholder; function safeActiveElement() { // Avoid IE9 `document.activeElement` of death // https://github.com/mathiasbynens/jquery-placeholder/pull/99 try { return document.activeElement; } catch ( err ) {} } function args( elem ) { // Return an object of element attributes var newAttrs = {}, rinlinejQuery = /^jQuery\d+$/; $.each( elem.attributes, function ( i, attr ) { if ( attr.specified && !rinlinejQuery.test( attr.name ) ) { newAttrs[ attr.name ] = attr.value; } } ); return newAttrs; } function clearPlaceholder( event, value ) { var input = this, $input = $( input ); if ( input.value === $input.attr( 'placeholder' ) && $input.hasClass( 'placeholder' ) ) { if ( $input.data( 'placeholder-password' ) ) { $input = $input.hide().next().show().attr( 'id', $input.removeAttr( 'id' ).data( 'placeholder-id' ) ); // If `clearPlaceholder` was called from `$.valHooks.input.set` if ( event === true ) { $input[ 0 ].value = value; return value; } $input.focus(); } else { input.value = ''; $input.removeClass( 'placeholder' ); if ( input === safeActiveElement() ) { input.select(); } } } } function setPlaceholder() { var $replacement, input = this, $input = $( input ), id = this.id; if ( !input.value ) { if ( input.type === 'password' ) { if ( !$input.data( 'placeholder-textinput' ) ) { try { $replacement = $input.clone().attr( { type: 'text' } ); } catch ( e ) { $replacement = $( '' ).attr( $.extend( args( this ), { type: 'text' } ) ); } $replacement .removeAttr( 'name' ) .data( { 'placeholder-password': $input, 'placeholder-id': id } ) .on( 'focus.placeholder drop.placeholder', clearPlaceholder ); $input .data( { 'placeholder-textinput': $replacement, 'placeholder-id': id } ) .before( $replacement ); } $input = $input.removeAttr( 'id' ).hide().prev().attr( 'id', id ).show(); // Note: `$input[0] != input` now! } $input.addClass( 'placeholder' ); $input[ 0 ].value = $input.attr( 'placeholder' ); } else { $input.removeClass( 'placeholder' ); } } function changePlaceholder( text ) { var hasArgs = arguments.length, $input = this; if ( hasArgs ) { if ( $input.attr( 'placeholder' ) !== text ) { $input.prop( 'placeholder', text ); if ( $input.hasClass( 'placeholder' ) ) { $input[ 0 ].value = text; } } } } if ( isInputSupported && isTextareaSupported ) { placeholder = prototype.placeholder = function ( text ) { var hasArgs = arguments.length; if ( hasArgs ) { changePlaceholder.call( this, text ); } return this; }; placeholder.input = placeholder.textarea = true; } else { placeholder = prototype.placeholder = function ( text ) { var $this = this, hasArgs = arguments.length; if ( hasArgs ) { changePlaceholder.call( this, text ); } $this .filter( ( isInputSupported ? 'textarea' : ':input' ) + '[placeholder]' ) .filter( function () { return !$( this ).data( 'placeholder-enabled' ); } ) .on( { 'focus.placeholder drop.placeholder': clearPlaceholder, 'blur.placeholder': setPlaceholder } ) .data( 'placeholder-enabled', true ) .trigger( 'blur.placeholder' ); return $this; }; placeholder.input = isInputSupported; placeholder.textarea = isTextareaSupported; hooks = { get: function ( element ) { var $element = $( element ), $passwordInput = $element.data( 'placeholder-password' ); if ( $passwordInput ) { return $passwordInput[ 0 ].value; } return $element.data( 'placeholder-enabled' ) && $element.hasClass( 'placeholder' ) ? '' : element.value; }, set: function ( element, value ) { var $element = $( element ), $passwordInput = $element.data( 'placeholder-password' ); if ( $passwordInput ) { $passwordInput[ 0 ].value = value; return value; } if ( !$element.data( 'placeholder-enabled' ) ) { element.value = value; return value; } if ( !value ) { element.value = value; // Issue #56: Setting the placeholder causes problems if the element continues to have focus. if ( element !== safeActiveElement() ) { // We can't use `triggerHandler` here because of dummy text/password inputs :( setPlaceholder.call( element ); } } else if ( $element.hasClass( 'placeholder' ) ) { if ( !clearPlaceholder.call( element, true, value ) ) { element.value = value; } } else { element.value = value; } // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363 return $element; } }; if ( !isInputSupported ) { valHooks.input = hooks; propHooks.value = hooks; } if ( !isTextareaSupported ) { valHooks.textarea = hooks; propHooks.value = hooks; } $( function () { // Look for forms $( document ).delegate( 'form', 'submit.placeholder', function () { // Clear the placeholder values so they don't get submitted var $inputs = $( '.placeholder', this ).each( clearPlaceholder ); setTimeout( function () { $inputs.each( setPlaceholder ); }, 10 ); } ); } ); // Clear placeholder values upon page reload $( window ).on( 'beforeunload.placeholder', function () { $( '.placeholder' ).each( function () { this.value = ''; } ); } ); } }( jQuery ) );