How to select all "empty" elements

Asked

Viewed 2,374 times

9

Is there any way to select all the empty elements of a page?

For some reason that I cannot explain, the code below does not select the input without text on my page:

$("input[value=''], select[value=''], textarea[value='']");

I know I can get them all input's, select's and textarea'empty s with a loop, if I first get all the elements with something like $("input, select, textarea") and then check the return of the method val for each of them. However, I would like to know if there is a special selector only for empty controls, which has a better performance than raw force filtering.

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

6 answers

5

Apparently, when you use [value=""] he observes only the attribute value, not the property value. That is, the value that was in Markup, not the current value. Example:

<input type="text" />
<input type="text" value="" />

The first the selector will never catch. The second, always will (even if you edit and put a value on it).

Watching selectors available by jQuery, I’m afraid there aren’t any that satisfy your requirement. @Gustavo Rodrigues' reply (preserved by @bfavaretto) would therefore be one of the only workarounds available (i.e. filter results by property value value).

  • 2

    The same applies to textarea:empty. See fiddle

  • 1

    @utluiz Truth, because the sub-elements of the textarea are used to initialize your property value, but otherwise they are left intact. Only if someone explicitly assigns the attributes of inputs/select (via .attr) or explicitly manipulate the descendants of textarea is that the result would change.

4

However, I would like to know if there is a special selector only for empty controls, which has a better performance than raw force filtering.

Answer: No, there is no.

Even your alternative using value="" is not 100% satisfactory in filtering elements with empty value.

Using the selector:

$('input[value=""]') //...

You would receive from the following elements:

<input type="text">              <!-- não retornaria (mas deveria retornar) -->
<input type="text" value>        <!-- retornaria -->
<input type="text" value="">     <!-- retornaria -->
<input type="text" value="foo">  <!-- não retornaria -->

As you can see, the first item of the example, even without having the attribute "value" and being empty, is not returned as an object by the selector.

The best solution would still be to loop through all the elements you want to check using the jQuery function .val() for example, to filter the empty elements.


Sample solution, using loop:

var s = $('input');
s.each(function(){
    var t = $(this);
    if(t.val()){
        t.addClass('exclua-me');
    }
});
var vazios = s.not('.exclua-me'); //aqui você tem os inputs vazios
EXEMPLO NO FIDDLE
  • 1

    The fourth case should be "would not return", no?

  • @mgibsonbr Yes, I who ate fly, corrected.

  • The problem of this approach with [value...] is that it does not take the fields that have been cleared via js.

  • 1

    If I could vote twice, I would give one more vote, for the trouble of citing every possible case.

3

There is no selector for that.

To treat everything at once, I suggest the approach that @Gustavo Rodrigues had posted (but deleted):

$('input, select, textarea').filter(function () {
    return !this.value.trim();
});
  • The textarea:empty continue returning the element if it is edited after page loading. View fiddle

  • Okay, I ruled out the mention of :Empty

2

For what you posted to work, the values must be explicitly defined as value="", and then it will be possible to select the elements input, select and textarea you want with the following expression:

$("input[value=''], select:has(option[value='']:selected), textarea:empty")

EDIT

I also improved the expression to select those that do not have the value attribute:

$("input[value=''], input:not([value]), select:has(option[value='']:selected), select:has(option:not([value]):selected), textarea:empty")

Poxa, unfortunately, it seems that these selectors can only see the original values printed in HTML, and not the current values... with the exception of the selector for the select.

EDIT 2

You can, however, create your own selector, as described in the code of this SOEN response: https://stackoverflow.com/a/15031698/195417

jQuery.extend(
  jQuery.expr[':'],
  {
    /// check that a field's value property has a particular value
    'field-value': function (el, indx, args) {
      var a, v = $(el).val();
      if ( (a = args[3]) ) {
        switch ( a.charAt(0) ) {
          /// begins with
          case '^':
            return v.substring(0,a.length-1) == a.substring(1,a.length);
          break;
          /// ends with
          case '$':
            return v.substr(v.length-a.length-1,v.length) == 
              a.substring(1,a.length);
          break;
          /// contains
          case '*': return v.indexOf(a.substring(1,a.length)) != -1; break;
          /// equals
          case '=': return v == a.substring(1,a.length); break;
          /// not equals
          case '!': return v != a.substring(1,a.length); break;
          /// equals
          default: return v == a; break;
        }
      }
      else {
        return !!v;
      }
    }
  }
);

And then wear it like this:

  • for values starting with "test": $('input:field-value(^teste)');
  • for values containing "test": $('input:field-value(*teste)');
  • for values ending with "test": $('input:field-value($teste)');
  • for values that are not equal to "test": $('input:field-value(!teste)');
  • for values equal to "test": $('input:field-value(=teste)');

Do not forget to give an upvote there to the SOEN guy if you find this a good solution... the merit is not mine. =)

2


The simplest way is input:not([value]),input[value='']:

http://jsfiddle.net/4rB65/

<input type="text">
<input type="text" value>
<input type="text" value="">
<input type="text" value="foo">

$(function() {
    $('input:not([value]),input[value=""]').css('border', 'solid 1px red');
});

1

In this fiddle comtemplamos the collection of elements that have no value however it is only possible to obtain the initial state of the fields.

Basically

$('input:not([value])') 

takes all the input which do not have the attribute value completed, and

$('input[value=""]')

takes all elements that have the attribute value worthless or empty. the joining of the two in a form with the treatment to know if there is select and textarea would be empty:

$('form input:not([value]), input[value=""], textarea:empty, select:empty');

But only this does not solve, because the first three selectors take the fields whose initial state is empty, that is, if the user changes or fills - los, these fields will still be selected by the query.

Particularly to solve the problem, I prefer to use the code of this fiddle which prevents a field that is filled from the server from being selected and at the same time is still limited to input which by default comes with no server value.

  • You are using a loop, not a native selector.

  • 1

    I didn’t understand. I tested (putting a value in one of the fields and clicking on the button) and it appeared 2 empty fields. I did something wrong?

  • @Tiagocésaroliveira the selector is 'form input:not([value]), input[name=""], select:empty, textarea:empty' the loop is just to grab all the selected values and display them

  • 1

    @mgibsonbr really, after editing the values keep coming, so I adjusted my answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.