Search code examples
javascriptvalidationvue.jstextvuelidate

How can Vuelidate be used to limit the min length of a text input?


How can Vuelidate be used to limit the min length of a text input? This is a child of a child component. In the code, minLength = 4. It appears that one must create methods to handle the resulting Vuelidate object in order to handle any form errors? Any help would be greatly appreciated.

console.log(this.$v.message_text.$params.minLength.min); outputs 4.

Vue component where Vuelidate validation is taking place:

<template>
        <div>
        <input type="text" name="message_text" id="message_text"
            class="form-control"
            placeholder="New message"
            v-model="message"
            @keyup.enter.prevent="sendMessage">
        </div>
</template>

<script>

import { required, minLength } from "vuelidate/lib/validators";

export default {
    props: ['activeChannel', 'username'],

    data() {
        return {
            message: '',
            message_text: ''
        };
    },


    validations: {
        message_text: {
          required,
          minLength: minLength(4)
        },
    },



    methods: {
        sendMessage() {
            let endpoint = `/channels/${this.activeChannel}/messages`;

            let data = {
                username: this.username,
                message: this.message
            };

            axios.post(endpoint, data);

            this.message = '';

            console.log(this.$v.message_text.$params.minLength.min);

        }
    }
}
</script>

<style>
</style>

The following lines are present in main app.js:

import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)

Solution

  • Answer found here: https://jsfiddle.net/b5v4faqf/ A method must be created to handle the form errors Vuelidate identifies.:

    <template>
            <div>
            <input type="text"
                class="form-control"
                placeholder="New message."
                v-model="$v.message.$model"
                :class="status($v.message)"
                @keyup.enter.prevent="sendMessage">
                <pre>{{ $v }}</pre>
            </div>
    </template>
    
    <script>
    
    import { required, minLength } from "vuelidate/lib/validators";
    
    export default {
        props: ['activeChannel', 'username'],
    
        data() {
            return {
                message: '',
            };
        },
    
    
        validations: {
            message: {
              required,
              minLength: minLength(4)
            },
        },
    
    
    
        methods: {
    
            status(validation) {
                return {
                error: validation.$error,
                dirty: validation.$dirty
                }
            },
    
            sendMessage() {
    
                // if its still pending or an error is returned do not submit
                this.$v.message.$touch();
                if (this.$v.message.$error) return;
    
                let endpoint = `/channels/${this.activeChannel}/messages`;
    
                let data = {
                    username: this.username,
                    message: this.message
                };
    
                axios.post(endpoint, data);
    
                this.message = '';
    
            }
        }
    }
    </script>
    
    <style scoped>
    
    input {
      border: 1px solid silver;
      border-radius: 4px;
      background: white;
      padding: 5px 10px;
    }
    
    .dirty {
      border-color: #5A5;
      background: #EFE;
    }
    
    .dirty:focus {
      outline-color: #8E8;
    }
    
    .error {
      border-color: red;
      background: #FDD;
    }
    
    .error:focus {
      outline-color: #F99;
    }
    
    
    </style>