MVC3 Razor Html.TextBoxFor:我可以使其像 TextAreaFor 一样多行吗?

发布于 2024-11-25 05:20:37 字数 2211 浏览 1 评论 0原文

我已经看过这篇文章:更改 Html.TextBox 的大小

但是我无法更改为 Html.TextAreaFor() 因为它没有让我设置动态默认值的属性(我正在制作一个编辑页面,我想动态填充当前的字段)数据可以然后进行修改)。即使我在视图模型中更改为 [DataType(DataType.MultilineText)] (它似乎更改为 textboxfor 并且我的默认值确实如此),我似乎也无法让 EditorFor 工作不出现)。

我的编辑视图采用一个包含两个模型的视图模型、一个要填充屏幕字段的空表单 (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>

有没有办法在 Html.TextBoxFor() 中设置“multiline”属性?

I've already seen this post: Changing the size of Html.TextBox

But I cannot change to Html.TextAreaFor() because it does not have an attribute for me to set a dynamic default value (I am making an edit page that I want to dynamically fill in the fields of the current data which can then be modified). I also can't seem to get the EditorFor to work even if I change to [DataType(DataType.MultilineText)] in my viewmodel (all it does it seem to change to textboxfor and my default values do not show up).

My edit view takes in a viewmodel containing two models, an empty form (OfferForm) to be filled with the onscreen fields, and the offer model containing the current data. I want to have textfields for the OfferForm, and dynamically fill them with the contents of the offer model's data.

Here is my 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>

Is there a way to set a "multiline" attribute in the Html.TextBoxFor()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人事已非 2024-12-02 05:20:37

您必须意识到 HTML 元素不是 Windows 控件,它们只是在某种程度上映射到它们。

HTML 元素必须是跨平台的,并且不能保证文本区域只是所有平台上的多行文本框,因此就 HTML 而言,文本框和文本区域是两个不同的东西。

所以答案是否定的,因为 HTML 中的文本框没有多行属性。

You have to realize that HTML elements are not windows controls, they just map to them somewhat.

HTML elements have to be cross platform, and there is no guarantee that a textarea is just a multi-line textbox on all platforms, so as far as HTML is concerned a textbox and a textarea are two different things.

So the answer is no, because there is no multiline attribute for a textbox in HTML.

櫻之舞 2024-12-02 05:20:37

最简单的方法是创建一个如下所示的 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 源中提取的,并进行了一些细微的更改以支持传入值。这应该适用于大多数情况,但您可能需要添加更多覆盖。这不是很干净,但应该可以让你继续。 :)

要让扩展显示在您的 razor 视图中,您可以在 Views 目录中编辑 Web.config 并添加命名空间(不是类名)放置该类的位置。然后它应该显示在智能感知中。

The simplest way to proceed would be to create an Html extension method like the following

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));
    }
}

You could then call it:

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

It only supports basic features and what not. The actual tag generation was pulled from Mvc3 source with slight changes to support passing the value in. This should work for most cases but you might need to add more overrides. This isn't very...clean but should get you going. :)

To get the extension to show up inside your razor views you edit the Web.config within the Views directory and add the namespace (not the class name) where you put this class. It should then show up in intellisense.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文