2015-09-08 6 views
7

ich eine Form bin Gebäude, und ich habe zu halten, ein Inline-bedingte mit einem Attribut readonly html hinzuzufügen:Wie kann ich wiederholende Inline conditionals für die Definition von Htmlattributes Html.EditorFor vermeiden()

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

Sie können‘ t Verwenden Sie eine Bedingung nur für den Wert @readonly der Eigenschaft, denn selbst wenn es auf Null gesetzt ist, wird es für den Client als readonly="" gerendert werden, und das ist genug für einen Browser, dieses Feld schreibgeschützt zu machen.

Es muss einen besseren Weg geben, dies zu tun als eine Inline-Bedingung für jedes Formularelement, nur um ein einzelnes Attribut hinzuzufügen, richtig?

+3

Sie könnten Sie besitzen Methode Htmlhelper Erweiterung erstellen - sagen '@ Html.ReadOnlyEditorFor (Ausdruck, Htmlattributes, isReadonly = true)', wo das Attribut hinzugefügt wird, je nach dem Wert des 'isReadonly' -Parameter –

+0

@StephenMuecke Wie würde ich das htmlAttributes-Objekt innerhalb dieses Helpers ändern, um die Eigenschaft' @ readonly' hinzuzufügen/zu entfernen? – travis

+1

Siehe [diese Antwort] (http://stackoverflow.com/questions/30127866/create-checkboxfor-mvc-helper-with-title-attribute-from-model-description/30135407#30135407) für ein Beispiel –

Antwort

2

Dank Steven Muecke für die ganze Hilfe (geben Sie ihm alle Ihre up-Stimmen oben in den Kommentaren und auf seine linkedanswers). Hier ist the solution.

Für ein Modell mit dieser Eigenschaft:

[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; } 

diese Erweiterung Methode erstellen:

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

Und es dann so in der Ansicht verwenden:

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

und alle Die Metadaten der Eigenschaft des Modells erscheinen für die ersten ins tance, dass es auf der Seite aufgerufen wird. Der resultierende HTML wird wie folgt aussehen:

<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" />