0

typeahead.js gives us the ability to render templates for our autocomplete suggestions using our engine of choice as long as the engine implements this API:

// engine has a compile function that returns a compiled template
var compiledTemplate = ENGINE.compile(template);

// compiled template has a render function that returns the rendered template
// render function expects the context to be first argument passed to it
var html = compiledTemplate.render(context);

Now dust.js has a slightly different take on the matter:

var compiled = dust.compile("Hello {name}!", "intro");
dust.loadSource(compiled);

Since I have dust.js already integrated, I'd like to use it to render typeahead's suggestions, too. I can probably wrap dust's engine object and provide the API required, but I'm wondering if there's a less intrusive and/or more elegant way to do this, e.g. by dynamically attaching the required functions to the dust object itself?

Edited to add: mixing what @user2103008 and @Simon have, here's what I'm using with typeahead-0.9.3:

function typeaheadFakeCompile(dustTemplateName) {
    return function(data) {
        var html;
        dust.render(dustTemplateName, data, function(err, out) { html = out; })
        return html;
    }
}

var compiled = dust.compile('Hello {name}!', 'myTemplate');
dust.loadSource(compiled);

$('selector').typeahead({
   template: typeaheadFakeCompile('myTemplate')
)};
mabi
  • 5,279
  • 2
  • 43
  • 78

1 Answers1

0

The template parameter passed to the typeahead plugin can be either a compiled template or a string. If it's a string, the typeahead plugin will attempt to compile it. Don't do this with dust. Instead, compile the dust templates like normal, but pass the template parameter as something like:

var compiled = dust.compile('Hello {name}!', 'myTemplate');
dust.loadSource(compiled);

$('selector').typeahead({
    template: fakeCompile('myTemplate')
)};

function fakeCompile (dustTemplateName) {
    return {
        render: function (data) {
            var html;
            dust.render(dustTemplateName, data, function (err,out) { html = out });
            return html;
        }
    }
}

Typeahead should use the "compiled" template as is without attempting another compile.

EDIT Thanks to @user2103008, fixed dust render callback function signature.

Simon
  • 1,756
  • 12
  • 8
  • Yeah, the anonymous object defining a `render` method was what I was looking for. Thanks! – mabi Oct 11 '13 at 12:12
  • I tried the same, and it didn't work for me. Apparently, the render method isn't even being called(added a console.log("Called") line in render). Any ideas ? – user2103008 Oct 30 '13 at 04:46
  • @user2103008, I'd need to see some code. Just a guess but could be typeahead isn't actually attempting to render due to some other issue somewhere else? – Simon Oct 30 '13 at 08:40
  • 1
    Figured it out: with typeaheadjs 0.9.3, template option in the dataset should point to the render function itself rather than an object. – user2103008 Oct 30 '13 at 11:57
  • 1
    Shouldn't the render function's signature be render: function (err,data) ? – user2103008 Oct 30 '13 at 22:35