Anriëtte Myburgh
Anriëtte Myburgh

Reputation: 13537

TypeAhead and Bloodhound only searching on first words in JSON array

I'm using TypeAhead to provide autocomplete results for a textbox. But it seems either Bloodhound or TypeAhead is only searching on the first words of found in the JSON array I'm providing.

The JSON looks as follows:

[
    {
        "name": "ALICE",
        "value": "ALICE",
        "physical_address": "ERF 270 CNR. OF THOMPSON AND INTWANA STREET, ALICE",
        "province": "PROVINCE",
        "tokens": [
            "ALICE",
            "PROVINCE",
            "ERF",
            "270",
            "CNR.",
            "OF",
            "THOMPSON",
            "AND",
            "INTWANA",
            "STREET",
            "ALICE"
        ]
    },
    {
        "name": "BUTTERWORTH",
        "value": "BUTTERWORTH",
        "physical_address": "SHOP NO. 1 MASONIC SHOPPING COMP, COR HIGH & BELL STREET BUTTERWORTH 4960",
        "province": "PROVINCE",
        "tokens": [
            "BUTTERWORTH",
            "PROVINCE",
            "SHOP",
            "NO.",
            "1",
            "MASONIC",
            "SHOPPING",
            "COMP",
            "COR",
            "HIGH",
            "&",
            "BELL",
            "STREET",
            "BUTTERWORTH",
            "4960"
        ]
    }
]

I'm intialising TypeAhead as follows:

HTML:

<div class="films">
    <input type="text" class="form-control typeahead" placeholder="Search" name="films" autocomplete="off" id="search">
</div>

Javascript:

/* TypeAhead invoked */
var _prefetch_url = $root_path + '/media/mod_storelocator/stores_json.php';

// constructs the suggestion engine
var films = new Bloodhound({
    datumTokenizer: function (d) {
        return Bloodhound.tokenizers.whitespace(d.value);
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    limit: 15,
    prefetch: _prefetch_url
});

// kicks off the loading/processing of `local` and `prefetch`
films.initialize();

$('.films .typeahead').typeahead(null, {
    displayKey : 'value',
    source: films.ttAdapter(),
    templates: {
        suggestion: Handlebars.compile([
            '<p class="repo-language">{{province}}</p>',
            '<p class="repo-name">{{name}}</p>',
            '<p class="repo-description">{{physical_address}}</p>'
        ].join(''))
    }
});

I'd really appreciate any help/pointers.

Upvotes: 2

Views: 1945

Answers (1)

mccannf
mccannf

Reputation: 16659

You were passing in d.value into the datumTokenizer, so it was using just the value object from each element in the array.

Note also that Bloodhound tokenizes the data itself, so you don't need to pass back the individual tokens in your JSON (i.e. you don't need the tokens object).

So I would change it to use Bloodhound to tokenize the value and the physical_address objects combined of each element in the array:

// constructs the suggestion engine
var films = new Bloodhound({
    datumTokenizer: function(d) { 
                      return Bloodhound.tokenizers.whitespace(d.name); 
                    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    limit: 15,
    prefetch: {
       url: _prefetch_url,
       filter: function(list) {
          return $.map(list, 
                 function(element) { 
                         return { name: element.value + " " + element.physical_address }; 
                 });
       }
    }
});

Have only been able to test this in a local context with this fiddle, but the prefetch should work the same way.

Upvotes: 1

Related Questions