简体   繁体   中英

Searchable Bootstrap Dropdown

So I'm trying to create a searchable list of links to divs that a user could use to quickly jump to that location on the page. This is using Flask and Bootstrap.

I successfully built a dropdown to do this, but it isn't searchable.

<li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown"
       aria-haspopup="true" aria-expanded="false">
        Quick Scroll
    </a>
    <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
        {% for company in active_companies %}
            <a class="dropdown-item" href="#company_{{ company[0] }}"
               role="button">
                {{ company[1] }}
            </a>
        {% endfor %}
    </div>
</li>

I've tried Bootstrap-Select , but I can't seem to get the library to load properly. Maybe a Bootstrap 4 issue, maybe Flask, maybe me. I tried loading Semantic UI's dropdown module (and refactoring to avoid any conflicts), but that didn't work either. So I set out to put one together on my own.

I've got this going right now. The dropdown is visible upon clicking the input box and closes upon clicking the input box. If I could just get it to close upon a click elsewhere I would be content. But my attempts to use window.onclick have failed.

If you could point me towards a Bootstrap implementation that would work, or see a flaw in what I'm doing (of which I'm sure there are countless) let me know.

    <form class="form-inline my-2 my-lg-0">
        <input onclick="myFunction()" type="text" class="live-search-box" placeholder="Company/Complex"/>
        <ul class="live-search-list dropdown-menu scrollable-menu" id="toggle-thingy">
            {% for company in active_companies %}
                <li>
                    <a class="dropdown-item" href="#company_{{ company[0] }}">
                        {{ company[1] }}
                    </a>
                </li>
            {% endfor %}
            {% for complex in company_complex %}
                <li>
                    <a class="dropdown-item" href="#P{{ complex[2] }}">
                        {{ complex[3] }}
                    </a>
                </li>
            {% endfor %}
        </ul>
    </form>

Using this JS:

jQuery(document).ready(function($){
/* Searches List Items */
$('.live-search-list li').each(function(){
$(this).attr('data-search-term', $(this).text().toLowerCase());
});

$('.live-search-box').on('keyup', function(){

var searchTerm = $(this).val().toLowerCase();

    $('.live-search-list li').each(function(){

        if ($(this).filter('[data-search-term *= ' + searchTerm + ']').length > 0 || searchTerm.length < 1) {
            $(this).show();
        } else {
            $(this).hide();
        }

    });

});

});

/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
    document.getElementById("toggle-thingy").classList.toggle("show");
}

And this CSS:

.live-search-list {
    position: absolute;
    margin-left: 10px;
    margin-right: 10px;
    top: 100%;
    left: 0;
    z-index: 1000;
    /*display: inline-block;*/
    float: left;
    min-width: 10rem;
    padding: 0 0;
    font-size: 0.875rem;
    color: #263238;
    text-align: left;
    list-style: none;
    background-color: #fff;
    background-clip: padding-box;
    border: 1px solid #cfd8dc;
}
.live-search-box {
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    line-height: 1.25;
    color: #607d8b;
    background-color: #fff;
    background-image: none;
    background-clip: padding-box;
    border: 1px solid rgba(0, 0, 0, 0.15);
    border-radius: 0;
    transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
}

.live-search-list li {
    list-style: none;
    padding: 0;
    margin: 5px 0;
}

.show {display:inline-block;}

.scrollable-menu {
    height: auto;
    max-height: 200px;
    overflow-x: hidden;
}

EDIT FOR THE MODERN ERA: Please do not use the below solution anymore! This was done because the incredible bootstrap-select plugin library had not been updated for Bootstrap 4 at the time. It now has! It's way better than my hacky solution.

I solved it. I took a default Bootstrap 4 dropdown like:

<div class="dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Dropdown button
  </button>
  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
    <a class="dropdown-item" href="#">Action</a>
    <a class="dropdown-item" href="#">Another action</a>
    <a class="dropdown-item" href="#">Something else here</a>
  </div>
</div>

And modified it to become:

<div class="dropdown nav-item">
    <input 
        class="dropdown-toggle form-control live-search-box" 
        id="quicksearch" 
        data-toggle="dropdown" 
        aria-haspopup="true" 
        aria-expanded="false" 
        placeholder="Company/Complex Name" 
        style="width: 250px;">
    <div class="dropdown-menu live-search-list" aria-labelledby="dropdownMenuButton">
        {% for company in active_companies %}
        <li>
            <a class="dropdown-item" href="#company_{{ company[0] }}">
                        {{ company[1] }}
                    </a>
        </li>
        {% endfor %} {% for complex in company_complex %}
        <li>
            <a class="dropdown-item" href="#P{{ complex[2] }}">
                        {{ complex[3] }}
                    </a>
        </li>
        {% endfor %}
    </div>
</div>

If you are having a hard time following, here is what I did.

I turned the <button> into an <input> , removed the classes btn and btn-secondary and the type="button" , added the class live-search-box to the <input> and the class live-search-list to the <div class="dropdown menu"> (so it can run the search function, which I will display below just in case). I then wrapped the <a> 's in <li> 's so the search will see them. I then added 'nav-item' to the parent because that's where I will be using this (you don't need to do this). The {%%} is merely jinja formatting for the python loops that populate this dropdown. It would work fine with a hardcoded list of <li> 's.

And there you have it. A functional searchable dropdown for Bootstrap 4.

The JS <li> search function that filters the dropdown.

jQuery(document).ready(function($){
/* Searches List Items */
$('.live-search-list li').each(function(){
$(this).attr('data-search-term', $(this).text().toLowerCase());
});

$('.live-search-box').on('keyup', function(){

var searchTerm = $(this).val().toLowerCase();

    $('.live-search-list li').each(function(){

        if ($(this).filter('[data-search-term *= ' + searchTerm + ']').length > 0 || searchTerm.length < 1) {
            $(this).show();
        } else {
            $(this).hide();
        }

    });

});

});

Try replacing with this function as I don't find your li containing data-search-term attribute.

  $('.live-search-box').keyup(function(){
   var searchTerm = $(this).val().toLowerCase();
    $('.live-search-list li').each(function(){
     var text = $(this).text().toLowerCase(); //Trythis
        (text.indexOf(valThis) !== -1) ? $(this).show() : $(this).hide();            
   });
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM