Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I do forEach on a selection box's options?

Tags:

javascript

Here is some output from the console that illustrates my question

var a=document.createElement("select"); <ENTER>
undefined

a.appendChild(document.createElement("option"));  <ENTER>
<option>​</option>​

a
<select>​…​</select>​

a.options
[<option>​</option>​]

a.options[0];
<option>​</option>​

So far, so good. But now

I type a.options. and I am to type forEach but I notice forEach isn't getting listed.

 a.options.forEach(function() {});
VM1048:2 Uncaught TypeError: a.options.forEach is not a function
    at <anonymous>:2:11
    at Object.InjectedScript._evaluateOn (<anonymous>:905:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:838:34)
    at Object.InjectedScript.evaluate (<anonymous>:694:21)

Yet a.options so looked like an array

And forEach definitely works for arrays, no error.

a=[1,2];
[1, 2]
typeof a
"object"
a.forEach(function(){});
undefined

I guess the options of a selection box maybe aren't an array.. so what are they?

I've heard of the 'arguments' pseudo-array.. I guess perhaps a selection box's 'options' is like that? / some object that has similar syntax to array?

like image 994
barlop Avatar asked Aug 10 '15 00:08

barlop


2 Answers

Because options is not an Array; it is an HTMLCollection. As such it does not have a forEach function-member.

The HTMLCollection interface represents a generic collection (array-like object) of elements (in document order) and offers methods and properties for selecting from the list.

One could use call with Array.prototype.forEach, since an HTMLCollection is array-like1:

Array.prototype.forEach.call(options, function ..)

1 The HTMLCollection interface has a length property and allows positional access via the indexer.

like image 183
user2864740 Avatar answered Oct 18 '22 07:10

user2864740


The answer given by user2864740 is excellent.

I will give an example of how to get access to options based on the provided solution and display text content of all of them in the console:

var select = $('#selector_here');
Array.prototype.forEach.call(select.options, function(option, index) {
  console.log('option ' + (index + 1) + ':', option.textContent);
  /* do some required magic here */
});
like image 2
Mario Boss Avatar answered Oct 18 '22 09:10

Mario Boss