Selecting empty text input using jQuery
Asked Answered
L

10

108

How do I identify empty textboxes using jQuery? I would like to do it using selectors if it is at all possible. Also, I must select on id since in the real code where I want to use this I don't want to select all text inputs.

In my following two code examples the first one accurately displays the value typed into the textbox "txt2" by the user. The second example identifies that there is an empty textbox, but if you fill it in it still regards it as empty. Why is this?

Can this be done using just selectors?

This code reports the value in textbox "txt2":

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(function() {
                $('#cmdSubmit').click(function() {
                    alert($('[id=txt2]').val());
                });             
            });
        </script>
    </head>
    <body>
        <form>
            <input type="text" name="txt1" id="txt1" value="123" /><br />
            <input type="text" name="txt2" id="txt2" value="" /><br />
            <input type="text" name="txt3" id="txt3" value="abc" /><br />
            <input type="submit" name="cmdSubmit" id='cmdSubmit' value="Send" /><br />
        </form>
    </body>
</html>

This code always reports textbox "txt2" as empty:

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(function() {
                $('#cmdSubmit').click(function() {
                    if($('[id^=txt][value=""]').length > 0) {
                        if (!confirm("Are you sure you want to submit empty fields?")) {
                            if (event.preventDefault) {
                                event.preventDefault();
                            } else {
                                event.returnValue = false;
                            }
                        }
                    }
                });             
            });
        </script>
    </head>
    <body>
        <form>
            <input type="text" name="txt1" id="txt1" value="123" /><br />
            <input type="text" name="txt2" id="txt2" value="" /><br />
            <input type="text" name="txt3" id="txt3" value="abc" /><br />
            <input type="submit" name="cmdSubmit" id='cmdSubmit' value="Send" /><br />
        </form>
    </body>
</html>
Lamella answered 19/8, 2009 at 11:47 Comment(3)
Does anyone know if '[value=]' ignores user input and only checks what's in the source?Lamella
Am I right that the :empty filter is made for this job? $('input[type=text]:empty').doStuff();Sharp
read the docs - docs.jquery.com/Selectors/empty. Empty is for elements that have no children, NOT no valueVarve
V
206

Another way

$('input:text').filter(function() { return $(this).val() == ""; });

or

$('input:text').filter(function() { return this.value == ""; });

or

// WARNING: if input element does not have the "value" attribute or this attribute was removed from DOM then such selector WILL NOT WORK! 
// For example input with type="file" and file does not selected.
// It's prefer to use "filter()" method.
// Thanks to @AaronLS
$('input:text[value=""]');

Working Demo

code from the demo

jQuery

 $(function() {

  $('#button').click(function() {

    var emptyTextBoxes = $('input:text').filter(function() { return this.value == ""; });
    var string = "The blank textbox ids are - \n";

    emptyTextBoxes.each(function() {
      string += "\n" + this.id;
    });
    alert(string);
  });

});
Varve answered 19/8, 2009 at 11:56 Comment(10)
For me: if($('[id^=txt]').filter(function() { return $(this).val() == ""; }).length > 0) { alert('WARNING'); }Lamella
What separates your last example from my second one? I need to select on id, since in the real code I won't look at all text inputs. My second example doesn't work with user input, but yours does.Lamella
Why does $('input:text[value=""]'); work, when $('[id^=txt][value=""]'); does not?Lamella
The working selector seems to be to do with :text in the selector - if you open the working demo and add /edit to the URL, you can play with the selector used. If you take off the :text, the selector no longer works correctly, even with $('input[value=""]'). Possibly a bug in the Sizzle selector engine, but I don't have time to investigate. By the way, I would suggest using an element tag in the selector, otherwise each element will be checked to see if there is a match for the attribute values.Varve
Thanks! It's as you say, and I have added my own answer with that information. Good tip about element tags as well.Lamella
Why are you guys making life so complicated? There is no need for this much code.Sharp
Nice answer! But you might also want to make sure the input element's value is literally null(blank spaces!). Make sure you trim out the blank spaces in that case. Something like this $('input:text').filter(function() { return $(this).val().trim() == ""; });St
Note that if the element is present but doesn't have a value attribute then [value=""] selector doesn't work since it doesn't find a value attribute. However the .filter technique does work in this scenario.Andrewandrewes
Can you write es6 with an arrow function here?Detect
@Detect if your target browsers support ECMAScript 6, yesVarve
F
26

