Jalle
Jalle

Reputation: 1624

ASP.NET MVC jquery autocomplete with value and text field

controller

public ActionResult Search(string id)
{
     id= Request.QueryString["term"];         
     var routeList = db.Movies.Where(r => r.Title.Contains(id))
                   .Take(5)
                   .Select(r => new { id = r.MovieID, label = r.Title, name = "MovieID" });
     return Json(routeList, JsonRequestBehavior.AllowGet);
}

View:

<input type="hidden"   id="MovieID"  name="MovieID" />
<input type="text" id="SelectedMovie" value=""/>
<script type="text/javascript" language="javascript">
   $("#SelectedMovie").autocomplete({
       source: function (request, response) {
           $.ajax({
              url: "/Transaction/Search", type: "POST", dataType: "json",                        
              data: { id: request.term }, 
              success: function (data) {
              response($.map(data, function (item) {                                
                return { label: item.label, value: item.id }; //updated code
               }));
             }
         });
     },
     select: function (event, ui) {
         $("#MovieID").val(ui.item.value);
         $("#SelectedMovie").val(ui.item.label);
         return false;
     }
  });
</script>

I have some kind of videostore app. When I go to rent a movie I need a combobox with movies which I can select by using autocomplete. Also requirement is that only ID (value) is saved to the databas and not the text itself.

EDIT: here is the full working exqample

Upvotes: 17

Views: 37278

Answers (3)

Faust
Faust

Reputation: 15404

Your .ajax() call is not specifying in an id. it's not in your data{} object, nor is it in a querystring as part of the url parameter (either approach would work).

Hence the null value in your Action method.

Anyway, you are immediately over-writing the method's id argument with Request.QueryString["term"]. Why to do that??

Instead of asking Request for the 'term' inside the method,you just bind that to the Action method as a parameter itself like below :

public ActionResult Search(string term)
{
    var routeList = db.Movies.Where(r => r.Title.Contains(term))
            .Take(5)
            .Select(r => new { id = r.MovieID, label = r.Title, name = "MovieID" });
    return Json(routeList, JsonRequestBehavior.AllowGet);
}

Upvotes: 4

JoeFletch
JoeFletch

Reputation: 3960

Since you are passing only a string to the Search() function on the server side, the data elements that you are passing via the $.ajax() call need to be changed.

public ActionResult Search(string id)//I think that the id that you are passing here needs to be the search term. You may not have to change anything here, but you do in the $.ajax() call
{
      id= Request.QueryString["term"];

      var routeList = db.Movies.Where(r => r.Title.Contains(id))//this is a text filter no?
                        .Take(5)
                        .Select(r => new { id = r.MovieID, label = r.Title, name = "MovieID" });
      return Json(routeList, JsonRequestBehavior.AllowGet);
}

$("#MovieID").autocomplete({
    source: function (request, response) {
        $.ajax({
            url: "/Transaction/Search", type: "POST", dataType: "json",
            //original code
            //data: { searchText: request.id, maxResults: 10 },
            //updated code; updated to request.term 
            //and removed the maxResults since you are not using it on the server side
            data: { id: request.term },

            success: function (data) {
                response($.map(data, function (item) {
                    //original code
                    //return { label: item.FullName, value: item.FullName, id: item.TagId }; 
                    //updated code
                    return { label: item.label, value: item.label, id: item.id };
                }));
            },
        select: function (event, ui) {
                //update the jQuery selector here to your target hidden field
            $("input[type=hidden]").val(ui.item.id);
        }
        });
    },
});

Let me know if this works/helps!

Upvotes: 20

Ronald Wildenberg
Ronald Wildenberg

Reputation: 32094

First, you should use the following return value from your function:

return { label: item.title, value: item.id };

According to the documentation you have to return objects with label and value properties (no id property). The label is what the user sees, the value is what's posted to the server.

Second, you pass a searchText and maxResults in the Ajax call, so your action method should have two parameters: public ActionResult Search(string searchText, int maxResults).

Can you apply these changes and see if it works?

Upvotes: 3

Related Questions