Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net MVC Unobtrusive Date Range Validation

I have a form with two date fields, Begin Date and End Date. I want to validate the two fields to ensure that the Begin Date is on or before the End Date. I have written a remote validator and assigned it to both fields, but that can lead to multiple messages for the same error. Also, if I correct one date the validation does not fire on the unmodified field leaving the old error message

How can I validate two date fields against one another to verify the the Begin date is before or on the End date?

like image 445
user1558501 Avatar asked Nov 01 '22 13:11

user1558501


1 Answers

I had the same problem some weeks ago. IMHO I think the best way to solve the problem is implement a client-side control using jquery. In this way you can call the validation every time that you change the value on StartDate or EndDate. In this case is better to call the server to validate your data that are on the client because you don't call the server.

In the following link there is a procedure to implement a client-side validation. Link

This is my solution :

Step 1 : Create The attribute class to validate the consecutive dates

public class ConsecutiveDateAttribute : ValidationAttribute, IClientValidatable
{
    public ConsecutiveDateAttribute()
    {
        ErrorMessage = "The date must be consecutive";
    }

    public override bool IsValid(object value)
    {
        return true;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule();
        rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
        rule.ValidationParameters.Add("datefield", metadata.PropertyName);
        rule.ValidationType = "consecutivedate";
        yield return rule;
    }
}

IsValid method return always true because I want to validate the values on the client-side. GetClientValidationRules function is used to pass to the cshtml page the couple field name and event validation name to call the validation for each field.

Step 2 : Decorate with the attribute ConsecutiveDate the fields that I want to validate

    [Required(), DataType(DataType.Date), ConsecutiveDate()]
    public DateTime StartDate { get; set; }

    [Required(), DataType(DataType.Date), ConsecutiveDate()]
    public DateTime EndDate { get; set; }

Step 3 : Implement in the page the javascript to validate the date

<script src="@Url.Content("~/Scripts/jquery-1.10.2.js")" type="text/javascript" />
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript" />
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>

<script type="text/javascript">

    if ($.validator && $.validator.unobtrusive) {

        $.validator.unobtrusive.adapters.addSingleVal("consecutivedate", "datefield");

        $.validator.addMethod("consecutivedate", function(value, element) {

            if ($("#StartDate").val() != "" && $("#EndDate").val() != "")
                return $("#StartDate").val() <= $("#EndDate").val();

            // IF both values are not polupated I don't want to validate the field
            return true;
        });

    }
</script>

$.validator.addMethod("consecutivedate", function(value, element) : this register the validation for each field that I want to validate.

like image 97
marco.fabbian Avatar answered Nov 08 '22 05:11

marco.fabbian