简体   繁体   中英

If statement to reveal div but hide other divs in a form?

I'm looking to create an if/else statement that will show one div but hide the others when a certain option is selected. For example see below. I attempted it in the first if statement but with no luck and can't seem to find how to add multiple actions in that first if bracket. Any help is appreciated.

Here is my JS:

function showSmallJobsite(small){
if(small.value == 3){
    document.getElementById('smalljobsite').style.display = "block",;
    document.getElementById('mediumjobsite','largejobsite').style.display = "none";
}
else if(small.value == 7){
    document.getElementById('mediumjobsite').style.display = "block";
}
else if(small.value == 8){
    document.getElementById('largejobsite').style.display = "block";
}
else (small.value == 0){
    document.getElementById('largejobsite').style.display = "block";
}   
}

Here is my HTML:

<label>Number of users on site:</label>
<select id="numberofstaff" onchange="showSmallJobsite(this)">
    <option value="0">--Select--</option>
    <option id="staffnumberthree" value="3">1-3</option>
    <option id="staffnumberseven" value="7">4-7</option>
    <option id="staffnumbereight" value="8">8+</option>
</select>
<div id="smalljobsite" style="display:none;">
<div class="fieldcontainer">
    <label>Plan Table?:</label>
        <select name="plan_table" required>
            <option>--Select--</option>
            <option>Yes</option>
            <option>No</option>
        <select>
</div>
<br>
<div class="fieldcontainer">
    <label>E-mail:</label>
        <select name="dslcablesmall" required>
            <option>--Select--</option>
            <option>DSL/Cable</option>
            <option>LTE Only</option>
        </select>
</div>
</div>
<div id="mediumjobsite" style="display:none;">
<br>
<div class="fieldcontainer">
    <label>Trailers?:</label>
        <input type="number" name="phone_number" maxlength="10" required>
</div>
<br>
<div class="fieldcontainer">
    <label>Plan Tables?:</label>
        <input type="email" name="email" maxlength="100" required>
</div>
<br>
<div class="fieldcontainer">
    <label>Phone System?:</label>
        <input type="text" name="project_name" maxlength="70" required>
</div>
<br>
<div class="fieldcontainer">
    <label>External Wifi?:</label>
        <input type="text" name="project_number" required>
</div>
</div>
<div id="largejobsite" style="display:none;">
<br><br>
<div class="fieldcontainer">
<label>Over 25 Users?:</label><input type="number" name="phone_number"             maxlength="10" required>
</div>
<br><br>
<div class="fieldcontainer">
    <label>Trailers or similar sized offices?:</label>
        <input type="email" name="email" maxlength="100" required>
</div>
<br><br>
<div class="fieldcontainer">
    <label>Plan Tables?:</label>
        <input type="text" name="project_name" maxlength="70" required>
</div>
<br><br>
<div class="fieldcontainer">
    <label>Second Copier?:</label>
        <input type="text" name="project_number" required>
</div>
</div>

getElementById requires a unique id of an element. If you are trying to be a bit more ambiguous, try document.querySelectorAll . You might have to restructure your html a bit. For example, put everything that you wish to show and hide inside a container div and then select all divs having specific class like 'hideable' or whatever.

Hide all those and then go into specific to display the one you wish to show.

Like so:

 (function() { 'use strict'; var flag = 2; //medium, should show small and medium, but not large. toggleAllUsing(flag); function toggleAllUsing(flag) { hide('#container .hideable'); switch(flag) { case 1: show('#container .show_if_small'); break; case 2: show('#container .show_if_medium'); break; case 3: show('#container .show_if_large'); break; } } function show(selector) { var h = document.querySelectorAll(selector); console.log(h); for(var i = 0, l = h.length; i < l; i++) { var el = h[i]; el.style.display = 'block'; } } function hide(selector) { var h = document.querySelectorAll(selector); for(var i = 0, l = h.length; i < l; i++) { var el = h[i]; el.style.display = 'none'; } } }()); 
 <div id='container'> <div class='hideable show_if_small show_if_medium show_if_large' id='small'> I am small, I should always appear (even if you select medium or large) </div> <div class='hideable show_if_medium show_if_large' id='medium'> I am medium. I should appear only when you select medium or large) </div> <div class='hideable show_if_large' id='large'> I am large. I should appear only when you select large) </div> </div> 

I would like to suggest a different approach to the JavaScript that should help achieve more easily the behaviour that you want, but also make it less prone to error (sometimes the case with lots of if statements) and easier to read.

If the criteria is that only one div is to be shown at a time, and all others hidden, then the first order of business in the JavaScript is to hide all of the divs immediately:

// JS
function showSmallJobsite(small){
    var jobsites = document.getElementsByClassName('jobsite');
    for(var i = 0; i < jobsites.length; i++) {
        jobsites[i].style.display = 'none';
    }
}

// HTML
<div id="smalljobsite" class="jobsite">
...
<div id="mediumjobsite" class="jobsite">
...
<div id="largejobsite" class="jobsite">
...

The final task would be to show the one that the user is interested in. Is it correct to say that there is a straight-forward mapping between "small.value" and the particular job site?

Suggested approach:

function showSmallJobsite(small){
    ...

    var map = {
        3: 'smalljobsite',
        7: 'mediumjobsite',
        8: 'largejobsite',
        0: 'largejobsite'
    }
    var show = document.getElementById(map[small.value]);
    show.style.display = 'block';
}

Alternatively:

// HTML
<div id="smalljobsite" class="jobsite smallvalue-3">
...
<div id="mediumjobsite" class="jobsite smallvalue-7">
...
<div id="largejobsite" class="jobsite smallvalue-8 smallvalue-0">
...

// JS
function showSmallJobsite(small){
    ...

    var show = document.getElementsByClassName('smallvalue-' + small.value);
    show.style.display = 'block';
}

Looking at the wider app I might have another alternative that is more optimal perhaps, but from the information given I would consider either of the above an improvement.

With less if statements I hope you'll find achieving the desired functionality easier and the likelihood of errors and unexpected behaviour less so.

Apologies if you don't deem this as directly helpful.

Note: Error in your original code at the end of line 3: ... "block",;

Another approach I would like to suggest is applying a classname to a containing div which then toggles the child forms. For example, say we had a select that triggered our JS:

<select onchange="showJobSite(this)">
    <option value="">Select</option>
    <option value="0">A large job site</option>
    <option value="8">Another large job site</option>
    <option value="3">A small job site</option>
    <option value="7">A medium job site</option>
</select>

Now, instead of if statements, we take the value and apply it as a class name. Since numbers are not valid class names, I'll append it to the letter j , for "job".

function showJobSite(obj){
    var el = document.getElementById('container');
    el.setAttribute('class', 'container j' + obj.value);
};

Finally, our CSS could be set up so that we hide everything, and then show the child forms based on the j + n class name. Like:

.container > div {
    display: none;
}
.container.j3 #smalljobsite,
.container.j7 #mediumjobsite,
.container.j0 #largejobsite,
.container.j8 #largejobsite{
    display: block;
}

Here's a fiddle for demonstration: http://jsfiddle.net/5knL7zf8/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM