Pytharelle
Pytharelle

Reputation: 73

Show/Hide Divs from Dropdown

This one is really straightforward but I somehow cannot get my head around it.

I have a Bootstrap Dropdown Menu with 3 Choices.

My page will be hosting 3 divs which should be hidden by default.

When clicking on one of the choice within the Dropdown, then I want the related div to appear.

HTML:

<div class="dropdown d-flex justify-content-center">
    <button class="btn bg-dark text-light dropdown-toggle rounded-bottom" style="border-radius: 0 !important;" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                Secure Acceptance Silent Order POST / Checkout API</button>
    <div id="target" class="dropdown-menu" aria-labelledby="dropdownMenu2">
        <button value="1" class="master dropdown-item" type="button">Auth/Sale using Transaction Endpoint</button>
        <button value="2" class="master dropdown-item" type="button">Auth/Sale using iFrame Transaction Endpoint</button>
        <button value="3" class="master dropdown-item" type="button">Auth/Sale with Token Creation</button>
    </div>
</div>
        
<div id="1" class="SAformX hidden" style="background-color:red;">
    <p>gergeyherghdesghderh</p>
</div>
<div id="2" class="SAformY hidden" style="background-color:blue;">
    <p>gergeyherghdesghderh</p>
</div>
<div id="3" class="SAformZ hidden" style="background-color:green;">
    <p>gergeyherghdesghderh</p>
</div>

By default, the forms with the class hidden are to be hidden :

<style>
    .hidden{
        visibility: hidden;
    }
</style>

Using Vanilla Javascript, I want to generate a Node of elements containing the class Master which is related to each button/chocie within the dropdown. And then, I want to pass its related ID to another function where :

This way, everytime you click on a dropdown choice, the page "soft reset" and hides all the divs that were not selected.

Javascript :

<script>
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.master').forEach(item => {
            item.addEventListener('click', () => {
                const id = item.value;
                MasterMenuToggle(id);
            });
        });
    })
function MasterMenuToggle(id) {

    document.querySelectorAll('.SAform').forEach(item => {
        item.className = "hidden";
    })
    document.getElementById(id).className = "visible"
}
</script>

The issue here is the "reset" part of my function MasterMenuToggle

document.querySelectorAll('.SAform').forEach(item => {
    item.className = "hidden";
})

Clicking on a dropdown item do make its related div appear but then they keep on appearing without the other hiding.

Can I loop through the IDs to simply ADD an inline CSS to each DIV to be safe?

Hope you can help !

Upvotes: 0

Views: 95

Answers (4)

Professor Abronsius
Professor Abronsius

Reputation: 33813

The task is quite simple if you break it down into two stages. The first stage is to hide all div elements when one of the three buttons is clicked and then show the relevant div based upon value & data-id of the button and div respectively. Rather than using a new class (hidden) you can use the inline declaration display='none' instead or, as suggested above by @connexo, use hidden=true ~ though I think there is a difference in how these are represented on the page with one occupying no space and the other will.

document.querySelectorAll('div#target > button').forEach( bttn=>{
    bttn.addEventListener('click',function(e){
        let col=document.querySelectorAll('div[data-id]');
            col.forEach( div=>{ div.style.display='none' } )
            
        document.querySelector('div[ data-id="'+this.value+'"]').style.display='block'
    })
})
/* css here only to prettify things */
div{ padding:0.25rem; color:white }
button{padding:0.5rem;margin:0.25rem;}
<div class="dropdown d-flex justify-content-center">
    <button class="btn bg-dark text-light dropdown-toggle rounded-bottom" style="border-radius: 0 !important;" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        Secure Acceptance Silent Order POST / Checkout API
    </button>
    
    <div id="target" class="dropdown-menu" aria-labelledby="dropdownMenu2">
        <button value="1" class="master dropdown-item" type="button">Auth/Sale using Transaction Endpoint</button>
        <button value="2" class="master dropdown-item" type="button">Auth/Sale using iFrame Transaction Endpoint</button>
        <button value="3" class="master dropdown-item" type="button">Auth/Sale with Token Creation</button>
    </div>
</div>

<!-- HTML element IDs cannot begin with a number, use a dataset attribute instead -->
<div data-id=1 class="SAformX hidden" style="background-color:red;">
    <p>Red div - data-id=1</p>
</div>

<div data-id=2 class="SAformY hidden" style="background-color:blue;">
    <p>Blue div - data-id=2</p>
</div>

<div data-id=3 class="SAformZ hidden" style="background-color:green;">
    <p>Green div - data-id=3</p>
</div>

Upvotes: 0

Sedki Sghairi
Sedki Sghairi

Reputation: 379

hiddenDivs = document.querySelectorAll('.SAform');
document.addEventListener('DOMContentLoaded', function() {
    hiddenDivs.forEach((x) => x.classList.add('.hidden'));
    document.querySelectorAll('.master').forEach((item) => {
        item.addEventListener('click', () => {
            const id = item.value;
            MasterMenuToggle(id);
        });
    });
});
function MasterMenuToggle(id) {
    hiddenDivs.forEach((x) => {
        if (x.id == id) {
            x.classList.remove('hidden');
        } else {
            x.classList.add('hidden');
        }
    });
}
.hidden {
    visibility: hidden;
}
    <div class="dropdown d-flex justify-content-center">
        <button class="btn bg-dark text-light dropdown-toggle rounded-bottom" style="border-radius: 0 !important;" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Secure Acceptance Silent Order POST / Checkout API
        </button>
        <div id="target" class="dropdown-menu" aria-labelledby="dropdownMenu2">
            <button value="1" class="master dropdown-item" type="button">Auth/Sale using Transaction Endpoint</button>
            <button value="2" class="master dropdown-item" type="button">Auth/Sale using iFrame Transaction Endpoint</button>
            <button value="3" class="master dropdown-item" type="button">Auth/Sale with Token Creation</button>
        </div>
    </div>
    
    <div id="1" class="SAform " style="background-color:red;">
        <p>gergeyherghdesghderh</p>
    </div>
    <div id="2" class="SAform " style="background-color:blue;">
        <p>gergeyherghdesghderh</p>
    </div>
    <div id="3" class="SAform " style="background-color:green;">
        <p>gergeyherghdesghderh</p>
    </div>

Upvotes: 0

Ali Mustafa Fidancı
Ali Mustafa Fidancı

Reputation: 123

You used the code for hide all divs

function MasterMenuToggle(id) {
    document.querySelectorAll('.SAform').forEach(item => {
        item.className = "hidden";
    })
}

But your div's class names are "SAformX", "SAformY" and "SAformZ". So the querySelectorAll('.SAform') cannot found any div. You can add "SAform" class name to your hidden divs.

*Sorry for my bad English :/

Here is working JSFiddle https://jsfiddle.net/7nf18dr6/3/

Upvotes: 1

Nathan
Nathan

Reputation: 58

You would need to use the classList.add or classList.remove function.

So if you want to reveal, use the remove to remove the hidden, else use the .add to hide again.

E.g. item.classList.add("hidden"); or item.classList.remove("hidden")

There are plenty of actions you can perform with classList which state here:

https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

Upvotes: 2

Related Questions