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

时间:2014-07-01 20:04:41

标签: c# javascript jquery asp.net-mvc json

我正在使用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 }));
        }

1 个答案:

答案 0 :(得分:1)

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