simple-vue-validator icon indicating copy to clipboard operation
simple-vue-validator copied to clipboard

ability to stop on first error

Open dasDaniel opened this issue 7 years ago • 6 comments

I'm using a combination of client and server side validation

a validator object may look like this:

validator: (value) => {
  return Validator
  .value(value)
  .required()
  .custom(() => {
     // my async validation
  })
}

the problem is that the async validation happens in parallel with the required() validator, meaning that I"m sending API requests even though i know they will fail.

Instead I end up implementing all the validations, such as required and min length, within the custom.

an option to have request run in series would help

debounce: 500, cache: true, sequntial: false|true ...

dasDaniel avatar Feb 22 '18 21:02 dasDaniel

Thanks so much for this repo.

I could really use this feature, too. 👍

@dasDaniel - How do you implement all those other validations within custom? I'm having trouble because Validator.value(value).email() returns a Rule object with only private properties. It would be great if a Rule had a boolean function that indicated if the rule passes or fails.

Thanks in advance for any suggestions.

chip avatar Apr 26 '18 16:04 chip

This is how I'm solving it I've got a validator class with my own validations that I call

        return Validator
          .value(value)
          .custom(() => {
            // step 1 - check format
            // validateEmail returns true if passed, message (String) if failed
            const localValidate = validateEmail(value);
            if (localValidate !== true) {
              return localValidate;
            }
            this.validatingEmail = true; // this adds a spinner icon and removes response
            // do async validation

the validation rule for email is

export function validateEmail(value) {
  if (value === null || value.trim() === '') {
    return 'This field cannot be blank';
  }
  const emailregex = new RegExp(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
  if (!emailregex.test(value)) {
    return 'Please enter a valid email';
  }
  return true;
}

but, obviously, this doesn't make use of built-in validations, hence having it stop on first fail would be helpful.

dasDaniel avatar Apr 26 '18 23:04 dasDaniel

@dasDaniel - Yeah, that's roughly the approach that I was thinking about implementing. Thanks so much for confirming your solution. 👍 Hopefully, your suggestion will get addressed at some point soon.

chip avatar Apr 27 '18 00:04 chip

@dasDaniel thank you for your solution 👍, following that direction, I updating the code a little bit, so that built-in validation rules can also be used. (please check out the new version 0.15.1)

  let validator = Validator.value(value).required();
  if (!validator.hasImmediateError()) {
   // skip the custom validation if there's already some errors
    validator.custom(() => {
       // my async validation
    })
  }
  return validator;

semisleep avatar Apr 27 '18 14:04 semisleep

could you provide an example of use with validators definition? I'll see if I can test and post example if I get to it.

dasDaniel avatar Apr 27 '18 15:04 dasDaniel

Sorry for the late reply, I thought I already posted the sample code, here's a more complete version of code:

validators: {
  email(value) {
    let validator = Validator.value(value).required().email();
    if (!validator.hasImmediateError()) {
     // skip the custom validation if email format is invalid
      validator.custom(() => {
         // ajax code to check if the email is already existed in backend
      })
    } 
    return validator;
  }
}

And the key is this hasImmediateError() method, which checks if there's any immediate error in current validator.

semisleep avatar May 04 '18 02:05 semisleep