Trouble with JavaScript collection of document elements











up vote
1
down vote

favorite












I'm not sure if I'm on the wrong course altogether, or just missing a minor bit. I have a page that has sections, subsections, and subsubsections. The latter are elements that all share a common formatting:



<select id="SubSubFlood"  class='hidden'>
<option></option>
</select>
<select id="SubSubHome" class='hidden'>
<option></option>
</select>


I can't name each one explicitly because they're dynamically generated, but they all start with "SubSub". I'm trying to create code that will change all of the SubSubs to class='hidden', then change the one I want to be visible to class='unhidden'. Here is my attempt:



function ShowSubSub(SelectID) {
var SubSub = document.getElementsByTagName("Select");
var item;
for (item in SubSub) {
if (item.ID.match(/SubSub.*/)) {
item.className = 'hidden';
}
}
item = document.getElementById(SelectID);
item.className = 'unhidden';
}


Where am I missing the boat? How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?










share|improve this question


















  • 1




    Can't use for ... in loop on an HTMLCollection. You'll need to use a traditional for loop. Alternatively, if you use document.querySelectorAll('select') you will get a NodeList and can then use forEach.
    – Randy Casburn
    Nov 21 at 15:03










  • @RandyCasburn for...in is for iterating over object properties, not for arrays - for those it is for ... of and that is safe on anything that is iterable (including NodeList and HTMLCollection).
    – connexo
    Nov 21 at 15:17












  • item.ID I assume will always return undefined. Maybe you meant item.id?
    – connexo
    Nov 21 at 15:22















up vote
1
down vote

favorite












I'm not sure if I'm on the wrong course altogether, or just missing a minor bit. I have a page that has sections, subsections, and subsubsections. The latter are elements that all share a common formatting:



<select id="SubSubFlood"  class='hidden'>
<option></option>
</select>
<select id="SubSubHome" class='hidden'>
<option></option>
</select>


I can't name each one explicitly because they're dynamically generated, but they all start with "SubSub". I'm trying to create code that will change all of the SubSubs to class='hidden', then change the one I want to be visible to class='unhidden'. Here is my attempt:



function ShowSubSub(SelectID) {
var SubSub = document.getElementsByTagName("Select");
var item;
for (item in SubSub) {
if (item.ID.match(/SubSub.*/)) {
item.className = 'hidden';
}
}
item = document.getElementById(SelectID);
item.className = 'unhidden';
}


Where am I missing the boat? How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?










share|improve this question


















  • 1




    Can't use for ... in loop on an HTMLCollection. You'll need to use a traditional for loop. Alternatively, if you use document.querySelectorAll('select') you will get a NodeList and can then use forEach.
    – Randy Casburn
    Nov 21 at 15:03










  • @RandyCasburn for...in is for iterating over object properties, not for arrays - for those it is for ... of and that is safe on anything that is iterable (including NodeList and HTMLCollection).
    – connexo
    Nov 21 at 15:17












  • item.ID I assume will always return undefined. Maybe you meant item.id?
    – connexo
    Nov 21 at 15:22













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I'm not sure if I'm on the wrong course altogether, or just missing a minor bit. I have a page that has sections, subsections, and subsubsections. The latter are elements that all share a common formatting:



<select id="SubSubFlood"  class='hidden'>
<option></option>
</select>
<select id="SubSubHome" class='hidden'>
<option></option>
</select>


I can't name each one explicitly because they're dynamically generated, but they all start with "SubSub". I'm trying to create code that will change all of the SubSubs to class='hidden', then change the one I want to be visible to class='unhidden'. Here is my attempt:



function ShowSubSub(SelectID) {
var SubSub = document.getElementsByTagName("Select");
var item;
for (item in SubSub) {
if (item.ID.match(/SubSub.*/)) {
item.className = 'hidden';
}
}
item = document.getElementById(SelectID);
item.className = 'unhidden';
}


Where am I missing the boat? How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?










share|improve this question













I'm not sure if I'm on the wrong course altogether, or just missing a minor bit. I have a page that has sections, subsections, and subsubsections. The latter are elements that all share a common formatting:



