Tips for getting Vue's element-ui validateField() function to function correctly in conjunction with v-if?

Kindly observe the password fields. The fields for 'Password' and 'Confirm Password' are displayed upon clicking on the 'Change Password?' button.

The provided code functions properly and effectively validates the form using 'v-show', however, it fails to validate when 'v-if' is utilized.

I comprehend the roles of 'v-show' and 'v-if', alongside the functionalities within 'data(){}'. This information is clearly outlined in element-ui's documentation which can be accessed via this URL:

<template lang="pug">
  el-dialog( width="600px", title="Users", :visible.sync="dialogVisible")
    el-form.demo-ruleForm(:model="editedItem", status-icon, :rules="formRules", ref="userForm", label-width="140px")
      el-form-item(label="Name", prop="firstName")
        el-input(v-model="editedItem.name", auto-complete="off")

      template(v-if="!changePassword")
        el-form-item
          el-button(@click="changePassword = true") Change Password?
      template(v-else)
        _el-form-item_(label="Password", prop="password")
          el-input(type="password", v-model="editedItem.password", auto-complete="off")
        
        _el-form-item_(label="Confirm Password", prop="confirmPassword")
          el-input(type="password", v-model="editedItem.confirmPassword", auto-complete="off")
    
    .dialog-footer(slot="footer")
      el-button(type="primary", @click="submitForm('userForm')") Save
</template>

<script>
export default {
  name: 'dialog-add-edit-user',
  props: {
    editedItem: Object,

  },
  data () {
    const validatePass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('Please input the password'))
      } else {
        if (this.confirmPassword !== '') {
          this.$refs.userForm.validateField('confirmPassword')
        }
        callback()
      }
    }

    const validatePass2 = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('Please input the password again'))
      } else if (value !== this.editedItem.password) {
        callback(new Error("The two inputs don't match!"))
      } else {
        callback()
      }
    }

    return {
      formRules: {
        password: [
          {
            validator: validatePass,
            trigger: 'blur'
          }
        ],
        confirmPassword: [
          {
            validator: validatePass2,
            trigger: 'blur'
          }
        ]
      },
      dialogVisible: false,
      changePassword: false,
      editedItem: {
        name: '',
        password: '',
        confirmPassword: ''
      }
    }
  },

  methods: {
    submitForm (formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$emit('save-item');
          console.log('Submit Successful!');
        } else {
          console.log('Error submitting the form');
          return false;
        }
      });
    }
  }
}
</script>

Answer №1

It seems like I've pinpointed the issue now.

Your validation is actually working fine, but it's only checking passwordChange, not name and password.

If you understand the functionality of `v-show` and `v-if`, you'll realize that these elements are dynamically added and removed based on conditions.

The problem arises because the element library goes through an initialization phase when these elements are added. Later on, the element can be referenced using `$refs[formName].validate`, as seen in `SubmitForm`.

When you use `v-if` or `v-else`, since the elements weren't present initially, they won't function correctly.

You have two choices: stick with `v-show`, which should be straightforward, or utilize a hack I've used with 3rd party libraries that lack manual or automatic reload capabilities. The hack involves adding a `key` attribute to the main element. Here's how your HTML would look:

<el-form
  class="demo-ruleForm"
  :model="editedItem"
  status-icon="status-icon"
  :key="'form'+changePassword"  <--- this is the magic
  :rules="formRules"
  ref="userForm"
  label-width="140px"
>

And in pug:

el-form.demo-ruleForm(:model="editedItem", :key="'form'+changePassword", status-icon, :rules="formRules", ref="userForm", label-width="140px")

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

Implementing a dual hover effect on a Div element

I am working with HTML code that includes an image and text <div class="subcontainer1"> <img src="a.png" alt="" class="imgcolumn"> <h3 class="header3">Hello</h3> </div> This setup places the content above the image. ...

Optimizing VueJS applications with browser caching features for faster loading

I've encountered an issue with my VueJS app. After running npm run build, a new set of dist/* files are generated. However, when I upload them to the server (replacing the old build) and try to access the page in the browser, it seems to be loading th ...

Issue with IE7 Dropdownlist not appearing after changing class name when onFocus event is triggered for the first time

I need to adjust the CSS class of a dropdownlist when it is focused on, in order to change its background color. However, in IE7, when the dropdownlist is clicked, the CSS class changes but the options list does not appear until the dropdownlist is clicke ...

