Tips for adapting my custom input component for compatibility with vee-validate?

I recently developed an input component for my Vue project and integrated it within my forms. My aim is to implement vee-validate for validating the inputs.

Initially, I attempted to validate my component like any regular input field. However, upon encountering difficulties in displaying error messages and inspecting Vue Devtools, I realized that errors are limited to the input component itself (despite having computed properties named "errors" and "fields" accessible by all components from root to input).

Subsequently, I referred to vee-validate documentation and explored using the Validation Provider and Validation Observer. These components proved to be complex, leaving me puzzled even after reading an article on Medium. The concept of scoped slots used by these components remains unclear to me.

I aspire to validate input components at the parent level and showcase their error messages above the form. Any approach, with or without Validation Observer and/or Validation Provider, is welcomed.

Here's a snippet of my input component:

<template>
  <div class="info-input-control">
    <div class="info-input-icon">
      <slot name="icon"><span uk-icon="icon: pencil; ratio: 1.4"></span></slot>
    </div>

    <input :id="id" :type="type" :value="value" :name="name"
           v-validate="validations || ''"
           @keyup.enter="$emit('enter')"
           @focus="isActive = true"
           @blur="isActive = value.length > 0"
           @input="$emit('input', $event.target.value)" :key="name">
    <label :for="id" :class="{'info-input-label': true, 'is-active': isActive}">{{label}}</label>

  </div>
</template>

<script>
    export default {
        name: 'InfoTextInput',
        props: {
            id: String,
            label: String,
            ltr: Boolean,
            name: {
                type: String,
                required: true
            },
            type: {
                type: String,
                required: true,
                validator: function (value) {
                    return ['text', 'password', 'email'].indexOf(value) !== -1
                }
            },
            validations: Object,
            value: String
        },
        data() {
            return {
                isActive: false
            }
        },
        mounted() {
            this.isActive = this.value.length > 0
        }
    }
</script>

Below is a simplified version of my form featuring just one input component:

<form action="#" @submit.prevent="userLogin">
    <div class="uk-text-danger">
        <span>Errors: </span>
        <span>{{errors.first('mobile')}}</span>
    </div>

    <div class="uk-flex uk-flex-center">
        <div class="uk-width-medium">
            <info-text-input type="text" id="user-login-phone" label="Mobile" name="mobile" ltr v-model="login.mobile" :validations="mobileValidations" key="login-mobile">
                <template v-slot:icon>
                    <span uk-icon="icon: phone; ratio: 1.4"></span>
                </template>
            </info-text-input>
        </div>
    </div>
</form>

P.S: I have globally registered Validation Observer and Validation Provider.

Answer №1

Take a look at this example:

<template>
  <div class="info-input-control">
    <div class="info-input-icon">
      <slot name="icon"><span uk-icon="icon: pencil; ratio: 1.4"></span></slot>
    </div>

    <input :id="id" :type="type" :name="name"
           v-model="localValue"
           v-validate="validations || ''"
           @keyup.enter="$emit('enter')"
           @focus="isActive = true"
           @blur="isActive = value.length > 0"
           @input="$emit('input', localValue)" :key="name">
    <label :for="id" :class="{'info-input-label': true, 'is-active': isActive}">{{label}}</label>

  </div>
</template>

<script>
    export default {
        $_veeValidate: {
           value() {
               return this.localValue;
           },
           name() {
              return this.name;
           }
        },
        name: 'InfoTextInput',
        props: {
            id: String,
            label: String,
            ltr: Boolean,
            name: {
                type: String,
                required: true
            },
            type: {
                type: String,
                required: true,
                validator: function (value) {
                    return ['text', 'password', 'email'].indexOf(value) !== -1
                }
            },
            validations: Object,
            value: String
        },
        data() {
            return {
                localValue: this.value,
                isActive: false
            }
        },
        mounted() {
            this.isActive = this.localValue.length > 0
        }
    }
</script>

I made some modifications, such as adding the $_veeValidate section in the script. I also updated your component to utilize the value prop but store changes in a local reactive variable called localValue. Usually, altering a prop's value is not recommended, though it may work in simple cases like this. For more information, review One-Way Data Flow.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using jQuery to combine a variable with the image source in order to replace the image attribute

I am trying to create a script that will display a greeting message to the user based on their local time. I found a script on Stack Overflow, but I am struggling with updating the image source. When I try to replace the image source, I encounter the follo ...

Is there a way to validate form input before inserting it into a database using the onsubmit event?

Looking for a way to enhance the verification process of my signup form, I aim to ensure that all data entered is validated before being saved in the database. The validation process involves checking if the phone number consists only of numerical values a ...

