user3802315
user3802315

Reputation: 19

Javascript: Trying to show different forms based on drop down value?

I'm trying to display different forms based on the value of the selected drop down. I've got it almost all working, although it seems that when two values both display the same form it gives me an error.

Here is the jsfiddle

And the code:

HTML:

<select id="C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown" name="form_select">
    <option value="">-- Select an Option --</option>
    <option value="Buy A Product">Buy A Product</option>
    <option value="Support">Support</option>
    <option value="Ask A Question">Ask A Question</option>
    <option value="Literature Request">Literature Request</option>
    <option value="AE Account">A&E Account</option>
</select>
<div id="C006_ctl00_ctl00_C006">Zip Code</div>
<div id="C007_ctl00_ctl00_C001">Support</div>
<div id="C008_ctl00_ctl00_C003">Ask A Question</div>
<div id="C009_ctl00_ctl00_formControls">Brochures</div>
<div id="C012_ctl00_ctl00_formControls">A&E Account Header</div>
<div id="C013_ctl00_ctl00_formControls">Literature Header</div>
<div id="C010_ctl00_ctl00_formControls">Street Address</div>
<div id="C006_ctl00_ctl00_C008">Product Interest</div>

CSS:

#C006_ctl00_ctl00_C006{display:none;}
#C006_ctl00_ctl00_C008{display:none;} 
#C007_ctl00_ctl00_C001{display:none;}
#C008_ctl00_ctl00_C003{display:none;} 
#C009_ctl00_ctl00_formControls{display:none;} 
#C010_ctl00_ctl00_formControls{display:none;} 
#C013_ctl00_ctl00_formControls{display:none;} 
#C012_ctl00_ctl00_formControls{display:none;} 

Javascript:

document.getElementById('C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown').addEventListener('change', function () {
    var style = this.value == "Buy A Product" ? 'block' : 'none';
    document.getElementById('C006_ctl00_ctl00_C006').style.display = style;
     document.getElementById('C006_ctl00_ctl00_C008').style.display = style;
});

document.getElementById('C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown').addEventListener('change', function () {
    var style = this.value == "Support" ? 'block' : 'none';
    document.getElementById('C007_ctl00_ctl00_C001').style.display = style;
});

document.getElementById('C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown').addEventListener('change', function () {
    var style = this.value == "Ask A Question" ? 'block' : 'none';
    document.getElementById('C008_ctl00_ctl00_C003').style.display = style;
});

document.getElementById('C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown').addEventListener('change', function () {
    var style = this.value == "Literature Request" ? 'block' : 'none';
    document.getElementById('C010_ctl00_ctl00_formControls').style.display = style;
    document.getElementById('C009_ctl00_ctl00_formControls').style.display = style;
});

document.getElementById('C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown').addEventListener('change', function () {
    var style = this.value == "AE Account" ? 'block' : 'none';
    document.getElementById('C012_ctl00_ctl00_formControls').style.display = style;
    document.getElementById('C010_ctl00_ctl00_formControls').style.display = style;
});

So when 'Literature Request' is selected, it's supposed to display Brochures and Street Address. When A&E Account is selected it is supposed to show 'A&E Account Header' and 'Street Address'. Both are supposed to display 'Street Address', although only A&E Account is displaying street address. Does anyone know why? I'm not all that fantastic at javascript... and I apologize for the terrible ID names. They were automatically given and I haven't changed them.

Upvotes: 1

Views: 1325

Answers (3)

blgt
blgt

Reputation: 8205

The reason for this behaviour is that when you select that option, the event handler for AE Account runs after the event handler for Literature Request. I recommend using just one event handler instead. Something along these lines is a lot more readable:

