Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
jQuery Placeholder Plugin - Fixes the placeholder attribute on non-supported browsers.
/*
* Placeholder plugin for jQuery
* @author Daniel Stocks (http://webcloud.se)
*/
(function($) {
function Placeholder(input) {
this.input = input;
if (input.attr('type') == 'password') {
this.handlePassword();
}
// Prevent placeholder values from submitting
$(input[0].form).submit(function() {
if (input.hasClass('placeholder')) {
input[0].value = '';
}
});
}
Placeholder.prototype = {
show : function(loading) {
// FF and IE saves values when you refresh the page. If the user refreshes the page with
// the placeholders showing they will be the default values and the input fields won't be empty.
if (this.input[0].value === '' || (loading && this.valueIsPlaceholder())) {
if (this.isPassword) {
try {
this.input[0].setAttribute('type', 'text');
} catch (e) {
this.input.before(this.fakePassword.show()).hide();
}
}
this.input[0].value = this.input.attr('placeholder');
this.input.addClass('placeholder');
}
},
hide : function() {
if (this.valueIsPlaceholder() && this.input.hasClass('placeholder')) {
if (this.isPassword) {
try {
this.input[0].setAttribute('type', 'password');
} catch (e) { }
// Restore focus for Opera and IE
this.input.show();
this.input[0].focus();
}
this.input[0].value = '';
this.input.removeClass('placeholder');
}
},
valueIsPlaceholder : function() {
return this.input[0].value == this.input.attr('placeholder');
},
handlePassword: function() {
var input = this.input;
input.attr('realType', 'password');
this.isPassword = true;
// IE < 9 doesn't allow changing the type of password inputs
if ($.browser.msie && input[0].outerHTML) {
var fakeHTML = input[0].outerHTML.replace(/type=(['"])?password\1/gi, 'type=$1text$1');
this.fakePassword = $(fakeHTML).val(input.attr('placeholder')).addClass('placeholder').focus(function() {
input.trigger('focus');
$(this).hide();
});
}
}
};
var supported = !!("placeholder" in document.createElement( "input" ));
$.fn.placeholder = function() {
return supported ? this : this.each(function() {
var input = $(this);
var placeholder = new Placeholder(input);
placeholder.show(true);
input.focus(function() {
placeholder.hide();
});
input.blur(function() {
placeholder.show(false);
});
// On page refresh, IE doesn't re-populate user input
// until the window.onload event is fired.
if ($.browser.msie) {
$(window).load(function() {
if(input.val()) {
input.removeClass("placeholder");
}
placeholder.show(true);
});
}
});
}
})(jQuery);
$(function() {
// For every input element with the placeholder attribute, do jQuery Placeholder
$('input[placeholder]').placeholder();
});

Wilfred commented Aug 9, 2013

Some notes on this when I tried it:

  • It uses $.browser.msie which is only present in jQuery < 1.9
  • It assumes that IE < 9 will throw an exception (line 26) when you set the type of a password input. In jQuery < 1.9 it unconditionally throws an exception so this code is accessing the element directly.
  • I believe that the above exception is not thrown by IE 9 running in IE 8 emulation mode. Gah.

Wilfred commented Aug 9, 2013

Yep, running this in IE 8 works fine, but I get ***** in password inputs in IE 9 (on Windows XP) emulation IE 8.

xmak commented Jan 26, 2014

Running this in IE8 DOESN'T work correctly. It throws the following error:

Message: 'b.browser.msie' is null or not an object
Line: 10
Char: 417
Code: 0
URI: http://.../jquery.placeholder.min.js

whic then stops the execution of other scripts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment