Reputation: 3993
I've been playing with javascript to create a drop down list that shows a div depending on which option is selected.
All the code can be seen here:
var select = document.getElementById('test'),
onChange = function(event) {
var shown = this.options[this.selectedIndex].value == 1;
document.getElementById('hidden_div').style.display = shown ? 'block' : 'none';
};
I want to know how do I streamline this code and remove repetition - maybe some kind of loop?
Upvotes: 2
Views: 559
Reputation: 11138
You don't need two event handlers, you can use variables (shown below) to determine which div
needs to be displayed or hidden.
var select = document.getElementById('test'), onChange = function(event) {
var div1 = 'hidden_div';
var div2 = 'hidden_div2';
var index1 = this.options[this.selectedIndex].value == 1;
var index2 = this.options[this.selectedIndex].value == 2;
if(index1 || index2){
document.getElementById(div1).style.display = index1 ? 'block' : 'none';
document.getElementById(div2).style.display = index2 ? 'block' : 'none';
}
else{
document.getElementById(div1).style.display = 'none';
document.getElementById(div2).style.display = 'none';
}
};
// attach event handler
if (window.addEventListener) {
select.addEventListener('change', onChange, false);
} else {
// of course, IE < 9 needs special treatment
select.attachEvent('onchange', function() {
onChange.apply(select, arguments);
});
}
Upvotes: 1
Reputation: 76395
Delegating a change event in IE<9 is a pain. It is possible, check this question to see how it's done, but it's not what you call elegant.
But your code doesn't delegate the event, so just attaching the handler directly at the onload
event should do the trick (and it's X-browser compatible):
document.getElementById('test').onchange = function(e)
{
e = e || window.event;//the only IE headache
var shown = this.options[this.selectedIndex].value == 1;
document.getElementById('hidden_div').style.display = shown ? 'block' : 'none';
//^^ could keep a reference to this in a closure
};
The full code (with onload
and closure reference to hidden div and preventing memory leaks in ie) should look like this:
var winLoad = function(e)
{
var hiddenDiv = document.getElementById('hidden_div');
document.getElementById('test').onchange = function(e)
{
var shown = !!(this.option[this.selectedIndex].value == 1);//to be safe, coerce to bool
hiddenDiv.style.display = shown ? 'block' : 'none';
};
if (window.addEventListener)
{
return window.removeEventListener('load',winLoad,false);
}
return window.detachEvent('onload',winLoad);
};
if (window.addEventListener)
{
window.addEventListener('load',winLoad,false);
}
else
{
window.attachEvent('onload',winLoad);
}
that should work fine on all major browsers, even IE7 (probably IE6, too)
Upvotes: 0
Reputation: 8275
Another code :
var select = document.getElementById('test'),
nbItems = 2,
onChange = function (event) {
var val = this.options[this.selectedIndex].value;
for (var i = 1; i <= nbItems; i++) {
document.getElementById('hidden_div' + i).style.display = val == i ? 'block' : 'none';
}
};
Upvotes: 1
Reputation: 53119
I'm not really sure what do you mean by "repetition" but my guess is, that you don't want to type every each of the div
s to be hidden/shown.
There could be multiple approaches to such task. The most universal is to have the div
id's in a separate array. Then you can hide all but the selected div.
var divs = ["hidden_div1", "special_hidden", "one_more_hidden"];
var select = document.getElementById('test');
var onchange = function(event) { //Use var!
var shown = this.options[this.selectedIndex].value;
for(var i=0; i<window.divs.length; i++) { //It would be more effective to save last shown div in a variable, but I've chosen this aproach with loop
var div = document.getElementById(window.divs[i]);
if(div!=null) {
if(i==shown)
div.style.display="block";
else
div.style.display="none";
}
}
};
select.addEventListener("change", onchange); //Could type the function right here, without using "onchange" variable
In my code, <option>
value represents index in the array. Here is jsFiddle.
Upvotes: 0