Search code examples
cssdrop-down-menubootstrap-4dropdownpopper.js

Bootstrap4 Dropdown menu fill input-group


I have a very simple bootstrap issue that I'd like to solve.

According to the guide (https://getbootstrap.com/docs/4.0/components/dropdowns/) the .dropdown-menu class and dropdown-toggle has to be wrapped within .dropdown, or another element that declares position: relative;.

But so far, I can only get it to work if I place the .dropdown-menu at the same level as my toggle. Because of this, I'm only able to get a small dropdown on the right hand corner like this.

Not Desired Result

However, if I were to move the entire .dropdown-menu div block down by two levels (inside the .input-group .dropdown div block), I'd achieve an effect like this ...

Desired, but script broken

... which is exactly what I wanted, however, on the console, bootstrap/popper would then spew out an error telling me that Cannot read property 'setAttribute' of undefined, and the dropdown menu would not retract anymore, and that's where I'm stuck.

I have included a working code sample (first image) in the bottom for you to try, and please tell me if I'm using the dropdown class wrong?

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<div class="container">
  <div class="row">
    <div class="col-12">
      <div class="input-group dropdown">
        <input type="text" class="form-control" id="project_search" placeholder="search ...">
        <div class="input-group-append">
          <div class="btn-group">
            <button class="btn bg-primary text-white" type="button">Search</button>
            <button class="btn bg-primary text-white dropdown-toggle dropdown-toggle-split" id="searchAdvancedFilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              <span class="caret"></span>
              <span class="sr-only">Toggle Dropdown</span>
            </button>
            <div class="dropdown-menu dropdown-menu-right w-100" aria-labelledby="searchAdvancedFilter">
              <h6 class="dropdown-header">Advanced Settings</h6>
              <div class="dropdown-divider"></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

I have figured out a way to resolve my issue, but then I encountered yet with another question, first of all, here's the code.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<div class="container">
  <div class="row">
    <div class="col-12">
      <div class="input-group dropdown">
        <input type="text" class="form-control" id="project_search" placeholder="search ...">
        <button class="btn bg-primary text-white" type="button">Search</button>
        <button class="btn bg-primary text-white dropdown-toggle dropdown-toggle-split" id="searchAdvancedFilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          <span class="caret"></span>
          <span class="sr-only">Toggle Dropdown</span>
        </button>
        <div class="dropdown-menu dropdown-menu-right w-100" aria-labelledby="searchAdvancedFilter">
          <h6 class="dropdown-header">Advanced Settings</h6>
          <div class="dropdown-divider"></div>
        </div>
      </div>
    </div>
  </div>
</div>

What I've done is I've removed both .input-group-append div and .btn-group div, and have my .dropdown-menu right under .dropdown, as well as having the toggle at the same level with the menu. Everything works fine ... expect the .input-group / .btn-group styles are now ruined.

Without manually using CSS class to override them, is there anything wrong with my class structure with the previous version that has caused it not to function what I wanted to achieve?


Solution

  • Make the containing btn-group position:static like this...

    https://www.codeply.com/go/6kJ3E53PuF

    <div class="container">
      <div class="row">
        <div class="col-12">
          <div class="input-group dropdown">
            <input type="text" class="form-control" id="project_search" placeholder="search ...">
            <div class="input-group-append">
              <div class="btn-group position-static">
                <button class="btn bg-primary text-white" type="button">Search</button>
                <button class="btn bg-primary text-white dropdown-toggle dropdown-toggle-split" id="searchAdvancedFilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                  <span class="caret"></span>
                  <span class="sr-only">Toggle Dropdown</span>
                </button>
                <div class="dropdown-menu dropdown-menu-right w-100" aria-labelledby="searchAdvancedFilter">
                  <h6 class="dropdown-header">Advanced Settings</h6>
                  <div class="dropdown-divider"></div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    

    How it works:

    The dropdown-menu in Bootstrap 4 is position:absolute, and by default, the btn-group is position:relative. A position:absolute element inside a position:relative container will size relative to the container. However, when a position:absolute element is placed inside a position:static container, it will no longer resize relative to the container. This is allowing the dropdown-menu to size the full-width of the dropdown. See this example of absolute inside relative vs. static.