0

使用 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

但在框中显示 tvID,而不是 agentName

谢谢你的帮助,

标记

4

2 回答 2

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);
};

注意:您可能需要稍微更改模型才能使用它,因为现在您将从隐藏字段而不是文本框中获取值。文本框只会提供名称。

于 2013-02-28T16:22:26.447 回答
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] 来删除它。自动完成框永远不会绑定到我的模型 - 它纯粹是标记。生成的输入被赋予适当的名称属性,因此在提交时它们会像其他表单元素一样被默认模型绑定器汇总和绑定。它支持一个人或多个人,能够从 JSON 对象中恢复值(用于编辑页面)等。

它仍然是一个早期版本,但它在内部运行良好。我只是对其进行了一些更新,以便更灵活地使用不同的服务端点并将其发布到GitHub现场演示)。您可能需要修改getEntityHtml以更改其将值存储到隐藏输入字段的方式 - 现在它使用分号连接值和标签。这对我们在服务器端很有用,但可能并不适合所有人。如果您使用 jQuery UI 主题,该控件使用 jQuery 自动完成并使用 jQuery UI 类进行装饰,以尝试匹配页面外观/感觉。

完全披露:如果我在其中到处使用“我”并不清楚,我就是作者。

于 2013-02-28T17:05:10.980 回答