简体   繁体   中英

Twitter Typeahead.js and remote URL that returns two lists instead of one

I read in twitter's typeahead.js documentation that its possible to have more than one remote sources.

I'd like to know if there is a similar approach, in which there is only one remote URL that returns many lists ,

example:

 //URL: Search?query=blah

 //returns this JSON:

 {
     error: false,
     persons = [
        {personId: 5, name: "John", surname: "Blah"},
        {personId: 12, name: "Blah", surname: "Edwards"},
     ],
     pets = [
        {petId: 534, petName: "Blah duck"},
        {petId: 123, petName: "Blah kitty"},
     ]
 }

As you can see, my searcher returns two lists: persons and pets. In each of these lists there are items containing the query word, "Blah"

How can I configure the bloodhound and the typeahead so that this works as it was two sources? but without having two sources (because that would do two ajax calls each time)

This is what I have, with the unknown code commented

// Typeahead
headerSearchBloodhound = new Bloodhound({
    datumTokenizer: function (item) { 
          /* how can I tokenize in this case? */ 
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
        url: '/Search',
        ajax: {
            beforeSend: function (xhr) {
                $(".searching-in-navbar").show();
            },
            data: {
                "query": $("#header-search").val(),
            }
        },
        filter: function (response) {
            $(".searching-in-navbar").hide();

            /* what should I return here if I have two lists rather than one? */
        }
    }
});

headerSearchBloodhound.initialize();

$("#header-search").typeahead({
    highlight: false,
    hint: true,
},
{
    name: 'headerSearch',
    displayKey: function (item) {
        /* 
             I want to display petName for pets and "name surname" for persons.
             How can I achieve that?
        */
    },
    source: headerSearchBloodhound.ttAdapter()
})
.on("typeahead:selected typeahead:autocompleted", function (e, item) {
    /*
        I want to redirect to /Persons/Details?personId=.. if it is a person
        or redirect to /Pets/Details?petId=.. if it is a pet.

        How do I achieve that?
    */
})
.on("typeahead:closed", function (e) {

    // Force lose focus
    $(":focus").blur();
    $(this).typeahead("val", "");
})
.on("typeahead:opened", function (e) { });

As you can see, the commented questions are very clear.
I know how to handle one list, but can't figure out a clean way of handling two lists.

I want the resulting textbox to be like this:
http://twitter.github.io/typeahead.js/examples/#multiple-datasets

这两个列表的外观如何

You'll need to call your AJAX outside of the Bloodhound and create two. Something along these lines:

$(document).ready(function(e) {

    // Call your business layer
    $.ajax({
        url: 'Search.php',
        type: 'GET',
        data: {'query': 'blah'},
        success: function(jsonData) {

            // Create the typeahead
            createTypeahead(jsonData);
        }
    }); // end ajax call

});



function createTypeahead(jsonData){

    // constructs the suggestion engines
    var persons = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        // `states` is an array of state names defined in "The Basics"
        local: $.map(jsonData.persons, function(state) { return { value: state }; })
    });
    var pets = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        // `states` is an array of state names defined in "The Basics"
        local: $.map(jsonData.pets, function(state) { return { value: state }; })
    });

    persons.initialize();
    pets.initialize();

    $("#header-search").typeahead({
            highlight: false,
            hint: true,
        },
        {
            name: 'persons',
            displayKey: 'persons',
            source: persons.ttAdapter(),
            templates: {
                header: '<h3 class="league-name">Persons</h3>'
            }

        },
        {
            name: 'pets',
            displayKey: 'pets',
            source: pets.ttAdapter(),
            templates: {
                header: '<h3 class="league-name">Pets</h3>'
            }

        }
    })
        .on("typeahead:selected typeahead:autocompleted", function (e, item) {
    })
        .on("typeahead:closed", function (e) {

            // Force lose focus
            $(":focus").blur();
            $(this).typeahead("val", "");
        })
            .on("typeahead:opened", function (e) { 
        }
    );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM