jQuery placeholder plugin for text/password fields: second try
September 20, 2012 15:08:15 Last update: September 21, 2012 11:55:58
The idea is simple: duplicate the input field and position one on top of the other. The top one will take the input, while the bottom one will serve the placeholder. The top one will have a transparent background so the value of the placeholder field will show through. The placeholder field is disabled so that it's value is not submitted with the form.
Here's the code:
But in practice, it's tricky. Notice that I used
for the background transparency. This is because
does not work for IE9. Even though the input is on top of the placeholder, the placeholder always gets the event when you click on the field. That might be an attempt for IE to thwart Clickjacking attacks. If that's the case, it didn't quite work since you can easily bypass it by setting transparency with '
Update: I just learned that there's a "pointer-events" CSS property that controls who gets the mouse clicks when there's an overlap. There's no change in IE behavior with respect to the setting.
Here's the code:
(function($) { $.fn.placeholder = function() { if ('placeholder' in document.createElement('input')) { return this; } this.filter('input[placeholder]').each(function() { var name = $(this).attr('name'); var $placeholder = $(this).nextAll('input[name="'+name+'-placeholder"]'); if ($placeholder.length > 0) { $(this).css({ 'width': $placeholder.css('width'), 'top': $placeholder.position().top + 'px', 'left': $placeholder.position().left + 'px' }); } else { $placeholder = $(this).clone(); $placeholder.attr('type', 'text') .attr('id', null) .attr('placeholder', null) .attr('name', $(this).attr('name') + '-placeholder') .attr('disabled', 'disabled') .val($(this).attr('placeholder')); $(this).after($placeholder) .css({ 'position': 'absolute', 'border': null, 'width': $placeholder.css('width'), 'background-color': 'rgba(255, 255, 255, 0)' }) .bind('keyup', function() { if (this.value) { $(this).nextAll('input[name="'+name+'-placeholder"]').val(''); } else { $(this).nextAll('input[name="'+name+'-placeholder"]').val($(this).attr('placeholder')); } }); } if (this.value) { $placeholder.val(''); } else { $placeholder.val($(this).attr('placeholder')); } }); return this; } })(jQuery);
But in practice, it's tricky. Notice that I used
'background-color': 'rgba(255, 255, 255, 0)'
for the background transparency. This is because
'background-color': 'transparent'
does not work for IE9. Even though the input is on top of the placeholder, the placeholder always gets the event when you click on the field. That might be an attempt for IE to thwart Clickjacking attacks. If that's the case, it didn't quite work since you can easily bypass it by setting transparency with '
rgba'.
Update: I just learned that there's a "pointer-events" CSS property that controls who gets the mouse clicks when there's an overlap. There's no change in IE behavior with respect to the setting.