twigg
twigg

Reputation: 3993

Javascript show div on HTML select

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:

http://jsfiddle.net/nmdTy/

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

Answers (4)

What have you tried
What have you tried

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);
    });
}

Working Fiddle

Upvotes: 1

Elias Van Ootegem
Elias Van Ootegem

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

Samuel Caillerie
Samuel Caillerie

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';
        }
    };

http://jsfiddle.net/nmdTy/11/

Upvotes: 1

Tom&#225;š Zato
Tom&#225;š Zato

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 divs 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

Related Questions