var elts = {
    address: document.getElementById('C010_ctl00_ctl00_formControls'),
    brochures: document.getElementById('C009_ctl00_ctl00_formControls'),
    accHeader: document.getElementById('C012_ctl00_ctl00_formControls'),
    litHeader: document.getElementById('C010_ctl00_ctl00_formControls'),
    zip: document.getElementById('C006_ctl00_ctl00_C006'),
    interest: document.getElementById('C006_ctl00_ctl00_C008'),
    question: document.getElementById('C008_ctl00_ctl00_C003'),
    support: document.getElementById('C007_ctl00_ctl00_C001')
}

document.getElementById('C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown').addEventListener('change', function () {
    var toShow = {
        address: 0, brochures: 0, accHeader: 0, litHeader: 0, zip: 0, interest: 0, question: 0, support: 0
    };
    switch(this.value == "Buy A Product") {
    case "Buy A Product": toShow.interest = 1; toShow.zip = 1; break;
    case "Support": toShow.support = 1; break;
    case "Ask A Question": toShow.question = 1; break;
    case "Literature Request": toShow.brochures = 1; toShow.address = 1; break;
    case "AE Account": toShow.accHeader = 1; toShow.address = 1; break;
    }

    for(var i in toShow) {
        elts[i].style.display = toShow[i] ? 'block' : 'none';
    }
});

Upvotes: 0

andrew
andrew

Reputation: 9583

Use a switch statement. I didn't do the whole thing but it should get you started

fiddle

document.getElementById('C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown').addEventListener('change', function () {
    document.getElementById('C006_ctl00_ctl00_C006').style.display = 'none';
    document.getElementById('C006_ctl00_ctl00_C008').style.display = 'none';
    document.getElementById('C008_ctl00_ctl00_C003').style.display = 'none';
    document.getElementById('C010_ctl00_ctl00_formControls').style.display = 'none';
    document.getElementById('C009_ctl00_ctl00_formControls').style.display = 'none';
    document.getElementById('C012_ctl00_ctl00_formControls').style.display = 'none';
    document.getElementById('C013_ctl00_ctl00_formControls').style.display = 'none';
    switch (this.value) {
        case "Buy A Product":
                 // show "Buy A Product" fields here etc
            break;
        case "Support":
            break;
        case "Ask A Question":
            break;
        case "Literature Request":
            break;
        case "AE Account":
            document.getElementById('C010_ctl00_ctl00_formControls').style.display = 'block';
            document.getElementById('C012_ctl00_ctl00_formControls').style.display = 'block';
            break;
    }
});

Upvotes: 1

MaxArt
MaxArt

Reputation: 22617

First of all, some style. There's no need to attach all those event listeners, as just on can do the trick:

document.getElementById('C002_ctl00_ctl00_C022_ctl00_ctl00_dropDown')
        .addEventListener('change', function () {
    var value = this.value;
    if (value === "Buy A Product") {
        ...
    } else if (value === "Support") {
        ...
    } ...
});

Inside every one of thos if branches, keep track of the elements you want to show. You can save some typing saving the ids instead:

if (value === "Buy A Product") {
    var show = ['C006_ctl00_ctl00_C006', 'C006_ctl00_ctl00_C008'];
} else if (...) {...

At the end of the if branches, hide every element except those in the show array:

[
    "C006_ctl00_ctl00_C006",
    "C007_ctl00_ctl00_C001",
    "C008_ctl00_ctl00_C003",
    "C009_ctl00_ctl00_formControls",
    "C012_ctl00_ctl00_formControls",
    "C013_ctl00_ctl00_formControls",
    "C010_ctl00_ctl00_formControls",
    "C006_ctl00_ctl00_C008"
].forEach(function(id) {
    var style = show.indexOf(id) > -1 ? "block" : "none";
    document.getElementById(id).style.display = style;
});

This should do the trick. I guess you have some questions, feel free to ask.

You issue depends on the fact that you're using several event listeners, and they all run when you change the value of the select element. So the last one (presumably) "wins" over the others as it's executed last and hides/shows the elements accordingly.

Upvotes: 2

Related Questions