【问题标题】:Creating a SelectListItem with the disabled="disabled" attribute使用 disabled="disabled" 属性创建 SelectListItem
【发布时间】:2010-04-16 17:38:37
【问题描述】:

我没有看到通过HtmlHelper 创建SelectListItem 的方法,该SelectListItem 将输出以下HTML:

<option disabled="disabled">don't click this</option>

SelectListItem 的唯一属性是:

new SelectListItem{
  Name = "don't click this",
  Value = string.Empty,
  Selected = false
}

我看到的唯一选择是

  1. 子类化 SelectListItem 以添加 Enabled 属性以获取视图的值
  2. 不使用HTML helper for DropDownList
  3. 创建一个新的HtmlHelper 扩展,接受我的新EnablableSelectList 并添加我的disabled 属性。

【问题讨论】:

    标签: asp.net-mvc html-helper


    【解决方案1】:

    自 ASP.NET MVC 5.2 起支持 Disabled 属性:

    new SelectListItem {
        // ...
        Disabled = true
    }
    

    请参阅API reference

    【讨论】:

    • 这也是世纪笑话!简而言之,它对名为DropdownList 的智障助手没有任何影响! :)
    • @Mrchief 您需要使用 IEnumerable 来尊重禁用标志,而不是 SelectList。见:stackoverflow.com/questions/29424365/…
    • 感谢@co7e 提供的有用信息!
    【解决方案2】:

    在完全重新创建帮助程序之前,我可能会尝试这样做。基本思想是您从帮助程序获得的 Html 格式应该是正确的,因此解析应该是安全的。因此,您可以通过制作自己的扩展程序来构建这个想法,该扩展程序使用现有扩展程序,但添加了禁用项目的功能。

    这样的事情可能会做(完全未经测试)

    public class CustomSelectItem : SelectListItem
    {
        public bool Enabled { get; set; }
    }
    
    public static class CustomHtmlHelpers
    {
        public static MvcHtmlString MyDropDownList(this HtmlHelper html, IEnumerable<CustomSelectItem> selectList)
        {
            var selectDoc = XDocument.Parse(html.DropDownList("", (IEnumerable<SelectListItem>)selectList).ToString());
    
            var options = from XElement el in selectDoc.Element("select").Descendants()
                                        select el;
    
            foreach (var item in options)
            {
                var itemValue = item.Attribute("value");
                if (!selectList.Where(x => x.Value == itemValue.Value).Single().Enabled)
                    item.SetAttributeValue("disabled", "disabled");
            }
    
            // rebuild the control, resetting the options with the ones you modified
            selectDoc.Root.ReplaceNodes(options.ToArray());
            return MvcHtmlString.Create(selectDoc.ToString());
        }
    }
    

    【讨论】:

    • +1 这绝对比重新创建整个辅助扩展更轻松;但是,如果我要重新创建它,我可能会窃取 Helper Extension 的源代码并稍微调整一下。
    【解决方案3】:

    客户端选项:例如,如果您给下拉列表一个“自定义”类,并且应该无法选择的项目值为 -1(例如),那么您可以执行以下操作:

    $('select.custom option[value=-1]').each(function () {
        $(this).attr("disabled", "disabled");
    });
    

    【讨论】:

      【解决方案4】:

      如果您想要做的只是阻止用户从列表中选择某个值,那么使用输入验证似乎更简单、更省时。无论如何,如果您想验证他们是否已做出选择,那么您很可能会这样做。

      【讨论】:

      • 我已经有使选择无效的输入验证,但是如果存在disabled="disabled" 属性,则除 IE 之外的所有其他浏览器根本不允许您选择该项目。
      • 未来 IE 8 将支持它,或者确实支持它。对于 IE 6 和 7,我同意您必须尝试创建自己的项目,但我不确定那里的最佳方法。再一次,我会看看需要多长时间才能解决这个问题,看看是否值得花时间在考虑到用户将使用的浏览器/版本的情况下进行故障排除。
      • 其实IE7确实遵守disabled="disabled"。在这个问题上,我必须收回对 IE 的所有不屑。我真的很惊讶Enabled 属性被排除在SelectListItem 之外。
      【解决方案5】:

      -----选项1 控制器:

      var ExpectedShipmentsRange = new List();

      ExpectedShipmentsRange.Add(new SelectListItem() { Text = "Selected number of shipments", Value="0", Disabled = true, Selected  = true });
      ExpectedShipmentsRange.Add(new SelectListItem() { Text = "0 to 20 shipments", Value = "0-20" });
      ExpectedShipmentsRange.Add(new SelectListItem() { Text = "20 to 40 shipments", Value = "20-40" });
      
      ViewBag.ExpectedShipmentsRange = ExpectedShipmentsRange;
      

      查看:

      @Html.DropDownListFor(m => m.ExpectedShipments, (IEnumerable<SelectListItem>)@ViewBag.ExpectedShipmentsRange, new { @class = "form-control" })
      

      -----选项2 控制器:

      ViewBag.citiesSa = _dbContext.Countries.ToList();
      

      查看:

      @Html.DropDownListFor(m => m.City, new SelectList(@ViewBag.citiesSa, "Id", "Name"), "Select your city", new { @class = "form-control" })
      

      -----选项3不支持禁用选项:

      List<SelectListItem> ExpectedShipmentsRange = new List<SelectListItem>();
      ExpectedShipmentsRange.Add(new SelectListItem() { Text = "0 to 20 shipments", Value = "0-20" });
      ExpectedShipmentsRange.Add(new SelectListItem() { Text = "20 to 40 shipments", Value = "20-40" });
      
      ViewBag.ExpectedShipmentsRange = new SelectList(ExpectedShipmentsRange, "Value", "Text");
      

      查看:

      @Html.DropDownListFor(m => m.ExpectedShipments, (SelectList)@ViewBag.ExpectedShipmentsRange, new { @class = "form-control" })
      

      【讨论】:

        【解决方案6】:

        我注意到在使用SelectList 填充DropDownListFor() 方法时,DisabledSelected 参数不受尊重。它们仅在使用 List&lt;SelectListItem&gt; 填充时才会受到尊重。但是,我在使用List&lt;SelectListItem&gt; 填充DropDownListFor() 时遇到了其他奇怪的错误,并发现使用SelectList 是填充DropDownListFor() 列表的正确选项。下面是一个如何创建SelectList 列表的示例:

            public static SelectList States = new SelectList(new[]
            {
                new SelectListItem { Text = "AL", Value = "AL" },
                new SelectListItem { Text = "AK", Value = "AK" },
                ...
            }, "Value", "Text", 1);
        

        在我的情况下,我需要disable 选择列表的第一项,我能够使用SelectList 这样做的唯一方法是为DropDownListFor() 方法创建一个扩展方法。这是我使用的类:

            public static class HtmlHelperExtensions
            {
                private static MvcHtmlString DisableFirstItemDropDownListFor(MvcHtmlString source, string sourceItemName, string sourceItemValue = "", string targetItemValue = "")
                {
                    string htmlString = source.ToHtmlString();
                    if (string.IsNullOrEmpty(sourceItemValue))
                    {
                        htmlString = htmlString.Replace("value=\"\"", "value=\"\" disabled=\"disabled\" selected=\"selected\"");
                    }
        
                    return new MvcHtmlString(htmlString);
                }
        
                public static MvcHtmlString DisableFirstItemDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes)
                {
                    return DisableFirstItemDropDownListFor(htmlHelper.DropDownListFor(expression, selectList, htmlAttributes), string.Empty);
                }
            }
        

        然后您可以在您的 .cshtml 文件中使用此方法,如下所示:

        @Html.DisableFirstItemDropDownListFor(x => x.YourFieldType, Model.YourModel, new { @class = "YourClass" })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-29
          • 2015-08-16
          • 1970-01-01
          • 2017-09-10
          • 1970-01-01
          • 1970-01-01
          • 2016-10-23
          • 1970-01-01
          相关资源
          最近更新 更多