要设置 Tab 键顺序,您需要做的就是tabindex
向生成的字段添加一个额外的属性。TextBoxFor
使用or之类的东西就很容易了DropDownListFor
,因为它们实际上htmlAttributes
专门为此目的使用了一个参数:
@Html.TextBoxFor(m => m.Foo, new { tabindex = 1 })
在过去,同样不能这么说EditorFor
。由于它是一个“模板化”帮助器,编辑器模板,而不是方法调用,会影响生成的内容。您可以在 的定义中看到这一点EditorFor
,因为没有htmlAttributes
像其他助手那样的参数,而是additionalViewData
.
从 MVC 5.1 开始,Microsoft 可以EditorFor
通过特殊命名的ViewData
键将额外的 HTML 属性传递给"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"]
像内置编辑器模板那样使用,您需要首先将默认属性与传入的属性结合起来,然后将整个 shebang 传递给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
根据生成的输入对于该特定模板默认应具有的属性来更改变量。