Bootstrap typeahead, change the datasource used by the bloodhound suggestion engine

I've a search field with autocomplete that is initialized like this:

    var reposVenda = new Bloodhound({
    datumTokenizer: function (d) { return Bloodhound.tokenizers.whitespace(d.bairro); },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    prefetch: {
        url: urlAutoCompleteVenda
    }
});

var reposAluguel = new Bloodhound({
    datumTokenizer: function (d) { return Bloodhound.tokenizers.whitespace(d.bairro); },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    prefetch: {
        url: urlAutoCompleteAluguel
    }
});

reposVenda.initialize();
reposAluguel.initialize();

$('#searchQuery').typeahead(null, {
    name: 'bairros',
    displayKey: 'bairro',
    source: reposVenda.ttAdapter(),
    templates: {
        suggestion: Handlebars.compile([
          '<p class="bairro-autocomplete">{{bairro}}</p>'
        ].join(''))
    },
    queryTokenizer: queryTokenizer
});

Now I need to change the source when user clicks a button on the page:

    $(".opt-busca-home").click(function (e) {
    e.preventDefault();

    var idItem = $(this).attr("id");
    buscaAtual = idItem.replace("opt-", "");

    if (buscaAtual == "comprar") {
        var autocomplete = $('#searchQuery').typeahead();
        autocomplete.data('typeahead').source = reposVenda.ttAdapter();
    }
    else {
        var autocomplete = $('#searchQuery').typeahead();
        autocomplete.data('typeahead').source = reposAluguel.ttAdapter();
    }
});

The problem is when I click the button to change the source the console tells me 'Uncaught TypeError: Cannot set property 'source' of undefined'

I tried every possible approach without success. The typeahead works but only with the initialized source. What I'm doing wrong?

Answers:

Answer

I've implemented a way of switching between data sources here:

http://jsfiddle.net/Fresh/EEuyL/

Note that whilst I've used local data sources in my answer, the solution will also be valid for prefetch/remote sources.

The code which I'm using to toggle between the different data sources is here:

var sourceSelected = $('#sourceSelected');
var toggle = false;

$('#switch').click(function () {
    titles.clear(); // First remove all suggestions from the search index

    if (!toggle) {
        toggle = true;
        titles.local = data2; // Next choose the desired alternate data source
        sourceSelected.text('Data Source 2');
    } else {
        toggle = false;
        titles.local = data1;
        sourceSelected.text('Data Source 1');
    }

    // Finally reinitialise the bloodhound suggestion engine
    titles.initialize(true); 
});

You can find the documentation for Bloodhound's clear method here, and its reinitialize method here.

Answer

I think a better way to do it will be to destroy the typeahead control and re-initialize it:

$(".opt-busca-home").click(function (e) {
    e.preventDefault();

    $('#searchQuery').typeahead('destroy');

    var idItem = $(this).attr("id");
    buscaAtual = idItem.replace("opt-", "");

    var source = null;
    if (buscaAtual == "comprar") {
        source = reposVenda.ttAdapter();
    }
    else {
        source = reposAluguel.ttAdapter();
    }

    $('#searchQuery').typeahead(null, {
        name: 'bairros',
        displayKey: 'bairro',
        source: source,
        templates: {
            suggestion: Handlebars.compile([
              '<p class="bairro-autocomplete">{{bairro}}</p>'
            ].join(''))
        },
        queryTokenizer: queryTokenizer
    });
});

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.