EditorFor()およびhtmlプロパティ


113

Asp.Net MVC 2.0プレビュービルドは、

Html.EditorFor(c => c.propertyname)

プロパティ名が文字列の場合、上記のコードはtexboxをレンダリングします。

MaxLengthプロパティとSizeプロパティをテキストボックスまたは独自のcssクラスプロパティに渡したい場合はどうなりますか?

アプリケーションのサイズと長さの組み合わせごとに1つのテンプレートを作成する必要がありますか?もしそうなら、それはデフォルトのテンプレートを使用可能にしません。

回答:


92

MVC3では、幅を次のように設定できます。

@Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" })

62
@vondip。エディタではなくテキストボックスであることを確認してください。Doenstはエディターで動作します。
Kasper Skov

1
また、textareasでも機能します。@ Html.TextAreaFor(c => c.PropertyName、new {style = "width:500px;"})
Tarzan

FormatString
AaronLS

14
この答えではありませんか、質問が何であるか、つまりEditorFor-Template機能を完全に無視しますか?
Philipp M

1
ただし、TextBoxForを使用すると、データ注釈として設定されている表示形式が無効になります
AndersLindén11年

61

/ Views / Shared / EditorTemplatesフォルダーにString.ascxという名前のEditorTemplateを作成して、これを解決しました。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% int size = 10;
   int maxLength = 100;
   if (ViewData["size"] != null)
   {
       size = (int)ViewData["size"];
   }
   if (ViewData["maxLength"] != null)
   {
       maxLength = (int)ViewData["maxLength"];
   }
%>
<%= Html.TextBox("", Model, new { Size=size, MaxLength=maxLength }) %>

私の見解では、私は

<%= Html.EditorFor(model => model.SomeStringToBeEdited, new { size = 15, maxLength = 10 }) %>

私の魅力のように機能します!


1
素晴らしい-私はすでにテンプレート化したdatepicker DateTimeドロップダウンを持っていましたが、それに追加の属性を渡すのは面倒であることがわかりました-これで解決しました、ありがとう!
Terry_Brown

maxlengthを指定したEditorForが機能しません(他の
TextBoxFor

@tjeerdhans、このコードを使用してCSSをカスタマイズしました。動作しますが、残念ながら元のcss値を置き換えます。代わりに元のCSSに追加するにはどうすればよいですか?
Rosdi Kasim 2013

33

@ Html.EditorForのHTML属性の設定に関するこのスレッドやその他のスレッドでの回答はどれも、私にとって大きな助けにはなりませんでした。しかし、私は素晴らしい答えを見つけました

@ Html.EditorForヘルパーのスタイリング

私は同じアプローチを使用しましたが、余分なコードをたくさん書くことなく、うまく機能しました。Html.EditorForのhtml出力のid属性が設定されていることに注意してください。ビューコード

<style type="text/css">
#dob
{
   width:6em;
}
</style>

@using (Html.BeginForm())
{
   Enter date: 
   @Html.EditorFor(m => m.DateOfBirth, null, "dob", null)
}

データアノテーションと「dd MMM yyyy」の日付形式のモデルプロパティ

[Required(ErrorMessage= "Date of birth is required")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd MMM yyyy}")]
public DateTime DateOfBirth { get; set; }

余分なコードをたくさん書くことなく、魅力のように動作しました。この回答はASP.NET MVC 3 Razor C#を使用しています。


1
MVC4でも私にとっては本当にうまくいきました。
atconway 2012

1
フォーマットは機能しましたが、データに対してボックスが事実上無効になっているため、nullが返されます。
Joe

2
それがMVCの人々にとって何であるか私は知りません、それは誰もが数のために複数の言語とフォーマットで動作するウェブサイトを書いた人が誰もいないようなものです。
adudley

とても良い。これは単純で、機能します。実際には、代替手段を提供するのではなく、OPの質問に答えます。MVC4の使用。
draconis 14

警告:DateTimeはtype = "datetime"としてレンダリングされるように見えますが、これは生年月日には間違っており、一部のブラウザー(Firefoxモバイルなど)は実際にはその入力タイプを正しくサポートしています。ユーザーが削除することは不可能です。
brianary

25

Kiran Chandのブログ投稿をご覧になりたい場合は、次のようなビューモデルでカスタムメタデータを使用します。

[HtmlProperties(Size = 5, MaxLength = 10)]
public string Title { get; set; }

これは、メタデータを利用するカスタムテンプレートと組み合わされます。私の意見ではクリーンでシンプルなアプローチですが、mvcに組み込まれているこの一般的なユースケースを確認したいと思います。


71
冗談ですか?これは、そのような単純なことには、やり過ぎです。ますます純粋なHTMLに戻り、MVCの肥大化したヘルパーメソッドを忘れています。5分前に、jquery日付ピッカーを正常に起動する単純なTextboxForがありました。これで、プリロードされた日付値の形式を変更したかっただけなので、EditorForに変更する必要がありました。しかし、突然、これらの過度に肥大化したカスタム拡張メソッドとヘルパーを作成しないと、自分のHTML属性を指定できなくなります。なんて冗談でしょう。もっと簡単な方法が必要です。狂った教授はいつやめるべきかわからないのです。
アーロン

1
あなたは文脈を混同していると思います。どのようにして2つの異なるEditorFor呼び出しを行い、それぞれが指定したリンクで独自のサイズとmaxlength値を取得できますか?EditorForを使用したくない場合は、TextBoxヘルパーまたは単純なhtmlをいつでも使用できます。しかし、それは問題ではありません!
chandmk '24

MVC最新のとして、あなたが持つ追加のHTML属性を指定することができます@Aaron EditorForとしてそれを渡すことによって:new { htmlAttributes: { @class = "yourclass" } }
JoeBrockhaus

17

「additionalViewData」に渡して、反対側でそれを読んでいる人が誰もいないことに驚いています。

ビュー(わかりやすくするために改行あり):

<%= Html.EditorFor(c => c.propertyname, new
    {
        htmlAttributes = new
        {
            @class = "myClass"
        }
    }
)%>

エディターテンプレート:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>

<%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %>

これに基づいて、属性のマージを考慮に入れるヘルパーを作成しました-stackoverflow.com/a/11498094/79842
Colin Bowern

6

問題は、テンプレートに複数のHTML要素が含まれる可能性があるため、MVCがサイズ/クラスを適用する要素を認識できないことです。自分で定義する必要があります。

テンプレートをTextBoxViewModelという独自のクラスから派生させます。

public class TextBoxViewModel
{
  public string Value { get; set; }
  IDictionary<string, object> moreAttributes;
  public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
  {
    // set class properties here
  }
  public string GetAttributesString()
  {
     return string.Join(" ", moreAttributes.Select(x => x.Key + "='" + x.Value + "'").ToArray()); // don't forget to encode
  }

}

テンプレートでこれを行うことができます:

<input value="<%= Model.Value %>" <%= Model.GetAttributesString() %> />

あなたの見解では、

<%= Html.EditorFor(x => x.StringValue) %>
or
<%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue, new IDictionary<string, object> { {'class', 'myclass'}, {'size', 15}}) %>