Preventing form submission with JavaScript by implementing multiple validation checks

Preventing a form from submitting when validation returns false is possible. Here's an example: <form name="registration" action="registration.php" onsubmit="return validate()"> <!-- some inputs like: --> <input type="text" id="us ...

Error encountered while fetching files from Google Cloud bucket using Firebase functions: RangeError - Maximum call stack size exceeded

I'm currently trying to access Firestore backup files stored in a Google Cloud bucket: export const retrieveFirestoreBackup = functions.https.onCall( async (data: RetrieveFirestoreBackupPayload, context) => { try { return await sto ...

A novel way to enhance a class: a decorator that incorporates the “identify” class method, enabling the retrieval

I have been given the task to implement a class decorator that adds an "identify" class method. This method should return the class name along with the information passed in the decorator. Let me provide you with an example: typescript @identity(' ...

Guide on crafting a scrollable and touch-responsive grid using CSS and JavaScript

I am seeking guidance on creating a grid with a variable number of columns and rows. It should be contained within a separate div and should not interfere with other objects or alter the parent's size. The grid needs to be square and I am currently u ...

The method for organizing boxes on the stack exchange website's list page

I can't help but wonder about a unique and innovative feature on this stackexchange page that showcases all the stackexchange sites in a grid layout. Upon clicking on a site box, it expands in size while the surrounding boxes adjust their positions t ...

Utilizing the correct method for binding checkboxes in Vue JS for effective two-way communication

I am working with data retrieved from a MySQL database where "1" and "0" represent boolean true and false. In my Vue component, I have set these values as shown below: data(){ return { form : { attribute_1 : "1", //attribute 1 is true ...

Determining the file size of an HTML and JavaScript webpage using JavaScript

Is there a way to determine the amount of bytes downloaded by the browser on an HTML+JS+CSS page with a set size during page load? I am looking for this information in order to display a meaningful progress bar to the user, where the progress advances bas ...

Concealing functions within Accessors

I've recently started working on a website project utilizing the node.js/express stack and I am experimenting with developing in the functional programming style, which is quite new to me. One issue I encountered was related to the express method res. ...

"Is it possible to use a Twitter widget with Mootools

I have been attempting to create a marquee for my twitter Account on my website. After some trial and error, I was able to achieve this using jQuery. Here is the code I used: <div id="twitter"> <p> Loading.....</p> <n ...

How can I use AngularJS to show a JSON value in an HTML input without any modifications?

$scope.categories = [ { "advertiser_id": "2", "tier_id": 1, "tier_name": "1", "base_cpm_price": "", "retarget_cpm": "", "gender": "", "location": "", "ageblock1": "", "ageblock2": "", "ageblock3": ...

Randomly loading Json files in Ionic is a great way to keep your

I have a div using *ngFor which loads values from a JSON file. I want to load values from different JSON files randomly each time the div is loaded. Is there a way to achieve this using Math.random() or any other methods? html file <div class= ...

Ways to execute additional grunt tasks from a registered plugin

I am currently in the process of developing a custom Grunt plugin to streamline a frequently used build process. Normally, I find myself copying and pasting my GruntFile across different projects, but I believe creating a plugin would be more efficient. Th ...

Executing Sequential Jquery Functions in ASP.Net

I have successfully implemented two JQuery functions for Gridview in ASP.Net 1. Enhancing Gridview Header and Enabling Auto Scrollbars <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script& ...

Tips for managing a basic click event within the Backbone.js framework

I am facing a challenge with a basic functionality in Backbone. I am trying to set up the <h1> element on my page so that when a user clicks on it, it smoothly navigates back to the homepage without a page reload. Here is the HTML snippet: <h1& ...

Strategies for detecting when a child checkbox is clicked within a parent li element

Below is a snippet of Vue Code illustrating the structure we're working with: <template> <li class="mm-product-item" v-on:click="edit(item)"> <p class="mm-product-info input-field"> <input ...

Confirmation of numerous checkbox selections

I am facing a challenge with a form that contains multiple questions answered through checkboxes. I need to validate that at least one checkbox is selected in all the questions, otherwise an alert message should pop up. Is it possible to achieve this val ...

What could be causing the npm server error in my Vue.js application?

After recently setting up Node.js and Vue.js, I decided to dive into my first project on Vue titled test. As part of the process, I attempted to configure the server using the command: npm run server However, I encountered the following error message: C ...

Tips for retrieving an input value following a DOM insertion

Developing a function to inject HTML into the DOM following an AJAX call like this: The function for injecting HTML $.ajax({ type: "POST", url: base_url + "main/GetTheLastSeq" }) .done(function( msg1 ) { ...