Mikhail Filchushkin
Mikhail Filchushkin

Reputation: 330

Vuejs pass vee-validate to custom checkbox input

I can not make custom checkbox component with vee-validate support. I'm newbie in Vue. In my app checkbox must be required. But it doesn't work. I read a lot of articles about vee-validate and custom inputs, but all examples based on simple custom text inputs.

Below my code at this moment.

Parent component:

    <!-- Custom text input. Vee-validate works nice. -->
    <input-text
        name="email"
        placeholder="Please, enter email"
        label="Email"
        :required="true"
        :type="'email'"
        :value.sync="shareholder.fields.email"
        v-validate.initial="'required|email'"
        data-vv-delay="500"
        :className="{'error': isShowError('email')}"
        :disabled="isDisabled"
    />

    <!-- Custom checkbox input. Vee-validate doesn't work. -->
    <checkbox2
        name="consent"
        v-if="consent"
        class="consent"
        :required="true"
        :disabled="isDisabled"
        :className="{'error': errors.first('consent')}"
        :error="errors.first('consent')"
        v-model="consentStatus"
        v-validate.initial="'required'"
    >
        {{consent.text}}<br><a :href="consent.link" target="_blank">{{consent.linkText}}</a>
    </checkbox2>
    {{ errors.first('consent') }}

File check-box.vue:

<template>
    <div class="checkbox"
         :class="{ active: !!value }"
    >
        <label class="control">
            <input
                @change="handleChange"
                type="checkbox"
                :name="name"
                :checked="value"
            />
            <span class="icon-checkbox"></span>
        </label>

        <div class="label">
            <slot />
        </div>
    </div>
</template>

<script src="./check-box.js"></script>
<style lang="stylus" src="./check-box.styl" scoped></style>

File check-box.js:

export default {
    name: 'checkbox2',
    inject: [ '$validator', ],
    // In one of articles I read I must bind event and value
    // with check box like below. But it seems it doesn't work too.
    model: {
        event: 'input',
        value: 'checked',
    },
    props: {
        value: {
            type: Boolean,
            default: false,
        },
        error: {
            type: String,
        },
        name: String,
        disabled: Boolean,
        className: Object,
        required: Boolean,
    },
    data: function() {
        return {
            checked: false,
        }
    },
    methods: {
        handleChange() {
            if (!this.disabled) {
                this.checked = !this.value
                 // If I emit 'change' instead of 'input',
                 // checkbox component works wrong.
                this.$emit('input', this.checked)
            }
        },
    },
    created() {
        this.checked = this.value
        this.$validator = this.$parent.$validator
    },
}

Upvotes: 0

Views: 10643

Answers (1)

Mikhail Filchushkin
Mikhail Filchushkin

Reputation: 330

User must check our check-box for making form valid.

At first, in vee-validate 'required' for Boolean is true when it isn't equal null. I.e. if consentStatus = null, then checkbox below by default is not valid (as I need).

<checkbox2
    name="consent"
    v-if="consent"
    class="consent"
    :required="true"
    :disabled="isDisabled"
    :className="{'error': errors.first('consent')}"
    :error="errors.first('consent')"
    v-model="consentStatus"
    v-validate.initial="'required'"
>
    {{consent.text}}<br><a :href="consent.link" target="_blank">{{consent.linkText}}</a>
</checkbox2>

But in this case both possible values (true and false) make this component valid.

Variant 1

By default rule v-validate.initial="{ is: true }" doesn't work for vee-validate 2.1.0-beta-9 and below. So we need a crutch.

In parent component js-file after imports we should define custom validator rule.

import { Validator } from 'vee-validate';

Validator.extend('isEqual', {
    getMessage: field => 'Your text in case of checkbox mistake. ' + field + ' is invalid.',
    validate: value => value
});

Code for parent vue file:

<checkbox2
    name="consent"
    v-if="consent"
    class="consent"
    :required="true"
    :disabled="isDisabled"
    :className="{'error': errors.first('consent')}"
    :error="errors.first('consent')"
    v-model="consentStatus"
    v-validate.initial="{ isEqual: true }" // Here is difference!
>
    {{consent.text}}<br><a :href="consent.link" target="_blank">{{consent.linkText}}</a>
</checkbox2>
{{ errors.first('consent') }}

Variant 2

We will compare values as numbers. Parent vue code:

<checkbox2
    name="consent"
    v-if="consent"
    class="consent"
    :required="true"
    :disabled="isDisabled"
    :className="{'error': errors.first('consent')}"
    :error="errors.first('consent')"
    v-model="consentStatus"
    v-validate.initial="{ is: 1 }" // Here is difference!
>
    {{consent.text}}<br><a :href="consent.link" target="_blank">{{consent.linkText}}</a>
</checkbox2>
{{ errors.first('consent') }}

File check-box.vue:

<template>
    <div class="checkbox"
         :class="{ active: !!value, error: !!error }"
    >
        <label class="control">
            <input
                @change="handleChange"
                type="checkbox"
                :name="name"
                :checked="value"
            />
            <span class="icon-checkbox"></span>
        </label>

        <div class="label">
            <slot />
        </div>
    </div>
</template>

<script src="./check-box.js"></script>
<style lang="stylus" src="./check-box.styl" scoped></style>

File check-box.js:

export default {
    name: 'checkbox2',
    props: {
        error: {
            type: String,
        },
        value: Boolean,
        name: String,
        disabled: Boolean,
        className: Object,
        required: Boolean
    },
    methods: {
        handleChange() {
            if (!this.disabled) {
                this.$emit('input', this.value ? 0 : 1);
            }
        }
    }
}

Upvotes: 1

Related Questions