Bootstrap Typeahead not showing hints as expected
Asked Answered
D

3

6

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.

Doubleripper answered 23/6, 2015 at 16:0 Comment(0)
D
24

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.

Doubleripper answered 24/6, 2015 at 14:49 Comment(3)
Could you provide a link to the GitHub issue?Cluj
Thanks a lot, we had an issue caused by the tab index not being correctly set on the hint element. When I encountered your question, I thought it could be related (it isn't however, but thanks for sharing the link)Cluj
Thank you very much for this, this is still an issue as the current version is still 0.11.1 and this fix resolved the problem for me. Note to anybody using the jQuery typeahead plugin - you can make the exact same change in the typeahead.jquery.js file to fix the issue there.Arrears
M
3

@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

Meath answered 11/3, 2016 at 8:35 Comment(0)
L
2

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

Louettalough answered 13/12, 2017 at 15:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.