0

I have a business rule of my page - controls with date should be in ascending order. I.e. entered value to Date1 < entered value to Date2 < Date3

My attribute:

public class CompareDateAttribute : ValidationAttribute, IClientValidatable
{
    public CompareDateAttribute(string datesString)
    {
        _datesString = datesString;
    }
    private string _datesString;

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule()
        {
            //ErrorMessage = this.FormatErrorMessage(metadata.DisplayName),
            ErrorMessage = String.Format("Invalid date {0}", metadata.PropertyName),
            ValidationType = "datecomparer"
        };
        rule.ValidationParameters.Add("dates", _datesString);
        yield return rule;
    }
}

client side:

$.validator.addMethod("datecomparer", function (value, element, param) {
    //var valid = true;
    var arrElements = param.split(',');
    var datePreviousStr = null;
    $.each(arrElements, function (index, v) {
        if (datePreviousStr == null)
        {
            datePreviousStr = $('#' + v).val();
        }
        else
        {
            var dateCurrentStr = $('#' + v).val();
            if (dateCurrentStr == '')
            {
                return false;
            }

            var dateCurrent = $.datepicker.parseDate("mm/dd/yy", dateCurrentStr);
            var datePrevious = $.datepicker.parseDate("mm/dd/yy", datePreviousStr);

            if (dateCurrent < datePrevious)
            {
                return false;
            }
            else
            {
                datePreviousStr = dateCurrentStr;
            }

        }
    });

    return true;
});

$.validator.unobtrusive.adapters.addSingleVal("datecomparer", "dates");

Model:

public class Valid6
{
    [CompareDate("Date1,Date2,Date3")]
    public DateTime Date1 { get; set; }
    [CompareDate("Date1,Date2,Date3")]
    public DateTime Date2 { get; set; }
    [CompareDate("Date1,Date2,Date3")]
    public DateTime Date3 { get; set; }
}

and view (necessary part):

<div class="form-horizontal">
    <h4>Valid6</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Date1, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Date1, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Date1, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Date2, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Date2, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Date2, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Date3, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Date3, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Date3, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>

also, part of result HTML:

<input class="form-control text-box single-line valid" data-val="true" data-val-date="The field Date3 must be a date." data-val-datecomparer="Invalid date Date3" data-val-datecomparer-dates="Date1,Date2,Date3" data-val-required="The Date3 field is required." id="Date3" name="Date3" type="datetime" value="">

but when I enter Date1='11/11/2010' and Date2='11/11/2009' debugger says, that datecomparer method returns false, but validator message is not appeared. Why and how to solve?

Sparky
  • 98,165
  • 25
  • 199
  • 285
Oleg Sh
  • 8,496
  • 17
  • 89
  • 159
  • You are complaining about a client-side problem but then you primarily show us server-side code. JavaScript does not care about your framework... it only sees what is ***rendered*** in the browser. – Sparky Mar 19 '15 at 23:23
  • I had added client side jquery code too... – Oleg Sh Mar 20 '15 at 00:46

1 Answers1

0

Found the solution - "return false;" inside loop returns only from loop and then find "return true" on the end of method.

should be like :

$.validator.addMethod("datecomparer", function (value, element, param) {
    var valid = true;
    var arrElements = param.split(',');
    var datePreviousStr = null;
    $.each(arrElements, function (index, v) {
        if (datePreviousStr == null)
        {
            datePreviousStr = $('#' + v).val();
        }
        else
        {
            var dateCurrentStr = $('#' + v).val();
            if (dateCurrentStr == '')
            {
                valid = false;
                return;
            }

            var dateCurrent = $.datepicker.parseDate("mm/dd/yy", dateCurrentStr);
            var datePrevious = $.datepicker.parseDate("mm/dd/yy", datePreviousStr);

            if (dateCurrent < datePrevious)
            {
                valid = false;
                return;
            }
            else
            {
                datePreviousStr = dateCurrentStr;
            }

        }
    });

    return valid;
});

$.validator.unobtrusive.adapters.addSingleVal("datecomparer", "dates");
Oleg Sh
  • 8,496
  • 17
  • 89
  • 159