2018年9月15日土曜日

ASP.NET MVC EditorForでhtmlAttributesを指定せずにclassを指定する

VisualStudio2017 / ASP.NET MVC 5 / Framework4.6.2 / C#


EditorForでclass属性を指定するには、htmlAttributes を使って下記のように書きます
@Html.EditorFor(mdl => mdl.ID, new { htmlAttributes = new { @class = "form-control" } })
少しの事なんだけどメンドクサイ…

EditorForを拡張したEditForExを作成し、htmlAttributesを指定せずにclass属性を設定できるようにしたいと思います。
こんな感じで設定できるようにします。
@Html.EditorForEx(mdl => mdl.ID, new { @class = "form-control" } )

カスタムヘルパーの作成

カスタムヘルパーEitorForExを作成します。
htmlAttributes属性はヘルパーの中でつけてあげます。

EitorForExヘルパーを使用したとき何か固定で付けたい属性があれば、指定しておきます。
Bootstrapを使用しているのであれば「form-control」を付けておいてもいいかもしれません。

また、通常のEditorForヘルパーはclass属性に「text-box single-line」を吐き出すので、これを出力しないようにします。

using System;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

using MyApp.Addon.Attributes;


namespace MyApp.Addon.Extentions
{
    /// 
    /// HTMLヘルパーに対する拡張クラス
    /// 
    public static class HtmlHelperEx
    {

        /// 
        /// EditorForヘルパーを拡張したヘルパー
        /// 機能
        /// htmlAttributesの指定なしにclass属性を指定する
        /// class属性にハードコーディングされる「text-box single-line」を削除する
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static IHtmlString EditorForEx<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, 
                                                                Expression<Func<TModel, TValue>> expression, 
                                                                object viewData)
        {
            //属性をディクショナリに変換
            var dicAttr = new RouteValueDictionary(viewData);
            
      //何か固定で足したい属性があればここで足す
            //属性を追加
            dicAttr.Add("maxlength", 10);

            /*
             * EditorForヘルパーでHTML属性を指定するには
             * @Html.EditorFor(mdl => mdl.ID, new { htmlAttributes = new { @class = "form-control", @readonly="readonly" } } )
             * と指定しなければならない。
             * 
             * これをEditorForExヘルパーでは
             * @Html.EditorFor(mdl => mdl.ID, new { @class = "form-control", @readonly="readonly" } )
             * と指定できるようにする。
             */
            dynamic htmlAttr = new { htmlAttributes = dicAttr };
            MvcHtmlString hstr = htmlHelper.EditorFor(expression, (object)htmlAttr);


            /*
             * 吐き出されるHtmlより class=属性の「text-box single-line」を外す
             */
            hstr = MvcHtmlString.Create(hstr.ToString().Replace(" text-box single-line", ""));
            
            return hstr;
        }

    }
}
よく使用するヘルパーであれば、Views/Web.configのnamespace要素に追加すると、各ビューにインポートを書かなくて済みます。
web.configに追加した場合、私の環境ではVisualStudioを再起動しないと、ビューで使用する際にコンパイルエラーになりました。

        
       ・・・省略
        

web.configに追加しない場合は、各ビューの先頭でインポートしてください。
@using MyApp.Addon.Extentions;

通常のEditorFor と 今回作成したEditorForExの出力をみてみます。
EditorFor
@Html.EditorFor(mdl => mdl.ID, new { htmlAttributes = new { @class = "form-control" } })

出力結果:

EditorForEx
@Html.EditorForEx(mdl => mdl.ID, new { @class = "form-control" })
出力結果


0 件のコメント: