我正在使用ASP.NET MVC 4开发一个CRUD项目。需要在搜索表单文本字段上实现自动完成。我已经能够使用json很好地使用json实现这一点。但是,当您选择其中一个自动完成结果时,这只会使用搜索词填充文本框。我需要的功能是,当用户选择其中一个自动完成结果(将显示记录的几个字段)时,应用程序直接转到该记录的详细信息,而不是仅将字符串值放在文本框中。怎么办呢?
下面是我自动完成的实现,如果有人正在寻找那种解决方案,只需将字符串值放在文本框中。我做了一个可重用的部分视图,我可以插入不同的视图:
使用MVC中的json创建javascript自动完成
部分可重用的cshtml类中的参数化脚本:
@{
var boxId = ViewData["BoxId"];
var controller = ViewData["Controller"];
var action = ViewData["Action"];
var paramName = ViewData["ActionParamName"];
var dataField = ViewData["DataFieldName"];
var data = "item." + dataField;
}
<script src="~/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.autocomplete.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#@(boxId)").autocomplete({
source: function (request, response) {
$.ajax({
url: "/@(controller)/@(action)",
type: "POST",
dataType: "json",
data: { @paramName : request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: @data , value: @data };
}))
}
})
},
messages: {
noResults: "", results: ""
}
});
})
</script>
注意 :: DataFieldName是结果对象上访问者的名称。在这种情况下,APP_People_SEARCH_Result对象具有名为FirstName
的存取器ALSO :: ActionParamName必须与控制器类中action方法中的参数名称匹配。在这种情况下,它是firstName(即字符串firstName)
您的View脚本将在何处使用:
@Html.Partial("_AutoComplete", new ViewDataDictionary { new KeyValuePair<string, object("BoxId", "FirstNameTextBox"), new KeyValuePair<string, object>("Controller", "People"), new KeyValuePair<string, object>("Action", "FirstNameAutoComplete"), new KeyValuePair<string, object> ("ActionParamName", "firstName"), new KeyValuePair<string, object>("DataFieldName", "FirstName") })
@using (Html.BeginForm("Select", "People", FormMethod.Post, new { @class = "myclass", id = "" }))
{
<p>First Name: @Html.TextBox("firstName", null, new { id = "FirstNameTextBox" }) </p>
<p><input type="submit" value="Search" /></p>
}
PeopleController.cs中的代码:
public JsonResult FirstNameAutoComplete(string firstName)
{
List<APP_People_SEARCH_Result> results = RunSearch(firstName, false);
return Json(results, JsonRequestBehavior.AllowGet);
}
它的来源如何:
<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.autocomplete.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#FirstNameTextBox").autocomplete({
source: function (request, response) {
$.ajax({
url: "/People/FirstNameAutoComplete",
type: "POST",
dataType: "json",
data: { firstName : request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.FirstName , value: item.FirstName };
}))
}
})
},
messages: {
noResults: "", results: ""
}
});
})
</script>
<form action="/People/Select" class="myclass" method="post">
<p>First Name: <input id="FirstNameTextBox" name="firstName" type="text" value="" /> </p>
<p><input type="submit" value="Search" /></p>
</form>
感谢Silkster的帮助。
我能够实现几乎可重用的部分cshtml文件:
@{
var boxId = ViewData["BoxId"];
var controller = ViewData["Controller"];
var action = ViewData["Action"];
var paramName = ViewData["ActionParamName"];
var idFieldID = ViewData["IdFieldID"];
var objectIdProperty = ViewData["ObjectId"];
var objectId = "item." + objectIdProperty;
//var recordResult = ViewData["RecordResult"];////doesnt work for label and value, have to hard-code it
}
<script src="~/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.autocomplete.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#@(boxId)").autocomplete({
source: function (request, response) {
$.ajax({
url: "/@(controller)/@(action)",
type: "POST",
dataType: "json",
data: { @paramName : request.term },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.FirstName + ' ' + item.LastName + ' ' + item.Department ,
value: item.FirstName + ' ' + item.LastName + ' ' + item.Department ,
recordKey : @objectId
};
}))
}
})
},
messages: {
noResults: "", results: ""
},
select: function (event, ui) {
if (ui.item) {
var elem = document.getElementById("@(idFieldID)");
elem.value = ui.item.recordKey;
$("form").submit();
}
}
});
})
</script>
在我看来,我添加了一个隐藏文本框来存储objedct的ID。除了当我尝试传入包含引号的字符串时,我几乎可以完全地对部分(如上所示)进行参数化,它们不会在生成的脚本中进行翻译。
观点:
//Couldn't get the following to work
@*@Html.Partial("_PeopleAutoComplete", new ViewDataDictionary { new KeyValuePair<string, object>("BoxId", "FirstNameTextBox"), new KeyValuePair<string, object>("Controller", "People"), new KeyValuePair<string, object>("Action", "FirstNameAutoComplete"), new KeyValuePair<string, object>("ActionParamName", "firstName"), new KeyValuePair<string, object>("IdFieldID", "people_ID"), new KeyValuePair<string, object>("ObjectId", "People_ID") , new KeyValuePair<string, object>("RecordResult", "item.FirstName + ' ' + item.LastName + ' ' + item.Department") })*@
//So I had to just use this. Values ended up being hard-coded
@Html.Partial("_PeopleAutoComplete", new ViewDataDictionary { new KeyValuePair<string, object>("BoxId", "FirstNameTextBox"), new KeyValuePair<string, object>("Controller", "People"), new KeyValuePair<string, object>("Action", "FirstNameAutoComplete"), new KeyValuePair<string, object>("ActionParamName", "firstName"), new KeyValuePair<string, object>("IdFieldID", "people_ID"), new KeyValuePair<string, object>("ObjectId", "People_ID")})
@Html.Partial("_PeopleAutoComplete", new ViewDataDictionary { new KeyValuePair<string, object>("BoxId", "LastNameTextBox"), new KeyValuePair<string, object>("Controller", "People"), new KeyValuePair<string, object>("Action", "LastNameAutoComplete"), new KeyValuePair<string, object>("ActionParamName", "lastName"), new KeyValuePair<string, object>("IdFieldID", "people_ID"), new KeyValuePair<string, object>("ObjectId", "People_ID")})
@using (Html.BeginForm("SearchResults", "People"))
{
<p><input type="submit" value="Search" /></p>
@Html.TextBox("people_ID", null, new {id = "people_ID", style = "display:none;" })
<p>First Name: @Html.TextBox("firstName", null, new { id = "FirstNameTextBox" })</p>
<p>Last Name: @Html.TextBox("lastName", null, new { id = "LastNameTextBox" })</p>
}
在我的控制器中,我首先检查People_ID是否为空。如果不是,我使用所选的ID重定向到详细信息屏幕:
if (people_ID != null)
{
return RedirectToAction("Details", "People", new RouteValueDictionary(new { id = (int)people_ID }));
}
答案 0 :(得分:1)
您可以在自动完成配置中定义选择方法。请参阅jQuery UI API参考:http://api.jqueryui.com/autocomplete/#event-select