asp.net-mvc 根据 Html.TextBoxFor 的条件设置禁用属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6660146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:19:25  来源:igfitidea点击:

Set disable attribute based on a condition for Html.TextBoxFor

asp.net-mvcasp.net-mvc-3razorhtml-helper

提问by Ghooti Farangi

I want to set disable attribute based on a condition for Html.TextBoxFor in asp.net MVC like below

我想在 asp.net MVC 中根据 Html.TextBoxFor 的条件设置禁用属性,如下所示

@Html.TextBoxFor(model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" disabled = (Model.ExpireDate == null ? "disable" : "") })

This helper has two output disabled="disabled " or disabled="". both of theme make the textbox disable.

这个助手有两个输出 disabled="disabled " 或 disabled=""。两个主题都使文本框禁用。

I want to disable the textbox if Model.ExpireDate == null else I want to enable it

如果 Model.ExpireDate == null 我想禁用文本框,否则我想启用它

回答by Darin Dimitrov

The valid way is:

有效的方法是:

disabled="disabled"

Browsers also might acceptdisabled=""but I would recommend you the first approach.

浏览器也可能接受,disabled=""但我建议您使用第一种方法。

Now this being said I would recommend you writing a custom HTML helper in order to encapsulate this disablingfunctionality into a reusable piece of code:

既然如此,我建议您编写一个自定义 HTML 帮助程序,以便将此禁用功能封装到可重用的代码段中:

using System;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

public static class HtmlExtensions
{
    public static IHtmlString MyTextBoxFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> expression, 
        object htmlAttributes, 
        bool disabled
    )
    {
        var attributes = new RouteValueDictionary(htmlAttributes);
        if (disabled)
        {
            attributes["disabled"] = "disabled";
        }
        return htmlHelper.TextBoxFor(expression, attributes);
    }
}

which you could use like this:

你可以这样使用:

@Html.MyTextBoxFor(
    model => model.ExpireDate, 
    new { 
        style = "width: 70px;", 
        maxlength = "10", 
        id = "expire-date" 
    }, 
    Model.ExpireDate == null
)


and you could bring even more intelligenceinto this helper:

你可以为这个助手带来更多的智慧

public static class HtmlExtensions
{
    public static IHtmlString MyTextBoxFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        object htmlAttributes
    )
    {
        var attributes = new RouteValueDictionary(htmlAttributes);
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        if (metaData.Model == null)
        {
            attributes["disabled"] = "disabled";
        }
        return htmlHelper.TextBoxFor(expression, attributes);
    }
}

so that now you no longer need to specify the disabled condition:

以便现在您不再需要指定禁用条件:

@Html.MyTextBoxFor(
    model => model.ExpireDate, 
    new { 
        style = "width: 70px;", 
        maxlength = "10", 
        id = "expire-date" 
    }
)

回答by Shimmy Weitzhandler

Actually, the internal behavior is translating the anonymous object to a dictionary. So what I do in these scenarios is go for a dictionary:

实际上,内部行为是将匿名对象翻译成字典。所以我在这些情况下做的是去查字典:

@{
  var htmlAttributes = new Dictionary<string, object>
  {
    { "class" , "form-control"},
    { "placeholder", "Why?" }        
  };
  if (Model.IsDisabled)
  {
    htmlAttributes.Add("disabled", "disabled");
  }
}
@Html.EditorFor(m => m.Description, new { htmlAttributes = htmlAttributes })

Or, as Stephen commented here:

或者,正如斯蒂芬在这里评论的那样:

@Html.EditorFor(m => m.Description,
    Model.IsDisabled ? (object)new { disabled = "disabled" } : (object)new { })

回答by user571646

I like Darin method. But quick way to solve this,

我喜欢达林方法。但快速解决这个问题的方法,

Html.TextBox("Expiry", null, new { style = "width: 70px;", maxlength = "10", id = "expire-date", disabled = "disabled" }).ToString().Replace("disabled=\"disabled\"", (1 == 2 ? "" : "disabled=\"disabled\""))

回答by MurtuzaB

I achieved it using some extension methods

我使用一些扩展方法实现了它

private const string endFieldPattern = "^(.*?)>";

    public static MvcHtmlString IsDisabled(this MvcHtmlString htmlString, bool disabled)
    {
        string rawString = htmlString.ToString();
        if (disabled)
        {
            rawString = Regex.Replace(rawString, endFieldPattern, " disabled=\"disabled\">");
        }

        return new MvcHtmlString(rawString);
    }

    public static MvcHtmlString IsReadonly(this MvcHtmlString htmlString, bool @readonly)
    {
        string rawString = htmlString.ToString();
        if (@readonly)
        {
            rawString = Regex.Replace(rawString, endFieldPattern, " readonly=\"readonly\">");
        }

        return new MvcHtmlString(rawString);
    }

