6

I'm trying to use the placeholder="xxx" attribute in my web application, and I don't want to have a special visual for IE9. Can people throw out some good suggestions for achieving this functionality in IE9?

I've found a couple links on here but none of the suggested scripts were sufficient... and the answers were from mid-2011, so I figured maybe there is a better solution out there. Perhaps with a widely-adopted jQuery plugin? I do not want to use anything that requires intrusive code such as requiring a certain css class or something.

Thanks.

EDIT - I also need this to work for password input fields.

// the below snippet should work, but isn't.
$(document).ready(function() {
   initPlaceholders()();
}

function initPlaceholders() {
        $.support.placeholder = false;
var test = document.createElement('input');
if ('placeholder' in test) {
    $.support.placeholder = true;
    return function() { }
} else {
    return function() {
        $(function() {
            var active = document.activeElement;
            $('form').delegate(':text, :password', 'focus', function() {
                var _placeholder = $(this).attr('placeholder'),
                    _val = $(this).val();
                if (_placeholder != '' && _val == _placeholder) {
                    $(this).val('').removeClass('hasPlaceholder');
                }
            }).delegate(':text, :password', 'blur', function() {
                var _placeholder = $(this).attr('placeholder'),
                    _val = $(this).val();
                if (_placeholder != '' && (_val == '' || _val == _placeholder)) {
                    $(this).val(_placeholder).addClass('hasPlaceholder');
                }
            }).submit(function() {
                $(this).find('.hasPlaceholder').each(function() { $(this).val(''); });
            });
            $(':text, :password').blur();
            $(active).focus();
        });
    }
}
}
Adam Levitt
  • 10,316
  • 26
  • 84
  • 145

3 Answers3

12

We just researched the same thing. We decided on reusing this gist, by Aaron McCall, after making some minor changes. The main advantage is that it's simple, easy to understand code:

  1. Remove the kernel and setup_placeholders parts. Just call it immediately in an anonymous function.

  2. Add var before test.

For browsers that support placeholder, it simply falls back to that. It also handles new input elements (note the use of delegate) in existing forms. But does not handle dynamic new form elements. It could probably be modified to do so with jQuery.on.

If you don't like this one, you can use one of the ones here. However, some of them are overcomplicated, or have questionable design decisions like setTimeout for detecting new elements.

Note that it needs to use two pairs of parens, since you're calling an anonymous function, then calling the returned function (this could be factored out differently):

(function () {
  // ...
})()();
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • Ah. Well, regardless, thanks for the link. There's no license specified; do you know if there is one? – Lusitanian Jul 03 '12 at 02:48
  • I actually just tried to do this, and nothing happened in IE9. I'm calling the suggested code starting with: $.support.placeholder = false;, but I don't see it picking up the placeholder attribute values.... and does this work for password fields? – Adam Levitt Jul 03 '12 at 02:48
  • @AdamLevitt, that snippet should clarify how it should be called. You can also refactor it to eliminate the "return a function" step. – Matthew Flaschen Jul 03 '12 at 02:52
  • 1
    @Adam, no, it will not work for password, but you can just add `, :password` after `:text`. – Matthew Flaschen Jul 03 '12 at 02:53
  • Hmm.. Matthew, thanks for the prompt and detailed assistance, but I'm still not 100% clear on how to call this, especially with the ()(). I created a function initPlaceholders() { $.support.placeholder = false; //... rest of function }... but calling it doesn't do anything. – Adam Levitt Jul 03 '12 at 02:54
  • Calling it should return a function, so it would be `initPlaceholders()()`. – Matthew Flaschen Jul 03 '12 at 02:57
  • Matt, I put my code in my original post. Maybe you could point out what I'm doing incorrectly? – Adam Levitt Jul 03 '12 at 03:00
  • @AdamLevitt, are you using text or password? Also, are there any errors? – Matthew Flaschen Jul 03 '12 at 03:02
  • I'm using password, actually, and no errors. Let me throw that :password part on there. Is there a special syntax for that? – Adam Levitt Jul 03 '12 at 03:03
  • Just replace `:text` with `:text, :password` across the whole function. – Matthew Flaschen Jul 03 '12 at 03:05
  • Ok, I did just this, but it's just not showing anything resembling a placeholder. It's not causing anything to break in firefox, but in IE9 it's showing blank boxes. – Adam Levitt Jul 03 '12 at 03:06
  • @Adam, you omitted two replacements in the function. – Matthew Flaschen Jul 03 '12 at 03:08
  • @Adam, there are two other places it says `:text`, but should say `:text, :password`. While you're at it, you may wish to use a variable for this. – Matthew Flaschen Jul 03 '12 at 03:12
  • @Matt - thanks again for the persistent help. I updated the original post with your suggested fixes, but it still displays nothing in the boxes. I'm starting to wonder if I have conflicting scripts, though I doubt it. – Adam Levitt Jul 03 '12 at 03:15
  • @Adam, are you sure the form exists at `ready` time? Other than that, I'll have to test in IE 9 tomorrow. Oh, and it's *in* a form, right? – Matthew Flaschen Jul 03 '12 at 03:17
  • 2
    For this to work on password-fields they would need to be changed to text-fields (which isn't allowed in some versions of IE (in which case you'll have to create a temporary text-field next to the password field)). Otherwise it would just display **** instead of the placeholder text. – powerbuoy Jul 03 '12 at 03:25
  • @powerbuoy, that makes sense, though I still don't know why it doesn't show stars for Adam (perhaps because of the refresh issue mentioned in [jQuery-Placeholder](https://github.com/danielstocks/jQuery-Placeholder/blob/master/jquery.placeholder.js)). I searched some more and I found a totally [different implementation](http://stackoverflow.com/a/6286267/47773) along those lines (temporary field). Sorry for the inconvenience. – Matthew Flaschen Jul 03 '12 at 03:35
  • The jquery `delegate()` function used in that gist has been superseded by `on()` as of jQuery 1.7. The syntax is only slightly different, just switch the positions of the selector and event arguments http://api.jquery.com/delegate/ – Ciaran Phillips Jan 07 '14 at 10:07
  • 1
    [This plugin by Mathias Bynens](https://github.com/mathiasbynens/jquery-placeholder) works flawlessly without any tweaking or modifications. – Sparky Mar 09 '14 at 21:40
8

I wrote a jquery plugin a while back that adds the placeholder support to any browser that does not support it and does nothing in those that do.

Placeholder Plugin

corymathews
  • 12,289
  • 14
  • 57
  • 77
2

Here's a jQuery plugin that works with password fields as well. It's not as tiny as the code suggested by Matthew but it has a few more fixes in it. I've used this successfully together with H5Validate as well.

http://webcloud.se/code/jQuery-Placeholder/

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
powerbuoy
  • 12,460
  • 7
  • 48
  • 78
  • This one works, but does not work on the password fields. Anyone have a solution for that? – Adam Levitt Jul 03 '12 at 23:09
  • Hmm, it _does_ work on password fields. You can see the relevant code starting from line 10 here: https://github.com/danielstocks/jQuery-Placeholder/blob/master/jquery.placeholder.js – powerbuoy Jul 03 '12 at 23:17
  • It's just strange because it's not actually behaving on the password fields. I did look at the code and see what you are pointing out. Hmm.... – Adam Levitt Jul 03 '12 at 23:26
  • That's very odd. Can you use a DOM inspector to see what's going on? (placeholder set, type-attribute changes or dummy text-field is inserted etc?) – powerbuoy Jul 03 '12 at 23:44