Disable enable dropdownlistfor based on model property in mvc

六眼飞鱼酱① 提交于 2019-12-02 09:12:14

It is not possible to include the condition (if/ternary statement(s)) inside the call to the DropDownListFor helper method because you cannot pass a line of c# code (with your if condition) where it expects an object for html attributes. Also all of the below markups will render a disabled SELECT.

<select disabled></select>
<select disabled="disabled"></select>
<select disabled="false"></select>
<select disabled="no"></select>
<select disabled="usingJqueryEnablePlugin"></select>
<select disabled="enabled"></select>

You can simply check the value of your Model property with an if condition and conditionally render the disabled version.

@if (!Model.IsReadOnly)
{
    @Html.DropDownListFor(s => s.ParentOrganisationID, 
                               new SelectList(Model.ParentOrganisations, "ID", "Name"))
}
else
{
    @Html.DropDownListFor(s => s.ParentOrganisationID, 
       new SelectList(Model.ParentOrganisations, "ID", "Name"),new {disabled="disabled"})
}

You may consider creating a custom html helper method which takes care of the if condition checking.

public static class DropDownHelper
{
    public static MvcHtmlString MyDropDownListFor<TModel, TProperty>
                 (this HtmlHelper<TModel> htmlHelper, 
                  Expression<Func<TModel, TProperty>> expression,
                  IEnumerable<SelectListItem> selectItems,
                  object htmlAttributes,
                  bool isDisabled = false)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression,
                                                                    htmlHelper.ViewData);

        IEnumerable<SelectListItem> items =
            selectItems.Select(value => new SelectListItem
            {
                Text = value.Text,
                Value = value.Value,
                Selected = value.Equals(metadata.Model)
            });
        var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        if (isDisabled && !attributes.ContainsKey("disabled"))
        {
             attributes.Add("disabled", "disabled");
        }
        return htmlHelper.DropDownListFor(expression,items, attributes);
    }
}

Now in your razor view,call this helper

@Html.MyDropDownListFor(s=>s.ParentOrganisationID,
               new SelectList(Model.ParentOrganisations, "ID", "Name")
                                           ,new { @class="myClass"},Model.IsReadOnly)
Guillaume

This is an HTML basic rule: from the moment you set the attribute disabled (regardless of its value), the element will be disabled.

To get what you want, you need to create an HTML extension DropDownListFor.

Please see this link.

The accepted answer from Shyju works great. But what if you want to use HTML5 data-* attributes in your custom helper? The standard MVC DropDownListFor provides a workaround by using an underscore (_) in place of the dash (-). And that helper is intelligent enough to convert the underscores to dashes when the markup is rendered.

Here is a custom helper that will provide a parameter to disable a DropDownList and also converts the HTML5 data-* attributes appropriately. It also preserves any other values passed in via the htmlAttributes parameter. The code is a little more concise as well (imo).

    public static MvcHtmlString MyDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> list, string optionLabel, object htmlAttributes, bool disabled)
    {
        var routeValues = new System.Web.Routing.RouteValueDictionary();

        // convert underscores to dashes...
        foreach (System.ComponentModel.PropertyDescriptor property in System.ComponentModel.TypeDescriptor.GetProperties(htmlAttributes))
        {
            routeValues.Add(property.Name.Replace('_', '-'), property.GetValue(htmlAttributes));
        }

        if(disabled)
        {
            routeValues.Add("disabled", "disabled");
        }

        return htmlHelper.DropDownListFor(expression, list, optionLabel, routeValues);
    }

And the markup:

@Html.MyDropDownListFor(m => m.MonthId, Model.Months, "Select Month", new { @class = "form-control", data_url = Url.Action("GetMonths") }, Model.IsDisabled)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!