Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap Typeahead not showing hints as expected

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.

like image 951
AngelGris Avatar asked Jun 23 '15 16:06

AngelGris


3 Answers

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.

like image 140
AngelGris Avatar answered Nov 16 '22 03:11

AngelGris


@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

like image 25
Marcin Avatar answered Nov 16 '22 03:11

Marcin


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

like image 2
Tim Ramsey Avatar answered Nov 16 '22 04:11

Tim Ramsey