I am looking for a way to dynamically populate a submenu depending on the selection of the main menu, then, when a user clicks on an item in the submenu, it populates two flexboxes with the contents of another file. I can’t figure out how to target a flexbox using JS; or, if that’s not possible, what I could do instead. For example:
MENU 1 MENU 2 MENU 3 // user selects menu 2, which populates the submenu from a file
^
submenu 1 submenu 2 submenu 3 // user selects submenu 3, which populates the flexbox containers
FLEXBOX CONTAINERS:
------------------------ ----------------------------------------- | SUBMENU 3 HTML PAGE | | SUBMENU 3 HTML PAGE | | | | | | | | | | has options that | | dynamically populates | | affect the contents | | based on the options selected | | of the other box | | in the other box | | | | | ------------------------ -----------------------------------------
Is this possible? What should I search to figure it out? I have Googled to no avail, I’m not searching for the right phrase. What should I be looking for?
Advertisement
Answer
Here is one possible implementation. You add an event listener on each trigger element—in my case, a button. When the button is clicked, you target the .flex element adjacent to the button and dynamically insert HTML content.
const btns = Array.from(document.querySelectorAll('button'))
const clearContent = () => {
Array.from(document.querySelectorAll('.flex')).forEach(item => item.innerHTML = '')
}
btns.forEach((btn, index) => {
btn.addEventListener("click", () => {
clearContent();
btn.parentNode.querySelector('.flex').innerHTML = menuContents[index]
})
})
const menuContents = [
'<div>sub 1</div><div>sub 2</div><div>sub 3</div>',
'<div>sub 4</div><div>sub 5</div><div>sub 6</div>',
'<div>sub 7</div><div>sub 8</div><div>sub 9</div>'
].flex {
text-align: center;
display: flex;
position: absolute;
left: 50%;
top: 1.5rem;
transform: translateX(-50%);
column-gap: 1rem;
white-space: nowrap;
}
.flex:empty {
display: none;
}
.outer {
position: relative;
}
body {
display: flex;
justify-content: center;
gap: 1rem;
}<div class="outer">
<button>
Menu 1
</button>
<div class="flex"></div>
</div>
<div class="outer">
<button>
Menu 2
</button>
<div class="flex"></div>
</div>
<div class="outer">
<button>
Menu 3
</button>
<div class="flex"></div>
</div>