Jesse Webb
Jesse Webb

Reputation: 45263

jQuery selector to count number of empty text-boxes doesn't work in IE9 / IE8

I have a form with many text-boxes for user input, all of which have placeholder attributes set on them. It is required that the user fills out all of the text inputs which have a certain pattern of name attribute value. On form submit, we are using a a jQuery selector to find/count all of the empty inputs (those which have an empty value attribute) so that we can highlight these input elements for the user to fill out. Unfortunately, I have found that Internet Explorer 8 & 9 (and probably earlier) consider placeholder values to be a value.

HTML:

<input name="tb1" type="text" placeholder="foo" />
<input name="tb2" type="text" placeholder="bar" />
<input name="tb3" type="text" placeholder="baz" />
<button id="b1" type="button">Count Empty Text-boxes</button>

JavaScript:

$('#b1').click(function () {
    var emptyTextboxes = $('input[name^="tb"][value=""]:visible');
    alert('Num empty text-boxes: ' + emptyTextboxes.length);
});

JSFiddle: http://jsfiddle.net/r6jC7/1/

In Firefox, Chrome, & IE10+ the JS will only count the text-boxes which have had text typed into them, regardless of their placeholder values. In IE9 and below, you will always see the message "Num empty text-boxes: 0", because the browser seems to be counting the placeholders.

My Question:

Is there a way I can update/change my jQuery selector in a way which IE8 and IE9 will behave similarly to modern browsers?

jQuery version: 1.7.2

Upvotes: 1

Views: 866

Answers (2)

Ry-
Ry-

Reputation: 225095

The value attribute is one inconsistency between jQuery and what really happens in the browser. You’re exposing it because :visible forces the selector into “jQuery mode”.

You can select based on what’s really in the HTML (:not([value])) and filter afterwards, relying on jQuery’s optimization:

var emptyTextboxes = $('input[name^="tb"]:not([value])').filter(':visible');

Demo. That feels a bit fragile, though. How about:

var emptyTextboxes = $('input[name^=tb]').filter(':visible').filter(function() {
    return !this.value;
});

That’ll work for both <input> and <input value="">.

Upvotes: 1

ArrayKnight
ArrayKnight

Reputation: 7356

Unfortunately, I don't believe there is direct selector which will be able to accomplish this. However, using jQuery's filtering functionality should provide the desired result set.

$('#b1').click(function () {
    var emptyTextboxes = $('input[name^="tb"]:visible');

    emptyTextboxes = emptyTextboxes.filter(function(index, el){ 
        return el.value == '' || el.value == el.getAttribute('placeholder');
    });

    alert('Num empty text-boxes: ' + emptyTextboxes.length);
});

Upvotes: 1

Related Questions