最初のフォームは文字列のデフォルトテンプレートをレンダリングします。2番目のフォームはカスタムテンプレートをレンダリングします。

代替構文は流暢なインターフェースを使用します:

public class TextBoxViewModel
{
  public string Value { get; set; }
  IDictionary<string, object> moreAttributes;
  public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
  {
    // set class properties here
    moreAttributes = new Dictionary<string, object>();
  }

  public TextBoxViewModel Attr(string name, object value)
  {
     moreAttributes[name] = value;
     return this;
  }

}

   // and in the view
   <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) %>

これをビューで行う代わりに、コントローラーで行うか、ViewModelで行うほうがよいことに注意してください。

public ActionResult Action()
{
  // now you can Html.EditorFor(x => x.StringValue) and it will pick attributes
  return View(new { StringValue = new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) });
}

また、基本のTemplateViewModelクラス(すべてのビューテンプレートの共通基盤)を作成できることにも注意してください。このクラスには、属性などの基本的なサポートが含まれます。

しかし、一般的に私はMVC v2にはもっと良いソリューションが必要だと思います。それはまだベータ版です-それを求めに行く;-)


私は、私がここに述べたようにこれに対処する良い方法があると思いstackoverflow.com/questions/1647609/... ...一言で言えばWPFは、問題を処理する方法に似た何かをして...任意のスタイル要素(この場合は上属性)テンプレートに渡され、テンプレートはスタイルを適用する内部要素を決定します...
vdhant

6

CSSを使用する方法だと思います。XAMLのように.NETコーディングでもっと多くのことができるといいのですが、ブラウザではCSSが重要です。

Site.css

#account-note-input { 
  width:1000px; 
  height:100px; 
} 

.cshtml

<div class="editor-label"> 
  @Html.LabelFor(model => model.Note) 
</div> 
<div class="editor-field"> 
  @Html.EditorFor(model => model.Note, null, "account-note-input", null) 
  @Html.ValidationMessageFor(model => model.Note) 
</div>

ジョー


これは、EditorForテンプレートの使用時にコントロール固有のCSSを変更する場合に非常に役立ちます。私はMVC4を使用していますが、これはうまくいきました。
atconway 2012

