Bootstrap Typeahead not showing hints as expected

5.3k views Asked by At

I'm using Typeahead to show hints from an items database and a stores database. When I show hints only from items it shows fine, when I show only from stores works fine too, but when I try to show mixed results it just shows the default empty message. Check the AJAX answer and in the three cases it seems fine, so it has to be on the client side.

The JS code is this:

var items = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote: {
    url: '/ajax/pesquisar/',
    prepare: function(query, settings) {
      tokens = query.trim().split(' ');
      return '/ajax/pesquisar/' + tokens.join('/') + '/';
    }
  }
});

$('input.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 1
},
{
    name: 'items',
    display: 'name',
    source: items,
    templates: {
      empty: [
        '<div class="empty-message">',
        'Nenhum item relacionado',
        '</div>'
      ].join('\n'),
      suggestion: Handlebars.compile('<a href="{{url}}"><div class="suggestion"><div class="icone" style="background-image:url({{img}});"></div>{{name}}</div></a>')
    }
});

The AJAX response just for items (showing properly):

[
  {
    "id":"00007531",
    "url":"\/higiene-e-limpeza\/cabelos\/condicionador-seda-cachos-comportados-e-definidos-350ml\/",
    "name":"Condicionador Seda Cachos Comportados e Definidos 350mL",
    "img":"\/img\/produtos\/7891037000315_I.png"
  },
  {
    "id":"00007641",
    "url":"\/higiene-e-limpeza\/cabelos\/shampoo-seda-cachos-comportados-e-definidos-350ml\/",
    "name":"Shampoo Seda Cachos Comportados e Definidos 350mL",
    "img":"\/img\/produtos\/7891037000308_I.png"
  }
]

Just for stores (working fine too):

[
  {
    "id":"00000001",
    "url":"\/nidobox\/montese\/",
    "name":"Supermercado Nidobox - Montese",
    "img":"\/img\/supermercados\/nidobox_i.jpg"
  },
  {
    "id":"00000002",
    "url":"\/nidobox\/damas\/",
    "name":"Supermercado Nidobox - Damas",
    "img":"\/img\/supermercados\/nidobox_i.jpg"
  },
  {
    "id":"00000003",
    "url":"\/nidobox\/aeroporto\/",
    "name":"Supermercado Nidobox - Aeroporto",
    "img":"\/img\/supermercados\/nidobox_i.jpg"
  }
]

And when mixing both results (showing the default empty message):

[
  {
    "id":"7531",
    "url":"\/higiene-e-limpeza\/cabelos\/condicionador-seda-cachos-comportados-e-definidos-350ml\/",
    "name":"Condicionador Seda Cachos Comportados e Definidos 350mL",
    "img":"\/img\/produtos\/7891037000315_I.png"
  },
  {
    "id":"7641",
    "url":"\/higiene-e-limpeza\/cabelos\/shampoo-seda-cachos-comportados-e-definidos-350ml\/",
    "name":"Shampoo Seda Cachos Comportados e Definidos 350mL",
    "img":"\/img\/produtos\/7891037000308_I.png"
  },
  {
    "id":"1",
    "url":"\/nidobox\/montese\/",
    "name":"Supermercado Nidobox - Montese",
    "img":"\/img\/supermercados\/nidobox_i.jpg"
  },
  {
    "id":"2",
    "url":"\/nidobox\/damas\/",
    "name":"Supermercado Nidobox - Damas",
    "img":"\/img\/supermercados\/nidobox_i.jpg"
  },
  {
    "id":"3",
    "url":"\/nidobox\/aeroporto\/",
    "name":"Supermercado Nidobox - Aeroporto",
    "img":"\/img\/supermercados\/nidobox_i.jpg"
  }
]

The search string used is "nido". . The only difference I see between them are the trailing zeros in the ID. Converted those IDs to int and still have the same problem. Can anyone see what I'm missing?

Thanks

EDIT: Sliced the results array to 4 hints on the server side and now typeahead instead of showing the empty message shows the first hint and not the other 3.

3

There are 3 answers

3
AngelGris On BEST ANSWER

Found the problem. It's a bug in typeahead.bundle.js (v 0.11.1). It's counting the number of rendered hints before appending them, so if the number of hints equals the limit it'll append an empty array.

To prevent this I just switched lines 1723 and 1724 so it looks like this:

that._append(query, suggestions.slice(0, that.limit - rendered));
rendered += suggestions.length;

Already reported the issue in typeahead's github.

0
Tim Ramsey On

Another option to work around the issue if you are using a hosted CDN version is to set limit:'Infinity' when initiating:

$(".input-search").typeahead({
        hint: true,
        highlight: true,
        minLength: 2,
    }, {
        limit:'Infinity',
        source: engine,           
    });

and then limit the results on the server

0
Marcin On

@Luciano Garcia Bes - to complete your anwser, below I've post all changes which are needed : you have rigth to switch those lines, but I need remove - rendered too. So finally It sholud looks like this (whole function):

            function async(suggestions) {
                suggestions = suggestions || [];
                if (!canceled && rendered < that.limit) {
                    that.cancel = $.noop;
                    that._append(query, suggestions.slice(0, that.limit));
                    rendered += suggestions.length;
                    that.async && that.trigger("asyncReceived", query);
                }
            }

more about this iisue : https://github.com/twitter/typeahead.js/issues/1415