3
votes

Really struggling with the in-built unobtrusive jquery validation set up by MVC3.

My object has a property like:

    [DisplayName("GP")]
    [DataType(DataType.Currency)]
    [DisplayFormat(NullDisplayText = "$0", DataFormatString = "{0:C0}", ApplyFormatInEditMode = true)]
    [Column("gross_profit")]
    public decimal? GrossProfit { get; set; }

The EditorFor makes a text box, which is fine, however validation fails because I want users to be able to enter currency prefixes... e.g. $48,000.. client side validation fails, saying the property is not a number.

I don't have a problem writing my own data annotations, and custom model binding for this, but I can't figure out how to stop MVC from automatically putting in that "data-val-number" into the text input just because it's of type decimal.

I believe that "data-val-number" is stopping jquery unobtrusive validation from passing because the input field contains a dollar sign, and maybe a comma.

So i'm not looking for any globalisation tips, rather a way to allow user to enter text like "$48,000" and have this pass validation...

I would want to follow the same approach for percentage values also... e.g. "25%"

1

1 Answers

1
votes

You don't want to use non-numeric values inside a decimal? property for display. There are a few ways to handle this but the default model binder in MVC will always try to explicitly map a ######.## to a decimal field. If you have auxiliary input such as $##,###.## it'll blow up because that cannot be directly cast to a decimal value.

You have 2 solutions, the first is to use input masking like:

http://www.xaprb.com/html-input-mask/html-form-input-mask.html

or

http://digitalbush.com/projects/masked-input-plugin/

Which tweaks only the UI display of the input.

Or you can use the same logic you have in the model with a string data type.

[DisplayName("GP")]
[DataType(DataType.Currency)]
[DisplayFormat(NullDisplayText = "$0", DataFormatString = "{0:C0}", ApplyFormatInEditMode = true)]
[Column("gross_profit")]
public string CurrencyDisplay { get; set; }

public decimal? CurrencyInput 
{
    get
    {
        //parse out non-int fields to return from value in CurrencyDisplay
    }

    set
    {
        //format string and seed into CurrencyDisplay
    }
}