2015-12-31 5 views
-1

Визуально говоря, на одном из моих MVC-представлений у меня есть около 20 полей в стандартном вертикальном порядке, причем первые 8 или около того имеют необязательные поля [Создать] в той же группе <div> над правой.Настройка TAB Order на MVC View с DropDownListFor()/EditorFor()?

Мой заказ по умолчанию в настоящее время попадает в мое первое выпадающее меню, затем идет прямо в [Создать], вниз, затем вправо и т. Д. Что бы я хотел сделать, установите порядок TAB туда, где он идет прямо по моим различным полей и оставьте поля [Создать] необязательными для пользователя (или в конце порядка вкладок). Хотя, по-видимому, существует много дискуссий по этому вопросу с помощью быстрого поиска, кажется, что существуют непоследовательные ответы; многие из них, казалось бы, пару лет назад относительно установки TAB Order в 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" } }) 

ответ

3

Чтобы установить порядок табуляции, все, что вам нужно сделать, это быть в состоянии добавить дополнительный атрибут, tabindex для генерируемого поля. Это достаточно просто с чем-то вроде TextBoxFor или DropDownListFor, так как они на самом деле принимают htmlAttributes параметр специально для этой цели:

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

В прошлом, то же самое можно сказать и о EditorFor. Поскольку это «шаблонный» помощник, шаблон редактора, а не вызов метода, влияет на то, что генерируется. Вы можете видеть это в определении EditorFor, так как нет htmlAttributes param, как у других помощников, но 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 «S поведение с помощью шаблонов по умолчанию:

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

Затем в шаблоне редактора:

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

Однако этот параметр не позволяет использовать атрибуты по умолчанию. Это все или ничего не подходит. Чтобы действительно иметь возможность использовать ViewData["htmlAttributes"], как это делают встроенные шаблоны редактора, вам нужно сначала объединить атрибуты по умолчанию с переданными в них, а затем передать весь shebang на htmlAttributes. У меня blog post that discusses that in depth, но 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 в зависимости от того, какие атрибуты должны иметь сгенерированные входные данные по умолчанию для этого конкретного шаблона.