I think I am missing something obvious while attempting to add autocomplete functionality in MVC 4. From what I have found in other posts I have been able to put together an example however the method in my controller is not being called.
What I have tried so far...
_Layout
@Styles.Render("~/Content/themes/base/css")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryui")
@Scripts.Render("~/bundles/jqueryval")
Controller
Public Function Numbers(term As String) As ActionResult
Return Json(New String() {"one", "two", "three", "four", "five", "six"}, JsonRequestBehavior.AllowGet)
End Function
View (I have hard coded the Home/Numbers for now)
<div class="editor-label">
@Html.LabelFor(Function(model) model.Number)
</div>
<div class="editor-field">
@Html.EditorFor(Function(model) model.Number)
@Html.ValidationMessageFor(Function(model) model.Number)
</div>
<script type="text/javascript">
$(function () {
$("#Number").autocomplete({
source: 'Home/Numbers',
minLength: 1
});
});
</script>
When I run my app and type in the textbox nothing happens. I have put a breakpoint in the "Numbers" function and it seems that it is never called.
My project can be found here http://www.filedropper.com/testapp
If you have the @Scripts.Render
lines at the bottom of the body
element in the layout and after the @RenderBody()
you need to put your script in the scripts
section:
@section scripts
<script type="text/javascript">
$(function () {
$("#Number").autocomplete({
source: '@Url.Action("Numbers","Home")',
minLength: 1
});
});
</script>
End Section
Because your script depends on jQuery so jQuery should be loaded first.
Or just move your @Scripts.Render
declaration into the head
in the layout then you don't need to put your code into the scripts
section (but you are better off with using the section)
This is the total code project of autocomplete textbox example .
http://blogs.msdn.com/b/stuartleeks/archive/2012/05/02/asp-net-mvc-amp-jquery-ui-autocomplete-part-2-editorfor.aspx
I suggest you to control errors in Chrome to ensure that jQuery libraries working properly.
if there is no problem, Try this script :
$(document).ready(function () {
$("#Number").each(function () {
$(this).autocomplete({ source: $(this).attr("data-autocomplete") });
});
});
Then in your Razor (C#):
<input type="text" id="Number" data-autocomplete="@Url.Action("Action","Controller")" autocomplete="on" />
If you want to use Razor Html Helpers instead of using 'input' tag, The id attribute is the same name of Model.Member. Notice that in Controller, you must input string with the 'term' name, as written in your code.
For security reasons, you must avoid using parameters in js file that shows the site technology. The method declared above never uses js file to get address of resource.
For Viewpage
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<input type="text" id="txtmasterserach" name="txtmasterserach" placeholder="City, region, district or specific hotel" autocomplete="off"/>
<input type="hidden" name="hidenkeyvalues" id="MovieID" />
<script type="text/javascript">
$(document).ready(function () {
$("#txtmasterserach").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Company/getautobox",
type: "POST",
dataType: "json",
data: { Prefix: request.term },
success: function (data) {
response($.map(data, function (item) {
return { value: item.Id, label: item.name };
}))
}
})
},
select: function (event, ui) {
$("#MovieID").val(ui.item.value);
$("#txtmasterserach").val(ui.item.label);
event.preventDefault();
return false;
},
focus: function (event, ui) {
$("#MovieID").val(ui.item.value);
// $("#txtmasterserach").val(ui.item.label);
event.preventDefault();
return false;
},
messages: {
noResults: "", results: ""
}
});
});
</script>
For Controller :
public class companyController : Controller
{
public JsonResult getautobox(String Prefix)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
SqlCommand cmd = new SqlCommand("procedurename", con);
cmd.Parameters.AddWithValue("@prefix", Prefix);
cmd.CommandType = CommandType.StoredProcedure;
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
List<autosearchdatalist> auto = new List<autosearchdatalist>();
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
auto.Add(new autosearchdatalist
{
Id = ds.Tables[0].Rows[i]["Id"].ToString(),
name = ds.Tables[0].Rows[i]["hotelname"].ToString()
});
}
}
if (ds.Tables[1].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[1].Rows.Count; i++)
{
auto.Add(new autosearchdatalist {
Id = ds.Tables[1].Rows[i]["Id"].ToString(),
name = ds.Tables[1].Rows[i]["hotelname"].ToString()
});
}
}
if (ds.Tables[2].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[2].Rows.Count; i++)
{
auto.Add(new autosearchdatalist
{
Id = ds.Tables[2].Rows[i]["Id"].ToString(),
name = ds.Tables[2].Rows[i]["hotelname"].ToString()
});
}
}
String msg = "";
return Json(auto);
}
}
Keep router setting default otherwise action will not call
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "company", action = "Index", id = UrlParameter.Optional }
);
}
}