94

@Html.EditorFor を使用してHtml5 プレースホルダーを記述する方法はありますか、それとも TextBoxFor 拡張機能を使用する必要がありますか?

@Html.TextBoxFor(model => model.Title, new { @placeholder = "Enter title here"})

または、DataAnnotations を介して 'Description' 表示属性を使用できる独自のカスタム拡張機能を作成することは理にかなっていますか (これに似ています)?

もちろん、同じ質問が「オートフォーカス」にも当てはまります。

4

7 に答える 7

122

Darin Dimitrovの回答でsmnbssがコメントしてPromptいるように、まさにこの目的のために存在するため、カスタム属性を作成する必要はありません。ドキュメントから:

UIでプロンプトの透かしを設定するために使用される値を取得または設定します。

これを使用するには、ビューモデルのプロパティを次のように装飾します。

[Display(Prompt = "numbers only")]
public int Age { get; set; }

このテキストは、便利な場所に配置されModelMetadata.Watermarkます。箱から出して、MVC 3のデフォルトのテンプレートはWatermarkプロパティを無視しますが、それを機能させるのは本当に簡単です。デフォルトの文字列テンプレートを微調整して、MVCにレンダリング方法を指示するだけです。Darinと同じように、String.cshtmlを編集するだけです。ただし、から透かしを取得するのではなく、からModelMetadata.AdditionalValues直接取得しますModelMetadata.Watermark

〜/ Views / Shared / EditorTemplates / String.cshtml:

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = "text-box single-line", placeholder = ViewData.ModelMetadata.Watermark })

そしてそれだけです。

ご覧のとおり、すべてを機能させるための鍵はplaceholder = ViewData.ModelMetadata.Watermark少しです。

複数行のテキストボックス(textareas)に対して透かしを有効にする場合は、MultilineText.cshtmlに対して同じことを行います。

〜/ Views / Shared / EditorTemplates / MultilineText.cshtml:

@Html.TextArea("", ViewData.TemplateInfo.FormattedModelValue.ToString(), 0, 0, new { @class = "text-box multi-line", placeholder = ViewData.ModelMetadata.Watermark })
于 2011-07-05T06:01:06.983 に答える
69

カスタム の作成については、次の記事DataAnnotationsModelMetadataProviderを参照してください。

また、新たに導入されたIMetadataAwareインターフェイスを使用して、ASP.NET MVC 3 に似た別の方法を次に示します。

このインターフェイスを実装するカスタム属性を作成することから始めます。

public class PlaceHolderAttribute : Attribute, IMetadataAware
{
    private readonly string _placeholder;
    public PlaceHolderAttribute(string placeholder)
    {
        _placeholder = placeholder;
    }

    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.AdditionalValues["placeholder"] = _placeholder;
    }
}

そして、モデルをそれで飾ります:

public class MyViewModel
{
    [PlaceHolder("Enter title here")]
    public string Title { get; set; }
}

次にコントローラーを定義します。

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }
}

対応するビュー:

@model MyViewModel
@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.Title)
    <input type="submit" value="OK" />
}

最後にエディタ テンプレート ( ~/Views/Shared/EditorTemplates/string.cshtml):

@{
    var placeholder = string.Empty;
    if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("placeholder"))
    {
        placeholder = ViewData.ModelMetadata.AdditionalValues["placeholder"] as string;
    }
}
<span>
    @Html.Label(ViewData.ModelMetadata.PropertyName)
    @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { placeholder = placeholder })
</span>
于 2011-04-28T19:53:38.783 に答える
23

実際、私はほとんどの場合、プレースホルダー テキストに表示名を使用することを好みます。以下は、DisplayName の使用例です。

  @Html.TextBoxFor(x => x.FirstName, true, null, new { @class = "form-control", placeholder = Html.DisplayNameFor(x => x.FirstName) })
于 2014-07-17T22:06:56.380 に答える
3

私はそのような単純なクラスを書きました:

public static class WatermarkExtension
{
    public static MvcHtmlString WatermarkFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        var watermark = ModelMetadata.FromLambdaExpression(expression, html.ViewData).Watermark;
        var htmlEncoded = HttpUtility.HtmlEncode(watermark);
        return new MvcHtmlString(htmlEncoded);
    }
}

使用方法は次のとおりです。

@Html.TextBoxFor(model => model.AddressSuffix, new {placeholder = Html.WatermarkFor(model => model.AddressSuffix)})

ビューモデルのプロパティ:

[Display(ResourceType = typeof (Resources), Name = "AddressSuffixLabel", Prompt = "AddressSuffixPlaceholder")]
public string AddressSuffix
{
    get { return _album.AddressSuffix; }
    set { _album.AddressSuffix = value; }
}

プロンプト パラメータに注意してください。この場合、ローカリゼーションのためにリソースからの文字列を使用しますが、文字列だけを使用することもできます。ResourceType パラメータは避けてください。

于 2014-10-23T22:02:31.843 に答える
1

TextBoxFor と PasswordFor に使用できる上記のアイデアを使用して作成したソリューションを次に示します。

public static class HtmlHelperEx
{
    public static MvcHtmlString TextBoxWithPlaceholderFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        return htmlHelper.TextBoxFor(expression, htmlAttributes.AddAttribute("placeholder", metadata.Watermark));

    }

    public static MvcHtmlString PasswordWithPlaceholderFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        return htmlHelper.PasswordFor(expression, htmlAttributes.AddAttribute("placeholder", metadata.Watermark));

    }
}

public static class HtmlAttributesHelper
{
    public static IDictionary<string, object> AddAttribute(this object htmlAttributes, string name, object value)
    {
        var dictionary = htmlAttributes == null ? new Dictionary<string, object>() : htmlAttributes.ToDictionary();
        if (!String.IsNullOrWhiteSpace(name) && value != null && !String.IsNullOrWhiteSpace(value.ToString()))
            dictionary.Add(name, value);
        return dictionary;
    }

    public static IDictionary<string, object> ToDictionary(this object obj)
    {
        return TypeDescriptor.GetProperties(obj)
            .Cast<PropertyDescriptor>()
            .ToDictionary(property => property.Name, property => property.GetValue(obj));
    }
}
于 2015-05-22T14:21:41.227 に答える