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?
The MaxLength for TextBoxes is set using the HTML MaxLength attribute using the HtmlAttributes parameter in Html. TextBox and Html. TextBoxFor helper functions.
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.
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.
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.
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.
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With