dobromir-hristov / vuelidate-error-extractor

Vuelidate form-group helper that extracts errors easily.
https://dobromir-hristov.github.io/vuelidate-error-extractor/
MIT License
138 stars 15 forks source link

Feature: define validation messages in component #2

Closed travisstaloch closed 7 years ago

travisstaloch commented 7 years ago

First of all, thank you for sharing this great library!

As far as I can tell, you have to define error messages globally at the top level of your application. Is it possible to define them within the component? It doesn't seem like they would be allowed to live within data.validations since vuelidate would produce errors. Could they somehow be defined alongside, maybe as data.validation_messages with keys matching data.validations?

Does this seem like a good idea? It would allow us to reuse field names in different components. Is there already someway to do this?

I see that there is a table of Component Props in the documentation with one of the fields being messages. Is this what I'm looking for? I'm not sure where these props are supposed to be used.

dobromir-hristov commented 7 years ago

What is wrong with defining them at the init level? That makes messages reusable on all components, its just a reference to an object any way. Other way is to pass a prop with messages but that is useful for special case messages that just need to overwrite the global ones, because you wish have to pass it every time. 

travisstaloch commented 7 years ago

Oh interesting. Where can you define and pass the messages prop?

It just seems like they should be defined next to the validations. I see what you mean that it promotes reuse when they're defined at the top level. But what happens when you want to have the same field name used in separate components with different validation messages?

dobromir-hristov commented 7 years ago

OK so maybe I have to make this more clear: To init you usually have this:

// messages.js
export default {
    required: 'The {attribute} field is required!',
    min: 'The {attribute} field should be at least {min} characters.'
}

// app.js

import vuelidateErrorExtractor from 'vuelidate-error-extractor'
import template from './my/custom/template'
import messages from './messages.js'

Vue.use(VuelidateErrorExtractor, {
  templates,
  messages,
})

Now when ever you use the error extractor, all your messages will be used.

If you want to overwrite one of them you can do

<template>
    <form-group :validator="$v.form.username" label='Username' :messages="localMessages">
        <input type="text" name="username" v-model="form.username" @input="$v.form.username.$touch()">
    </form-group>
</template>

<script>
    import {required} from 'vuelidate/lib/validations'

    export default {
        data () {
            return {
                form: {
                    username: '',                   
                },
                localMessages: {
                    required: 'You should really fill in the {attribute} field!'
                }
            }
        },
        validations: {
            form: {
                username: { required() }
            }
        }
    }
</script>
travisstaloch commented 7 years ago

Thank you very much. This has cleared things up a lot for me. So far I have been misusing the library like so. main.js

Vue.use (vuelidateErrorExtractor, {
  template: templates.foundation,
  messages: {
    password: ' is too short',
    email: ' is invalid',
    password2: ' must match password'
  }
})

signup.vue

<template>
  <md-layout md-tag="form" md-align="center">
    <textfield v-model="email" identifier="email" label="Email address" type="email" icon="person" :v="$v"></textfield>
    <textfield v-model="password" @keyup.enter="signup" identifier="password" label="Password" type="password" icon="lock" :v="$v"></textfield>
    <textfield v-model="password2" @keyup.enter="signup" identifier="password2" label="Confirm password" type="password" icon="lock" :v="$v"></textfield>
    <md-button @click.prevent="signup" class="md-accent md-raised" :disabled="loading || $v.$invalid">Sign up</md-button>
  </md-layout>
