Reputation: 1793
The following jQuery autocomplete code is not displaying the results in MVC3. When I debug the code, I can see it is calling the QuickSearchByLastName correctly. Can someone tell me if my code is incorrect? (I also tried with jquery-1.6.2.min.js with no luck) Thank you!
Index.cshtml:
@using (Ajax.BeginForm(new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "results"
}
))
{
<input type="text" name="q" data-autocomplete="@Url.Action("QuickSearchByLastName","Search")" />
}
<div id="results" >
</div>
----------------------------------------------------------------
Search Controller:
public ActionResult QuickSearchByLastName(string term)
{
using (var context = new CSCContext())
{
var searchResults = context.Students
.Where(s => s.LastName.Contains(term) && s.IsActive == true)
.Take(10)
.Select(s => new { label = s.LastName });
return Json(searchResults, JsonRequestBehavior.AllowGet);
}
}
_Layout.cshtml:
@Content.Script("jquery-1.4.4.min.js", Url)
@Content.Script("jquery.unobtrusive-ajax.min.js", Url)
@Content.Script("jquery-ui.min.js", Url)
@Content.Script("jquery.validate.min.js", Url)
@Content.Script("jquery.validate.unobtrusive.min.js", Url)
@Content.Script("CSC.js", Url)
@RenderSection("scripts", false)
CSC.js
$(document).ready(function ()
{
$(":input[data-autocomplete]").each(function ()
{
$(this).autocomplete({
source: $(this).attr("data-autocomplete")
}
);
});
});
The following code fixed the issue:
public ActionResult QuickSearchByLastName(string term)
{
var context = new CSCContext();
try
{
var searchResults = context.Students
.Where(s => s.LastName.Contains(term) && s.IsActive == true)
.Take(10)
.Select(s => new { label = s.LastName });
return Json(searchResults.ToList(), JsonRequestBehavior.AllowGet);
}
finally
{
context.Dispose();
}
}
Upvotes: 1
Views: 4706
Reputation: 47774
Short answer : Refer this post jQuery UI autocomplete with ASP.NET Web API
Long answer :
Step 1 : Getting Web Api Ready
Lets first create a web api method that will return a list of item (Artists) using the search term query sent from the autocomplete textbox. In this post I am not using database, instead I'll be using List to keep this example as simple as possible.
Below is how I have defined my Artist class
public class Artist
{
public int Id { get; set; }
public int Name { get; set; }
}
Next I have created a Web Api GET method that will use the search term entered in the autocomplete textbox and with a little help of LINQ will return a list of matching results.
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace Autocomplete.Controllers
{
public class ArtistApiController : ApiController
{
public List<Artist> ArtistList = new List<Artist>
{
new Artist{Id = 1, Name = "Sonu Nigam"},
new Artist{Id = 2, Name = "Sunidhi Chauhan"},
new Artist{Id = 3, Name = "Shreya Goshal"},
new Artist{Id = 4, Name = "Mohit Chauhan"},
new Artist{Id = 5, Name = "Nihkil Dsouza"},
new Artist{Id = 6, Name = "Kailash Kher"},
new Artist{Id = 7, Name = "Atif Aslam"},
new Artist{Id = 8, Name = "Ali Zafar"},
new Artist{Id = 9, Name = "Shafaqat Ali"},
new Artist{Id = 10, Name = "Shankar Madahevan"}
};
// GET api/values
public IEnumerable<Artist> Get(string query)
{
return ArtistList.Where(m => m.Name.Contains(query)).ToList();
}
}
}
Our server side code is ready ! Time to test it out.
Step 2 : Client side code
Include jquery-ui.js and jquery.ui.css in your html
<script type="text/javascript" src="~/Scripts/jquery-1.7.1.min.js" ></script>
<script type="text/javascript" src="~/Scripts/jquery-ui-1.8.20.min.js" ></script>
<link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" />
<div id="body">
<label for="autocomplete-textbox">Search : </label>
<input type="text" id="autocomplete-textbox" />
</div>
<script type="text/javascript">
$(document).ready(function (){
$('#autocomplete-textbox').autocomplete({
source: function (request, response) {
// prepare url : for example '/api/artistapi?query=sonu
var autocompleteUrl = '/api/artistapi' + '?query=' + request.term;
$.ajax({
url: autocompleteUrl,
type: 'GET',
cache: false,
dataType: 'json',
success: function (json) {
// call autocomplete callback method with results
response($.map(json, function (data, id) {
return {
label: data.Name,
value: data.Id
};
}));
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
console.log('some error occured', textStatus, errorThrown);
}
});
},
minLength: 2,
select: function (event, ui) {
alert('you have selected ' + ui.item.label + ' ID: ' + ui.item.value);
$('#autocomplete-textbox').val(ui.item.label);
return false;
}
});
});
</script>
One thing to note here is that inside the success method I have used the following code :
response($.map(json, function (data, id) {
return {
label: data.Name,
value: data.Id
};
}));
data.Id and data.Name is used because in the ajax response (as shown below) data is returned in this format.
Step 3 : Test & Output :
Taken from here
Upvotes: 1
Reputation: 1480
I was having the same problem as rk1962 (and a quick websearch shows plenty of other people having the same issue). I replicated Darin's code from above and it worked. It is when I take the script from the top of Index.cshtml and place it in a separate scripts file that it stops working - QuickSearchByLastName doesn't get called.
Andrew
Upvotes: 0
Reputation: 11
For some reason, the script file
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
needs to be included in the top, NOT as specified in the bottom of any file to increase performance.
If you do it will work.
Upvotes: 1
Reputation: 1038720
I have tried replicating your scenario to no avail as it always worked for me. Here's what I did.
HomeController:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult QuickSearchByLastName(string term)
{
var results = Enumerable
.Range(1, 5)
.Select(x => new {
id = x,
label = "label " + x,
value = "value " + x
});
return Json(results, JsonRequestBehavior.AllowGet);
}
}
Index.cshtml
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/base/jquery-ui.css" type="text/css" media="all" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$(':input[data-autocomplete]').each(function () {
$(this).autocomplete({
source: $(this).attr('data-autocomplete')
});
});
});
</script>
@using (Html.BeginForm())
{
<input type="text" name="q" data-autocomplete="@Url.Action("QuickSearchByLastName", "Home")" />
}
I used jquery-1.5.1.min.js
and jquery-ui-1.8.11.min.js
which are bundled by default with ASP.NET MVC 3 RTM. I also tried putting this in a Ajax.BeginForm
and also importing the default unobtrusive scripts and it was still working for me.
Upvotes: 5