jQueryUI自动完成在MVC4中显示值而不是标签c#

时间:2013-02-28 15:21:37

标签: jquery asp.net-mvc jquery-ui

使用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,并在发布到控制器时不会导致验证错误:

自动完成正确显示

Auto complete shows correctly

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

But shows tvID in the box, rather than the agentName

感谢您的帮助,

标记

2 个答案:

答案 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对象恢复值(用于编辑页面)等。

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

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