CyclingFreak
CyclingFreak

Reputation: 1625

ASP.NET MVC 3 - Custom client side validation not working

I'm trying to implement a custom client side validation, but it is not working. I'm basing myself on the article on Codeproject http://www.codeproject.com/Articles/275056/Custom-Client-Side-Validation-in-ASP-NET-MVC3

I also looked here on SO, but I think I'm implementing it in the correct manner, but I'm overlooking something. My goal is to validate a date (required, date format and not earlier than another date on the form). The first two can be done with data annotations, the last I have to do with custom validation.

I have on my base class some dataannotations (ClassLibrary is in VB.NET):

Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations

<MetadataType(GetType(CM_CONTRACTVALIDATIONData))>
Partial Public Class CM_CONTRACTACTIVATION
    '...
End Class

Public Class CM_CONTRACTVALIDATIONdata
'...
<DataType(DataType.Date)>
<Required()>
Public Property TakeBackDeviceWhen
'..
End Class

In the javascript file I have added the custom method:

//validation
$.validator.addMethod("checkPickupDate", function (value, element) {
    return false;
});
$("#form").validate({
    rules: {
        TakeBackDeviceWhen: {
            checkPickupDate: true
        }
    },
    messages: {
        TakeBackDeviceWhen: {
            checkPickupDate: "Test"
        }
    }
}
);

My chtml file is as follow:

@Html.TextBox("TakeBackDeviceWhen", Model.TakeBackDeviceWhen.HasValue ? Model.TakeBackDeviceWhen.Value.ToShortDateString() : "", new { style = "Width: 200px" })

The resulting HTML is as follow:

<input id="TakeBackDeviceWhen" class="hasDatepicker" type="text" value="" style="Width: 200px" name="TakeBackDeviceWhen" data-val-required="The TakeBackDeviceWhen field is required." data-val="true">

It seems that neither my type validation and my custom validation isn't implemented.

What is going wrong?

Upvotes: 0

Views: 4658

Answers (1)

CyclingFreak
CyclingFreak

Reputation: 1625

OK, solved it. I hope :-)

What did I learned today: (1) Don't use EditorFor: when you scaffold it from a MVC template, input fields are generated to EditorFor, it seems that you can't add custom unobtrusive validation tags. So, I was trying to get this fixed, untill I changed it to TextBoxFor.

(2) You can add custom validation methods in jQuery, but you can't mix them with unobtrusive validation. After adding a custom method, you have to also add it to the unobtrusive adapters. And don't forget to add jQuery on the bottom :-s (I got this from jQuery.validator.unobtrusive.adapters.addMinMax round trips, doesn't work in MVC3)

$(function () {
$.validator.addMethod("checkpickupdate", function (value, element) {
    if (value == "20/09/2012") {
        return false;
    } else {
        return true;
    }
});

$.validator.unobtrusive.adapters.addBool("checkpickupdate");
} (jQuery));

(3) Add validation tags to the input field in the htmlAttributes:

@Html.TextBox("TakeBackDeviceWhen", Model.TakeBackDeviceWhen.HasValue ? Model.TakeBackDeviceWhen.Value.ToShortDateString() : "",
                new { 
                    style = "Width: 200px", 
                    data_val = "true", 
                    data_val_required = "verplicht!",
                    data_val_date = "moet datum zijn",
                    data_val_checkpickupdate = "wow"
                 })

(4) Datatype data annotations will not enforce a validation. You have to add it like in (3). You can add a custom ValidationAttribute like (for server side validation):

public class MustBeDateAttribute : ValidationAttribute {
    public override bool IsValid(object value) {
        try
        {
            DateTime dte = DateTime.Parse(value.ToString());
            return true;
        }
        catch (Exception)
        {
            return false;
            throw;
        }
    }
}

And this is the resulting html output:

<input type="text" value="" style="Width: 200px" name="TakeBackDeviceWhen" id="TakeBackDeviceWhen" data-val-required="required!" data-val-date="has to be a date" data-val-checkpickupdate="custom error" data-val="true" class="hasDatepicker valid">

As I'm using my ClassLibrary in different projects, I'm now going to try to seperate the dataannotations meta data from the class library (maybe with dependency resolver).

Upvotes: 1

Related Questions