How to create an input field to only allow numbers using EF and data annotations?

I am trying to figure out if there is a way to make sure that only numerical input is allowed using data annotations and Entity Framework.

I am using the following code

[Required] [DisplayName("Client No")] [Column("client_no", TypeName = "smallint")] public virtual Int16 Number { get; set; } 

I want this to be displayed using a class of numbers.

In one place I use the following

 <input type="number" name="searchClientNo" class="numericOnly" /><br /> 

but in the input form I use

 @Html.EditorFor(m => m.Number, EditorTemplate.TextBox) 

where I have a custom editor for the following code

 <div class="editor-label"> @Html.Label((ViewData.ModelMetadata.DisplayName??ViewData.ModelMetadata.PropertyName), new Dictionary<string, object> { { "for", ViewData.ModelMetadata.PropertyName } }) </div> <div class="editor-field"> @Html.TextBox("", (object)Model, new Dictionary<string, object> { { "id", ViewData.ModelMetadata.PropertyName }, { "name", ViewData.ModelMetadata.PropertyName }, { "class", "text-box single-line"}, { "data-bind", "value: " + ViewData.ModelMetadata.PropertyName }, }) @Html.ValidationMessage(ViewData.ModelMetadata.PropertyName, new Dictionary<string, object> { { "data-valmsg-for", ViewData.ModelMetadata.PropertyName } }) </div> 

I am wondering how I can keep this code intact, but still use a text text box. Do I need to use UIHint?

Or, alternatively, is it possible to make my existing EditorFor smarter?

I found this blog post http://robseder.wordpress.com/2012/06/01/uihint-displaytemplates-and-editortememplates-in-mvc/ , but I already use a custom editor. Maybe I need to add a new type, say, EditorTemplate.NumericTextBox and add another editor? It seems this might work, I'm going to try it tomorrow ...

Thank you very much in advance.

+6
source share
2 answers

You can write your own editor template ~/Views/Shared/EditorTemplates/NumberTemplate.cshtml :

 @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { type = "number" }) 

and then decorate your view model property with a UIHint attribute:

 [Required] [DisplayName("Client No")] [Column("client_no", TypeName = "smallint")] [UIHint("NumberTemplate")] public virtual Int16 Number { get; set; } 

and inside your view:

 @Html.EditorFor(x => x.Number) 

or if you do not want to use the UIHint attribute in your view model, you can define EditorTemplate.NumericTextBox = "NumberTemplate" , and then:

 @Html.EditorFor(m => m.Number, EditorTemplate.NumericTextBox) 
+9
source

I just want to share my solution if it can help someone:

My new editor For:

 <div class="editor-label"> @Html.Label((ViewData.ModelMetadata.DisplayName??ViewData.ModelMetadata.PropertyName), new Dictionary<string, object> { { "for", ViewData.ModelMetadata.PropertyName } }) </div> <div class="editor-field"> @if (ViewData.ModelMetadata.ModelType.IsNumeric()) { @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { type = "number", @class = "numericOnly" }) } else { @Html.TextBox("", (object)Model, new Dictionary<string, object> { { "id", ViewData.ModelMetadata.PropertyName }, { "name", ViewData.ModelMetadata.PropertyName }, { "class", "text-box single-line"}, { "data-bind", "value: " + ViewData.ModelMetadata.PropertyName }, }) } @Html.ValidationMessage(ViewData.ModelMetadata.PropertyName, new Dictionary<string, object> { { "data-valmsg-for", ViewData.ModelMetadata.PropertyName } }) </div> 

And the IsNumeric extension method is based on the code I found on the C # MSDN forum, and this is its implementation:

 /// <summary> /// Checks is the object is of numeric type /// see http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/66a7dc8d-f276-4d45-8da4-f8d9857db52c/ /// </summary> /// <param name="obj"></param> /// <returns></returns> public static bool IsNumeric(object obj) { return (obj == null) ? false : IsNumeric(obj.GetType()); } public static bool IsNumeric(this Type type) { if (type == null) return false; TypeCode typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Byte: case TypeCode.Decimal: case TypeCode.Double: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.SByte: case TypeCode.Single: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: return true; } return false; } 
+1
source

All Articles