Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MVC3 jQuery自动完成-用户必须选择选项,选项ID发送到服务器_Jquery_Asp.net_Asp.net Mvc_Asp.net Mvc 3_Jquery Ui Autocomplete - Fatal编程技术网

MVC3 jQuery自动完成-用户必须选择选项,选项ID发送到服务器

MVC3 jQuery自动完成-用户必须选择选项,选项ID发送到服务器,jquery,asp.net,asp.net-mvc,asp.net-mvc-3,jquery-ui-autocomplete,Jquery,Asp.net,Asp.net Mvc,Asp.net Mvc 3,Jquery Ui Autocomplete,背景 目前在我的一个项目中,我使用jQueryautocomplete处理一些字段 要提供上下文,应用程序记录将运行。每次运行都必须有一条与之相关联的路线。一条路线意思是,用户在那里跑步 当用户键入路线时,其路线的列表将通过自动完成选项显示,但数据库需要路线ID进行验证 为了补偿这一点,我将RouteID存储在HiddenForHtmlHelper中。当用户从autocomplete选择路线时,将分配HiddenFor 我的问题是什么 如果用户键入路线的全名,而不是从自动完成列表中选择它或输

背景
目前在我的一个项目中,我使用jQuery
autocomplete
处理一些字段

要提供上下文,应用程序记录
将运行
。每次
运行
都必须有一条与之相关联的
路线
。一条
路线
意思是,用户在那里跑步

当用户键入
路线
时,其
路线
的列表将通过
自动完成
选项显示,但数据库需要
路线ID
进行验证

为了补偿这一点,我将
RouteID
存储在
HiddenFor
HtmlHelper中。当用户从
autocomplete
选择路线时,将分配
HiddenFor

我的问题是什么
如果用户键入
路线的全名
,而不是从
自动完成
列表中选择它或输入一个不存在的
路线
,则不会分配
隐藏的
。当发生这种情况时,我必须按其名称查找
路由
,并验证它是否存在于服务器上

我希望不必为每个
自动完成
创建此工作环境

底线
是否有办法使
自动完成
更像一个
选择列表
?我希望用户别无选择,只能从
autocomplete
列表中选择一个选项的文本,并将所选选项的值发送到服务器

如果我必须坚持使用
HiddenFor
方法,是否至少有办法强制用户从
autocomplete
列表中选择一个选项


下面是我目前使用的代码

加价

@Html.LabelFor(model => model.RouteID, "Route")
<input type="text" data-autocomplete-url="@Url.Action("../Route/GetRoutesByUser")" />
@Html.HiddenFor(m => m.RouteID)

代码

public ActionResult GetRoutesByUser(string term)
{
    var routeList = db.Routes.Where(r => r.Name.Contains(term))
                    .Take(5)
                    .Select(r => new { id = r.RouteID, label = r.Name, name = "RouteID"});
    return Json(routeList, JsonRequestBehavior.AllowGet);
}

我将使用
change
事件进行此操作,如果未选择项目,则清除
input
的值:

$('*[data-autocomplete-url]')
    .each(function () {
        $(this).autocomplete({
            source: $(this).data("autocomplete-url"),
            minLength: 2,
            select: function (event, ui) {
                log(ui.item.id, ui.item.name);
            },
            change: function (event, ui) { 
                if (!ui.item) { 
                    this.value = '';
                } else {
                    // Populate your hidden input.
                }
            }
        });
    });
});

示例:

好吧,在反复尝试之后,我想出了以下实现:

下面的代码是一个名为
@Html.AutocompleteWithHiddenFor
HtmlHelper
。HtmlHelper将基于传入的
控制器
操作
创建一个
输入
HTML元素,该元素具有
数据自动完成url
属性

如果
输入
元素需要一个
,那么您也可以传入该值。将为传入的
Model
属性创建
HiddenFor
,并为
Model
创建
ValidationMessageFor

现在,我所要做的就是使用
@Html.AutocompleteWithHiddenFor
,并通过控制器和操作(可能还有值)传入所需的任何表达式,以获得自动完成功能,并将ID传递给服务器,而不是文本

jQuery

  $('*[data-autocomplete-url]')
    .each(function () {
        $(this).autocomplete({
            source: $(this).data("autocomplete-url"),
            minLength: 2,
            select: function (event, ui) {
                log(ui.item.id, ui.item.name);
            }
        });
    });
$(function () {
    function log(id, name) {
        var hidden = $('#' + name);
        hidden.attr("value", id);
    }

    $('*[data-autocomplete-url]')
    .each(function () {
        $(this).autocomplete({
            source: $(this).data("autocomplete-url"),
            minLength: 2,
            select: function (event, ui) {
                log(ui.item.id, ui.item.name);
            },
            change: function (event, ui) {
                if (!ui.item) {
                    this.value = '';
                } else {
                    log(ui.item.id, ui.item.name);
                }
            }
        });
    });
});

自动完成助手类

public static class AutocompleteHelper
{
     /// <summary>
     /// Given a Model's property, a controller, and a method that belongs to that controller, 
     /// this function will create an input html element with a data-autocomplete-url property
     /// with the method the autocomplete will need to call the method. A HiddenFor will be
     /// created for the Model's property passed in, so the HiddenFor will be validated 
     /// and the html input will not.
     /// </summary>
      /// <returns></returns>
      public static MvcHtmlString AutocompleteWithHiddenFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, string controllerName, string actionName, object value = null)
      {
          // Create the URL of the Autocomplete function
          string autocompleteUrl = UrlHelper.GenerateUrl(null, actionName,
                                                       controllerName,
                                                       null,
                                                       html.RouteCollection,
                                                       html.ViewContext.RequestContext,                                                              
                                                       includeImplicitMvcValues: true);

           // Create the input[type='text'] html element, that does 
           // not need to be aware of the model
           String textbox = "<input type='text' data-autocomplete-url='" + autocompleteUrl + "'";

           // However, it might need to be have a value already populated
           if (value != null)
           {
               textbox += "value='" + value.ToString() + "'";
           }

           // close out the tag
           textbox += " />";

           // A validation message that will fire depending on any 
           // attributes placed on the property
           MvcHtmlString valid = html.ValidationMessageFor(expression);

           // The HiddenFor that will bind to the ID needed rather than 
           // the text received from the Autocomplete
           MvcHtmlString hidden = html.HiddenFor(expression);

           string both = textbox + " " + hidden + " " + valid;
           return MvcHtmlString.Create(both);
     }
}
或者如果它需要一个值


非常感谢你带我去参加变革活动。它在可用性方面确实有所帮助。经过一番周折,我想出了自己的实现,为这个过程提供了一个可重用的HtmlHelper;并使用System.Web.Mvc.Html;当然否则它就不会建造。我省略了它们,因为代码已经足够长了。VisualStudio也会让您知道需要导入哪些库。
@Html.LabelFor(model => model.RouteID, "Route")
@Html.AutocompleteWithHiddenFor(model => model.RouteID, "Route", "GetRoutesByUser") 
@Html.LabelFor(model => model.Route, "Route")
@Html.AutocompleteWithHiddenFor(model => model.RouteID, "Route", "GetRoutesByUser", @Model.RouteName)