ASP.NET MVC 3 Razor - Додавання класу до EditorFor


189

Я намагаюся додати клас до вхідних даних.

Це не працює:

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

1
ей, ти навіть ім'я теж отримав! - (для мого коду)
Пінч

1
ПРИМІТКА. Для деяких відповідей, навіть якщо вони правильні, можливо, доведеться очистити кеш браузера, щоб він був актуалізований. Це особливо справедливо, якщо рішення засноване на css або включає клас css! Щойно витратив
чималий

Відповіді:


183

Додавати клас Html.EditorForне має сенсу, оскільки всередині його шаблону у вас може бути багато різних тегів. Тому вам потрібно призначити клас всередині шаблону редактора:

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

і в користувацькому шаблоні:

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

5
Це чудово працює, дякую. У моїй моделі виникли проблеми з форматуванням значення поля за анотацією DisplayFormat. Відформатовано як помічено за допомогою EditorFor та DisplayFor, але не TextBoxFor :( Здається, я повинен використовувати користувальницький шаблон, якщо хтось не може вказати мені на щось, що мені не вистачає?
Sean

З тією ж проблемою, коли TextBoxFor не шанує набір DisplayFormat.
Jocull

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

3
У мене є така ж проблема, але я не можу використовувати TextBoxFor, як мені потрібен DisplayFormat, який працює з редактором або дисплеєм, але в той же час мені потрібен і клас, щоб я міг відображати текст у форматі для читання
НА

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
Я майже пропустив це, оскільки він є 3-м у списку. Напевно, було б корисно скласти це власне питання, а потім відповісти на нього самостійно.
Робд Садлер

Під час MVC 2,3,4 я не мав сенсу ... але, оскільки все більше людей почали користуватися та скаржитися на їх відсутність - це раптом стало сенсом у MVC 5: D +1
Piotr Kula

Це, на мій погляд, зараз має бути прийнятою відповіддю.
Манфред

101

Ви не можете встановити клас для загального редактораFor. Якщо ви знаєте редактор, який хочете, можете скористатися ним відразу, там ви можете встановити клас. Вам не потрібно створювати будь-які власні шаблони.

@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

Цей мені допоміг! Дякуємо @przno
Йоаким М

29

У мене була така ж розчарована проблема, і я не хотів створювати шаблон EditorTemplate, який застосовувався до всіх значень DateTime (в моєму інтерфейсі були випадки, коли я хотів відобразити час, а не спадний календар інтерфейсу jQuery ). У моєму дослідженні основними проблемами, з якими я стикався, були:

  • Стандартний помічник TextBoxFor дозволив мені застосувати користувальницький клас "вибору дати", щоб зробити ненав'язливий календарем інтерфейсу jQuery UI, але TextBoxFor не форматуватиме DateTime без часу, тому спричиняючи невдачу візуалізації календаря.
  • Стандартний редакторFor відображатиме 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 або просто контроль дати, використовуючи DateTimePickerForта оновлюючи поле дати дати, яке ви представляєте, [DataType(DataType.Date)]або [DataType(DataType.DateTime)]? Ви також можете легко ввести його, скажімо, у мм / dd / yyyy .ParseFormats(new string[] { "MM/dd/yyyy" })(або легко змінити його на все, що завгодно). Якщо це недійсне значення, поле відображатиметься як порожнє, не маючи цього коду.
vapcguy

Бритва не впізнає @MyHtmlHelpers.CalenderTextBoxFor(model => model.ExpirationDate). Будь-які ідеї, як це здійснити?
Мехдівей

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.Створено, новий {cssClass = "дата"}) не працював для мене
Алан Макдональд

1
Це спрацювало для мене & є кращою відповіддю, ніж зазначено. Він надає перевагу використання шаблону, але дозволяє здійснити деяке налаштування без хакерів jQuery.
Чад Хеджкок

TextBoxFor ігнорує інші атрибути, які можна встановити в моделі, наприклад "DataType's".
Маркус

8

Не існує жодного EditorForпереопрацювання, яке дозволяє передати анонімний об'єкт, властивості якого певним чином додаватимуться як атрибути на деякий тег, особливо для вбудованих шаблонів редактора. Вам потрібно буде написати свій власний шаблон редактора та передати потрібне значення як додаткові дані перегляду.


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

не дозволяє передавати жодних аргументів для поля Text

Ось як можна застосувати атрибути.

@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(). Я передаю htmlAttributes як тип object. Я використовую MVC RouteValueDictionaryдля розбору переданих htmlAttributes. Зливаю атрибути там, де вони вже є, або додаю новий атрибут, якщо він ще не існує.

У випадку, якщо введення не зрівняється, XDocument.Parse()я відмовляюся від усієї надії та повертаю початковий рядок введення.

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


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, як, наприклад, лише для читання, відключення тощо.


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.EditorДля тега 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.