Typeahead custom template Without Handlebars
Asked Answered
P

3

29

I'm trying to implement the Typeahead.JS "Custom Template" example.

$('#custom-templates .typeahead').typeahead(null, {
  name: 'best-pictures',
  displayKey: 'value',
  source: bestPictures.ttAdapter(),
  templates: {
    empty: [
      '<div class="empty-message">',
      'unable to find any Best Picture winners that match the current query',
      '</div>'
    ].join('\n'),
    suggestion: Handlebars.compile('<p><strong>{{value}}</strong> – {{year}}</p>')
  }
});

Specifically this line:

suggestion: Handlebars.compile('<p><strong>{{value}}</strong> – {{year}}</p>')

Initially I didn't realise you need to explicitly require Handlebars as a dependancy:

Uncaught ReferenceError: Handlebars is not defined

When I remove Handlebars...

suggestion: '<p><strong>' + value + '</strong> – ' + year + '</p>'

It gives another JS error:

Uncaught ReferenceError: value is not defined

Is it possible to use a custom view template without using Handlebars engine?

Pigmentation answered 24/3, 2015 at 1:32 Comment(0)
P
70

Use this format:

suggestion: function(data) {
    return '<p><strong>' + data.value + '</strong> – ' + data.year + '</p>';
}

Taken from this thread.

Pigmentation answered 24/3, 2015 at 1:32 Comment(0)
A
5

This might help - I've integrated it with Bootstrap:

<div class="col-lg-3" id="the-basics">
<input type="text" class="typeahead form-control" placeholder="my placeholder" aria-describedby="basic-addon1">
</div>

$('#the-basics .typeahead').typeahead(null, {
  name: 'best-pictures',
  display: 'imageUrl',
  source: function show(q, cb, cba) {
    console.log(q);
    var url = '/yoururl/'+q;
    $.ajax({ url: url })
    .done(function(res) {
      cba(res.list);;
    })
    .fail(function(err) {
      alert(err);
    });
  },
    limit:10,
  templates: {
    empty: [
      '<div class="empty-message">',
        'No data',
      '</div>'
    ].join('\n'),
    suggestion: function(data) {
      return '<p><strong>' + data.itemName + '</strong> - <img height:"50px" width:"50px" src='+data.imageUrl+'></p>';
    }
  }
});
Antecede answered 27/7, 2017 at 13:49 Comment(0)
B
0

You can be a bit more terse and kinda get the best of both worlds nowadays with arrow syntax and Javascript String Interpolation. You get to avoid calling in an external library and still get nice code readability:

suggestion: d => `<p><strong>${data.value}</strong> - ${data.year}</p>`

Note that Javascript String Interpolation uses backticks instead of single quotes to start end end the string. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

If you're using more elaborate JSON data rather than a simple array of strings, you should be aware of 3 things Typeahead is going to do to you that are not documented:

First, before getting to Typeahead, you are going to have to configure Bloodhound to tokenize the right part of your JSON. Assuming data like:

[ { id: 1, name: "Ford" }, { id: 2 ...

You'll need Bloodhound configured like:

{
    identify: d => d.id,
    datumTokenizer: d => Bloodhound.tokenizers.whitespace(d.name)
}

Once you apply your template:

display: 'name',
templates: {
    suggestion: d => {
        var s = d.name.replace(d._query, '<strong>$&</strong>');
        return `<div>${s}</div>`;
    }
}
  1. You will be passed a mixin object. The JSON data in our example uses id/name pairs. The object passed to the suggestion function has that pair plus an inserted value _query which contains a string, what the user has typed in the searchbox so far. So in the above, `d = { _query: 'f', name: 'Ford', id: 1 }

  2. You become responsible for applying your own highlighting. In the above, I'm performing this with a simple replace - take the query and call String.replace on it with $& wrapped in strong to leverage JS's builtin match insertion.

  3. The template you return is going to get modified significantly. The tt- classes are going to get applied throughout, which by default is going to cause the above, simple template with a div and strong tag that has no classes applied...

...will actually render in the DOM like this:

<div class="tt-suggestion tt-selectable tt-cursor">
    <strong class=tt-highlight>F</strong>ord
</div>
<div class="tt-suggestion tt-selectable">
    <strong class=tt-hightlight>F</strong>ord F150
</div>
...

So your simple div and strong above are going to get a lot of tt- classes inserted. If you overrode those classes in your Typeahead config then obviously those classes will be applied instead. The tt-cursor class tells you which one is currently keyboard-selected (with the up/down keys for example).

Edit: Markdown couldn't handle a transition from a numbered list to a code block, so I had to break it up with an awkward ellipsis break.

Binetta answered 10/7, 2023 at 19:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.