Set disable attribute based on a condition for Html.TextBoxFor

150,733

Solution 1

The valid way is:

disabled="disabled"

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

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

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 intelligence into 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" 
    }
)

Solution 2

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 { })

Solution 3

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\""))

Solution 4

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)
)

Solution 5

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

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

Related videos on Youtube

Ghooti Farangi
Author by

Ghooti Farangi

Updated on June 06, 2020

Comments

  • Ghooti Farangi
    Ghooti Farangi almost 4 years

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

    @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.

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

  • Ghooti Farangi
    Ghooti Farangi almost 13 years
    I want to disable the textbox if Model.ExpireDate == null else I want to enable it
  • Mir
    Mir over 11 years
    This solution is great - as far as it goes... but it would be nice to find a clean solution that doesn't require putting a wrapper around every HtmlHelper we use that might have a disabled attribute (TextBoxFor, TextAreaFor, CheckBoxFor, etc.) Ideally something that works inline with the existing ones. I've built a solution that basically just wraps the anonymous object and returns a RouteValueDictionary - but it doesn't feel especially clean.
  • Shautieh
    Shautieh over 10 years
    "disabled", "disabled=''" and "disabled='disabled'" are all equally valid in html, and it is misleading (and false) to say that the shorter ones might only be accepted by the different browsers. Cf. dev.w3.org/html5/markup/syntax.html#syntax-attr-empty
  • Geeky Guy
    Geeky Guy over 7 years
    If you use the disabled attribute in a control, the control will be disabled no matter what value the attribute has. Even the presence of the attribute without a value will disable the control.
  • Jozef Krchňavý
    Jozef Krchňavý about 7 years
    Works if you change rawstring.Length - 2 for 7 and add " " after last ".
  • Shadi Alnamrouti
    Shadi Alnamrouti over 6 years
    I think you should surround this with @Html.Raw()
  • Carsten
    Carsten over 6 years
    This solution works really well, and I suspect downvoters may have overlooked that the expression is boolean. When the expression is boolean, the disabled attribute will render as disabled="disabled" if the expression is true, or be completely omitted if false. Which is exactly what you want.
  • Andez
    Andez over 5 years
    This will either render disabled="false" or disabled="true", no?
  • erhan355
    erhan355 over 5 years
    Doesn't work with TextAreaFor, need a solution for all kind of input types
  • Carmine Checker
    Carmine Checker about 4 years
    @Html.EditorFor(m => m.Description, Model.IsDisabled ? (object)new { disabled = "disabled" } : (object)new { }) => this seems the best way. Thanks
  • RasikaSam
    RasikaSam about 4 years
    IMHO, this is the best answer