Avoiding duplicate inline conditions for determining htmlAttributes Html.EditorFor ()

I am creating a form and I need to use the inline condition to add the readonly html attribute:

 @Html.LabelFor(model => model.EventDate) <div class="row"> <div class="col-xs-3"> @Html.EditorFor(model => model.EventDate, new { htmlAttributes = Model.IsEditorReadOnly ? (object)new { @class = "form-control input-lg", @type = "date", @readonly = "readonly" } : (object)new { @class = "form-control input-lg", @type = "date" } }) </div> </div> @Html.ValidationMessageFor(model => model.EventDate) 

You cannot use the condition only for the value of the @readonly property, because even if it is set to null, it will be returned to the client as readonly="" , and this is enough for the browser to make this field read-only.

There should be a better way to do this than the inline condition for each form element to only add one attribute, right?

+7
c # asp.net-mvc razor asp.net-mvc-5 html-helper
source share
1 answer

Thanks to Steven Muecke for all the help (give him all your votes above in the comments and related answers ). Here is the solution .

For a model with this property:

 [Display(Name = "Event Date")] [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)] [Range(typeof(DateTime), "01-01-2010", "12-31-2030")] public DateTime? EventDate { get; set; } 

Create this extension method:

 public static IHtmlString ReadOnlyEditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes = null, bool isReadOnly = false) { IDictionary<string, object> attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); if (isReadOnly) { attributes.Add("readonly", "readonly"); } return html.EditorFor(expression, new { htmlAttributes = attributes }); } 

And then use it in the view as follows:

 @Html.ReadOnlyEditorFor(model => model.EventDate, new { @class = "form-control input-lg", @type = "date" }, Model.IsEditorReadOnly) 

And all the model property metadata will appear for the first instance that is called on the page. The resulting html will look like this:

 <input class="form-control input-lg text-box single-line" data-val="true" data-val-date="The field Event Date must be a date." data-val-range="The field Event Date must be between 1/1/2010 12:00:00 AM and 12/31/2030 12:00:00 AM." data-val-range-max="12/31/2030 00:00:00" data-val-range-min="01/01/2010 00:00:00" id="EventDate" name="EventDate" type="date" value="08-01-2015" /> 
+2
source share

All Articles