141

It seems it's a very well known problem but all the solutions I found on Google don't work on my newly downloaded IE9.

Which is your favorite way in order to enable the Placeholder property on the input and textarea tags?

Optional: I lost a lot of time on that and didn't look for the required property yet. Would you also have some advice for this? Obviously I can check the value in PHP, but to help the user this property is very convenient.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
chriscatfr
  • 2,592
  • 3
  • 24
  • 32
  • I'm back into HTML after 4yrs. Meaning I'm open to any advise to replace my outdated tools. I restart almost from zero. I've been trying mainly with JQuery and many copy/past from google results, my [lastest try](http://plugins.jquery.com/project/placeholder-html5) – chriscatfr Jun 16 '11 at 01:05

11 Answers11

186

HTML5 Placeholder jQuery Plugin
- by Mathias Bynens (a collaborator on HTML5 Boilerplate and jsPerf)

https://github.com/mathiasbynens/jquery-placeholder

Demo & Examples

http://mathiasbynens.be/demo/placeholder

p.s
I have used this plugin many times and it works a treat. Also it doesn't submit the placeholder text as a value when you submit your form (... a real pain I found with other plugins).

Chris Jacob
  • 11,878
  • 7
  • 47
  • 42
  • We are working with a custom CRM. I added this code and the works as expected, but they submit their forms via javascript. The submit button has `onclick="_IW.FormsRuntime.submit(this.form);"`. Is there anyway I can change this onclick event to first clear the placeholders, and then run this CRM code that exists in the onclick? – Leeish Feb 04 '13 at 17:43
  • 1
    i copied the github js file into my src code. Still no go with the placeholder. – Philo Oct 17 '13 at 19:15
  • 2
    This indeed works a treat, however it's a pain to use on single page applications. You need to trigger it manually for dynamically added fields. Other than that, works great! – smets.kevin Nov 18 '13 at 14:41
  • @smets.kevin What do you mean by you need to trigger it manually? I have an issue where even using the plugin my placeholders are still loading as "null" until I delete null out and then the correct placeholder appears when the input loses focus. I have tried using the jquery id to call the placeholder() function and still can not get it to work... – tjfo Mar 03 '14 at 20:23
  • 1
    Thanks, neat plugin, however one problem I have is with ie9 the placeholder disappears when the text input is on focus. This is different than HTML5 behavior – gerrytan Apr 08 '14 at 01:35
  • 1
    It works nice with one big 'but', $('input').val() returns the placeholder value when the input is empty. Because I'm working with AJAX framework, that placeholders are sent to server... – Danubian Sailor Apr 17 '14 at 07:58
  • I am using this plugin but it is giving me place holder value when I use jquery val() function, where as on site it says that I can use jquery.val funtion and I should not get the value of the placeholder. Can anyone enlighten this fact and let me know? – Ch Faizan Mustansar Dec 12 '14 at 07:10
  • If this one doesn't fit your needs, you can find several alternatives in the [Modernizr polyfill listing](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#web-forms--input-placeholder). – philzelnar Jul 23 '15 at 14:29
  • @DanglingPointer I think they fixed that, it works for me now wit the .val() too – Sajjan Sarkar Apr 20 '16 at 01:10
  • For @Philo and others ... This plugin is a tool not a an autorunner, therefore if you'd peaked into README, you would see you have to then use it in your own JS: `$('input, textarea').placeholder();` – jave.web Nov 01 '16 at 12:10
21

I think this is what you are looking for: jquery-html5-placeholder-fix

This solution uses feature detection (via modernizr) to determine if placeholder is supported. If not, adds support (via jQuery).

matt
  • 413
  • 5
  • 12
  • 2
    It works, but it's not the greatest code. At the top `$(this)` should be assigned to a variable which can be used throughout the code. Calling `$` for every expression that uses `$(this)` is a no-no straight out of "Don't Write jQuery Like This 101". – Sami Samhuri Nov 29 '11 at 01:10
  • 20
    You have to be careful with this code since if you submit the form, the placeholder value will be submitted as a form value. Should clear it before it gets submitted. – ericbae Feb 22 '12 at 05:26
  • Curious since I'm new to the HTML 5 features battle: Is it modernizer that causes this to be a bad solution or the jquery-html5-placeholder-fix itself (or both)? – Snekse Dec 07 '12 at 21:25
  • Updated link which fixes issues in above comments http://kamikazemusic.com/web-development/revisiting-html5-placeholder-fixes/ – Brent May 11 '15 at 18:02
  • Note requires Modernizer script with HTML Input features – Brent May 11 '15 at 18:18
