ASP.NET MVC 3 Razor - Добавление класса в EditorFor


189

Я пытаюсь добавить класс для входа.

Это не работает:

@Html.EditorFor(x => x.Created, new { @class = "date" })

1
эй, ты даже правильно понял имя! - (для моего кода)
Pinch

1
ПРИМЕЧАНИЕ. Для некоторых ответов, даже если они правильные, может потребоваться очистить кэш браузера, чтобы они были актуализированы. Это особенно верно, если решение основано на CSS или включает класс CSS! Просто потратил некоторое время, осознавая это с немного другой проблемой ...
JosephDoggie

Ответы:


183

Добавлять класс Html.EditorForне имеет смысла, так как внутри его шаблона вы можете иметь много разных тегов. Поэтому вам нужно назначить класс внутри шаблона редактора:

@Html.EditorFor(x => x.Created)

и в пользовательском шаблоне:

<div>
    @Html.TextBoxForModel(x => x.Created, new { @class = "date" })
</div>

5
Это прекрасно работает, спасибо. Возникли проблемы при форматировании значения поля в аннотации DisplayFormat в моей модели. Отформатированный как аннотированный с EditorFor и DisplayFor, но не TextBoxFor :( Похоже, я должен использовать пользовательский шаблон, если кто-то не может указать мне на то, что мне не хватает.?
Шон

Возникла та же проблема, когда TextBoxFor не поддерживает набор DisplayFormat.
jocull

14
Это GroundController для ModelTom, я посылаю вам вид и я плаваю наиболее MVC способом.
Трент Стюарт

3
У меня такая же проблема, но я не могу использовать TextBoxFor , как мне нужно DisplayFormat, который работает с редактором или Display, но в то же время класс я потребность тоже, так что я может отображать текст в виде только для чтения
AT

153

Начиная с ASP.NET MVC 5.1 возможно добавление класса в класс EditorFor(исходный вопрос определил ASP.NET MVC 3, и принятый ответ по-прежнему является лучшим из рассмотренных).

@Html.EditorFor(x=> x.MyProperty,
    new { htmlAttributes = new { @class = "MyCssClass" } })

Смотрите: Что нового в ASP.NET MVC 5.1, поддержка Bootstrap для шаблонов редактора


Это потрясающе. Спасибо!
Нил

1
Я почти пропустил это, так как это третье место в списке. Вероятно, было бы полезно составить свой собственный вопрос, а затем ответить на него самостоятельно.
Робб Садлер

Во время MVC 2,3,4 я не имел смысла ... но поскольку все больше людей начали использовать и жаловаться на его отсутствие - это внезапно стало
Петр Кула

Это должно быть принятым ответом по моему мнению.
Манфред

101

Вы не можете установить класс для универсального EditorFor. Если вы знаете, какой редактор вам нужен, вы можете сразу его использовать, там вы можете установить класс. Вам не нужно создавать какие-либо пользовательские шаблоны.

@Html.TextBoxFor(x => x.Created, new { @class = "date" }) 

5
Хорошая сделка, было приятно не создавать собственный шаблон.
Стив Дуитсман

ты сэкономил много времени для меня, Джо!
Прашант Бенни

40

Ты можешь использовать:

@Html.EditorFor(x => x.Created, new { htmlAttributes = new { @class = "date" } })

(По крайней мере, с ASP.NET MVC 5, но я не знаю, как это было с ASP.NET MVC 3.)


Пожалуйста, прочтите заголовок вопроса, это проблема для MVC3, вы предоставляете решение MVC5, которое вводит в заблуждение.
Винсент

11
И вы, пожалуйста, прочитайте весь мой пост, где я написал это для MVC5. Это был первый результат от Google, поэтому после того, как я нашел нужное решение, поделитесь им здесь, может быть, оно поможет некоторым людям.
Пржно

Этот помог мне! Спасибо @przno
Йоаким М

29

У меня была такая же неприятная проблема, и я не хотел создавать шаблон EditorTemplate, который применялся ко всем значениям DateTime (в моем пользовательском интерфейсе были моменты, когда я хотел отображать время, а не раскрывающийся календарь JQuery UI ). В моем исследовании коренные проблемы, с которыми я столкнулся, были:

  • Стандартный помощник TextBoxFor позволил мне применить пользовательский класс «средства выбора даты» для визуализации ненавязчивого календаря пользовательского интерфейса jQuery, но TextBoxFor не будет форматировать DateTime без времени, что приведет к сбою рендеринга календаря.
  • Стандартный EditorFor будет отображать DateTime в виде отформатированной строки (когда он украшен соответствующими атрибутами, такими как [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")], но он не позволяет мне применять пользовательский класс «выбора даты»).

Поэтому я создал собственный класс HtmlHelper, который имеет следующие преимущества:

  • Метод автоматически преобразует DateTime в ShortDateString, необходимый для календаря jQuery (jQuery завершится ошибкой, если будет время).
  • По умолчанию помощник применяет необходимые атрибуты htmlAttributes для отображения календаря jQuery, но при необходимости их можно переопределить.
  • Если дата пуста, ASP.NET MVC поместит дату 1/1/0001 в качестве значения.

Этот метод заменяет это пустой строкой.

public static MvcHtmlString CalenderTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
    var mvcHtmlString = System.Web.Mvc.Html.InputExtensions.TextBoxFor(htmlHelper, expression, htmlAttributes ?? new { @class = "text-box single-line date-picker" });
    var xDoc = XDocument.Parse(mvcHtmlString.ToHtmlString());
    var xElement = xDoc.Element("input");
    if (xElement != null)
    {
        var valueAttribute = xElement.Attribute("value");
        if (valueAttribute != null)
        {
            valueAttribute.Value = DateTime.Parse(valueAttribute.Value).ToShortDateString();
            if (valueAttribute.Value == "1/1/0001")
                valueAttribute.Value = string.Empty;
        }
    }
    return new MvcHtmlString(xDoc.ToString());
}

А для тех, кто хочет знать синтаксис JQuery, который ищет объекты с date-pickerукрашением класса, чтобы затем отобразить календарь, вот он:

$(document).ready(function () {
    $('.date-picker').datepicker({ inline: true, maxDate: 0, changeMonth: true, changeYear: true });
    $('.date-picker').datepicker('option', 'showAnim', 'slideDown');
});

Это помогло мне только сейчас, небольшая проблема с этим - вы должны проверить, чтобы убедиться, что значение ValueAttribute.Value не пусто или не пропущено, прежде чем передавать его в метод DateTime.Parse, в противном случае вы рискуете вызвать исключение FormatException в пустое поле.
Moo

Спасибо. Вы мне очень помогли.
Бронзато

Это помогло мне, однако, если вы реализуете это и ожидаете, что поле выполнит проверку, вам нужно будет применить эту логику: stackoverflow.com/questions/12023970/…
Аарон Ньютон

Хорошая работа, но знаете ли вы, что вы можете контролировать, появляется ли элемент DateTime или просто элемент управления Date, просто используя DateTimePickerForи обновляя поле даты модели, которое вы представляете, [DataType(DataType.Date)]или [DataType(DataType.DateTime)]? Вы также можете поместить его, скажем, в mm / dd / yyyy форму .ParseFormats(new string[] { "MM/dd/yyyy" })(или легко изменить его так, как вам хочется). Если оно пустое, поле отображается как пустое без необходимости кодировать его.
vapcguy

Бритва не узнает @MyHtmlHelpers.CalenderTextBoxFor(model => model.ExpirationDate). Есть идеи, как это реализовать?
Mehdiway

15

Можно предоставить класс или другую информацию через AdditionalViewData - я использую это, когда я позволяю пользователю создавать форму на основе полей базы данных (propertyName, editorType и editorClass).

На основании вашего первоначального примера:

@Html.EditorFor(x => x.Created, new { cssClass = "date" })

и в пользовательском шаблоне:

<div>
    @Html.TextBoxFor(x => x.Created, new { @class = ViewData["cssClass"] })
</div>

8
@ Html.EditorFor (x => x.Created, new {cssClass = "date"}) у меня не сработал
Алан Макдональд

1
Это сработало для меня и является лучшим ответом, чем отмеченный. Это обеспечивает преимущество использования шаблона, но позволяет вносить некоторые изменения без использования JQuery.
Чед Хедккок,

TextBoxFor игнорирует другие атрибуты, которые можно установить в модели, например, DataType.
Маркус

8

Не существует какого-либо EditorForпереопределения, позволяющего передавать анонимный объект, свойства которого каким-либо образом добавляются в качестве атрибутов для какого-либо тега, особенно для встроенных шаблонов редактора. Вам нужно будет написать свой собственный шаблон редактора и передать желаемое значение в качестве дополнительных viewdata.


2
@Html.EditorFor(m=>m.Created ...) 

не позволяет передавать аргументы для текстового поля

Вот как вы можете применять атрибуты.

@Html.TextBoxFor(m=>m.Created, new { @class= "date", Name ="myName", id="myId" })

2

Используя jQuery, вы можете сделать это легко:

$("input").addClass("class-name")

Вот ваш входной тег

@Html.EditorFor(model => model.Name)

Для DropDownlist вы можете использовать это:

$("select").addClass("class-name")

Для выпадающего списка:

@Html.DropDownlistFor(model=>model.Name)

2

Хотя вопрос был нацелен на MVC 3.0, мы обнаружили, что проблема сохраняется и в MVC 4.0. MVC 5.0 теперь изначально содержит перегрузку для htmlAttributes.

Я вынужден использовать MVC 4.0 на своем нынешнем месте работы, и мне нужно было добавить класс css для интеграции с JQuery. Я решил эту проблему с помощью одного метода расширения ...

Метод продления:

using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using System.Xml.Linq;

namespace MyTest.Utilities
{
    public static class MVCHelperExtensionMethods
    {
        public static MvcHtmlString AddHtmlAttributes(this MvcHtmlString input, object htmlAttributes)
        {
            // WE WANT TO INJECT INTO AN EXISTING ELEMENT.  IF THE ATTRIBUTE ALREADY EXISTS, ADD TO IT, OTHERWISE
            // CREATE THE ATTRIBUTE WITH DATA VALUES.

            // USE XML PARSER TO PARSE HTML ELEMENT
            var xdoc = XDocument.Parse(input.ToHtmlString());
            var rootElement = (from e in xdoc.Elements() select e).FirstOrDefault();

            // IF WE CANNOT PARSE THE INPUT USING XDocument THEN RETURN THE ORIGINAL UNMODIFIED.
            if (rootElement == null)
            {
                return input;
            }

            // USE RouteValueDictionary TO PARSE THE NEW HTML ATTRIBUTES
            var routeValueDictionary = new RouteValueDictionary(htmlAttributes);

            foreach (var routeValue in routeValueDictionary)
            {
                var attribute = rootElement.Attribute(routeValue.Key);

                if (attribute == null)
                {
                    attribute = new XAttribute(name: routeValue.Key, value: routeValue.Value);
                    rootElement.Add(attribute);
                }
                else
                {
                    attribute.Value = string.Format("{0} {1}", attribute.Value, routeValue.Value).Trim();
                }
            }

            var elementString = rootElement.ToString();
            var response = new MvcHtmlString(elementString);
            return response;
        }
    }
}

Использование HTML-разметки:

@Html.EditorFor(expression: x => x.MyTestProperty).AddHtmlAttributes(new { @class = "form-control" })

(Не забудьте включить пространство имен метода расширения в представление бритвы)

Объяснение: Идея состоит в том, чтобы внедрить в существующий HTML. Я решил проанализировать текущий элемент, используя Linq-to-XML, используя XDocument.Parse(). Я передаю атрибуты html как тип object. Я использую MVC RouteValueDictionaryдля анализа переданных htmlAttributes. Я объединяю атрибуты там, где они уже существуют, или добавляю новый атрибут, если он еще не существует.

В случае, если ввод не разбирается, XDocument.Parse()я оставляю все надежды и возвращаю исходную строку ввода.

Теперь я могу использовать преимущество DisplayFor (отображение типов данных, например, валюты), но также могу указывать классы CSS (и любые другие атрибуты в этом отношении). Может быть полезно для добавления таких атрибутов, как data-*, или ng-*(угловой).


1

Вы можете создать такое же поведение, создав простой пользовательский редактор с именем DateTime.cshtml, сохранив его в Views / Shared / EditorTemplates.

@model DateTime

@{
    var css = ViewData["class"] ?? "";
    @Html.TextBox("", (Model != DateTime.MinValue? Model.ToString("dd/MM/yyyy") : string.Empty), new { @class = "calendar medium " + css});
}

и в ваших взглядах

@Html.EditorFor(model => model.StartDate, new { @class = "required" })

Обратите внимание, что в моем примере я жестко программирую два класса CSS и формат даты. Вы можете, конечно, изменить это. Вы также можете сделать то же самое с другими html-атрибутами, такими как readonly, disabled и т. Д.


1

Я использовал другое решение с использованием селекторов атрибутов CSS, чтобы получить то, что вам нужно.

Укажите HTML-атрибут, который вы знаете, и укажите нужный вам относительный стиль.

Как ниже:

input[type="date"]
{
     width: 150px;
}

1

Нет необходимости создавать собственный шаблон для MVC 4. Используйте TextBox вместо EditFor, здесь специальные html-атрибуты не поддерживаются, он поддерживается только из MVC 5. TextBox должен поддерживать MVC 4, я не знаю о другой версии.

@Html.TextBox("test", "", new { @id = "signupform", @class = "form-control", @role = "form",@placeholder="Name" })


0

Мне просто нужно было установить размер одного текстового поля на одной странице. Атрибуты кодирования в модели и создание пользовательских шаблонов редактора были излишними, поэтому я просто обернул вызов @ Html.EditorFor тегом span, который вызывал класс, который определяет размер текстового поля.

Объявление класса CSS:

.SpaceAvailableSearch input
{
    width:25px;
}

Посмотреть код:

<span class="SpaceAvailableSearch">@Html.EditorFor(model => model.SearchForm.SpaceAvailable)</span>

0

Один из лучших способов применения класса @Html.EditorFor()в MVC3 RAzor -

@Html.EditorFor(x => x.Created)


<style type="text/css">

#Created
{
    background: #EEE linear-gradient(#EEE,#EEE);   
    border: 1px solid #adadad;
    width:90%;
    }
</style>

Это добавит выше стиль к вашему EditorFor()

Это работает для MVC3.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.