Ray
Ray

Reputation: 396

MVC EditorFor Optionally ReadOnly

Yesterday, after extensive testing, I got the following to optionally apply the readonly attribute to a control based on the value of ViewBag.CanEdit;

@Html.EditorFor(m => m.Location, new { htmlAttributes = new { @class = "form-control", @readonly = (ViewBag.CanEdit == true ? Html.Raw("") : Html.Raw("readonly")) } })

Based on the success of this testing I implemented and tested it in several parts of my project. Today I started on a new section of the code and commenced implementing the same code only to have it consistently fail - every control is readonly.

When I inspected the controls they either have readonly or readonly=readonly as the attribute? I then went back to the code I refactored yesterday to find the same problem; every control is now readonly regardless of the value of ViewBag.CanEdit?

Can anyone explain why this would have worked yesterday but fails today?

Upvotes: 2

Views: 2302

Answers (2)

Farhad Jabiyev
Farhad Jabiyev

Reputation: 26635

As a better approach, I have created this method and I am using this in my project, whenever I need such thing. It will make your code much cleaner.

Firstly, add this class to your project:

 public static class HtmlBuildersExtended
    {
        public static RouteValueDictionary ConditionalReadonly(
            bool isReadonly,
            object htmlAttributes = null)
        {
            var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            if (isReadonly)
                dictionary.Add("readonly", "readonly");

            return dictionary;
        }
   }

Then you can change your code as:

@Html.TextBoxFor(model => model.Location, 
      HtmlBuildersExtended.ConditionalReadonly(
          (bool)ViewBag.CanEdit, new { @class = "form-control" }));

Or if you want to use EditorFor helper, then:

@Html.EditorFor(model => model.Location,
             HtmlBuildersExtended.ConditionalReadonly((bool)ViewBag.CanEdit, 
                    new
                    {
                        htmlAttributes = new
                        {
                            @class = "form-control"
                        }
                    }));

Upvotes: 2

Nitin Varpe
Nitin Varpe

Reputation: 10694

Try this

@Html.TextBoxFor(model => model.Location, !ViewBag.CanEdit 
    ? (object)new { @class = "form-control", @readonly ="readonly" } 
    : (object)new { @class = "form-control" })

Upvotes: 1

Related Questions