web-dev-qa-db-ja.com

ASP.NET MVCのEditorFor()のHtml属性

Html属性をEditorFor()に渡せないのはなぜですか?例えば;

<%= Html.EditorFor(model => model.Control.PeriodType, 
    new { disabled = "disabled", readonly = "readonly" }) %>

メタデータを使いたくない

更新:ソリューションはビューからこれを呼び出すことでした:

 <%=Html.EditorFor( model => model.Control.PeriodEndDate, new {Modifiable=model.Control.PeriodEndDateModifiable})%>

カスタムEditorTemplates/String.ascxでViewData["Modifiable"]を使用します。読み取り専用属性や無効な属性を入力に追加するかどうかを決定するビューロジックがあります。EditorFor()に渡される匿名オブジェクトはadditionalViewDataというパラメーターで、 ViewDataコレクションのエディターテンプレートに渡されます。

126
Typo Johnson

EditorForはメタデータで動作するため、html属性を追加する場合は 常に実行できます です。別のオプションは、単にカスタムテンプレートを記述し、TextBoxForを使用することです。

<%= Html.TextBoxFor(model => model.Control.PeriodType, 
    new { disabled = "disabled", @readonly = "readonly" }) %>    
96
Darin Dimitrov

UpdateMVC 5.1は以下のアプローチを直接サポートするようになったため、組み込みエディターでも機能します。 http://www.asp.net/mvc/overview/releases/mvc51-release-notes#new-features (それは偉大な心が同じように考えているか、彼らが読んだかのいずれかです私の答え :)

更新の終了

独自のエディターテンプレートを使用している場合、または組み込みエディターで以下のアプローチを直接サポートしているMVC 5.1を使用している場合。

@Html.EditorFor(modelItem => item.YourProperty, 
  new { htmlAttributes = new { @class="verificationStatusSelect", style = "Width:50px"  } })

次に、テンプレートで(MVC 5.1の単純型には必要ありません)

@Html.TextBoxFor(m => m, ViewData["htmlAttributes"])
114
AntonK

MVC 5.1以降、次のことができるようになりました。

@Html.EditorFor(model => model, new { htmlAttributes = new { @class = "form-control" }, })

http://www.asp.net/mvc/overview/releases/mvc51-release-notes#new-features

42
vtforester

現在、ASP.Net MVC 5.1は、そのサポートを組み込みました。

リリースノートから

EditorForで匿名オブジェクトとしてHTML属性を渡すことができるようになりました。

例えば:

@Html.EditorFor(model => model, 
              new { htmlAttributes = new { @class = "form-control" }, })
6

VB.Netコード構文MVC 5.1のhtml属性 EditorFor

@Html.EditorFor(Function(x) x.myStringProp, New With {.htmlAttributes = New With {.class = "myCssClass", .maxlength="30"}}))
4
Max

なぜ使用しないのですか

@Html.DisplayFor(model => model.Control.PeriodType)
3
Mhoque

EditorForを引き続き使用できます。スタイル/いずれかのhtml属性をViewDataとして渡すだけです。

@Html.EditorFor(model => model.YourProperty, new { style = "Width:50px" })

EditorForはテンプレートを使用してレンダリングするため、プロパティのデフォルトテンプレートをオーバーライドし、スタイル属性をViewDataとして渡すだけで済みます。

したがって、EditorTemplateは次のようになります。

@inherits System.Web.Mvc.WebViewPage<object>

@Html.TextBoxFor(m => m, new { @class = "text ui-widget-content", style=ViewData["style"] })
2
Ralph W

メタデータを使用したくない場合は、[UIHint("PeriodType")]属性を使用してプロパティを装飾するか、その複雑なタイプの場合は何も装飾する必要はありません。 EditorForは、EditorTemplatesフォルダーでPeriodType.aspxまたはascxファイルを探し、代わりにそれを使用します。

2
John Farrell
Html.TextBoxFor(model => model.Control.PeriodType, 
    new { @class="text-box single-line"})

このように使用できます。 Html.EditorForと同じ出力、およびhtml属性を追加できます

1
zamoldar

私の場合、追加の属性を受け取ることができるHTML5数値入力エディターテンプレートを作成しようとしていました。きちんとしたアプローチは、独自のHTMLヘルパーを作成することですが、.ascxテンプレートが既にあるので、このアプローチを使用しました。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<input id="<%= Regex.Replace(ViewData.TemplateInfo.GetFullHtmlFieldId(""), @"[\[\]]", "_") %>" name="<%= ViewData.TemplateInfo.HtmlFieldPrefix %>" type="number" value="<%= ViewData.TemplateInfo.FormattedModelValue %>"
<% if (ViewData["attributes"] != null)
   {
       Dictionary<string, string> attributes = (Dictionary<string, string>)ViewData["attributes"];
       foreach (string attributeName in attributes.Keys){%>
        <%= String.Format(" {0}=\"{1}\"", attributeName, attributes[attributeName])%>
       <% }
   } %> />

