skip to Main Content

I currently have a dropdown that is written completely with html and css, and I currently have the functionality that: if a user clicks an option from the menu – it will open a submenu via a hidden radiobutton. However, with radiobuttons – once you select one option – you can not deselect it as the user. That is why I would like to implement the functionality of clicking a checked radiobutton deselects it (if it is in the dropdown).


 const DROPDOWN_SELECTION = document.querySelectorAll(".menu input[type='radio']");
DROPDOWN_SELECTION.forEach( element => {
    element.addEventListener("click", () => {
        if(element.checked === true){
            element.checked = false;
        }
    });
}); 
.dropdown{
    width: 250px;
    background-color:black;
    color:white;
}

.dropdown label{
    font-size:30px;
}

.dropdown ul{
    display: none;
}

[id^=btn]:checked + ul{
    display:block;
}


.dropdown input{
    display: none;
}
    <div class ="dropdown">
        <label for = "btn-Main" class="button">Dropdown List</label>
        <input type="checkbox" id="btn-Main">
        <ul class="menu">
            <li>
                <label for = "btn-Two" class="first">Option A</label>
                <input type="radio" name="faction" id="btn-Two">
                <ul>
                    <li>Option A.1</li>
                    <li>Option A.2</li>
                </ul>
            </li>

            <li>
                <label for = "btn-Three" class="second">Option B
                    <span class ="arrow down"></span>
                </label>
                <input type="radio" name="faction" id="btn-Three">
                <ul>
                    <li>Option B.1</li>
                    <li>Option B.2</li>
                </ul>
            </li>

        </ul>
    </div>

The above code was my attempt at creating this functionality, however upon testing – the submenus no longer open. My hypothesis is that the code checks if the radio button is checked after the checked value has changed from the user input, and not before. Thus, a user cannot open the submenu as it will automatically uncheck. I have added just the tiniest bit of styling so that the end result makes more sense visually


The reason I did not use checkboxes instead of radio buttons is because of the functionality that you can only select one option at a time as a radio button. This means only one submenu may be open at any given time and will avoid clutter and automatically close other submenus. I would like the option to further reduce clutter by allowing users to close a submenu that they are viewing by clicking on it again.

There are some people who have had similar issues. However, their code was in jQuery, whilst mine is in javascript – and I would like to find a solution that is in javascript as I am new to web design and would prefer not to learn a new language before I finish my first project. Regardless, here are some links from people who had similar issues (in jQuery):


Stack Overflow JQuery version of this question:
Uncheck Radio Button with double click
how to uncheck a radio button

2

Answers


  1. Chosen as BEST ANSWER

    So I have found a way to implement the functionality I am talking about, however - it does add an extra step for the user if they want to open another submenu as they are forced to close the current submenu first. I will try to find a solution to fix this but for now here is the current solution - simply change the js file:

    var subMenuOpen = false;
    
    const DROPDOWN_SELECTION = document.querySelectorAll(".menu input[type='radio']");
     DROPDOWN_SELECTION.forEach( element => {
        element.addEventListener("click", () => {
            if(subMenuOpen === true){
                element.checked = false;
                subMenuOpen = false;
            }
            else {
                subMenuOpen = true;
            }
        });
     }); 
    

  2. Here is a solution that uses checkboxes and then just unchecks other checkboxes when a sub menu is clicked. Same functionality as the radio buttons but uses checkboxes so the users can easily close a submenu.

    (function() {
      // get all the checkboxes (submenus)
      const menuHeaders = document.querySelectorAll('div.dropdown > .menu input[type="checkbox"]');
      // loop over them
      [...menuHeaders].forEach((mnu) => {
        // add a click event handler
        mnu.addEventListener('click', (e) => {
          // loop over all submenu headers
            [...menuHeaders].forEach(function(item) {
            // check if the header is the clicked header
            if (item !== e.target){
              // uncheck this option
                item.checked = false;
            }
          });
        })
      })
    })()
    .dropdown{
        width: 250px;
        background-color:black;
        color:white;
    }
    
    .dropdown label{
        font-size:30px;
    }
    
    .dropdown ul{
        display: none;
    }
    
    [id^=btn]:checked + ul{
        display:block;
    }
    
    
    .dropdown input{
        display: none;
    }
    <div class="dropdown">
      <label for="btn-Main" class="button">Dropdown List</label>
      <input type="checkbox" id="btn-Main">
      <ul class="menu">
        <li>
          <label for="btn-Two" class="first">Option A</label>
          <input type="checkbox" name="faction" id="btn-Two">
          <ul>
            <li>Option A.1</li>
            <li>Option A.2</li>
          </ul>
        </li>
    
        <li>
          <label for="btn-Three" class="second">Option B
            <span class="arrow down"></span>
          </label>
          <input type="checkbox" name="faction" id="btn-Three">
          <ul>
            <li>Option B.1</li>
            <li>Option B.2</li>
          </ul>
        </li>
    
        <li>
          <label for="btn-Four" class="second">Option C
            <span class="arrow down"></span>
          </label>
          <input type="checkbox" name="faction" id="btn-Four">
          <ul>
            <li>Option C.1</li>
            <li>Option C.2</li>
          </ul>
        </li>
      </ul>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search