Bootstrap input dropdown, change activation behavior

自作多情 提交于 2019-12-24 11:39:09

问题


I'm trying to implement a dropdown box to show search options, much the way the Stack Overflow tag search box works. The search itself is working great, but I can't get the box to show up at the right times.

Here's the template:

<div class="dropdown">
    <input class="entryInput" id="query" name="query" type="text"
        data-toggle="dropdown"/>
    <ul class="dropdown-menu" role="menu" aria-labelledby="query">
        {{#each queryResults}}
            <li><a class="result" data-id="{{_id}}">{{firstname}}</a></li>
        {{/each}}
    </ul>
</div>

This code works, and the list displays in the dropdown, but it displays an empty stub when the input is first clicked (see my screencap to see what that empty stub looks like), and disappears when I begin typing.

Elsewhere in my app, I manage Session.get('query') and Session.get('queryPopulated'), which are the values I want this dropdown to react to. query is simply storing the query itself in real-time, and queryPopulated is a boolean that is set when the user chooses a result. I want the dropdown to stay active as long as these things are true:

  • the input has focus;
  • the query is valid (so no showing a lame stub);
  • and queryPopulated is false (because there's no more reason to display, the user chose a result).

The Bootstrap docs only provide a toggle method, and that just isn't really fine-grained enough. I need to manually take control of the dropdown's reactions, and I'm not sure how to do that with the events and methods it's exposed.

How do I override the behavior?

Here's what that lame stub looks like.

Thanks in advance!

Update

I now have this javascript managing the dropdown:

Template.entryStudentInput.rendered = function() {
    $('.dropdown').on('shown.bs.dropdown', function(){
        console.log('show');
        if(!Session.get('query')) {
            console.log('query is false in show');
            $('.dropdown').dropdown('toggle');
        }
    });
};

That block above successfully prevents the dropdown from showing when empty, but I can't get the dropdown to show again once the query is valid.

Here's another block, meant only as an experiment, reacting to key events:

Template.entryStudentInput.events({
    'keyup #query': function(e, t) {
        console.log('should toggle');
        $('dropdown').dropdown('toggle');
        // These didn't work either.
        // $(t.find('.dropdown')).dropdown('toggle');
        // t.find('.dropdown').dropdown('toggle');
    }
});

It should simply toggle back and forth every time a key is pressed, but it doesn't do anything at all. The console log shows up just like it should, but there's no change whatsoever on the dropdown. It seems like I just have no control over the dropdown from anywhere but the $('.dropdown').on event handlers.


回答1:


You just have to reverse toggle effect of your ul when it doesn't have children.

Exemple with 2 dropdowns, 1 with and 1 without children.

Bootply : http://www.bootply.com/120571

JS :

$('.dropdown').on('shown.bs.dropdown', function(){
    if( $(this).find('.dropdown-menu').children().length == 0)
    {
      $(this).dropdown('toggle');
    }
});

HTML :

<div class="col-md-6">
  <div class="dropdown">
      <input class="entryInput" id="query" name="query" type="text" data-toggle="dropdown">
      <ul class="dropdown-menu" role="menu" aria-labelledby="query">
              <li><a class="result" data-id="{{_id}}">{{firstname}}</a></li>
              <li><a class="result" data-id="{{_id}}">{{firstname}}</a></li>
              <li><a class="result" data-id="{{_id}}">{{firstname}}</a></li>
              <li><a class="result" data-id="{{_id}}">{{firstname}}</a></li>
              <li><a class="result" data-id="{{_id}}">{{firstname}}</a></li>
              <li><a class="result" data-id="{{_id}}">{{firstname}}</a></li>
      </ul>
  </div>
 </div>

UPDATE :

To achieve what you want so, a better method is to affect the hidden class when no children, and remove this class when your query populate it.

Bootply : http://www.bootply.com/120667

As you can see in this exemple [ a setTimeout is running to emulate your achieved query] , when the first ul don't have children, nothing append, and when this ul is populated, the dropdown appear.

JS:

$('.dropdown').on('shown.bs.dropdown', function(e){
    if( $(this).find('.dropdown-menu').children().length == 0)
    {
      $(this).find('.dropdown-menu').addClass('hidden');
    }
});

setTimeout(function(){
   $('.dropdown').first().find('.dropdown-menu').append($('.dropdown').last().find('.dropdown-menu').html());
  $('.dropdown').first().find('.dropdown-menu').removeClass('hidden');
  alert('5s elapsed');
}, 5000);



回答2:


I found it was cleaner to abandon the dropdown box entirely. It didn't fit my needs. I instead have just created a list-group that appears/reappears as the query changes.

<div class="input-group">
    <input class="entryInput form-control" id="query" name="query" type="text"
        {{#if session "queryPopulated"}}readonly{{/if}}/>
    <span class="input-group-btn">
        <button id="cancelQuery" class="btn btn-default" type="button"
        {{#unless session "queryPopulated"}}disabled{{/unless}}>
            <span class="glyphicon glyphicon-remove">
        </button>
    </span>
</div>
<div class="list-group" {{#unless queryShow}}hidden{{/unless}}>
    {{#each queryResults}}
        <a href="#" class="result list-group-item" data-id="{{_id}}">{{firstname}} {{lastname}}</a>
    {{else}}
        <a href="#" class="list-group-item">There are no results for that search.</a>
    {{/each}}
</div>

The queryShow helper is implemented like this:

Template.entryStudentInput.queryShow = function() {
    return Session.get('query') && !Session.get('queryPopulated');
};

This works great, although it does push content it downwards. I personally don't care.



来源:https://stackoverflow.com/questions/22285537/bootstrap-input-dropdown-change-activation-behavior

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!