Frontend Validation

Packages:

Overview:

  • vee-validate's Form component uses name attribute to identify and validate input component values. It is required to add/ use name attribute in custom input components that uses vee-validate.

<TextInputV2
    v-model="form.name" 
    name="name" 
    placeholder="What is your title?" 
    :error="form.errors.name" 
    label="Name*"
/>
// or
<SelectInputV2
    v-model="form.business_type"
    name="business_type"
    :error="form.errors.business_type" 
    label="Type"
>
    <option :value="null" selected disabled>Select Business Type</option>
    <option value="Company">Company</option>
    <option value="Individual">Individual</option>
    <option value="Partnership">Partnership</option>
    <option value="Self managed superannuation fund">Self managed superannuation fund</option>
    <option value="Superannuation fund">Superannuation fund</option>
    <option value="Trust">Trust</option>
    <option value="Others">Others</option>
</SelectInputV2>
  • To add validation (given that custom input component has been updated to use vee-validate such as TextInputV2 and SelectInputV2 ), first create validation schema:

import * as Yup from 'yup'

export default {
    data() {
        return {
            schema: Yup.object().shape({
                // name_attribute: yup_validation_rules
                name: Yup.string().required().max(50),
                business_type: Yup.string().required().nonNullable()
            })
        }
    }
}

// or, for importing only what is needed
import { object, string } from 'yup'

export default {
    data() {
        return schema: object().shape({
            // name_attribute: yup_validation_rules
            name: string().required().max(50),
            business_type: string().required().nonNullable()
        })
    }
}
  • Then add it in the Form component using the validation-schema prop:

<Form
    v-slot="{ meta }"
    :validation-schema="schema"
    @submit="onSubmit"
>
    <TextInputV2
        v-model="form.name" 
        name="name" 
        placeholder="What is your title?" 
        :error="form.errors.name" 
        label="Name*"
    />
    
    <LoadingButton
        :loading="loading"
        type="submit"
        class="m-2 w-full justify-center rounded-lg bg-primary-500 px-3 py-2 text-sm font-semibold text-white shadow-sm"
        :class="{'hover:bg-primary-800': meta.valid, 'cursor-not-allowed': !meta.valid}"
        :disabled="meta.validating || !meta.valid"
    >
        {{ condition ? 'Save' : 'Add' }}
    </LoadingButton>
</Form>
import * as Yup from 'yup'
import { Form } from 'vee-validate'
import LoadingButton from '@/Shared/LoadingButton'
import TextInputV2 from '@/Shared/TextInputV2'
import SelectInputV2 from '@/Shared/SelectInputV2'

export default {
    components: {
        Form,
        TextInputV2,
        SelectInputV2,
        LoadingButton
    },
    data() {
        return {
            schema: Yup.object().shape({
                // name_attribute: yup_validation_rules
                name: Yup.string().required().max(50),
                // we can use .string('label') to use custom labels when displaying error instead of the default named property e.g. business_type
                business_type: Yup.string().required().nonNullable().string('Business type')
            })
        }
    },
    methods: {
        onSubmit() {
            // inertia call here...
        }
    }
}

Last updated