The Vuex store has been refreshed, but the DOM remains unchanged

I've scoured all the discussions on this topic and can't find a solution. My Vuex store is updating correctly, but the DOM isn't reflecting the changes. Here's a screenshot of the issue One of my getters, called returnAmazonCredential ...

Increasing the nth-child Selector in Jquery

Referring to this I am looking to cycle through the nth-child selector, which involves: var i = 1; var tmp = $(this).find('td:nth-child(i+1)'); // I wonder how this can be achieved i++; I have rows with dynamically generated columns i ...

When the jquery loop fails to function

I need to dynamically add a class to a specific tag using jQuery depending on an if condition. Here's the code snippet: if ($(".asp:contains('Home')")) { $("ul.nav-pills a:contains('Home')"). parent().addClass('active ...

Using JSON to pass a function with parameters

I have a small issue that I'm struggling to solve. My dilemma lies in sending a JSON with a function, along with parameters. Typically, it's easy to send a function in JSON like this: var jsonVariable = { var1 : 'value1', var2 : &apos ...

Tips for saving data obtained from an ajax call

My jquery ajax function has a callback that creates an array from retrieved json data. Here's an example: success: function (response) { callback(response); }, The callback function, in this case createQuestionsArray(), populates ...

Modify the parent div's background color on mouseover of the child li

I want to update the background image of a parent div that contains a series of ul li elements. Here is the HTML code I am working with: <section class="list" id="services"> <div class="row"> <ul> <li>& ...

Equalize the color of overlapping background events with non-overlapping background events in fullcalendar

events:[ {overlap:false, display:'background', start:'2021-12-23 10:15:00', end:'2021-12-23 10:30:00'}, {overlap:false, display:'background', start:'2021-12-23 10:30:00', end:'2021-12-23 10:45:00&a ...

jquery has a strange behavior where the dialog window will cover up the scrollbar when the main

Currently, I am utilizing jQuery dialog to display a dialog window. I have managed to position it at the bottom left corner as desired. However, when the main window contains a scrollbar, the dialog ends up overlapping with the scrollbar instead of alignin ...

I am developing a quiz application using JavaScript, and I am wondering how I can smoothly transition from one question to the

I'm working on developing a quiz application and I'm facing an issue where my quiz is skipping question 2 when moving from one question to the next using the "next" button. I have a total of 3 questions in my quiz and for some reason, it jumps fr ...

Retrieving selected options from a jQuery mobile multiselect for database storage

I'm currently working on extracting values from a select list in a jQuery mobile application. Here's the markup for my select element: <div data-role="fieldcontain"> <label for="stuff" class="select">Stuff:</label ...

Tips on retrieving Bootstrap selectpicker value by using loops in Jquery

I am attempting to perform a basic validation using jQuery, where I need to iterate through all elements to check for the existence of values. The validation script is working well except for the jQuery selectpicker functionality. Here's what I have t ...

Incorporating Ruby on Rails: Sending a fresh POST request to API and instantly

I'm a beginner in the field of ruby on rails. Our website allows users to search and receive a list of results. Now, I want to incorporate sorting functionality for the results (by price, rating, etc). The API handles the sorting process, so all I ne ...

Why is a unique key important in vue.js?

Here's what I'm trying to say: Imagine we have a v-for directive in our own custom Vue component being utilized like this: <my-custom-component v-for="item in items" :key="item.id">{{item.remark}}</ my-custom-component> Why do we n ...

Using the @ Symbol in Javascript ES6 Module Imports

One of the folders in my node_modules directory is called @mymodule, and within it, there is another folder named 'insidefolder'. The path to this folder looks like this: node_modules/@mymodule/insidefolder When trying to import insidefolder us ...

The controller is not receiving the isolated scope value

I have implemented angular-slider.js on a webpage where a server request is triggered upon changing the slider's value. I am looking to delay this action until the user releases the mouse button, specifically during onmouseup event. Incorporating thi ...

Managing browser window close events in a Vue.js application

As the user prepares to close the browser, I aim to transmit information to the server indicating that they have gone offline. Despite extensive research into this matter over a period of days, I have yet to uncover a solution. Can anyone provide guidanc ...

Tips for indicating request parameters in Drive.Comments.list

I have successfully retrieved the default 20 comments using the code below by specifying a single fileId parameter. However, I am interested in pulling back one hundred comments or paginating to the next set of 20 out of curiosity. In my getComments funct ...