You could also do it by defining your own selector:

$.extend($.expr[':'],{
    textboxEmpty: function(el){
        return $(el).val() === "";
    }
});

And then access them like this:

alert($(':text:textboxEmpty').length); //alerts the number of text boxes in your selection
Flop answered 19/8, 2009 at 12:9 Comment(1)
I'm a little concerned about the performance. But probably the easiest answer!Trygve
A
20
$(":text[value='']").doStuff();

?

By the way, your call of:

$('input[id=cmdSubmit]')...

can be greatly simplified and speeded up with:

$('#cmdSubmit')...
Allista answered 19/8, 2009 at 11:48 Comment(6)
I guess there's a closing square bracket missing. A common source of jQuery not working as expected, hard to spot :-/Hecate
Your first example is basically what my not working example does. I want to know if the user added text to the input field, your example does not do this.Lamella
I was hasty, your example seems to work, but it doesn't select on id, which I must do.Lamella
Doing "input[id=..]" is not the same as "#". # does not give you an array of objects.Treasonous
@Treasonous if you're using multiple elements on a page with the same ID, you're doing it wrongGlyn
@SeanKendle not really. But to each, their own.Treasonous
S
12

As mentioned in the top ranked post, the following works with the Sizzle engine.

$('input:text[value=""]');

In the comments, it was noted that removing the :text portion of the selector causes the selector to fail. I believe what's happening is that Sizzle actually relies on the browser's built in selector engine when possible. When :text is added to the selector, it becomes a non-standard CSS selector and thereby must needs be handled by Sizzle itself. This means that Sizzle checks the current value of the INPUT, instead of the "value" attribute specified in the source HTML.

So it's a clever way to check for empty text fields, but I think it relies on a behavior specific to the Sizzle engine (that of using the current value of the INPUT instead of the attribute defined in the source code). While Sizzle might return elements that match this selector, document.querySelectorAll will only return elements that have value="" in the HTML. Caveat emptor.

Scagliola answered 2/12, 2011 at 2:41 Comment(0)
H
6

$("input[type=text][value=]")

After trying a lots of version I found this the most logical.

Note that text is case-sensitive.

Highams answered 29/6, 2012 at 15:25 Comment(0)
E
4

There are a lot of answers here suggesting something like [value=""] but I don't think that actually works . . . or at least, the usage is not consistent. I'm trying to do something similar, selecting all inputs with ids beginning with a certain string that also have no entered value. I tried this:

$("input[id^='something'][value='']")

but it doesn't work. Nor does reversing them. See this fiddle. The only ways I found to correctly select all inputs with ids beginning with a string and without an entered value were

$("input[id^='something']").not("[value!='']")

and

$("input[id^='something']:not([value!=''])")

but obviously, the double negatives make that really confusing. Probably, Russ Cam's first answer (with a filtering function) is the most clear method.

Effervesce answered 20/11, 2012 at 20:56 Comment(0)
S
4

Building on @James Wiseman's answer, I am using this:

$.extend($.expr[':'],{
    blank: function(el){
        return $(el).val().match(/^\s*$/);
    }
});

This will catch inputs which contain only whitespace in addition to those which are 'truly' empty.

Example: http://jsfiddle.net/e9btdbyn/

Swedenborgianism answered 26/9, 2014 at 11:43 Comment(0)
P
3

I'd recommend:

$('input:text:not([value])')
Patriciapatrician answered 19/8, 2009 at 12:19 Comment(2)
This won't work, because [attribute] looks for the presence of an attribute - not whether it has a value or not. <input value=""> will still match.Petrick
This was helpful to me when using Laravel for generating form fields (e.g. {{Form::text('first_name', Input::old('first_name'), array('class' => 'form-control', 'required'))}}) because Laravel doesn't add a 'value' attribute if it's blank. So I then used: $('input:text:not([value]):visible:enabled:first'); to find the first visible empty enabled text input field.Deck
L
1

This will select empty text inputs with an id that starts with "txt":

$(':text[value=""][id^=txt]')
Lamella answered 19/8, 2009 at 12:57 Comment(0)
P
0

Since creating an JQuery object for every comparison is not efficient, just use:

$.expr[":"].blank = function(element) {
    return element.value == "";
};

Then you can do:

$(":input:blank")
Perennate answered 19/12, 2019 at 8:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.