Reputation: 31
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"?
Upvotes: 1
Views: 63
Reputation: 92627
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>
Upvotes: 0
Reputation: 56783
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:
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"]')
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"]'))
so it's cross-browser safe to use forEach
on the result:
[...document.querySelectorAll('[id^="SubSub"]')].forEach((section) => {})
In that loop, simply add the classname to the classList
:
section.className.add('hidden')
Upvotes: 2
Reputation: 6739
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?
Upvotes: 5