6

MVC 5と同様に、属性を追加する場合は、簡単に行うことができます

 @Html.EditorFor(m => m.Name, new { htmlAttributes = new { @required = "true", @anotherAttribute = "whatever" } })

このブログから見つかった情報


3

プロパティの属性を定義できます。

[StringLength(100)]
public string Body { get; set; }

これはとして知られていSystem.ComponentModel.DataAnnotationsます。あなたが見つからない場合ValidationAttribute必要なものが場合は、常にカスタム属性を定義できます。

よろしく、カルロス


3
彼は、検証ではなくmaxlengthのようなHTML属性について語っています。
Mathias F

私は考えを望むビューエンジンもDataAnnotationsに従うでしょう。私はまだMVC2をいじっていません。
mxmissile 2009年

StringLengthデータ注釈を試しました。EditorForでは機能しませんでした。
wayne.blackmon

3

これは最も洗練されたソリューションではないかもしれませんが、簡単です。HtmlHelper.EditorForクラスの拡張機能を記述できます。その拡張機能では、ヘルパーのViewDataにオプションを書き込むオプションパラメーターを指定できます。ここにいくつかのコードがあります:

まず、拡張メソッド:

public static MvcHtmlString EditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, TemplateOptions options)
{
    return helper.EditorFor(expression, options.TemplateName, new
    {
        cssClass = options.CssClass
    });
}

次に、オプションオブジェクト:

public class TemplateOptions
{
    public string TemplateName { get; set; }
    public string CssClass { get; set; }
    // other properties for info you'd like to pass to your templates,
    // and by using an options object, you avoid method overload bloat.
}

そして最後に、String.ascxテンプレートからの行は次のとおりです。

<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = ViewData["cssClass"] ?? "" }) %>

率直に言って、これはあなたのコードを今後も維持しなければならない貧しい魂にとっては単純明快だと思います。また、テンプレートに渡したい他のさまざまな情報にも簡単に拡張できます。これまでのところ、周囲のhtmlを標準化するのに役立つテンプレートのセットにできるだけ多くラップしようとしているプロジェクトでは、http://bradwilson.typepad.com/blog/2009/でうまく機能しています。10 / aspnet-mvc-2-templates-part-5-master-page-templates.html


3

自分の質問に答えるためにブログエントリを書きました

テンプレートのHTML属性サポートの追加-ASP.Net MVC 2.0 Beta


(ビュー)モデルにHTMLフォーマットプロパティを配置するという考えは、ビューとロジックを分離するというMVCの考えに反しています。モデルがHTMLで異なる表現を必要とする場合はどうなりますか?
saintedlama 2012年

2
@Saintedlama:viewmodelの唯一の目的はviewに構造化データモデルを提供することなので、viewmodelにデータアノテーションを付けることは完全に問題ありません。MVC用語では通常、ビュー関連のプロパティを持たないはずのDBエンティティを表すmodelと混同しないでください。とはいえ、彼のビューモデルアノテーションがHTMLxxxで始まるのは残念ですが、これはプレゼンテーションレイヤーとしてHTMLを意味しますが、どこかに線を引く必要があります。:)その上、彼が言うsilverlightアプリのためにviewmodelを再利用するならば、彼は彼のviewmodelにSL属性を簡単に加えることができます。
Boris B.

3

Html.EditorForで機能しない理由はわかりませんが、TextBoxForを試してみましたが、うまくいきました。

@Html.TextBoxFor(m => m.Name, new { Class = "className", Size = "40"})

...そして検証も機能します。


必要なもの@class = "className"
JoeBrockhaus 14

2

私の実践では、HtmlHelperを1つだけ含むEditorTemplates(ほとんどの場合はTextBox)を使用するのが最善であることを発見しました。より複雑なhtml構造のテンプレートが必要な場合は、別のHtmlHelperを作成します。

TextBoxのhtmlAttributesの代わりにViewDataオブジェクト全体を貼り付けることができると仮定します。さらに、特別な処理が必要な場合は、ViewDataの一部のプロパティのカスタマイズコードを記述できます。

@model DateTime?
@*
    1) applies class datepicker to the input;
    2) applies additionalViewData object to the attributes of the input
    3) applies property "format" to the format of the input date.
*@
@{
    if (ViewData["class"] != null) { ViewData["class"] += " datepicker"; }
    else { ViewData["class"] = " datepicker"; }
    string format = "MM/dd/yyyy";
    if (ViewData["format"] != null)
    {
        format = ViewData["format"].ToString();
        ViewData.Remove("format");
    }
}

@Html.TextBox("", (Model.HasValue ? Model.Value.ToString(format) : string.Empty), ViewData)

