How to make entry field to allow numbers only using EF and Data Annotations?

asp.net-mvc data-annotations entity-framework

Question

I'm attempting to determine whether it's possible to use Data Annotations and Entity Framework to ensure that only numeric input is permitted.

I'm employing the code below.

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

I want the number class to be used when displaying this.

I use the following one time only.

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

Nevertheless, the entry form I'm using

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

where I've created a custom EditorFor with the code below.

<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'm wondering how I may use the numeric-only textbox while maintaining the current code. Does UIHint have to be used?

Alternatively, is it possible to enhance the intelligence of my current EditorFor?

I discovered this blog post, although I already use a unique EditorFor. The need to add a new type, like EditorTemplate, can arise. Add another editor and use NumericTextBox? I'm going to give this a go tomorrow because it sounds like it might work.

Many thanks in advance.

1
6
12/21/2012 3:04:55 PM

Accepted Answer

You might create a unique editor template.~/Views/Shared/EditorTemplates/NumberTemplate.cshtml :

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

after which embellish your view model property with theUIHint attribute:

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

in your field of view:

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

or if you choose not to utilize theUIHint You could define attributes on your view model.EditorTemplate.NumericTextBox = "NumberTemplate" after that:

@Html.EditorFor(m => m.Number, EditorTemplate.NumericTextBox)
9
12/21/2012 10:38:00 AM

Popular Answer

Just thought I'd offer my answer in case it could be helpful to someone:

New Editor I Am:

<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 implementation of the IsNumeric extension method, which I found in the C# MSDN forum, is as follows:

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


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow