2

I am very familiar with conditionally hiding or displaying elements when using Angular. I am less familiar with doing so with straight HTML and JS. I have an HTML page that makes use of twitter-bootstrap 3.4.0. With this HTML page I initially want to display one master drop-menu. Then, depending on what selection a user makes, I want to conditionally display one of several secondary drop-menus. This is my master drop-menu HTML:

<div class="dropdown">
  <button class="btn btn-default btn-primary dropdown-toggle" type="button" data-toggle="dropdown"
    onclick="loadCategoryList()">
    Select Job Category
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" id="selectCategory"></ul>
</div>

And here's the JS being referenced:

let selectCat = document.getElementById("selectCategory");

// Load category list into drop-menu
async function loadCategoryList() {
  const categoryArr = ["option 1", "option 2", "option 3", "emailer"];
  while (selectCat.firstChild) {
    selectCat.removeChild(selectCat.firstChild);
  }
  for (let i = 0; i < categoryArr.length; i++) {
    let opt = categoryArr[i];
    let a = document.createElement("a");
    a.textContent = opt;
    a.setAttribute('href', '#');
    a.setAttribute('class', 'btn btn-link');
    let li = document.createElement("li");
    li.appendChild(a);
    selectCat.appendChild(li);
  }
}

Then I have a secondary drop-menu div node that looks like this:

<div class="dropdown">
  <button class="btn btn-default btn-primary dropdown-toggle" type="button" data-toggle="dropdown"
    onclick="loadEmailersList()">
    Select Email Type
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" id="selectEmailer"></ul>
</div>

The change I want to make is I that I only want to display this secondary "emailer" div node if the selection from the master category list drop-menu was "emailer". In other words, the "emailer" drop-menu node should be hidden, and only become visible if and when the selection from the master category-list drop-menu is equal to "emailer".

I'm unclear how much of this happens in the HTML vs in the JS. How do I accomplish this using HTML, JS and Bootstrap?

Muirik
  • 6,049
  • 7
  • 58
  • 116
  • Hey Muirik , is there a chance you could condense this down into a slightly smaller snippet or comment through where there is trouble. Bonus points if you can inject it as a runnable stack snippet :) – KyleMit Nov 25 '19 at 14:05
  • I'm using Bootstrap 3.4.0. I reduced the snippet size. Basically I only want the div node for "emailer" to display if a user selects "emailer" from the initial drop-menu list. Initially and otherwise it should remain hidden. – Muirik Nov 25 '19 at 14:08
  • For example, here's a [pastbin](https://pastebin.com/D0yvJUdv) of a starter for a stack snippet that you could include in your answer. But if you do so, you'll see it's hard to get running (and thus potentially debug). It would be really helpful if you could get it to a runnable state – KyleMit Nov 25 '19 at 14:13
  • I made changes above so you can see the array of menu items. – Muirik Nov 25 '19 at 14:15
  • I've now taken that out. That'll only be used in the secondary drop-menu to populate the value to a text field. – Muirik Nov 25 '19 at 14:18

1 Answers1

3

To modify the visibility of an element, you can use jQuery's .hide(), .show(), or .toggle()

You'll also have determine which item was clicked in a dropdown menu

To start off hidden, you could use something like style="display: none;"

Together, it should look a little something like this:

// handle click event on dropdown menu item
$('#category .dropdown-menu').on('click', 'li a', function(e) {
  
  // determine which item was selected
  var selText = $(this).text();
  
  // determine whether email box should be visible
  var showEmail = selText === "Email"

  // show/hide visibility
  $('#box').toggle(showEmail);
});
#category, #box {
  margin: 10px;
}
#box {
    width: 200px;
    height: 100px;
    background: cornflowerblue;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 5rem;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>

<div class="dropdown" id="category">
  <button class="btn btn-default dropdown-toggle" id="dropdownMenu1" 
          type="button" data-toggle="dropdown" 
          aria-haspopup="true" aria-expanded="true">
    Pick Category
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
    <li><a href="#">Email</a></li>
    <li><a href="#">Another action</a></li>
    <li><a href="#">Something else here</a></li>
  </ul>
</div>

<div id="box" style="display: none;"> Email </div>
KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • Thanks. Just to clarify, is there not a way to do this without using jQuery? – Muirik Nov 25 '19 at 14:53
  • Well, you can, but bootstrap requires jquery anyway, so you should already have it loaded as a dependency – KyleMit Nov 25 '19 at 14:54
  • Right. And is doing it with jQuery less verbose than it would be without using jQuery? – Muirik Nov 25 '19 at 14:56
  • 1
    Yeah, I mean if you just wanted to show/hide an element using vanilla js, I wouldn't recommend adding jQuery from scratch, but since you area already paying the cost of loading it, there's no reason in the world not to use it - and I think the syntax is a little cleaner – KyleMit Nov 25 '19 at 14:59