MVC3 Razor Html.TextBoxFor: можно ли сделать его многострочным, как TextAreaFor? - PullRequest
0 голосов
/ 19 июля 2011

Я уже видел этот пост: Изменение размера Html.TextBox

Но я не могу изменить на Html.TextAreaFor(), потому что у него нет атрибута для меня, чтобы установитьдинамическое значение по умолчанию (я делаю страницу редактирования, которую хочу динамически заполнять поля текущих данных, которые затем могут быть изменены).Я также не могу заставить EditorFor работать, даже если я изменил на [DataType(DataType.MultilineText)] в моей модели представления (все, что он делает, похоже, на textboxfor и мои значения по умолчанию не отображаются).

Myпредставление редактирования принимает модель представления, содержащую две модели, пустую форму (OfferForm), которая должна быть заполнена экранными полями, и модель offer, содержащую текущие данные.Я хочу иметь текстовые поля для OfferForm и динамически заполнять их содержимым данных модели offer.

Вот мой HTML:

<div class="InLine">
                    <div class="InLine editor-label-container">
                        <div class="editor-label">
                            @Html.LabelFor(model => model.OfferForm.Description)
                        </div>
                    </div>
                    <div class="InLine editor-field-container">
                        <div class="editor-field">
                            @Html.TextBoxFor(model => model.OfferForm.Description, new { @Value = @Html.DisplayFor(model => model.Offer.Description)})
                            @Html.ValidationMessageFor(model => model.Offer.Description)
                        </div>
                    </div>
                </div>
                <div class="InLine">
                    <div class="InLine editor-label-container">
                        <div class="editor-label">
                            @Html.LabelFor(model => model.OfferForm.SMSText)
                        </div>
                    </div>
                    <div class="InLine editor-field-container">
                        <div class="editor-field">
                            @Html.TextBoxFor(model => model.OfferForm.SMSText, new { @Value = @Html.DisplayFor(model => model.Offer.SmsText)})
                            @Html.ValidationMessageFor(model => model.Offer.SmsText)
                        </div>
                    </div>
                </div>

Есть ли способустановить атрибут "multiline" в Html.TextBoxFor()?

Ответы [ 2 ]

3 голосов
/ 19 июля 2011

Вы должны понимать, что HTML-элементы - это , а не элементы управления окнами, они просто немного им соответствуют.

Элементы HTML должны быть кроссплатформенными, и нет гарантии, что текстовая область является просто многострочным текстовым полем на всех платформах, так что для HTML текстовое поле и текстовая область - это две разные вещи.

Таким образом, ответ отрицательный, поскольку в HTML нет многострочного атрибута для текстового поля.

2 голосов
/ 19 июля 2011

Самый простой способ - создать метод расширения Html, подобный следующему

public static class HtmlTextAreaExtensions {

    public static IHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int cols, object htmlAttributes = null, string Value = null) {
        return TextAreaFor<TModel, TProperty>(htmlHelper, expression, rows, cols, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), Value);
    }

    public static IHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int cols, IDictionary<string, string> htmlAttributes = null, string Value = null) {
        var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var name = ExpressionHelper.GetExpressionText(expression);

        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        Dictionary<string, object> rowsAndColumns = new Dictionary<string, object>();
        if (rows > 0) {
            rowsAndColumns.Add("rows", rows.ToString(CultureInfo.InvariantCulture));
        } else {
            rowsAndColumns.Add("rows", "5");
        }
        if (cols > 0) {
            rowsAndColumns.Add("cols", cols.ToString(CultureInfo.InvariantCulture));
        } else {
            rowsAndColumns.Add("cols", "20");
        }
        TagBuilder tagBuilder = new TagBuilder("textarea");
        tagBuilder.GenerateId(fullName);
        tagBuilder.MergeAttributes(htmlAttributes, true);
    tagBuilder.MergeAttributes(rowsAndColumns, false);  // Only force explicit rows/cols
        tagBuilder.MergeAttribute("name", fullName, true);

        // If there are any errors for a named field, we add the CSS attribute.
        ModelState modelState;
        if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0) {
            tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
        }

        tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));

        string value;
        if (Value != null) {
            value = Value;
        } else if (modelState != null && modelState.Value != null) {
            value = modelState.Value.AttemptedValue;
        } else if (modelMetadata.Model != null) {
            value = modelMetadata.Model.ToString();
        } else {
            value = String.Empty;
        }

        // The first newline is always trimmed when a TextArea is rendered, so we add an extra one
        // in case the value being rendered is something like "\r\nHello".
        tagBuilder.SetInnerText(Environment.NewLine + value);

        return new HtmlString(tagBuilder.ToString(TagRenderMode.Normal));
    }
}

Вы могли бы тогда назвать это:

@Html.TextAreaFor(f => f.ModelProperty, Value=f.SomeOtherModelProperty)

Он поддерживает только основные функции, а что нет. Фактическая генерация тегов была получена из источника Mvc3 с небольшими изменениями для поддержки передачи значения. Это должно работать в большинстве случаев, но вам может потребоваться добавить больше переопределений. Это не очень ... чисто, но должно помочь вам. :)

Чтобы расширение отображалось в видах бритвы, вы редактируете Web.config в каталоге Views и добавляете пространство имен (не имя класса), в которое вы помещаете это учебный класс. Затем он должен появиться в intellisense.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...