Search code examples
javascriptasp.net-mvctwitter-bootstrapbootstrap-typeaheadtwitter-typeahead

Cannot post Id with Twitter Bootstrap Typeahead


I use Twitter Bootstrap Typeahead in my MVC5 project and it list the related records properly. Although I can retrieve the Id value of the selected record on updater section, I cannot post it on form submit. I tried many different combinations of the Id parameter, but did not make any sense. How to post Id parameter with Twitter Bootstrap Typeahead?

View:

@Html.HiddenFor(m => m.StudentId)

<input id="StudentId" name="StudentId" type="text" class="form-control tt-input" 
    autocomplete="off" spellcheck="false" dir="auto">

<script>
    $("#StudentId").typeahead({
        minLength: 1,
        source: function (query, process) {
            var lookups = [];
            map = {};

            // This is going to make an HTTP post request to the controller
            return $.post('/Grade/StudentLookup?query=%QUERY', { query: query }, function (data) {

                // Loop through and push to the array
                $.each(data, function (i, lookup) {
                    map[lookup.Name] = lookup;
                    lookups.push(lookup.Name);
                });

                // Process the details
                process(lookups);
            });
        },
        updater: function (item) {
            var selectedId = map[item].Id;
            console.log("Selected : " + selectedId);
            return item;
        }
    });
</script>


Controller:

public ActionResult StudentLookup(string query)
{
    var students = repository.Students.Select(m => new StudentViewModel
    {
        Id = m.Id,
        Name = m.Name + " " + m.Surname                
    })
    .Where(m => m.Name.StartsWith(query));
    return Json(students, JsonRequestBehavior.AllowGet);
}

Solution

  • Seperate the fields into Name and Id, you can even make the ID field hidden or readonly.

    <input id="StudentName" type="text" class="form-control tt-input" 
        autocomplete="off" spellcheck="false" dir="auto">
    
    <input id="StudentId" name="StudentId" type="text">
    
    <script>
        $("#StudentName").typeahead({
            minLength: 1,
            source: function (query, process) {
                var lookups = [];
                map = {};
    
                // This is going to make an HTTP post request to the controller
                return $.post('/Grade/StudentLookup?query=%QUERY', { query: query }, function (data) {
    
                    // Loop through and push to the array
                    $.each(data, function (i, lookup) {
                        map[lookup.Name] = lookup;
                        lookups.push(lookup.Name);
                    });
    
                    // Process the details
                    process(lookups);
                });
            },
            updater: function (item) {
                var selectedId = map[item].Id;
                console.log("Selected : " + selectedId);
                $("#StudentId").val(selectedId)
                return item;
            }
        });
    </script>