0
for (var chkbox in jQuery("#dialog-message input[type='checkbox']")) {
    alert(chkbox.val() + " " + chkbox.is("checked"));
}

is not working; I get errors saying that val and is are undefined. I'd like to iterate over the check boxes inside the dialog-message element so I can see which ones are checked and execute some other code for the ones that are, but these errors are happening instead.

ekolis
  • 6,270
  • 12
  • 50
  • 101
  • The proper jQuery way is [`.each(...)`](https://api.jquery.com/each/). Inside the function, use `$(this)` to do something with the current element. –  Oct 03 '19 at 15:36
  • What is your end-goal? If you're trying to get only the checked inputs, you don't need to iterate over them - just use the [`:checked` selector](https://api.jquery.com/checked-selector/). – Tyler Roper Oct 03 '19 at 15:39
  • Possible duplicate of [jQuery to loop through elements with the same class](https://stackoverflow.com/questions/4735342/jquery-to-loop-through-elements-with-the-same-class) –  Oct 03 '19 at 15:40
  • For reference, using `of` instead of `in` and `$(chkbox)` instead of `chkbox` will fix your code. –  Oct 03 '19 at 15:49
  • This isn't a duplicate, the question Chris linked to doesn't concern how to use for...in/of loops. This question and selected answer adds useful info. – t1m0thy Oct 03 '19 at 16:02
  • @t1m0thy The duplicate answers the question, that's what counts. Using `for ... in` on a jQuery object won't work properly anyway; are you suggesting a duplicate has to address a wrong approach to solving the problem at hand? It sure doesn't. –  Oct 03 '19 at 16:09
  • Not if you read past the headline. The "duplicate" asks "how?" this asks "why doesn't this work?" This question invites additional information and discussion on another way of approaching the task. The other could be considered PART OF this question. Part of something cannot be considered a duplicate of the whole thing. – t1m0thy Oct 03 '19 at 18:56

3 Answers3

1

for...in does not behave as you're expecting.

In your case, chkbox is not the checkbox element; it is an integer representing the index of the item in the collection. Integers have neither a .value nor a .checked property, hence the undefined error.

Instead, use jQuery's .each():

$("#dialog-message input[type=checkbox]").each(function() {
  console.log(`${this.value} is checked: ${this.checked}`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dialog-message">
    <input type="checkbox" value="1" />
    <input type="checkbox" value="2" checked />
    <input type="checkbox" value="3" />
    <input type="checkbox" value="4" checked />
</div>

However, if your goal is to get a collection of only the checked (or unchecked) elements, you don't need to iterate through them; you can select them using the :checked selector (or :not(:checked) for unchecked):

$("#dialog-message input[type=checkbox]:checked").css("zoom", "2");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dialog-message">
    <input type="checkbox" value="1" />
    <input type="checkbox" value="2" checked />
    <input type="checkbox" value="3" />
    <input type="checkbox" value="4" checked />
</div>
Tyler Roper
  • 21,445
  • 6
  • 33
  • 56
0

Use the jQuery.each() function: https://api.jquery.com/jQuery.each/

jQuery.each(jQuery("#dialog-message input[type='checkbox']"), function(index, chkbox) {
  alert(chkbox.val() + " " + chkbox.is("checked"));
});
sorayadragon
  • 1,087
  • 7
  • 21
  • 1
    With your code, `chkbox` is an HTMLInputElement, not a jQuery object. –  Oct 03 '19 at 15:39
0

JQuery has .each()

https://api.jquery.com/jQuery.each/

$('div').each(function(idx){ console.log(idx, this) })

this being the current element. An advantage of using $.each here is arguably cleaner, more readable code and you also get the benefit of chaining.

However it is worth noting (although probably not relevant for your example) that a for loop will most likely perform (much)better when iterating over large collections of elements. For example you could write it like this;

let test = $('input'); 
for(let i = 0; i < test.length; i++){ 
    console.log(test[i].checked) 
}

Further, for...in will work but 1) chkbox will be the index of the checkbox in the collection and 2) unlike my first for... example where i will always be an integer index, for...in this will loop over all properties of the returned JQuery object. You can use hasOwnProperty(i) to filter out inherited properties like this;

test = $('input'); 
for(let i in test){ 
    if(!test.hasOwnProperty(i)) { 
        continue ; 
    } 
    console.log(test[i].checked) 
}
t1m0thy
  • 2,688
  • 3
  • 14
  • 14