Is there a way for comparing dates on Valdr?

421 views Asked by At

I'm using Valdr on my project and I need to validate that a date input "startDate" is before another date input "endDate".

<input id="startDate" name="startDate" type="text" ng-model="project.startDate"/>
<input id="endDate" name="endDate" type="text" ng-model="project.endDate"/>

I know that, without Valdr, this problem can be solved using a custom directive, as shown here: Directive for comparing two dates

I found a little unclear how to create a custom validator on Valdr that uses the values of other fields.

4

There are 4 answers

0
Marcel Stör On

The answer is short but dissatisfactory: valdr does currently not support this. There is an open feature request on GitHub, though.

0
peso_junior On

Until the feature gets implemented in valdr, you can use your own validator directive and kind of make it talk to valdr. The directive can require a 'form' and can get the names of the date models you want to compare. Then you do your logic to compare the two values and set the validity of the appropriate 'ngModelController'. Since you need to provide an error when setting the validity to that model, the error name will be your connection with valdr.

After that, you just only need to map the error in the 'valdrMessage' service:

.run(function (valdrMessage) {

valdrMessage.angularMessagesEnabled = true;

valdrMessage.addMessages({
  'date': 'Invalid date!'
});

});

Valdr will show the message bellow the invalid field as usual.

0
Manuel Manhart On

Actually you can solve this through a custom validator, which can get another field and compare the values with each other. The code below is using the valdr-bean-validation for serverside generation of valodation.json.

If you want to use it without this, just look into the JS code and add the validator in your validation.json manually.

Java Annotation (serverside declaration of the valdr validator):

package validation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR,
        ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
public @interface DateFormat {

    String message();

    Class[] groups() default { };

    String beforeFieldName();
}

Java Bean (usage of the annotation, this class has to be used in the generation of validation.json):

package pojo;

import validation.DateFormat;

public class RegistrationPojo implements BasePojo {

    @NotNull(message = "message.date1.required")
    private Date date1;

    @NotNull(message = "message.date2.required")
    @DateFormat(message = "message.date2.date", beforeFieldName = "date1")
    private Date date2;

}

JS (implementation of the custom validator and registering it in valdr):

module.factory('validation.DateFormat', [
    function () {
    return {
        name: 'validation.DateFormat',
        validate: function (value, constraint) {
            var minOk = true;
            var maxOk = true;
            var format = false; // constraint.pattern is mandatory
            //do not validate for required here, if date is null, date will return true (valid)

            console.log("my date validator called");
            console.log("    beforeFieldName: " + constraint.beforeFieldName);

            var field = document.querySelector('[name="' + constraint.beforeFieldName + '"]');
            console.log("field value: " + (field ? field.value : "null"));
            return (!field || value > field.value);
        }
    };
}]);

module.config([
    "valdrProvider", 
function(valdrProvider) {
    valdrProvider.addValidator('validation.DateFormat');
}]);
0
viktapikta On

You could go with this solution:

  1. Have a bool value calculated upon changes in any of the date fields - a value indicating if the validation rule is met
  2. Create a simple custom validator to check if that value is true or not
  3. Register your validator and add a constraint for that calculated value
  4. Place a hidden input for that calculated value anywhere you like your validation message to appear