Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC5: Can @Html.TextBoxFor (or EditorFor) get its MaxLength from the Model's Data Annotation?

It seems like there should be a way of specifying a Model annotation like:

[Display(Name="State")]
[MaxLength(2)]
public string State { get; set; }

so that when it is used in an EditorFor or TextBoxFor, like:

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

or

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

the generation of the html would set the input field's maxlength to 2. Right now, I need to do this:

@Html.TextBoxFor(model => model.State, new { maxlength = 2 })

Since this violates the DRY principle, I'm wondering if there is already a built in way to have this flow from the data annotations to the input field?

like image 438
Michael Witt Avatar asked Mar 08 '14 15:03

Michael Witt


People also ask

How do I set the MaxLength for HTML TextBoxFor in MVC?

The MaxLength for TextBoxes is set using the HTML MaxLength attribute using the HtmlAttributes parameter in Html. TextBox and Html. TextBoxFor helper functions.

How does HTML EditorFor work?

Simply put, the Html. EditorFor method allows the developer to retain control over the display of form elements by data type (ie. string, boolean, int…etc) or model attribute at a global level rather than at an individual view level. This allows for cleaner ASP markup and easily scalable form controls.

What is the difference between TextBoxFor and EditorFor?

TextBoxFor: It will render like text input html element corresponding to specified expression. In simple word it will always render like an input textbox irrespective datatype of the property which is getting bind with the control. EditorFor: This control is bit smart.

What is the difference between using HTML TextBoxFor and HTML TextBox?

IMO the main difference is that Textbox is not strongly typed. TextboxFor take a lambda as a parameter that tell the helper the with element of the model to use in a typed view. You can do the same things with both, but you should use typed views and TextboxFor when possible.


3 Answers

There's an answer here that describes a way to get hold of additional metadata values within the view. With this in mind, you can do something like this...

Annotate your model:

[AdditionalMetadata("MaxLength", 30)]
public string State { get; set; }

Define a custom editor template (String.cshtml):

@{
    string maxLength = ViewData.ModelMetadata.AdditionalValues.ContainsKey("MaxLength")
        ? ViewData.ModelMetadata.AdditionalValues["MaxLength"].ToString() : null;
}

@Html.TextBox("", Model, new { maxlength = maxLength })

Then just do:

@Html.EditorFor(m => m.State)

This might need some tweaking and could be improved by defining a custom attribute instead of just using AdditionalMetadata but it should get you started.

I tend to wrap up calls to the model's additional metadata in a custom HTML helper, too.

like image 179
Ant P Avatar answered Oct 20 '22 12:10

Ant P


Here is what I did to get around this.

Created a js file to handle adding in the required field marker and maxlength attribute:

var formUtility = function () {
    return {
        AddMaxLength: function () {
            $("input[data-val-length-max]").each(function () {
                $(this).attr("maxlength", $(this).attr("data-val-length-max"));
            });
        },
        ShowRequiredFields: function () {
            $("input[data-val-required]").each(function () {
                $(this).prev().prepend("<span>* </span>");
            });
        }
    }
}();

After linking it on the page where I need it, just call it like this:

    <script>
        formUtility.AddMaxLength();
        formUtility.ShowRequiredFields();
    </script>
like image 22
cooperonthego Avatar answered Oct 20 '22 10:10

cooperonthego


This is not currently supported, you can vote for this feature.

I think by using ContainerType and PropertyName properties of ModelMetadata you can obtain the PropertyInfo, and from that query for the MaxLength attribute, all this in a custom editor template.

like image 26
Max Toro Avatar answered Oct 20 '22 11:10

Max Toro