Reputation: 1624
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
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
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
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