Reputation: 470
Consider the following simplified html
code:
<html>
<head>
<style>
.opts {display: none}
</style>
</head>
<body onload = "list = document.getElementsByClassName('opts')">
<form>
<ul>
<li>
<label>Show Options?</label>
<input type="radio" onclick="list[0].style.display = 'block'; list[1].style.display = 'block'; list[2].style.display = 'block';">yes<br>
<input type="radio" onclick="list[0].style.display = 'none'; list[1].style.display = 'none'; list[2].style.display = 'none';">no<br>
</li>
<li class="opts">
<label>Option 1</label>
<input type="text">
</li>
<li class="opts">
<label>Option 2</label>
<input type="text">
</li>
<li class="opts">
<label>Option 3</label>
<input type="text">
</li>
... etc ...
</ul>
</form>
</body>
</html>
Basically, it uses javascript to show or hide optional elements according to user onclick
event.
Issue
Currently, for each element in getElementsByClassName
there is a line setting 'manually' the display property:
list[0].style.display = 'block';
list[1].style.display = 'block';
list[2].style.display = 'block';
Is there a simpler way to do that? For example, something like:
list[All].style.display = 'block';
ps: of course this could be done via some for loop
and an additional function declaration, but I'm looking for an easy inline js code (ie: no external js files)
Based on comments, there are two proposed ways to easily code this inline without external files:
1) spread syntax
[...list].forEach(el => el.style.display = 'block')
2) for loop
new syntax
for (const x of list) x.style.display = "block";
Particularly, I've decided to use the for loop
new syntax due to be easier to read then the spread syntax. However, since both ways are somewhat recent features of JavaScript, caution is advised for older browsers compatibility.
Upvotes: 1
Views: 1352
Reputation: 147363
Consider toggling classes rather than directly setting display values. Also, for a straight binary selection, I'd just use a checkbox.
Iterating over an array using forEach isn't a lot of code, and accommodating older browsers is simple too:
function toggleOpts() {
var opts = Array.from(document.querySelectorAll('.opts'));
opts.forEach(function(opt) {
opt.style.display = this.checked ? '' : 'none';
}, this);
}
window.onload = function() {
document.getElementById('optToggle').addEventListener('click', toggleOpts, false);
}
<title>Sample</title>
<form>
<ul>
<li>
<label for="optToggle">Show Options?
<input type="checkbox" id="optToggle" checked>yes
</label>
</li>
<li class="opts">
<label>Option 1</label>
<input type="text">
</li>
<li class="opts">
<label>Option 2</label>
<input type="text">
</li>
<li class="opts">
<label>Option 3</label>
<input type="text">
</li>
</ul>
</form>
Upvotes: 0
Reputation:
// setup for the environment
const All = Symbol("All");
const setter = {set: function(fn) {
for (var i = 0; i < this.length; i++) {
fn(this[i], i, this);
}
}};
Object.defineProperty(HTMLCollection.prototype, All, setter);
Object.defineProperty(NodeList.prototype, All, setter);
// Your code
const list = document.getElementsByClassName('opts')
list[All] = x => x.style.fontWeight = "bold";
<form>
<ul>
<li>
<label>Show Options?</label>
<input type="radio" onclick="list[0].style.display = 'block'; list[1].style.display = 'block'; list[2].style.display = 'block';">yes<br>
<input type="radio" onclick="list[0].style.display = 'none'; list[1].style.display = 'none'; list[2].style.display = 'none';">no<br>
</li>
<li class="opts">
<label>Option 1</label>
<input type="text">
</li>
<li class="opts">
<label>Option 2</label>
<input type="text">
</li>
<li class="opts">
<label>Option 3</label>
<input type="text">
</li>
... etc ...
</ul>
</form>
Upvotes: 1