以下は、ビューの構文と出力されるhtmlの例です。

@Html.EditorFor(m => m.Date)
<input class="datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="01/08/2012">
@Html.EditorFor(m => m.Date, new { @class = "myClass", @format = "M/dd" })
<input class="myClass datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="1/08">

2

問題はEditorForのためです WEFXの提案ではなくEditorFor。

個々の入力ボックスを変更するには、EditorForメソッドの出力を処理できます。

<%: new HtmlString(Html.EditorFor(m=>m.propertyname).ToString().Replace("class=\"text-box single-line\"", "class=\"text-box single-line my500pxWideClass\"")) %>

MVCがEditorForテキストボックスのクラスを.text-boxで設定することが判明したため、すべてのEditorForsを変更することもできます。したがって、スタイルシートまたはページでこのスタイルをオーバーライドできます。

.text-box {
    width: 80em;
}

さらに、スタイルを設定できます

input[type="text"] {
    width: 200px;
}
  • これは.text-boxをオーバーライドし、EditorForなどのすべての入力テキストボックスを変更します。

すべてのEditorFor()テキストボックスが入力type = "text"であるとは限りません。DateTimeプロパティはtype = "datetime"としてレンダリングされるようです。
ブライアリー2015年

2

Clsss属性の設定はTextAreaコントロールに対しては機能しましたが、TextBoxForコントロールまたはEditorForコントロールに対しては機能しませんでした。

私は以下を試してみました&それは私のために働きました:

@ Html.TextBoxFor(model => model.Title、new {Class = "textBox"、style = "width:90%;"})

この場合も、検証は完全に機能しています。


2

これを回避する方法の1つは、ビューモデルのデリゲートに、このような特別なレンダリングの印刷を処理させることです。ページングクラスに対してこれを実行しました。モデルのパブリックプロパティを公開しますFunc<int, string> RenderUrl。それを処理するために。

したがって、カスタムビットの記述方法を定義します。

Model.Paging.RenderUrl = (page) => { return string.Concat(@"/foo/", page); };

Pagingクラスのビューを出力します。

@Html.DisplayFor(m => m.Paging)

...そして実際のPagingビュー:

@model Paging
@if (Model.Pages > 1)
{
    <ul class="paging">
    @for (int page = 1; page <= Model.Pages; page++)
    {
        <li><a href="@Model.RenderUrl(page)">@page</a></li>
    }
    </ul>
}

それは複雑すぎる問題と見なすことができましたが、私はどこでもこれらのポケットベルを使用しており、同じボイラープレートコードを表示してレンダリングするのを我慢できませんでした。


1

更新:ええと、モデルは値で渡されるので属性は保持されないため、明らかにこれは機能しません。この答えはアイデアとして残しておきます。

別の解決策は、モデルの独自の属性をチェックする独自のTextBox / etcヘルパーを追加することだと思います。

public class ViewModel
{
  [MyAddAttribute("class", "myclass")]
  public string StringValue { get; set; }
}

public class MyExtensions
{
  public static IDictionary<string, object> GetMyAttributes(object model)
  {
     // kind of prototype code...
     return model.GetType().GetCustomAttributes(typeof(MyAddAttribute)).OfType<MyAddAttribute>().ToDictionary(
          x => x.Name, x => x.Value);
  }
}

<!-- in the template -->
<%= Html.TextBox("Name", Model, MyExtensions.GetMyAttributes(Model)) %>

これは簡単ですが、便利/柔軟性はありません。



0

/ Views / Shared / EditorTemplatesフォルダーにあるString.ascxという名前のEditorTemplateを利用する@tjeerdansの回答が本当に気に入りました。これは、この質問に対する最も簡単な答えのようです。しかし、Razor構文を使用したテンプレートが必要でした。さらに、MVC3はデフォルトとして文字列テンプレートを使用しているようです(StackOverflowの質問「文字列のmvc表示テンプレートは整数に使用されます」を参照)。そのため、モデルを文字列ではなくオブジェクトに設定する必要があります。私のテンプレートはこれまでのところ機能しているようです:

@model object 

@{  int size = 10; int maxLength = 100; }

@if (ViewData["size"] != null) {
    Int32.TryParse((string)ViewData["size"], out size); 
} 

@if (ViewData["maxLength"] != null) {
    Int32.TryParse((string)ViewData["maxLength"], out maxLength); 
}

@Html.TextBox("", Model, new { Size = size, MaxLength = maxLength})

0

解決しました!!
Razorの場合、構文は次のとおりです。
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" })これにより、テキスト領域の幅がスタイルパラメータで定義した幅に調整されます。
ASPXの構文は次のとおりです。
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
これは、トリックを行います

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.