<select id="SubSubFlood"  class='hidden'>
<option></option>
</select>
<select id="SubSubHome" class='hidden'>
<option></option>
</select>


I can't name each one explicitly because they're dynamically generated, but they all start with "SubSub". I'm trying to create code that will change all of the SubSubs to class='hidden', then change the one I want to be visible to class='unhidden'. Here is my attempt:



function ShowSubSub(SelectID) {
var SubSub = document.getElementsByTagName("Select");
var item;
for (item in SubSub) {
if (item.ID.match(/SubSub.*/)) {
item.className = 'hidden';
}
}
item = document.getElementById(SelectID);
item.className = 'unhidden';
}


Where am I missing the boat? How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?







javascript regex for-loop getelementsbytagname






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 at 14:56









Bob Cooper

163




163








  • 1




    Can't use for ... in loop on an HTMLCollection. You'll need to use a traditional for loop. Alternatively, if you use document.querySelectorAll('select') you will get a NodeList and can then use forEach.
    – Randy Casburn
    Nov 21 at 15:03










  • @RandyCasburn for...in is for iterating over object properties, not for arrays - for those it is for ... of and that is safe on anything that is iterable (including NodeList and HTMLCollection).
    – connexo
    Nov 21 at 15:17












  • item.ID I assume will always return undefined. Maybe you meant item.id?
    – connexo
    Nov 21 at 15:22














  • 1




    Can't use for ... in loop on an HTMLCollection. You'll need to use a traditional for loop. Alternatively, if you use document.querySelectorAll('select') you will get a NodeList and can then use forEach.
    – Randy Casburn
    Nov 21 at 15:03










  • @RandyCasburn for...in is for iterating over object properties, not for arrays - for those it is for ... of and that is safe on anything that is iterable (including NodeList and HTMLCollection).
    – connexo
    Nov 21 at 15:17












  • item.ID I assume will always return undefined. Maybe you meant item.id?
    – connexo
    Nov 21 at 15:22








1




1




Can't use for ... in loop on an HTMLCollection. You'll need to use a traditional for loop. Alternatively, if you use document.querySelectorAll('select') you will get a NodeList and can then use forEach.
– Randy Casburn
Nov 21 at 15:03




Can't use for ... in loop on an HTMLCollection. You'll need to use a traditional for loop. Alternatively, if you use document.querySelectorAll('select') you will get a NodeList and can then use forEach.
– Randy Casburn
Nov 21 at 15:03












@RandyCasburn for...in is for iterating over object properties, not for arrays - for those it is for ... of and that is safe on anything that is iterable (including NodeList and HTMLCollection).
– connexo
Nov 21 at 15:17






@RandyCasburn for...in is for iterating over object properties, not for arrays - for those it is for ... of and that is safe on anything that is iterable (including NodeList and HTMLCollection).
– connexo
Nov 21 at 15:17














item.ID I assume will always return undefined. Maybe you meant item.id?
– connexo
Nov 21 at 15:22




item.ID I assume will always return undefined. Maybe you meant item.id?
– connexo
Nov 21 at 15:22












3 Answers
3






active

oldest

votes

















up vote
5
down vote













SubSub will contain an array like object, so when you put it in a for each loop, you'll be enumerating it's properties, not the elements themselves. So item in the loop will not be the first select, it'll be 0. I suggest changing it to a normal for loop






function ShowSubSub(SelectID) {
var SubSub = document.getElementsByTagName("Select");
var item;
for (var i =0; i < SubSub.length; i++) {
if (SubSub[i].id.match(/SubSub.*/)) {
SubSub[i].className = 'hidden';
}
}
item = document.getElementById(SelectID);
item.className = 'unhidden';
}

ShowSubSub('SubSubHome')

.hidden{

display:none;
}

<select id="SubSubFlood" class='hidden'>
<option>Flood</option>
</select>
<select id="SubSubHome" class='hidden'>
<option>Home</option>
</select>





P.S. is there any reason for having an unhidden class, can't you just remove the hidden class?






share|improve this answer





















  • Exactly what I needed. Tested it out, and it did just what I needed it to.
    – Bob Cooper
    Nov 21 at 19:49


















up vote
2
down vote













This replies to the question:




How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?




