最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Searchable Bootstrap Dropdown - Stack Overflow

programmeradmin2浏览0评论

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 pany in active_panies %}
            <a class="dropdown-item" href="#pany_{{ pany[0] }}"
               role="button">
                {{ pany[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 pany in active_panies %}
                <li>
                    <a class="dropdown-item" href="#pany_{{ pany[0] }}">
                        {{ pany[1] }}
                    </a>
                </li>
            {% endfor %}
            {% for plex in pany_plex %}
                <li>
                    <a class="dropdown-item" href="#P{{ plex[2] }}">
                        {{ plex[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;
}

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 pany in active_panies %}
            <a class="dropdown-item" href="#pany_{{ pany[0] }}"
               role="button">
                {{ pany[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 pany in active_panies %}
                <li>
                    <a class="dropdown-item" href="#pany_{{ pany[0] }}">
                        {{ pany[1] }}
                    </a>
                </li>
            {% endfor %}
            {% for plex in pany_plex %}
                <li>
                    <a class="dropdown-item" href="#P{{ plex[2] }}">
                        {{ plex[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;
}
Share Improve this question edited Feb 28, 2017 at 21:21 Jon asked Feb 28, 2017 at 19:03 JonJon 4322 gold badges7 silver badges20 bronze badges 2
  • have you tried select2? – Vishal Kumar Sahu Commented Feb 28, 2017 at 19:04
  • Nope, I'll give it a whirl – Jon Commented Feb 28, 2017 at 19:07
Add a ment  | 

2 Answers 2

Reset to default 2

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 bee:

<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 pany in active_panies %}
        <li>
            <a class="dropdown-item" href="#pany_{{ pany[0] }}">
                        {{ pany[1] }}
                    </a>
        </li>
        {% endfor %} {% for plex in pany_plex %}
        <li>
            <a class="dropdown-item" href="#P{{ plex[2] }}">
                        {{ plex[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();            
   });
  });
发布评论

评论列表(0)

  1. 暂无评论