55

My ViewModel has a property of selected and selectable. Both are boolean. I would like my view to have a checkbox that is enabled when selectable is true and disabled when selectable is false. What is the proper razor syntax to accomplish this ?

I tried the code below on a list of items in a table. Every row comes back with a disabled checkbox regardless of selectable value.

 @Html.CheckBoxFor(modelItem => item.Selected, new { @disabled = !item.Selectable })
1
  • 2
    Question: What is item? I see on your lambda that you have modelItem => item.Selected, but is item independent from the model itself? Or perhaps you meant to say modelItem => modelItem.Selected? Commented Jan 6, 2014 at 0:14

4 Answers 4

101

It is not easy to achieve this with an if condition inside the helper method because all the below markups will render a disabled chechbox.

<input type="checkbox" disabled>
<input type="checkbox" disabled="disabled">
<input type="checkbox" disabled="false">
<input type="checkbox" disabled="no">
<input type="checkbox" disabled="enabled">

This should work in the razor. Simple If condition and rendering what you want.

@if(item.Selected)
{ 
  @Html.CheckBoxFor(modelItem => item.Selected)
}
else
{
    @Html.CheckBoxFor(modelItem => item.Selected, new { @disabled = "disabled"})
}

You may consider writing a custom html helper which renders the proper markup for this.

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

1 Comment

For HTML5 I write new { @disabled = "" } as <input type="checkbox" disabled /> is valid and used by W3C in their samples.
38

This won't work because <input disabled="anything" /> will result in a disabled control. You need to only have a @disabled property when it should be disabled.

Try something like this:

@Html.CheckBoxFor(modelItem => item.Selected, item.Selectable ?  (object)new {} :  (object)new { @disabled = "disabled" })

Note that you might need to cast to (object)

2 Comments

This is a much cleaner option than the selected answer. You do need to cast as object; in my case I had this working: @Html.EditorFor(p => item.Selected, new {htmlAttributes = item.Selectable ? (object)new { } : (object)new { @disabled = "disabled" }})
You might just be able to go new object() on the left side
8

The problem is when you have to add more than 1 HTML attribute. That's a mess:

@if(item.Selected)
{ 
  @Html.CheckBoxFor(modelItem => item.Selected, new { @data_foo = "bar"})
}
else
{
    @Html.CheckBoxFor(modelItem => item.Selected, new { @data_foo = "bar", @disabled = "disabled"})
}

What I do to solve this is to use a IDictionary<string, object> that is previously loaded:

var htmlAttributes = new Dictionary<string, object>{
    {"data-foo", "bar"}
};
if(!item.Selected)
{
    htmlAttributes.Add("disabled", "disabled");
}

And then I create the checkbox component only once:

@Html.CheckBoxFor(modelItem => item.Selected, htmlAttributes)

Comments

3

Sorry, my previous answer was wrong.

The input-element will be disabled as soon as it gets the attribute disabled. It doesn't matter if the value is true, false. In HTML you can't set disabled to false.

So you will have to set the disabled attribute only when the condition is valid.

something like:

object attributes = null;
if (!item.Selectable)
{
    attributes = new { disabled = "disabled"};
}
@Html.CheckBoxFor(modelItem => item.Selected, attributes)

2 Comments

I tried your recommendation. Everything comes back as disabled.
you probably need @ prefixes

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.