ASP.NET MVC jquery autocomplete with value and text field
Asked Answered
C

3

17

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

Calvinna answered 20/9, 2012 at 11:8 Comment(2)
1st please tell me if my controller is OK ? when I run it manually I get no results , search term (id) is passed as null ??Calvinna
I would expect to pass request.term NOT request.id to the $.ajax() call.Declinature
D
20

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!

Declinature answered 20/9, 2012 at 12:41 Comment(5)
OK this works. but instead of showing ID in same field i need to save it in hidden one. please helpCalvinna
@Jalle, my answer has been updated to reflect the changes that you need. Let me know if this helps!Declinature
@JoeFletch, everything is working as expected except that the event is not triggered when I select the value on the drop. I have placed my debugger inside the 'select: function (event, ui) {' but the compiler never reaches there. Do you have any idea concerning what might be wrong?Rurik
@LuisGouveia not a clue. I do not have any of your code posted, so I do not know your circumstances.Declinature
@Declinature thank you but I figured it out myself a couple of days after my comment. I am sorry that I didn't tell you.Rurik
R
4

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);
}
Realtor answered 20/9, 2012 at 11:51 Comment(0)
T
3

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?

Typebar answered 20/9, 2012 at 11:17 Comment(1)
Hadn't even noticed that one. When the property names differ it definitely isn't going to work.Typebar

© 2022 - 2024 — McMap. All rights reserved.