Using Twitter Typeahead in ASP.net MVC

wegelagerer picture wegelagerer · Oct 30, 2014 · Viewed 9.5k times · Source

After having a couple of hours spent just to get Twitter typeahead displaying autocomplete values I'm having a hard time figuring out how to replace all dropdownlists in Create and Edit actions in my controller.

There are couple of problem I'm aware of having. First one is how to pass the ID (key) of the selected object to the typeahead.My JSON has Key value which is basically ID and Value value which is Name of the object. JSON can be seen below.

[{"Key":1,"Value":"Test1"},{"Key":2,"Value":"Test2)"},{"Key":4,"Value":"Adagreb d.o.o."},{"Key":5,"Value":"AGB Nielsen."}]

After getting and converting JSON to an array of Javascript objects data is passed to the control that should display autocomplete (typeahead).

        var substringMatcher = function (strs) {
        //ommited for brevity
        };

        function getJson(url) {
        //ommited for brevity
        }

        function simpleArray(target) {
            var arr = [];
            $.each(target, function (i, e) {
                $.each(e, function (key, val) {
                    arr.push(val);
                    console.log(val + "-" + key);
                });
            });
            return arr;
        }

        function typeaheadSetup(control, data) {          
            $(control).typeahead({
                hint: true,
                highlight: true,
                minLength: 2
            }, {
                displayKey: 'value',
                source: substringMatcher(simpleArray(data))
            });
        }

        var companies = getJson('/Ticket/GetCompanies');
        typeaheadSetup('#idFirma', companies);

My question is how to pass the ID (Key) while displaying the value (Value) and by also being able to save this by passing the model to the database.

Answer

Koti Panga picture Koti Panga · Oct 30, 2014

We should use Bloodhound's ttAdapter which comes from typeahead bundle and can capture the selected suggestion-item from typeahead:selected event.

Below is the script for your reference:

TestCase#1 with local dataset Working fiddle

<label for="company_search">Company Search:</label>
<input id="company_search" type="text" class="typeahead" />
<div id="selectedCompany"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://twitter.github.io/typeahead.js/releases/0.10.4/typeahead.bundle.js"></script>
<script>
   $(function () {
       var $SelectedCompany = $('#selectedCompany').hide(),
           companyList = [{"Key":1,"Value":"Test1"},{"Key":2,"Value":"Test2)"},{"Key":4,"Value":"Adagreb d.o.o."},{"Key":5,"Value":"AGB Nielsen."}];

       var companies = new Bloodhound({
           datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Value'),
           queryTokenizer: Bloodhound.tokenizers.whitespace,
           local: companyList
           //,prefetch: '/path/to/prefetch'
           //,remote: {/* You can use this for ajax call*/ } 
       });

       companies.initialize();

       $('#company_search').typeahead({ highlight: true, minLength: 2 }, {
           name: 'companies', displayKey: 'Value', source: companies.ttAdapter()
       })
       .on("typeahead:selected", function (obj, company) {
           $SelectedCompany.html("Selected Company: " + JSON.stringify(company)).show();
       });

   });
</script>

Edit:
TestCase#2 with remote dataset Working fiddle

<input class="typeahead" placeholder="Type here to Search Movie..."></input>
<div id="selectedSuggestion"></div>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://twitter.github.io/typeahead.js/releases/0.10.4/typeahead.bundle.js"></script>
    <script>
   $(function () {
       //Docs: https://github.com/twitter/typeahead.js/blob/master/doc/bloodhound.md#remote
       var $SelectedSuggestion = $('#selectedSuggestion').hide(),
           movies = new Bloodhound({
               datumTokenizer: function (datum) {
                   return Bloodhound.tokenizers.whitespace(datum.title);
               },
               queryTokenizer: Bloodhound.tokenizers.whitespace,
               remote: {
                   url: 'http://api.themoviedb.org/3/search/movie?query=%QUERY&api_key=470fd2ec8853e25d2f8d86f685d2270e',
                   filter: function (movies) {
                       return movies.results;
                   }
               }
           });

       // Initialize the Bloodhound suggestion engine
       movies.initialize();

       // Instantiate the Typeahead UI
       $('.typeahead').typeahead(null, {
           displayKey: 'title',
           source: movies.ttAdapter()
       })
           .on("typeahead:selected", function (obj, selectedItem) {
           $SelectedSuggestion.html("Selected Suggestion Item: " + JSON.stringify(selectedItem)).show();
       });
   });
    </script>