使用jQueryUI自动完成 - 我返回一个“代理”列表及其ID,我的控制器返回正确的JSON,例如:
[{"tvid":12,"agentName":"Smith Gary"},{"tvid":43,"agentName":"Walls Arthur"},{"tvid":623,"agentName":"Mena Ati"}]
我的JavaScript是:
$("#tvID").autocomplete({
source: function (request, response) {
$.ajax({
url: "/AgentList/AutoCompleteAnalyst",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { value: item.tvid, label: item.agentName };
}))
}
})
},
messages: {
noResults: "", results: ""
}
});
我的观点是:
<div class="editor-label">
@Html.LabelFor(model => model.tvID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.tvID)
@Html.ValidationMessageFor(model => model.tvID)
</div>
自动完成功能显示正常,但是当我从列表中选择一个名称时,它是填充上面文本框的tvID(对数据库有效,因为它是我需要的tvID) - 但是,无论如何我在文本框中显示agentName,并在发布到控制器时不会导致验证错误:
自动完成正确显示
但是在框中显示tvID,而不是agentName
感谢您的帮助,
标记
答案 0 :(得分:2)
试试这个并告诉我它是否有效:
$("#tvID").autocomplete({
source: function (request, response) {
$.ajax({
url: "/AgentList/AutoCompleteAnalyst",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { value: item.tvid, label: item.agentName };
}))
}
})
},
messages: {
noResults: "", results: ""
}
}).data("autocomplete")._renderItem = function(ul,item){
return $("<li>")
.append($("<a>").text(item.label)).append($("input:hidden")).attr("name","some_name").val(item.tvid)
.appendTo(ul);
};
注意:您可能需要稍微更改模型才能使用它,因为现在您将从隐藏字段而不是文本框中获取值。文本框仅提供名称。
答案 1 :(得分:2)
正如gaurav所建议的那样,注入一个隐藏的输入标记与使用自动完成原样一样好。即使选项具有标签和值,当您选择一个时,该值也会放入可见输入控件中并完成其工作。
我可以看到几个选项。
自定义自动填充
您可以使用两个输入,一个是虚拟可见的输入,一个是隐藏的输入,用于您想要提交的值(绑定到您的模型)。然后,您可以通过编写自己的select
处理程序来更改自动完成的工作方式,该处理程序将获取标签并将其放入可见输入中,并将值放入模型绑定的隐藏输入中。
假设您有两个输入,第一个是可见的并且用户输入用于搜索,第二个是隐藏的并且将存储提交/绑定的值并且具有一个tvidValue类,您可以配置自动完成,如下所示:
focus: function( event, ui ) {
//prevent the autocomplete's input from changing as the
//user navigates the available options.
this.selectedItem = null;
return false;
},
select: function( event, ui ) {
if ( ui.item ) {
valueCtl = $this.next("input.tvidValue").val(ui.item.value);
this.value = ui.item.label;
return false;
}
}
然后在您的HTML中,类似以下内容可以让您在tvidDisplay上挂钩自动完成:
<input class='tvidDisplay' />
@Html.EditorFor(model => model.tvID, new { @class='tvidValue', style='display:none' })
此方法的缺点是显示以前的值(在编辑页面上;或在服务器端验证失败后返回到视图)。您需要添加一个小函数来从模型绑定的隐藏输入字段中获取值,并将其解析为存储在可见字段中的名称。这可以通过使用包含这两个值的ViewModel来缓解。
此外,如果用户编辑搜索字段但未选择有效的自动填充值,则select
处理程序将不会触发,您将不知道更新隐藏输入的值。
自动填充的自定义控件
第二种方法 - 我选择的方法 - 是在自动完成之上创建一个包装器。它会在某些显示名称的HTML内部生成一个隐藏的输入,并使用[x]来删除它。自动完成框永远不会绑定到我的模型 - 它纯粹是标记。生成的输入被赋予适当的name属性,因此在提交时,它们将被默认模型绑定器卷起并绑定,就像其他表单元素一样。它支持单个人或多个人,能够从JSON对象恢复值(用于编辑页面)等。
它仍然是一个早期版本,但它在内部运作良好。我刚刚对其进行了一些更新,以便更灵活地使用不同的服务端点并将其发布到GitHub(live demo)。您可能希望修改getEntityHtml
以更改将值存储到隐藏输入字段的方式 - 现在它将值和标签用分号连接起来。这对我们在服务器端有用,但可能并不适合所有人。该控件使用jQuery自动完成,并使用jQuery UI类进行修饰,以尝试匹配页面外观,如果您使用的是jQuery UI主题。
完全披露:如果我在那里到处使用“我”并不清楚,我就是作者。