Сделать Editor для рендеринга десятичного значения как type = "text", а не type = "number" - PullRequest
0 голосов
/ 25 августа 2018

У меня есть два свойства в классе модели:

public int? IntTest { get; set; }
public decimal? DecimalTest { get; set; }

Которые я затем отображаю с помощью:

@Html.EditorFor(model => model.IntTest, new { htmlAttributes = new { @class = "form-control"} })
@Html.EditorFor(model => model.DecimalTest, new { htmlAttributes = new { @class = "form-control"} })

Я ожидал, что оба они будут отображаться как входные данные html типачисло, но не десятичное, я получаю:

<input class="form-control text-box single-line" data-val="true" data-val-number="The field IntTest must be a number." id="IntTest" name="IntTest" type="number" value="" />
<input class="form-control text-box single-line" data-val="true" data-val-number="The field IntTest must be a number." id="DecimalTest" name="DecimalTest" type="text" value="" />

Десятичное значение отображается как type="text", тогда как int зарегистрирован как type="number".

Этот вопрос подразумевает, что это не ожидаемое поведение, поэтому я делаю что-то не так?

Если это ожидаемое поведение, есть ли способ изменить EditorFor, чтобы отобразить все десятичные дроби как type="number"вместо того, чтобы добавлять type = "number" в htmlAttributes каждого десятичного поля?

1 Ответ

0 голосов
/ 26 августа 2018

HTML, который вы видите, является поведением по умолчанию. Методы EditorFor() используют шаблоны по умолчанию (если вы не создали пользовательский EditorTemplate для типа), как определено в TemplateHelpers.cs .

Для typeof intbyte и long) используется NumberInputTemplate, а для typeof decimal используется DecimalTemplate. Эти шаблоны определены в DefaultEditorTemplates.cs , которые предназначены для decimal

internal static string DecimalTemplate(HtmlHelper html)
{
    if (html.ViewContext.ViewData.TemplateInfo.FormattedModelValue == html.ViewContext.ViewData.ModelMetadata.Model)
    {
        html.ViewContext.ViewData.TemplateInfo.FormattedModelValue = String.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewContext.ViewData.ModelMetadata.Model);
    }
    return StringTemplate(html);
}

который в свою очередь вызывает

internal static string StringTemplate(HtmlHelper html)
{
    return HtmlInputTemplateHelper(html);
}

и для int

internal static string NumberInputTemplate(HtmlHelper html)
{
    return HtmlInputTemplateHelper(html, inputType: "number");
}

Обратите внимание, что NumberInputTemplate определяет inputType как "number", который добавляет атрибут type="number", где StringTemplate использует значение по умолчанию inputType, которое генерирует type="text".

Чтобы добавить type="number" для decimal, вам нужно вручную добавить атрибут, используя либо

@Html.EditorFor(m => m.DecimalTest, new { htmlAttributes = new { type = "number", @class = "form-control"} })

или

@Html.TextBoxFor(m => m.DecimalTest, new { type = "number", @class = "form-control"})

Альтернативой может быть создание пользовательского EditorTemplate в /Views/Shared/EditorTemplates/Decimal.cshtml для typeof decimal, например

@model decimal?
@{
    var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(ViewData["htmlAttributes"]);
    if (!attributes.ContainsKey("type"))
    {
         attributes.Add("type", "number");
    }
    string formatString = ViewData.ModelMetadata.DisplayFormatString ?? "{0:N2}";
}
@Html.TextBoxFor(m => m, formatString , attributes)

и на главном экране используйте

@Html.EditorFor(model => model.DecimalTest, new { htmlAttributes = new { @class = "form-control"} })

Другой альтернативой может быть создание собственного метода расширения HtmlHelper (скажем, @Html.DecimalFor(...)) для генерации html.

...