Search code examples
javascriptbootstrap-5

How can I close the dropdown programmatically on button click?


I have the below Bootstrap 5 dropdown menu of labeled checkboxes, with data-bs-auto-close="outside", so that the menu closes on outside click.

<div class="dropdown">
  <button type="button" class="btn btn-success dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
    Dropdown button
  </button>
  <div class="dropdown-menu">
    <div class="px-1">
      <input class="form-check-input" type="checkbox" id="option1" name="filter">
      <label for="option1">Option 1</label>
    </div>

    <div class="px-1">
      <input class="form-check-input" type="checkbox" id="option2" name="filter">
      <label for="option2">Option 2</label>
    </div>

    <div class="btn-group px-1 mt-2 w-100">
      <button onclick="closeFilter()" type="button" class="apply btn btn-sm btn-success">Apply</button>
      <button onclick="closeFilter()" type="button" class="reset btn btn-sm btn-success">Reset</button>
    </div>
  </div>
</div>

I want the menu to close when any of the buttons "Apply" and "Reset" is clicked. For this purpose, I have the function below:

function closeFilter() {
  let dropDown = event.target.closest('.dropdown');
  let dropDownButton = dropDown.querySelector('.dropdown-toggle');
  dropDownButton.style.border = '1px solid red';
  dropDownButton.dropdown('toggle');
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />

<div class="dropdown">
  <button type="button" class="btn btn-success dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
    Dropdown button
  </button>
  <div class="dropdown-menu">
    <div class="px-1">
      <input class="form-check-input" type="checkbox" id="option1" name="filter">
      <label for="option1">Option 1</label>
    </div>

    <div class="px-1">
      <input class="form-check-input" type="checkbox" id="option2" name="filter">
      <label for="option2">Option 2</label>
    </div>

    <div class="btn-group px-1 mt-2 w-100">
      <button onclick="closeFilter()" type="button" class="apply btn btn-sm btn-success">Apply</button>
      <button onclick="closeFilter()" type="button" class="reset btn btn-sm btn-success">Reset</button>
    </div>
  </div>
</div>

However, the above function throws the error:

dropDownButton.dropdown is not a function

Where is my mistake?


Solution

  • You need to get the instance of the specific dropdown. You can use bootstrap.Dropdown.getInstance(element) for this.

    function closeFilter() {
      let dropDown = event.target.closest('.dropdown');
      let dropDownButton = dropDown.querySelector('.dropdown-toggle');
      dropDownButton.style.border = '1px solid red';
    
      bootstrap.Dropdown.getInstance(dropDownButton).toggle();
    }
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
    
    <div class="dropdown">
      <button type="button" class="btn btn-success dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
        Dropdown button
      </button>
      <div class="dropdown-menu">
        <div class="px-1">
          <input class="form-check-input" type="checkbox" id="option1" name="filter">
          <label for="option1">Option 1</label>
        </div>
    
        <div class="px-1">
          <input class="form-check-input" type="checkbox" id="option2" name="filter">
          <label for="option2">Option 2</label>
        </div>
    
        <div class="btn-group px-1 mt-2 w-100">
          <button onclick="closeFilter()" type="button" class="apply btn btn-sm btn-success">Apply</button>
          <button onclick="closeFilter()" type="button" class="reset btn btn-sm btn-success">Reset</button>
        </div>
      </div>
    </div>