Using functions on {{value}} before rendering datum as typeahead suggestions

798 views Asked by At

I have a basic template:

<p><a href="{{queryString}}{{valueModified}}">{{value}}</a></p>

And I have a function that I want to run {{value}} through before appending it to the query string:

valueModified = encodeURIComponent(value);

But I don't know how to do that as part of the initialization of the typeahead object:

$(document).ready(function() {
    $('.genericSearchBox').typeahead({
        prefetch: 'genericItemList.json',
        limit: 10,
        template: // ???
     });
});

Would a precompiled template be able to handle this entirely?

If so, what is the syntax for passing one to .typeahead() as part of defining the dataset?

What I've tried:

My JavaScript experience is limited and my experience with templates moreso (having just today learned about what they are and how they work). I've spent the afternoon reading about template-related topics, but most templates I've seen so far just defined HTML markup structure and various {{value}} placeholders.

I gave it a try by concatenating some literal strings and the encodeURIComponent function call, but it just broke the initialization:

template: '<p><a href=http://search.domain.edu/search?x=12&y=12&access=p&site=domain&output=xml_no_dtd&client=domain-v5&sort=date%253AD%253AL%253Ad1&proxystylesheet=domain-v5&oe=UTF-8&q=' + encodeURIComponent(value); + '>' + value + '</a></p>'

I didn't think it was possible when I attempted it. From what I understand, the syntax of .typeahead() looks for a dataset--and I've only seen functions used as part of assigning values to variables, not in defining datasets.

I can accomplish what I want by editing typeahead.js directly and replacing its default <p>{{value}}</p> template, but that doesn't strike me as a good long-term solution. I'm hoping someone might have a more appropriate suggestion that doesn't require modifying the plugin directly.

Thank you.

1

There are 1 answers

1
Nitzan Shaked On

There are several ways to solve this.

You could, for example, wrap your template engine with an adapter (something that conforms to the interface Tyepahead is expecting of template engines) to do what you want (it's a 2-liner).

Another, possibly more straight-forward way is process the results, and populate your datum with valueModified, and then use valueModified in the template directly. Something like:

$(document).ready(function() {
    $('.genericSearchBox').typeahead({
        prefetch: 'genericItemList.json',
        limit: 10,
        template: '<p><a href="{{queryString}}{{valueModified}}">{{value}}</a></p>',
        filter: function(response) {
            // sanity tests go here here
            retval = []
            for (var i = 0; i < response.length; i++) {
                retval.push({ value: response[i], title: response[i], valueModified: encodeURIComponent(response[i]) });
            }
            return retval;
        }
    });
});

... when the template engine is run, it is run in the context of your specific datum, so you have access to valueModified e.g.