Richard Reddy
Richard Reddy

Reputation: 2170

jQuery UI Autocomplete with MVC fails to display the items returned

I've been banging my head against this issue for a while now and I'm not sure what I'm doing wrong.

I have a very simple JSON call to one of my controllers that I want to return client names along with the relevant ID values using jquery ui autocomplete. I can see the results in Firebug but the autocomplete is always returning an empty list.

The number of items in the list generated by jquery is correct - for example, if I am returned 3 results then I see the suggest menu with 3 blank list items. The problem seems to be that the jquery does not parse my response correctly.

I am not using jquery validate on the textbox as some other questions on here have suggested.

I am running this locally if that makes a difference.

Below is the jquery/HTML I use:

<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">        google.load("jquery", "1.6.4")</script>
<script type="text/javascript">        google.load("jqueryui", "1.8.16")</script>
<script type="text/javascript">
    $(document).ready(function () {
        $("#clientEntered").autocomplete({
            source: '@Url.Action("ClientAutoSuggest", "Clients")'
        });
    });

</script>

<input type="text" name="clientEntered" id="clientEntered" />

My controller looks something like this:

public JsonResult ClientAutoSuggest(string term)
    {
        var filteredClients = (from c in clientService.GetClients()
                               where c.Name.ToLower().StartsWith(term.ToLower())
                              select new { ClientID = c.ClientID, Name = c.Name }).Take(10);

        return Json(filteredClients, JsonRequestBehavior.AllowGet);
    }

As mentioned above, I do see results passed back in Firebug but the generated list is always empty.

Example - if 2 results are returned I will see the 2 results in Firebug:

[{"ClientID":1,"Name":"Client 1"},{"ClientID":2,"Name":"Client 2"}]

If I look at the generated source I see the following (correct 2 items but blank):

<ul style="z-index: 1; top: -16px; left: 0px; display: block; width: 1864px; position: relative;" aria-activedescendant="ui-active-menuitem" role="listbox" class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all"><li></li><li></li></ul>

I have tried different configurations for parsing the response but nothing I try seems to work. Any suggestions or help would be great, thanks!

EDIT: Got it working thanks to Kevin's answer below. The issue was down to not mapping the response correctly. The code below works great now.

$("#clientEntered").autocomplete({
            source: function(request, response) {
            $.ajax({
              url: '@Url.Action("ClientAutoSuggest", "Clients")',
              data: request,
              dataType: "json",
              type: "POST",
              success: function(data){
                  response($.map(data,function(item){
                  return { label: item.Name,value: item.Name, id: item.ClientId }
                  }));
              }
            });
           },
        });

Upvotes: 1

Views: 2344

Answers (1)

Kevin Cloet
Kevin Cloet

Reputation: 2976

I don't see any reference 2 the actually autocomplete JS? You probably have it somewhere else but I just wanted to let you know.

The real problem probably is caused by your '@Url.Action'. It will just execute that action and return the results. There is *no mapping to the textbox.

The best practice would just to make a simple Ajax call and do the mapping when you receive the response.

Should be something like this, just wrote it quick so don't shoot me but you should get the picture ;)

$("#clientEntered").autocomplete({
            source: function(request,response)
            {
               $.ajax({
                 url: "/Clients/ClientAutoSuggest",
                 type:"POST",
                 dataType:"json",
                 data: { term: request.term },
                 success:function(data){
                    response($.map(data,function(item){
                      return { label: item.Name,value: item.Name, id: item.ClientId
                    }))
                 }

                })
            }
});

Upvotes: 5

Related Questions