[...document.querySelectorAll('[id^="SubSub"]')].forEach(section => section.className.add('hidden'))


will achieve just that.



So let's break that up:





  1. First of all use an attribute selector that matches all elements that have an id value starting with SubSub: [id^="SubSub"].



    Query the document for all of these: document.querySelectorAll('[id^="SubSub"]')




  2. Spread the NodeList you get to into an array using ... (spread operator):



    [...document.querySelectorAll('[id^="SubSub"]')]


    Alternatively, you could also use Array.from(iterable):



    Array.from(document.querySelectorAll('[id^="SubSub"]'))



  3. so it's cross-browser safe to use forEach on the result:



    [...document.querySelectorAll('[id^="SubSub"]')].forEach((section) => {})



  4. In that loop, simply add the classname to the classList:



    section.className.add('hidden')







share|improve this answer























  • If Nodelist.forEach not supported in the browser highly unlikely spread operator is
    – charlietfl
    Nov 21 at 15:05












  • I guess because it's hard to read and because it has no explanation whatsoever
    – Oram
    Nov 21 at 15:05






  • 1




    This solution just hides all elements by settings their class to "hidden". But the question also says, a single one should get a unhidden class.
    – David
    Nov 21 at 15:07






  • 1




    Guys, where does the answer mention it is only meant to replace parts of the code?
    – David
    Nov 21 at 15:11






  • 1




    I rather doubt OP is transpiling with babel
    – charlietfl
    Nov 21 at 15:15




















up vote
0
down vote













The problem is that getElementsByTagName returns HTMLCollection which "not work" with for-in, instead use



for (let i =0; i<SubSub.length; i++) {
let item = SubSub[i];
if (item.id.match(/SubSub.*/)) {
item.className = 'hidden';
}
}





function ShowSubSub(SelectID) {
var SubSub = document.getElementsByTagName("Select");
console.log(SubSub);
for (let i =0; i<SubSub.length; i++) {
let item = SubSub[i];
if (item.id.match(/SubSub.*/)) {
item.className = 'hidden';
}
}
item = document.getElementById(SelectID);
console.log(item);
item.className = 'unhidden';
}

ShowSubSub('SubSubHome');

.hidden {
background: red;
}

.unhidden {
background: blue;
}

<select id="SubSubFlood" >
<option></option>
</select>
<select id="SubSubHome" >
<option></option>
</select>





I also develop a little improvement to connexo solution:



function ShowSubSub(SelectID) 
{
[...document.querySelectorAll('[id^="SubSub"]')].map(s =>
s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
)
}

ShowSubSub('SubSubHome');





   function ShowSubSub(SelectID) 
{
[...document.querySelectorAll('[id^="SubSub"]')].map(s =>
s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
)
}

ShowSubSub('SubSubHome');

.hidden {
background: red;
}

.unhidden {
background: blue;
}

<select id="SubSubFlood" >
<option></option>
</select>
<select id="SubSubHome" >
<option></option>
</select>