</template>
<script>
export default {
  components: { textfield: require('../components/forms/Textfield.vue') },
  data() {
    return {
      email: '',
      password: '',
      password2: ''
    }
  },
  validations: {
    email: {
      email
    },
    password: {
      minLength: minLength(5)
    },
    password2: {
      sameAsPassword: sameAs('password')
    }
  },
</script>

Textfield.vue

<template>
  <md-input-container :class="{'md-input-invalid': v[identifier].$invalid}">
    <md-icon v-if="icon">{{icon}}</md-icon>
    <label>{{label}}</label>
    <md-input :type="type" :id="identifier" :name="identifier" @input="onInput" :value="value" required></md-input>
    <span v-if="v[identifier].$invalid" class="md-error">{{label + getErrorMessage(identifier) }}</span>
  </md-input-container>
</template>
<script>
import { extractorMixin } from 'vuelidate-error-extractor'
export default {
  ...
  mixins: [extractorMixin]
}

This might help explain my initial message about the field names. It seems I am misusing field names in messages where there should be vuelidate method names. Then, maybe misusing getErrorMessage in textfield.vue. While this works, I can see it doesn't follow intended usage.

Originally I had

messages: {
  minLength: ' is too short',
  email: ' is invalid',
  sameAs : ' must match password'
}

but was seeing some errors which led me to change the keys to field names.

I am going to try again making a custom template and following your example. Thanks again.

dobromir-hristov commented 7 years ago

The error messages keys correspond to the validation rule name so required will need a required, and email will need email: 'Email is not valid' and so forth.

dobromir-hristov commented 7 years ago

BTW Get error message can insert properties so you dont have to do Label + getMessage(). Check my templates, they pass the attribute property which corresponds to The {attribute} is not valid on the messages.

travisstaloch commented 7 years ago

Yes I like that you can use the use the attribute placeholder in the messages. I'm getting the hang of it now, trying to use a custom template.

One thing that doesn't make sense right now, how to use custom templates. You said templates. Can you pass an array there? If not, how can I use the validation messages in many different templates throughout my application? Can you explain what is the purpose of a template? What happens when we pass a custom template to VuelidateErrorExtractor? What are the predefined foundation and bootstrap templates?

dobromir-hristov commented 7 years ago

Only one template. Doesnt really make sense to have 2-3 wrappers that do the same logic - extract errors. Also they would probably need to touch the same error messages. Anything more is just too far stretched for a open source plugin to support out of the box.

Custom template is what you are doing there. Creating your own component and adding the mixin to it.

travisstaloch commented 7 years ago

Can you explain what happens when we pass a custom template to VuelidateErrorExtractor? What are the predefined foundation and bootstrap templates?

dobromir-hristov commented 7 years ago

Oh.. they are premade for Foundation and Bootstrap css frameworks. You are using material design so they dont concern you.

travisstaloch commented 7 years ago

So can you just pass null for the template if you're not using the predefined templates?

On Sep 15, 2017 8:01 AM, "Dobromir Hristov" notifications@github.com wrote:

Oh.. they are premade for Foundation and Bootstrap css frameworks. You are using material design so they dont concern you.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dobromir-hristov/vuelidate-error-extractor/issues/2#issuecomment-329807913, or mute the thread https://github.com/notifications/unsubscribe-auth/ABfYy0d-58LiNpuUYD52kCUEczARo5gcks5sipEWgaJpZM4PYhOm .

dobromir-hristov commented 7 years ago

You have to feed it your own template there. Look at the documentation, there is a section for custom templates.

vishaltripathi189 commented 3 years ago

OK so maybe I have to make this more clear: To init you usually have this:


// messages.js
export default {
  required: 'The {attribute} field is required!',
  min: 'The {attribute} field should be at least {min} characters.'
}

Is This {min} still working? It was working for me in past but stopped working for some time. {attribute} is still working.

dobromir-hristov commented 3 years ago

I think the validator changed the property name. Please inspect the data, the plugin hasn't been changed in a while, so it's not it.

ayushbhatt-7 commented 2 years ago

The problem persist and definitely there are some changes in the rollup or with paramhandling changes in 'vuelidate Error Extractor". @dobromir-hristov please look into this if you have the bandwidth

dobromir-hristov commented 2 years ago

I have not used vuelidate in a while, so sorry about the headache it's causing.

I will try to look into this in my free time. Work days are impossible for me atm.