AustinGil/vuetensils

VInput custom error messages.

AustinGil opened this issue · 5 comments

Hey @TheJaredWilcurt and @gwenf I've been using Vuetensils more at work and running into the issue where I want to be able to support error messages. Ive got a syntax like this so far

<VInput
  label="Label"
  required
  minlength="6"
  type="email"
  :errors="{
    required: 'This field is required',
    minlength: l => `Must be at least ${l} characters.`,
    type: t => `Must be of type ${t}`,
  }"
/>

I've been able to get around this for the most part with a wrapper component, but I think this would be a nice addition. What do you think of the syntax?

Been using Vee-Validate 2 at work for about 2.5 years. Version 3 is a completely different library/approach. So rather than update to it and re-write our codebase with it in mind, we are considering evaluating other options (like Vuelidate), or simply not using a validation library. More than 60% of the time we handle the validation of elements on a page by hand anyways.

Often because the validation we have is not based on the input, but the context of the input with other inputs. Like not allowing the user to set the "start date" after the "end date" on a reservation. Stuff like this is just too easy to do in Vue via a computed property, and too complicated to bother with having a 3rd-party library handle it.

I'm against the addition of any automated validation. Especially with this API, as there are just way too many edge cases you would need to validate for (email, phone (dear god), credit card, min/max length, ASYNC UNIQUE NAME VALIDATION OMG, alpha only, regex, etc). Vee-Validate actually lists 27 different types. That would be quite the large object, and a lot of bloat for Vuetensils, which is meant to be a a small, style-free, A11Y focused component library.

If users want validation, there are several existing options they could pull in. Perhaps, just showing an example page in the docs of how to pair Vuetensils with Vuelidate and Vee-Validate would be better.

With that said, though I'm against having the validation logic in Vuetensils, showing a validation message under an input is very common. I wouldn't mind a single prop for passing in a validationErrorMessage="string". So that my parent component or 3rd-party validation plugin can handle the validation, and then just pass in some text to be displayed if there is a problem. A custom class prop for this would be nice to control the styling of it based on success/failure messages.

Yeah, I get your point, but there is already some validation logic baked in, using just HTML validators and the Validity API. The amount of code needed to support basic error messages is not so much:

errorMessages() {
      const { errors, invalid, $attrs } = this;
      if (!errors || !isType(errors, 'object')) return false;

      const messages = {};

      for (const attr of [
        'type',
        'required',
        'minlength',
        'maxlength',
        'min',
        'max',
        'pattern',
      ]) {
        if (invalid[attr] && errors[attr]) {
          messages[attr] = isType(errors[attr], 'function')
            ? errors[attr]($attrs[attr])
            : errors[attr];
        }
      }

      return Object.keys(messages).length ? messages : undefined;
    },```

Could possibly be even less. But it would be much less than adding something like Vuelidate (which BTW, I would recommend if you're looking for some more powerful validation lib). 

@TheJaredWilcurt

Another option is to include something like what Vuetify does with its rules prop https://vuetifyjs.com/en/components/inputs/#rules

I like it because the validation logic is passed off to the user to implement. Then we could provide validators that could be imported optionally, but are not included by default. So it could be something like

<template>
  <VInput :rules="rules" />
</template>

<script>
import {required, minLength, maxLength} from 'vuetensils/validators' // or any other validator
export default {
  data: () => ({
    rules: [
      required('this value is required'),
      minLength(2, 'Must be greater than 2'),
      maxLength(10, 'Cannot exceed 10')
    ]
  })
}
</script>

This is just a theoretical design

Yeah, I think that's better

Finally got around to publishing what I think it s good solution https://vuetensils.austingil.com/components/input.html#validation