How to select all "empty"

8

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

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

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

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

    
asked by anonymous 25.02.2014 / 19:29

6 answers

1

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

link

<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');
});
    
25.02.2014 / 20:17
4

Apparently, when using [value=""] it looks only at the attribute value , not the property value . That is, the value that was in the markup, not the current value. Example:

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

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

Looking at the selectors available by jQuery , I'm afraid there are none that meet your requirement. The reply from @Gustavo Rodrigues ( preserved by @bfavaretto ) would therefore be one of the only workarounds available (ie filter the results by the value property value).

    
25.02.2014 / 19:41
3

There is no selector for this.

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

$('input, select, textarea').filter(function () {
    return !this.value.trim();
});
    
25.02.2014 / 19:46
3
  

However, I would like to know if there is any special selector for empty controls only, which performs better than brute-force filtering.

Answer: No, it does not exist.

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

Using the selector:

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

You would receive 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 in the example, even without having the "value" attribute and being empty, is not returned as an object by the selector.

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

Solution example 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     
25.02.2014 / 19:45
2

For what you posted to work, the values should be explicitly set to value="" , and then you can select the elements input , select and textarea you want with the following expression:

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

EDIT

I made an improvement in the expression to also 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")
Unfortunately, it seems that these selectors can only see the original values printed in HTML, not the current values ... with the exception of the selector for select .

EDIT 2

You can, however, create your own selector, as described in the SOEN response code: link

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 use this:

  • for values beginning with "test": $('input:field-value(^teste)');
  • for values that contain "test": $('input:field-value(*teste)');
  • for values that end with "test": $('input:field-value($teste)');
  • for values that are not equal to "test": $('input:field-value(!teste)');
  • for values that are 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. =)

    
25.02.2014 / 19:50
1

In this fiddle we contemplate the collection of elements that do not have value yet it is only possible to get the initial state of the fields.

Basically

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

takes all input that does not have the value attribute filled, and

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

Gets all elements that have the empty% or empty% attribute. the join of the two in a form with the treatment to know if there is value and select empty would be:

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

But this does not resolve, because the first three selectors take fields whose initial state is empty, that is, if the user changes or fills them, those fields will still be selected by the query.

Particularly to solve the problem, I'd rather use the code in this fiddle that prevents a field that is populated from the server selected and at the same time, it is still limited to the textarea which by default comes without server value.

    
25.02.2014 / 19:40