-1

視覚的に言えば、私の MVC ビューの 1 つで、標準的な縦方向の順序で約 20 のフィールドがあり、最初の 8 つほど<div>は右側の同じグループにオプションの [作成] ボックスがあります。

私のデフォルトのタブ オーダーは現在、最初のドロップダウンにヒットし、[作成] に右に移動し、次のドロップダウンに移動し、次に右に移動します。私がやりたいことは、タブ オーダーをさまざまなフィールドに直接移動する場所に設定し、ユーザーのオプションとして (またはタブ オーダーの最後に) ボックスを [作成] します。クイック検索でこれについて多くの議論があるようですが、一貫性のない答えがあるようです。それらの多くは、タブ オーダーの設定に関して数年前からのようですが、カスタム エディター テンプレートを使用するか、または?EditorFor()に切り替えることを余儀なくされています。TextBoxFor()

誰かがこれについて検討できることを願っています。以下は、私のフィールドの詳細です。

(8 of these DropDownListFor()):
@Html.DropDownListFor(model => model.STATUS_ID, (SelectList)ViewBag.Model_List, htmlAttributes: new { @class = "form-control dropdown", @id = "selectStatus" })

(12 of these EditorFor()):
@Html.EditorFor(model => model.NOTE, new { htmlAttributes = new { @class = "form-control" } })
4

1 に答える 1

3

tabindexタブ オーダーを設定するには、生成されたフィールドに追加の属性を追加できるようにするだけです。TextBoxForまたはのようなものを使用すると、実際にはこの目的専用DropDownListForのパラメーターを実際に取るため、簡単です。htmlAttributes

@Html.TextBoxFor(m => m.Foo, new { tabindex = 1 })

以前は、同じことは言えませんでしたEditorFor。これは「テンプレート化された」ヘルパーであるため、メソッド呼び出しではなくエディター テンプレートが生成されるものに影響します。これは の定義で確認できます。他EditorForhtmlAttributesヘルパーのようなパラメーターはなく、additionalViewData.

MVC 5.1 以降、Microsoft は追加の HTML 属性をEditorFor、特別な名前のViewDataキーを介して に渡すことができるようにしました"htmlAttributes"。その結果、 のようなものを使用した場合と同じことを達成できますがTextBoxFor、もう少し冗長です。

@Html.EditorFor(m => m.Foo, new { htmlAttributes = new { tabindex = 1 } })

ほら、あなたはまだ実際にadditionalViewDataここを通過していますが、その追加のビュー データには をキーとする無名オブジェクトが含まれていますhtmlAttributes組み込みのエディターテンプレートはViewData["htmlAttributes"]、生成された要素に追加の属性を追加するために使用する方法を知っています。ただし、Microsoft はこれを使用するように特別にプログラムしているため、これは既定のエディター テンプレートにのみ適用されます。独自のカスタム エディター テンプレートを追加するとすぐに、最初の場所に戻ります。

カスタム エディター テンプレートを使用してこれにアプローチする方法はいくつかあります。まず、タブ インデックスをビュー データとして直接渡し、それをテンプレートで利用することができます。

@Html.EditorFor(m => m.Foo, new { tabindex = 1 })

次に、エディター テンプレートで次のようにします。

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { tabindex = ViewData["tabindex"]})

EditorFor次に、デフォルトのテンプレートを使用して の動作を模倣できます。

@Html.EditorFor(m => m.Foo, new { htmlAttributes = new { tabindex = 1 } })

次に、エディター テンプレートで次のようにします。

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, ViewData["htmlAttributes"])

ただし、このオプションでは「デフォルト」属性を使用できません。これは、オール オア ナッシングのアプローチです。組み込みのエディター テンプレートと同じように真に利用できるようにするViewData["htmlAttributes"]には、最初にデフォルトの属性を渡された属性と組み合わせてから、シバン全体を に渡す必要がありますhtmlAttributesそれについて詳しく説明しているブログ投稿がありますが、TL;DR: 次の拡張機能が必要です。

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;

public static partial class HtmlHelperExtensions
{
    public static IDictionary<string, object> MergeHtmlAttributes(this HtmlHelper helper, object htmlAttributesObject, object defaultHtmlAttributesObject)
    {
        var concatKeys = new string[] { "class" };

        var htmlAttributesDict = htmlAttributesObject as IDictionary<string, object>;
        var defaultHtmlAttributesDict = defaultHtmlAttributesObject as IDictionary<string, object>;

        RouteValueDictionary htmlAttributes = (htmlAttributesDict != null)
            ? new RouteValueDictionary(htmlAttributesDict)
            : HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributesObject);
        RouteValueDictionary defaultHtmlAttributes = (defaultHtmlAttributesDict != null)
            ? new RouteValueDictionary(defaultHtmlAttributesDict)
            : HtmlHelper.AnonymousObjectToHtmlAttributes(defaultHtmlAttributesObject);

        foreach (var item in htmlAttributes)
        {
            if (concatKeys.Contains(item.Key))
            {
                defaultHtmlAttributes[item.Key] = (defaultHtmlAttributes[item.Key] != null)
                    ? string.Format("{0} {1}", defaultHtmlAttributes[item.Key], item.Value)
                    : item.Value;
            }
            else
            {
                defaultHtmlAttributes[item.Key] = item.Value;
            }
        }

        return defaultHtmlAttributes;
    }
}

次に、カスタム エディター テンプレートの先頭に以下を追加する必要があります。

@{
    var defaultHtmlAttributesObject = new { type = "date", @class = "form-control" };
    var htmlAttributesObject = ViewData["htmlAttributes"] ?? new { };
    var htmlAttributes = Html.MergeHtmlAttributes(htmlAttributesObject, defaultHtmlAttributesObject);
}

defaultHtmlAttributesObject生成された入力がその特定のテンプレートに対してデフォルトで持つべき属性に応じて、変数を変更します。

于 2015-12-31T19:18:53.693 に答える