如何使文本框自动完成结果选择直接导航到记录详细信息

本文关键字:选择 导航 详细信息 记录 结果 文本 何使 | 更新日期: 2023-09-27 18:11:13

我正在使用ASP.NET MVC 4开发一个CRUD项目。需要在搜索表单文本字段上实现自动完成。我已经能够使用jQuery实现这一点,使用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 的访问者

:ActionParamName必须与控制器类中操作方法中参数的名称匹配。在这种情况下,它是firstName(即字符串firstName(

在您的视图中使用的脚本:

@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>

在我的视图中,我添加了一个隐藏的文本框来存储对象的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是否为null。如果不是,我使用选择的ID重定向到详细信息屏幕:

if (people_ID != null)
        {
            return RedirectToAction("Details", "People", new RouteValueDictionary(new { id = (int)people_ID }));
        }

如何使文本框自动完成结果选择直接导航到记录详细信息

您可以在自动完成配置中定义一个select方法。参见jQuery UI API参考:http://api.jqueryui.com/autocomplete/#event-选择