1

I want to disable or enable a textbox based on boolean value, I created this extension method:

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.Add("disabled", "\"disabled\"");
            }
            return htmlHelper.TextBoxFor(expression, htmlAttributes);
        }

And that how I used:

        <div class="col-md-10">
            @Html.MyTextBoxFor(model => model.Body, new { @class = "form-control"}, true)
        </div>

but its not working, I'm new to Htmlhelper class, though it's not hard to understand, but I certainly missed something!

Edit:

I tried this simple method, to find out the problem:

public static IHtmlString MyTextBox(this HtmlHelper htmlHelper,object htmlAttributes, bool disabled)
        {
            IDictionary<string, object> attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
            //var attrs = new Dictionary<string,string>();
            if (disabled)
            {
                attrs.Add("disabled", "disabled");
                attrs.Add("value", "txxxxxxt");
            }
            return htmlHelper.TextBox("txtbx", attrs);
        }

And that has been rendered: <input id="txtbx" name="txtbx" type="text" value="System.Collections.Generic.Dictionary``2[System.String,System.String]">

10
  • 1
    Maybe it is just a typo in the sample: why do you call the original version of TextBoxFor with htmlAttributes as a parameter instead of attributes? Commented Oct 25, 2016 at 13:12
  • I'll pass a Boolean expression, not just true or false Commented Oct 25, 2016 at 13:16
  • try using IDictionary<string, object> attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); Commented Oct 25, 2016 at 13:19
  • Not working too :( Commented Oct 25, 2016 at 13:44
  • Why you need disabled parameter, when you can pass it in htmlattribute as { disabled= (1==0)}. Commented Oct 25, 2016 at 13:49

1 Answer 1

3

The code for you extension method needs to be

public static IHtmlString MyTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool disabled)
{
    IDictionary<string, object> attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
    if (disabled)
    {
        attrs.Add("disabled", "disabled");
    }
    return htmlHelper.TextBoxFor(expression, attrs);
}

In your first code example, your use of

return htmlHelper.TextBoxFor(expression, htmlAttributes);

is returning the original attributes, not the updated attributes that includes the disabled attribute. It should have been

return htmlHelper.TextBoxFor(expression, attributes);

In your second code example, your using the TextBox() method rather that TextBoxFor() and the 2nd parameter is the value, not the attributes, and it should have been

return htmlHelper.TextBox("txtbx", null, attrs);

although that would not have bound to your property because of the incorrect name attribute.

Side note: Its a bit unclear why you would ever want to do this. Disabled controls do not submit a value so you may as well just render the value of the property as text in the view. If you do want its value to be submitted, then it should be readonly, not disabled

Sign up to request clarification or add additional context in comments.

2 Comments

Great, thanks! I tried to pass value attribute but didn't rendered , do you know why, though attribute like style is working fine. I tried this: @Html.MyTextBoxFor(model => model.Body, new { @class = "form-control", style="background-color:yellow;", value="hurray"}, true)
Why would you want to do that. You never set the value attribute (or the name attribute) when using HtmlHelper methods (the methods set that attribute based on value of the property). So if model.Body="hurray" then it will be generated correctly (setting the value attribute screws up model binding)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.