share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414757%2ftrouble-with-javascript-collection-of-document-elements%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    5
    down vote













    SubSub will contain an array like object, so when you put it in a for each loop, you'll be enumerating it's properties, not the elements themselves. So item in the loop will not be the first select, it'll be 0. I suggest changing it to a normal for loop






    function ShowSubSub(SelectID) {
    var SubSub = document.getElementsByTagName("Select");
    var item;
    for (var i =0; i < SubSub.length; i++) {
    if (SubSub[i].id.match(/SubSub.*/)) {
    SubSub[i].className = 'hidden';
    }
    }
    item = document.getElementById(SelectID);
    item.className = 'unhidden';
    }

    ShowSubSub('SubSubHome')

    .hidden{

    display:none;
    }

    <select id="SubSubFlood" class='hidden'>
    <option>Flood</option>
    </select>
    <select id="SubSubHome" class='hidden'>
    <option>Home</option>
    </select>





    P.S. is there any reason for having an unhidden class, can't you just remove the hidden class?






    share|improve this answer





















    • Exactly what I needed. Tested it out, and it did just what I needed it to.
      – Bob Cooper
      Nov 21 at 19:49















    up vote
    5
    down vote













    SubSub will contain an array like object, so when you put it in a for each loop, you'll be enumerating it's properties, not the elements themselves. So item in the loop will not be the first select, it'll be 0. I suggest changing it to a normal for loop






    function ShowSubSub(SelectID) {
    var SubSub = document.getElementsByTagName("Select");
    var item;
    for (var i =0; i < SubSub.length; i++) {
    if (SubSub[i].id.match(/SubSub.*/)) {
    SubSub[i].className = 'hidden';
    }
    }
    item = document.getElementById(SelectID);
    item.className = 'unhidden';
    }

    ShowSubSub('SubSubHome')

    .hidden{

    display:none;
    }

    <select id="SubSubFlood" class='hidden'>
    <option>Flood</option>
    </select>
    <select id="SubSubHome" class='hidden'>
    <option>Home</option>
    </select>





    P.S. is there any reason for having an unhidden class, can't you just remove the hidden class?






    share|improve this answer





















    • Exactly what I needed. Tested it out, and it did just what I needed it to.
      – Bob Cooper
      Nov 21 at 19:49













    up vote
    5
    down vote










    up vote
    5
    down vote









    SubSub will contain an array like object, so when you put it in a for each loop, you'll be enumerating it's properties, not the elements themselves. So item in the loop will not be the first select, it'll be 0. I suggest changing it to a normal for loop






    function ShowSubSub(SelectID) {
    var SubSub = document.getElementsByTagName("Select");
    var item;
    for (var i =0; i < SubSub.length; i++) {
    if (SubSub[i].id.match(/SubSub.*/)) {
    SubSub[i].className = 'hidden';
    }
    }
    item = document.getElementById(SelectID);
    item.className = 'unhidden';
    }

    ShowSubSub('SubSubHome')

    .hidden{

    display:none;
    }

    <select id="SubSubFlood" class='hidden'>
    <option>Flood</option>
    </select>
    <select id="SubSubHome" class='hidden'>
    <option>Home</option>
    </select>





    P.S. is there any reason for having an unhidden class, can't you just remove the hidden class?






    share|improve this answer












    SubSub will contain an array like object, so when you put it in a for each loop, you'll be enumerating it's properties, not the elements themselves. So item in the loop will not be the first select, it'll be 0. I suggest changing it to a normal for loop






    function ShowSubSub(SelectID) {
    var SubSub = document.getElementsByTagName("Select");
    var item;
    for (var i =0; i < SubSub.length; i++) {
    if (SubSub[i].id.match(/SubSub.*/)) {
    SubSub[i].className = 'hidden';
    }
    }
    item = document.getElementById(SelectID);
    item.className = 'unhidden';
    }

    ShowSubSub('SubSubHome')

    .hidden{

    display:none;
    }

    <select id="SubSubFlood" class='hidden'>
    <option>Flood</option>
    </select>
    <select id="SubSubHome" class='hidden'>
    <option>Home</option>
    </select>





    P.S. is there any reason for having an unhidden class, can't you just remove the hidden class?






    function ShowSubSub(SelectID) {
    var SubSub = document.getElementsByTagName("Select");
    var item;
    for (var i =0; i < SubSub.length; i++) {
    if (SubSub[i].id.match(/SubSub.*/)) {
    SubSub[i].className = 'hidden';
    }
    }
    item = document.getElementById(SelectID);
    item.className = 'unhidden';
    }

    ShowSubSub('SubSubHome')

    .hidden{

    display:none;
    }

    <select id="SubSubFlood" class='hidden'>
    <option>Flood</option>
    </select>
    <select id="SubSubHome" class='hidden'>
    <option>Home</option>
    </select>





    function ShowSubSub(SelectID) {
    var SubSub = document.getElementsByTagName("Select");
    var item;
    for (var i =0; i < SubSub.length; i++) {
    if (SubSub[i].id.match(/SubSub.*/)) {
    SubSub[i].className = 'hidden';
    }
    }
    item = document.getElementById(SelectID);
    item.className = 'unhidden';
    }

    ShowSubSub('SubSubHome')

    .hidden{

    display:none;
    }

    <select id="SubSubFlood" class='hidden'>
    <option>Flood</option>
    </select>
    <select id="SubSubHome" class='hidden'>
    <option>Home</option>
    </select>






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 21 at 15:03









    George

    4,34311731




    4,34311731












    • Exactly what I needed. Tested it out, and it did just what I needed it to.
      – Bob Cooper
      Nov 21 at 19:49


















    • Exactly what I needed. Tested it out, and it did just what I needed it to.
      – Bob Cooper
      Nov 21 at 19:49
















    Exactly what I needed. Tested it out, and it did just what I needed it to.
    – Bob Cooper
    Nov 21 at 19:49




    Exactly what I needed. Tested it out, and it did just what I needed it to.
    – Bob Cooper
    Nov 21 at 19:49












    up vote
    2
    down vote













    This replies to the question:




    How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?




    [...document.querySelectorAll('[id^="SubSub"]')].forEach(section => section.className.add('hidden'))


    will achieve just that.



    So let's break that up:





    1. First of all use an attribute selector that matches all elements that have an id value starting with SubSub: [id^="SubSub"].



      Query the document for all of these: document.querySelectorAll('[id^="SubSub"]')




    2. Spread the NodeList you get to into an array using ... (spread operator):



      [...document.querySelectorAll('[id^="SubSub"]')]


      Alternatively, you could also use Array.from(iterable):



      Array.from(document.querySelectorAll('[id^="SubSub"]'))



    3. so it's cross-browser safe to use forEach on the result:



      [...document.querySelectorAll('[id^="SubSub"]')].forEach((section) => {})



    4. In that loop, simply add the classname to the classList:



      section.className.add('hidden')







    share|improve this answer























    • If Nodelist.forEach not supported in the browser highly unlikely spread operator is
      – charlietfl
      Nov 21 at 15:05












    • I guess because it's hard to read and because it has no explanation whatsoever
      – Oram
      Nov 21 at 15:05






    • 1




      This solution just hides all elements by settings their class to "hidden". But the question also says, a single one should get a unhidden class.
      – David
      Nov 21 at 15:07






    • 1




      Guys, where does the answer mention it is only meant to replace parts of the code?
      – David
      Nov 21 at 15:11






    • 1




      I rather doubt OP is transpiling with babel
      – charlietfl
      Nov 21 at 15:15

















    up vote
    2
    down vote













    This replies to the question:




    How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?




    [...document.querySelectorAll('[id^="SubSub"]')].forEach(section => section.className.add('hidden'))


    will achieve just that.



    So let's break that up:





    1. First of all use an attribute selector that matches all elements that have an id value starting with SubSub: [id^="SubSub"].



      Query the document for all of these: document.querySelectorAll('[id^="SubSub"]')




    2. Spread the NodeList you get to into an array using ... (spread operator):



      [...document.querySelectorAll('[id^="SubSub"]')]


      Alternatively, you could also use Array.from(iterable):



      Array.from(document.querySelectorAll('[id^="SubSub"]'))



    3. so it's cross-browser safe to use forEach on the result:



      [...document.querySelectorAll('[id^="SubSub"]')].forEach((section) => {})



    4. In that loop, simply add the classname to the classList:



      section.className.add('hidden')







    share|improve this answer























    • If Nodelist.forEach not supported in the browser highly unlikely spread operator is
      – charlietfl
      Nov 21 at 15:05












    • I guess because it's hard to read and because it has no explanation whatsoever
      – Oram
      Nov 21 at 15:05






    • 1




      This solution just hides all elements by settings their class to "hidden". But the question also says, a single one should get a unhidden class.
      – David
      Nov 21 at 15:07






    • 1




      Guys, where does the answer mention it is only meant to replace parts of the code?
      – David
      Nov 21 at 15:11






    • 1




      I rather doubt OP is transpiling with babel
      – charlietfl
      Nov 21 at 15:15















    up vote
    2
    down vote










    up vote
    2
    down vote









    This replies to the question:




    How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?




    [...document.querySelectorAll('[id^="SubSub"]')].forEach(section => section.className.add('hidden'))


    will achieve just that.



    So let's break that up:





    1. First of all use an attribute selector that matches all elements that have an id value starting with SubSub: [id^="SubSub"].



      Query the document for all of these: document.querySelectorAll('[id^="SubSub"]')




    2. Spread the NodeList you get to into an array using ... (spread operator):



      [...document.querySelectorAll('[id^="SubSub"]')]


      Alternatively, you could also use Array.from(iterable):



      Array.from(document.querySelectorAll('[id^="SubSub"]'))



    3. so it's cross-browser safe to use forEach on the result:



      [...document.querySelectorAll('[id^="SubSub"]')].forEach((section) => {})



    4. In that loop, simply add the classname to the classList:



      section.className.add('hidden')







    share|improve this answer














    This replies to the question:




    How do I get JavaScript to change every tag with an ID that starts with "SubSub" to class="hidden"?




    [...document.querySelectorAll('[id^="SubSub"]')].forEach(section => section.className.add('hidden'))


    will achieve just that.



    So let's break that up:





    1. First of all use an attribute selector that matches all elements that have an id value starting with SubSub: [id^="SubSub"].



      Query the document for all of these: document.querySelectorAll('[id^="SubSub"]')




    2. Spread the NodeList you get to into an array using ... (spread operator):



      [...document.querySelectorAll('[id^="SubSub"]')]


      Alternatively, you could also use Array.from(iterable):



      Array.from(document.querySelectorAll('[id^="SubSub"]'))



    3. so it's cross-browser safe to use forEach on the result:



      [...document.querySelectorAll('[id^="SubSub"]')].forEach((section) => {})



    4. In that loop, simply add the classname to the classList:



      section.className.add('hidden')








    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 21 at 15:24

























    answered Nov 21 at 15:03









    connexo

    19.7k73353




    19.7k73353












    • If Nodelist.forEach not supported in the browser highly unlikely spread operator is
      – charlietfl
      Nov 21 at 15:05












    • I guess because it's hard to read and because it has no explanation whatsoever
      – Oram
      Nov 21 at 15:05






    • 1




      This solution just hides all elements by settings their class to "hidden". But the question also says, a single one should get a unhidden class.
      – David
      Nov 21 at 15:07






    • 1




      Guys, where does the answer mention it is only meant to replace parts of the code?
      – David
      Nov 21 at 15:11






    • 1




      I rather doubt OP is transpiling with babel
      – charlietfl
      Nov 21 at 15:15




















    • If Nodelist.forEach not supported in the browser highly unlikely spread operator is
      – charlietfl
      Nov 21 at 15:05












    • I guess because it's hard to read and because it has no explanation whatsoever
      – Oram
      Nov 21 at 15:05






    • 1




      This solution just hides all elements by settings their class to "hidden". But the question also says, a single one should get a unhidden class.
      – David
      Nov 21 at 15:07






    • 1




      Guys, where does the answer mention it is only meant to replace parts of the code?
      – David
      Nov 21 at 15:11






    • 1




      I rather doubt OP is transpiling with babel
      – charlietfl
      Nov 21 at 15:15


















    If Nodelist.forEach not supported in the browser highly unlikely spread operator is
    – charlietfl
    Nov 21 at 15:05






    If Nodelist.forEach not supported in the browser highly unlikely spread operator is
    – charlietfl
    Nov 21 at 15:05














    I guess because it's hard to read and because it has no explanation whatsoever
    – Oram
    Nov 21 at 15:05




    I guess because it's hard to read and because it has no explanation whatsoever
    – Oram
    Nov 21 at 15:05




    1




    1




    This solution just hides all elements by settings their class to "hidden". But the question also says, a single one should get a unhidden class.
    – David
    Nov 21 at 15:07




    This solution just hides all elements by settings their class to "hidden". But the question also says, a single one should get a unhidden class.
    – David
    Nov 21 at 15:07




    1




    1




    Guys, where does the answer mention it is only meant to replace parts of the code?
    – David
    Nov 21 at 15:11




    Guys, where does the answer mention it is only meant to replace parts of the code?
    – David
    Nov 21 at 15:11




    1




    1




    I rather doubt OP is transpiling with babel
    – charlietfl
    Nov 21 at 15:15






    I rather doubt OP is transpiling with babel
    – charlietfl
    Nov 21 at 15:15












    up vote
    0
    down vote













    The problem is that getElementsByTagName returns HTMLCollection which "not work" with for-in, instead use



    for (let i =0; i<SubSub.length; i++) {
    let item = SubSub[i];
    if (item.id.match(/SubSub.*/)) {
    item.className = 'hidden';
    }
    }





    function ShowSubSub(SelectID) {
    var SubSub = document.getElementsByTagName("Select");
    console.log(SubSub);
    for (let i =0; i<SubSub.length; i++) {
    let item = SubSub[i];
    if (item.id.match(/SubSub.*/)) {
    item.className = 'hidden';
    }
    }
    item = document.getElementById(SelectID);
    console.log(item);
    item.className = 'unhidden';
    }

    ShowSubSub('SubSubHome');

    .hidden {
    background: red;
    }

    .unhidden {
    background: blue;
    }

    <select id="SubSubFlood" >
    <option></option>
    </select>
    <select id="SubSubHome" >
    <option></option>
    </select>





    I also develop a little improvement to connexo solution:



    function ShowSubSub(SelectID) 
    {
    [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
    s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
    )
    }

    ShowSubSub('SubSubHome');





       function ShowSubSub(SelectID) 
    {
    [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
    s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
    )
    }

    ShowSubSub('SubSubHome');

    .hidden {
    background: red;
    }

    .unhidden {
    background: blue;
    }

    <select id="SubSubFlood" >
    <option></option>
    </select>
    <select id="SubSubHome" >
    <option></option>
    </select>








    share|improve this answer



























      up vote
      0
      down vote













      The problem is that getElementsByTagName returns HTMLCollection which "not work" with for-in, instead use



      for (let i =0; i<SubSub.length; i++) {
      let item = SubSub[i];
      if (item.id.match(/SubSub.*/)) {
      item.className = 'hidden';
      }
      }





      function ShowSubSub(SelectID) {
      var SubSub = document.getElementsByTagName("Select");
      console.log(SubSub);
      for (let i =0; i<SubSub.length; i++) {
      let item = SubSub[i];
      if (item.id.match(/SubSub.*/)) {
      item.className = 'hidden';
      }
      }
      item = document.getElementById(SelectID);
      console.log(item);
      item.className = 'unhidden';
      }

      ShowSubSub('SubSubHome');

      .hidden {
      background: red;
      }

      .unhidden {
      background: blue;
      }

      <select id="SubSubFlood" >
      <option></option>
      </select>
      <select id="SubSubHome" >
      <option></option>
      </select>





      I also develop a little improvement to connexo solution:



      function ShowSubSub(SelectID) 
      {
      [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
      s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
      )
      }

      ShowSubSub('SubSubHome');





         function ShowSubSub(SelectID) 
      {
      [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
      s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
      )
      }

      ShowSubSub('SubSubHome');

      .hidden {
      background: red;
      }

      .unhidden {
      background: blue;
      }

      <select id="SubSubFlood" >
      <option></option>
      </select>
      <select id="SubSubHome" >
      <option></option>
      </select>








      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        The problem is that getElementsByTagName returns HTMLCollection which "not work" with for-in, instead use



        for (let i =0; i<SubSub.length; i++) {
        let item = SubSub[i];
        if (item.id.match(/SubSub.*/)) {
        item.className = 'hidden';
        }
        }





        function ShowSubSub(SelectID) {
        var SubSub = document.getElementsByTagName("Select");
        console.log(SubSub);
        for (let i =0; i<SubSub.length; i++) {
        let item = SubSub[i];
        if (item.id.match(/SubSub.*/)) {
        item.className = 'hidden';
        }
        }
        item = document.getElementById(SelectID);
        console.log(item);
        item.className = 'unhidden';
        }

        ShowSubSub('SubSubHome');

        .hidden {
        background: red;
        }

        .unhidden {
        background: blue;
        }

        <select id="SubSubFlood" >
        <option></option>
        </select>
        <select id="SubSubHome" >
        <option></option>
        </select>





        I also develop a little improvement to connexo solution:



        function ShowSubSub(SelectID) 
        {
        [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
        s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
        )
        }

        ShowSubSub('SubSubHome');





           function ShowSubSub(SelectID) 
        {
        [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
        s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
        )
        }

        ShowSubSub('SubSubHome');

        .hidden {
        background: red;
        }

        .unhidden {
        background: blue;
        }

        <select id="SubSubFlood" >
        <option></option>
        </select>
        <select id="SubSubHome" >
        <option></option>
        </select>








        share|improve this answer














        The problem is that getElementsByTagName returns HTMLCollection which "not work" with for-in, instead use



        for (let i =0; i<SubSub.length; i++) {
        let item = SubSub[i];
        if (item.id.match(/SubSub.*/)) {
        item.className = 'hidden';
        }
        }





        function ShowSubSub(SelectID) {
        var SubSub = document.getElementsByTagName("Select");
        console.log(SubSub);
        for (let i =0; i<SubSub.length; i++) {
        let item = SubSub[i];
        if (item.id.match(/SubSub.*/)) {
        item.className = 'hidden';
        }
        }
        item = document.getElementById(SelectID);
        console.log(item);
        item.className = 'unhidden';
        }

        ShowSubSub('SubSubHome');

        .hidden {
        background: red;
        }

        .unhidden {
        background: blue;
        }

        <select id="SubSubFlood" >
        <option></option>
        </select>
        <select id="SubSubHome" >
        <option></option>
        </select>





        I also develop a little improvement to connexo solution:



        function ShowSubSub(SelectID) 
        {
        [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
        s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
        )
        }

        ShowSubSub('SubSubHome');





           function ShowSubSub(SelectID) 
        {
        [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
        s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
        )
        }

        ShowSubSub('SubSubHome');

        .hidden {
        background: red;
        }

        .unhidden {
        background: blue;
        }

        <select id="SubSubFlood" >
        <option></option>
        </select>
        <select id="SubSubHome" >
        <option></option>
        </select>








        function ShowSubSub(SelectID) {
        var SubSub = document.getElementsByTagName("Select");
        console.log(SubSub);
        for (let i =0; i<SubSub.length; i++) {
        let item = SubSub[i];
        if (item.id.match(/SubSub.*/)) {
        item.className = 'hidden';
        }
        }
        item = document.getElementById(SelectID);
        console.log(item);
        item.className = 'unhidden';
        }

        ShowSubSub('SubSubHome');

        .hidden {
        background: red;
        }

        .unhidden {
        background: blue;
        }

        <select id="SubSubFlood" >
        <option></option>
        </select>
        <select id="SubSubHome" >
        <option></option>
        </select>





        function ShowSubSub(SelectID) {
        var SubSub = document.getElementsByTagName("Select");
        console.log(SubSub);
        for (let i =0; i<SubSub.length; i++) {
        let item = SubSub[i];
        if (item.id.match(/SubSub.*/)) {
        item.className = 'hidden';
        }
        }
        item = document.getElementById(SelectID);
        console.log(item);
        item.className = 'unhidden';
        }

        ShowSubSub('SubSubHome');

        .hidden {
        background: red;
        }

        .unhidden {
        background: blue;
        }

        <select id="SubSubFlood" >
        <option></option>
        </select>
        <select id="SubSubHome" >
        <option></option>
        </select>





           function ShowSubSub(SelectID) 
        {
        [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
        s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
        )
        }

        ShowSubSub('SubSubHome');

        .hidden {
        background: red;
        }

        .unhidden {
        background: blue;
        }

        <select id="SubSubFlood" >
        <option></option>
        </select>
        <select id="SubSubHome" >
        <option></option>
        </select>





           function ShowSubSub(SelectID) 
        {
        [...document.querySelectorAll('[id^="SubSub"]')].map(s =>
        s.id==SelectID ? s.className=('unhidden') : s.className=('hidden')
        )
        }

        ShowSubSub('SubSubHome');

        .hidden {
        background: red;
        }

        .unhidden {
        background: blue;
        }

        <select id="SubSubFlood" >
        <option></option>
        </select>
        <select id="SubSubHome" >
        <option></option>
        </select>






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 21 at 15:32

























        answered Nov 21 at 15:06









        Kamil Kiełczewski

        7,97375486




        7,97375486






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414757%2ftrouble-with-javascript-collection-of-document-elements%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)