17

If you want to do it without using jquery or modenizer you can use the code below:

(function(){

     "use strict";

     //shim for String's trim function..
     function trim(string){
         return string.trim ? string.trim() : string.replace(/^\s+|\s+$/g, "");
     }

     //returns whether the given element has the given class name..
     function hasClassName(element, className){ 
         //refactoring of Prototype's function..
         var elClassName = element.className;
         if(!elClassName)
             return false;
         var regex = new RegExp("(^|\\s)" + className + "(\\s|$)");
         return regex.test(element.className);
     }

     function removeClassName(element, className){
         //refactoring of Prototype's function..
         var elClassName = element.className;
         if(!elClassName)
             return;
         element.className = elClassName.replace(
             new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ');
     }

     function addClassName(element, className){
         var elClassName = element.className;
         if(elClassName)
             element.className += " " + className;
         else
             element.className = className;
     }

     //strings to make event attachment x-browser.. 
     var addEvent = document.addEventListener ?
            'addEventListener' : 'attachEvent';
     var eventPrefix = document.addEventListener ? '' : 'on';

     //the class which is added when the placeholder is being used..
     var placeHolderClassName = 'usingPlaceHolder';

     //allows the given textField to use it's placeholder attribute
     //as if it's functionality is supported natively..
     window.placeHolder = function(textField){

         //don't do anything if you get it for free..
         if('placeholder' in document.createElement('input'))
             return;

         //don't do anything if the place holder attribute is not
         //defined or is blank..
         var placeHolder = textField.getAttribute('placeholder');        
         if(!placeHolder)
             return;

         //if it's just the empty string do nothing..
         placeHolder = trim(placeHolder);
         if(placeHolder === '')
             return;

         //called on blur - sets the value to the place holder if it's empty..
         var onBlur = function(){
             if(textField.value !== '') //a space is a valid input..
                 return;
             textField.value = placeHolder;
             addClassName(textField, placeHolderClassName);
         };

         //the blur event..
         textField[addEvent](eventPrefix + 'blur', onBlur, false);

         //the focus event - removes the place holder if required..
         textField[addEvent](eventPrefix + 'focus', function(){
             if(hasClassName(textField, placeHolderClassName)){
                removeClassName(textField, placeHolderClassName);
                textField.value = "";
             }
         }, false);

         //the submit event on the form to which it's associated - if the
         //placeholder is attached set the value to be empty..
         var form = textField.form;
         if(form){
             form[addEvent](eventPrefix + 'submit', function(){
                 if(hasClassName(textField, placeHolderClassName))
                     textField.value = '';
            }, false);
         }

         onBlur(); //call the onBlur to set it initially..
    };

}());

For each text field you want to use it for you need to run placeHolder(HTMLInputElement), but I guess you can just change that to suit! Also, doing it this way, rather than just on load means that you can make it work for inputs which aren't in the DOM when the page loads.

Note, that this works by applying the class: usingPlaceHolder to the input element, so you can use this to style it (e.g. add the rule .usingPlaceHolder { color: #999; font-style: italic; } to make it look better).

Mark Rhodes
  • 10,049
  • 4
  • 48
  • 51
  • 1
    Sorry - I really don't know if that's easy to do - I guess you'd want to display the actual text value, rather than the "symbols". The only hack I can think of to do this would be to switch it for a text input unless it has focus or a value, otherwise display it as a password field. – Mark Rhodes Feb 04 '14 at 19:43
  • @StephenPatten Have a look at [my fix](http://stackoverflow.com/a/23618495/498624) for placeholders with password fields. I do exactly what Mark suggested :) – CatDadCode May 12 '14 at 21:21
8

Here is a much better solution. http://bavotasan.com/2011/html5-placeholder-jquery-fix/ I've adopted it a bit to work only with browsers under IE10

<!DOCTYPE html>
<!--[if lt IE 7]><html class="no-js lt-ie10 lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
<!--[if IE 7]><html class="no-js lt-ie10 lt-ie9 lt-ie8" lang="en"> <![endif]-->
<!--[if IE 8]><html class="no-js lt-ie10 lt-ie9" lang="en"> <![endif]-->
<!--[if IE 9]><html class="no-js lt-ie10" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--><html class="no-js" lang="en"><!--<![endif]-->

    <script>
    // Placeholder fix for IE
      $('.lt-ie10 [placeholder]').focus(function() {
        var i = $(this);
        if(i.val() == i.attr('placeholder')) {
          i.val('').removeClass('placeholder');
          if(i.hasClass('password')) {
            i.removeClass('password');
            this.type='password';
          }     
        }
      }).blur(function() {
        var i = $(this);  
        if(i.val() == '' || i.val() == i.attr('placeholder')) {
          if(this.type=='password') {
            i.addClass('password');
            this.type='text';
          }
          i.addClass('placeholder').val(i.attr('placeholder'));
        }
      }).blur().parents('form').submit(function() {
        //if($(this).validationEngine('validate')) { // If using validationEngine
          $(this).find('[placeholder]').each(function() {
            var i = $(this);
            if(i.val() == i.attr('placeholder'))
              i.val('');
              i.removeClass('placeholder');

          })
        //}
      });
    </script>
    ...
    </html>
  • doesn't work on IE8 since IE does not allow jQuery to manipulate input types (check out comment from Bill on December 20, 2011 at 1:48 pm on http://bavotasan.com/2011/html5-placeholder-jquery-fix/) – forste Nov 07 '12 at 20:45
  • also assumes you are submitting a form. Most Single page apps i've seen do not use forms. just click handlers. – chovy Apr 23 '13 at 21:12
5

If you want to input a description you can use this. This works on IE 9 and all other browsers.

<input type="text" onclick="if(this.value=='CVC2: '){this.value='';}" onblur="if(this.value==''){this.value='CVC2: ';}" value="CVC2: "/>
gdoron
  • 147,333
  • 58
  • 291
  • 367
Erdem KAYA
  • 67
  • 1
  • 1
  • 1
    Didn't test it myself, but guessing this doesn't work well if you tab to the field instead of click it. I see this bug in a lot of websites, or ones like it. – eselk Apr 10 '13 at 22:44
  • With this solution you also need to check for this value on form submit. – Igor Jerosimić Dec 29 '14 at 09:11
  • I am surprised this got any votes, this should not be used even when posted in 2012/2013 – LocalPCGuy Apr 14 '15 at 19:39
  • If you happen to write into the input what should be the placeholder ('CV2: ') what you typed will be deleted. – Daniel Nov 30 '15 at 09:59
2

Using mordernizr to detect browsers that are not supporting Placeholder, I created this short code to fix them.

//If placeholder is not supported
if (!Modernizr.input.placeholder){ 

    //Loops on inputs and place the placeholder attribute
    //in the textbox.
    $("input[type=text]").each( function() { 
       $(this).val($(this).attr('placeholder')); 
    })
}
Etienne Dupuis
  • 13,548
  • 6
  • 47
  • 58
  • 2
    You have to be careful with this code since if you submit the form, the placeholder value will be submitted as a form value. You should clear it before it gets submitted. – chriscatfr Oct 23 '15 at 19:27
  • 3
    @chriscatfr: How would one do that properly in this example? If my placeholder is 'Password' and my password actually is 'Password'? – Lain Apr 27 '16 at 09:20
  • You could use the concept of "dirty" for fields like this. Flag the field as clean upon entry (maybe use data-dirty="false"). If they submit the form without changing the placeholder text, you'll see that the field is clean, so clear it. If they did change it, even to the same value as the placeholder, then it's dirty and you do submit that value. – oooyaya May 04 '16 at 14:36
  • for the password and other solution please look at the https://jsfiddle.net/AlexanderPatel/1pv2174c/3/ – Shirish Patel May 20 '16 at 11:41
  • `placeholder` property was standardized as string => no need for Modernizr actually::::::::::::::::::::::::::::: `if( typeof $('').get(0).placeholder == "undefined" ){ ... }` is enaugh test for not-supporting, tested in IE9 mode emulation - works. – jave.web Nov 01 '16 at 12:30
  • Also, performance speaking, you should first select subset by fast selector, and filter that by attribute selector and possibly add textarea too: `$('input').filter('[type="text"]').add('textarea')` – jave.web Nov 01 '16 at 12:33
  • Lastly, what if an element does not have any placeholder? The final set should be filtered as `.filter('[placeholder]')` – jave.web Nov 01 '16 at 12:40
2

I know I'm late but I found a solution inserting in the head the tag:

<meta http-equiv="X-UA-Compatible" content="IE=edge"/> <!--FIX jQuery INTERNET EXPLORER-->
decadenza
  • 2,380
  • 3
  • 18
  • 31
  • Did you test this in IE9 ? Because otherwise IE10+ supports placeholder... – jave.web Nov 01 '16 at 12:12
  • Of course, it's just strange, that IE9 does not support it itself that a tag would turn it on - was it an experimental feature backthen? Is this referenced somewhere? :) – jave.web Nov 02 '16 at 12:47
1

to make it work in IE-9 use below .it works for me

JQuery need to include:

jQuery(function() {
   jQuery.support.placeholder = false;
   webkit_type = document.createElement('input');
   if('placeholder' in webkit_type) jQuery.support.placeholder = true;});
   $(function() {

     if(!$.support.placeholder) {

       var active = document.activeElement;

       $(':text, textarea, :password').focus(function () {

       if (($(this).attr('placeholder')) && ($(this).attr('placeholder').length > 0) &&         ($(this).attr('placeholder') != '') && $(this).val() == $(this).attr('placeholder')) {
          $(this).val('').removeClass('hasPlaceholder');
        }
      }).blur(function () {
if (($(this).attr('placeholder')) && ($(this).attr('placeholder').length > 0) &&  ($(this).attr('placeholder') != '') && ($(this).val() == '' || $(this).val() ==   $(this).attr('placeholder'))) {
     $(this).val($(this).attr('placeholder')).addClass('hasPlaceholder');
}
});

$(':text, textarea, :password').blur();
$(active).focus();
$('form').submit(function () {
     $(this).find('.hasPlaceholder').each(function() { $(this).val(''); });
});
}
});

CSS Style need to include:

.hasPlaceholder {color: #aaa;}
m1crdy
  • 1,371
  • 2
  • 25
  • 58
Suresh Gupta
  • 605
  • 7
  • 4
1

A bit late to the party but I use my tried and trusted JS that takes advantage of Modernizr. Can be copy/pasted and applied to any project. Works every time:

// Placeholder fallback
if(!Modernizr.input.placeholder){

    $('[placeholder]').focus(function() {
      var input = $(this);
      if (input.val() == input.attr('placeholder')) {
        input.val('');
        input.removeClass('placeholder');
      }
    }).blur(function() {
      var input = $(this);
      if (input.val() == '' || input.val() == input.attr('placeholder')) {
        input.addClass('placeholder');
        input.val(input.attr('placeholder'));
      }
    }).blur();
    $('[placeholder]').parents('form').submit(function() {
      $(this).find('[placeholder]').each(function() {
        var input = $(this);
        if (input.val() == input.attr('placeholder')) {
          input.val('');
        }
      })
    });

}
egr103
  • 3,858
  • 15
  • 68
  • 119
0

I usually think fairly highly of http://cdnjs.com/ and they are listing:

//cdnjs.cloudflare.com/ajax/libs/placeholder-shiv/0.2/placeholder-shiv.js

Not sure who's code that is but it looks straightforward:

document.observe('dom:loaded', function(){
  var _test = document.createElement('input');
  if( ! ('placeholder' in _test) ){
    //we are in the presence of a less-capable browser
    $$('*[placeholder]').each(function(elm){
      if($F(elm) == ''){
        var originalColor = elm.getStyle('color');
        var hint = elm.readAttribute('placeholder');
        elm.setStyle('color:gray').setValue(hint);
        elm.observe('focus',function(evt){
          if($F(this) == hint){
            this.clear().setStyle({color: originalColor});
          }
        });
        elm.observe('blur', function(evt){
          if($F(this) == ''){
            this.setValue(hint).setStyle('color:gray');
          }
        });
      }
    }).first().up('form').observe('submit', function(evt){
      evt.stop();
      this.select('*[placeholder]').each(function(elm){
        if($F(elm) == elm.readAttribute('placeholder')) elm.clear();
      });
      this.submit();
    });
  }
});
cwd
  • 53,018
  • 53
  • 161
  • 198
0

I searched on the internet and found a simple jquery code to handle this problem. In my side, it was solved and worked on ie 9.

$("input[placeholder]").each(function () {
        var $this = $(this);
        if($this.val() == ""){
            $this.val($this.attr("placeholder")).focus(function(){
                if($this.val() == $this.attr("placeholder")) {
                    $this.val("");
                }
            }).blur(function(){
                if($this.val() == "") {
                    $this.val($this.attr("placeholder"));
                }
            });
        }
    });
Günay Gültekin
  • 4,486
  • 8
  • 33
  • 36
  • 2
    your Placeholder becomes the value. If you submit they will be sent. With the placeholder.js of the correct answer, fields are kept empty – chriscatfr Oct 08 '14 at 07:48