このいビットは、数値型の入力を作成し、キー「属性」を持つViewDataディクショナリを探します。キー/値のペアを属性として追加して、辞書を反復処理します。 ID属性の正規表現は無関係です。コレクションで使用される場合、GetFullHtmlFieldId()は角括弧[]を含むIDを返します。これは通常アンダースコアとしてエスケープされます。

このテンプレートは、次のように呼び出されます。

Html.EditorFor(m => m.Quantity, "NumberField", new { attributes = new Dictionary<string, string>() { { "class", "txtQuantity" } } }

冗長ですが、動作します。テンプレートでリフレクションを使用して、辞書を使用する代わりにプロパティ名を属性名として使用することができます。

1
xr280xr

私は今日、nullable boolにバインドするチェックボックスについて同じ問題に取り組んでいますが、(コードではなく)モデルを変更できないため、これを処理するより良い方法を考え出す必要がありました。それは少し強引ですが、私が遭遇する可能性のあるケースの99%で動作するはずです。明らかに、各入力タイプに対して有効な属性を手動で入力する必要がありますが、チェックボックスについてはすべて取得していると思います。

Boolean.cshtmlエディターテンプレート:

@model bool?

@{
    var attribs = new Dictionary<string, object>();
    var validAttribs = new string[] {"style", "class", "checked", "@class",
        "classname","id", "required", "value", "disabled", "readonly", 
        "accesskey", "lang", "tabindex", "title", "onblur", "onfocus", 
        "onclick", "onchange", "ondblclick", "onmousedown", "onmousemove", 
        "onmouseout", "onmouseover", "onmouseup", "onselect"};
    foreach (var item in ViewData) 
    {
        if (item.Key.ToLower().IndexOf("data_") == 0 || item.Key.ToLower().IndexOf("aria_") == 0) 
        {
            attribs.Add(item.Key.Replace('_', '-'), item.Value);
        } 
        else 
        {
            if (validAttribs.Contains(item.Key.ToLower()))
            {
                attribs.Add(item.Key, item.Value);
            }
        }
    }
}

@Html.CheckBox("", Model.GetValueOrDefault(), attribs)
1
Isochronous

コントローラーでViewDataを使用して条件を設定します

ViewData["Modifiable"] = model.recProcessed;

次に、エディターテンプレートでこのビューデータを使用して、コントロールのhtml属性を設定します

@Html.RadioButton(prefix, li.Value, li.Selected, @ViewData["Modifiable"].ToString().ToLower() == "true" ? (object)new  { @id = li.Value, @disabled = "disabled" } : new { @id = li.Value })
1
reine varghese

Views/Shared/EditorTemplates/MyTypeEditor.vbhtmlでタイプ用の独自のテンプレートを作成するだけです

@ModelType MyType

@ModelType MyType
@Code
    Dim name As String = ViewData("ControlId")
    If String.IsNullOrEmpty(name) Then
        name = "MyTypeEditor"
    End If
End Code

' Mark-up for MyType Editor
@Html.TextBox(name, Model, New With {.style = "width:65px;background-color:yellow"})

モデルプロパティを使用してビューからエディターを呼び出します。

@Html.EditorFor(Function(m) m.MyTypeProperty, "MyTypeEditor", New {.ControlId = "uniqueId"})

VB構文をご容赦ください。それがまさに私たちのやり方です。

1
Darrel Lee

MVC 5.1以降のソリューション(ローカルHtmlAttributesをマージし、EditorTemplatesで定義されます):

Shared\EditorTemplates\String.cshtml:

@Html.TextBoxFor(model => model, new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark }.ToExpando().MergeHtmlAttributes(ViewData["htmlAttributes"].ToExpando()))

拡張機能:

public static IDictionary<string, object> MergeHtmlAttributes(this ExpandoObject source1, dynamic source2)
{
    Condition.Requires(source1, "source1").IsNotNull().IsLongerThan(0);

    IDictionary<string, object> result = source2 == null
        ? new Dictionary<string, object>()
        : (IDictionary<string, object>) source2;

    var dictionary1 = (IDictionary<string, object>) source1;

    string[] commonKeys = result.Keys.Where(dictionary1.ContainsKey).ToArray();
    foreach (var key in commonKeys)
    {
        result[key] = string.Format("{0} {1}", dictionary1[key], result[key]);
    }

    foreach (var item in dictionary1.Where(pair => !result.ContainsKey(pair.Key)))
    {
        result.Add(item);
    }

    return result;
}

public static ExpandoObject ToExpando(this object anonymousObject)
{
    IDictionary<string, object> anonymousDictionary = new RouteValueDictionary(anonymousObject);
    IDictionary<string, object> expando = new ExpandoObject();
    foreach (var item in anonymousDictionary)
        expando.Add(item);
    return (ExpandoObject)expando;
}

public static bool HasProperty(this ExpandoObject expando, string key)
{
    return ((IDictionary<string, object>)expando).ContainsKey(key);
}

使用法:

@Html.EditorFor(m => m.PromotionalCode, new { htmlAttributes = new { ng_model = "roomCtrl.searchRoomModel().promoCode" }})
0
Sergey