and then....

进而....

@Html.TextBoxFor(model => model.Name, new { @class= "someclass"}).IsDisabled(Model.ExpireDate == null)

回答by mfsumption

One simple approach I have used is conditional rendering:

我使用的一种简单方法是条件渲染:

@(Model.ExpireDate == null ? 
  @Html.TextBoxFor(m => m.ExpireDate, new { @disabled = "disabled" }) : 
  @Html.TextBoxFor(m => m.ExpireDate)
)

回答by Andrei Tserakhau

If you don't use html helpers you may use simple ternary expression like this:

如果您不使用 html 助手,您可以使用简单的三元表达式,如下所示:

<input name="Field"
       value="@Model.Field" tabindex="0"
       @(Model.IsDisabledField ? "disabled=\"disabled\"" : "")>

回答by kooldave98

This is late, but may be helpful to some people.

这已经很晚了,但可能对某些人有所帮助。

I have extended @DarinDimitrov's answer to allow for passing a second object that takes any number of boolean html attributes like disabled="disabled" checked="checked", selected="selected"etc.

我已经扩展了@DarinDimitrov 的答案,以允许传递第二个对象,该对象采用任意数量的布尔 html 属性,例如disabled="disabled" checked="checked", selected="selected"等。

It will render the attribute only if the property value is true, anything else and the attribute will not be rendered at all.

仅当属性值为 true 时才会呈现该属性,其他任何内容都不会呈现该属性。

The custom reuseble HtmlHelper:

自定义可重用 HtmlHelper:

public static class HtmlExtensions
{
    public static IHtmlString MyTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                                Expression<Func<TModel, TProperty>> expression,
                                                                object htmlAttributes,
                                                                object booleanHtmlAttributes)
    {
        var attributes = new RouteValueDictionary(htmlAttributes);

        //Reflect over the properties of the newly added booleanHtmlAttributes object
        foreach (var prop in booleanHtmlAttributes.GetType().GetProperties())
        {
            //Find only the properties that are true and inject into the main attributes.
            //and discard the rest.
            if (ValueIsTrue(prop.GetValue(booleanHtmlAttributes, null)))
            {
                attributes[prop.Name] = prop.Name;
            }                
        }                                

        return htmlHelper.TextBoxFor(expression, attributes);
    }

    private static bool ValueIsTrue(object obj)
    {
        bool res = false;
        try
        {
            res = Convert.ToBoolean(obj);
        }
        catch (FormatException)
        {
            res = false;
        }
        catch(InvalidCastException)
        {
            res = false;
        }
        return res;
    }

}

Which you can use like so:

您可以像这样使用:

@Html.MyTextBoxFor(m => Model.Employee.Name
                   , new { @class = "x-large" , placeholder = "Type something…" }
                   , new { disabled = true})

回答by Niels Bosma

Is solved this using RouteValueDictionary (works fine as htmlAttributes as it's based on IDictionary) and an extension method:

使用 RouteValueDictionary(作为 htmlAttributes 工作正常,因为它基于 IDictionary)和一个扩展方法解决了这个问题:

public static RouteValueDictionary AddIf(this RouteValueDictionary dict, bool condition, string name, object value)
{
    if (condition) dict.Add(name, value);
    return dict;
}

Usage:

用法:

@Html.TextBoxFor(m => m.GovId, new RouteValueDictionary(new { @class = "form-control" })
.AddIf(Model.IsEntityFieldsLocked, "disabled", "disabled"))

Credit goes to https://stackoverflow.com/a/3481969/40939

归功于https://stackoverflow.com/a/3481969/40939

回答by Basheer AL-MOMANI

if you dont want to use Html Helpers take look it my solution

如果您不想使用 Html Helpers,请查看我的解决方案

disabled="@(your Expression that returns true or false")"

that it

@{
    bool isManager = (Session["User"] as User).IsManager;
}
<textarea rows="4" name="LetterManagerNotes" disabled="@(!isManager)"></textarea>

and I think the better way to do it is to do that check in the controller and save it within a variable that is accessible inside the view(Razor engine) in order to make the view free from business logic

我认为更好的方法是在控制器中进行检查并将其保存在视图(Razor 引擎)内可访问的变量中,以便 the view free from business logic

回答by Kjell Rilbe

Yet another solution would be to create a Dictionary<string, object>before calling TextBoxForand pass that dictionary. In the dictionary, add "disabled"key only if the textbox is to be diabled. Not the neatest solution but simple and straightforward.

另一种解决方案是Dictionary<string, object>在调用TextBoxFor并传递该字典之前创建一个。在字典中,"disabled"仅当要禁用文本框时才添加键。不是最简洁的解决方案,但简单明了。