When using veevalidate to reset a form in TypeScript, the form is not fully reset as

When I have a form with veevalidate and submit it, the data is emitted to the parent component, but I struggle with resetting the form. According to the veevalidate guidelines, the form should be reset using $refs.

  • To set up the refs, follow this link:
  • To reset the form, refer to:

My TypeScript app follows the guidelines, and the component structure looks like this:

<template>
    <div>
        <ValidationObserver v-slot="{ handleSubmit }" ref="form">
            <form :model="form" @submit.prevent="handleSubmit(onSubmit)" novalidate>
                <a-input-with-validation
                        :placeholder="placeholder"
                        :label="placeholder"
                        auto-complete="off"
                        name="comment"
                        type="text"
                        v-model="form.comment"
                        rules="required"
                />

                <a-button-submit :translation-key="$t('dict.save')"/>
            </form>
        </ValidationObserver>
    </div>
</template>

<script lang="ts">
  import { Component, Prop, Vue } from 'vue-property-decorator'
  import { ValidationObserver, ValidationProvider } from 'vee-validate'
  import { OItemCommentFormChildOutput } from '@/components/organisms/forms/OItemCommentFormInterfaces'
  import AInputWithValidation from '@/components/atoms/inputs/AInputWithValidation.vue'
  import AButtonSubmit from '@/components/atoms/buttons/AButtonSubmit.vue'

  @Component({
    components: {
      AButtonSubmit,
      AInputWithValidation,
      ValidationObserver,
      ValidationProvider
    }
  })
  export default class OItemCommentForm extends Vue {
    @Prop()
    comment?: string
    @Prop({ default: true })
    add!: boolean

    $refs!: {
      form: InstanceType<typeof ValidationObserver>;
    }
    placeholder!: string

    form: OItemCommentFormChildOutput = {
      comment: ''
    }

    mounted () {
      this.$refs.form;
    }

    created () {
      this.placeholder = String(this.add ? this.$t('dict.addComment') : this.$t('dict.editComment'))
      this.form.comment = this.comment || ''
    }

    onSubmit () {
      this.$emit('child-output', this.form as OItemCommentFormChildOutput)
      // this.form.comment = ''
      this.$refs.form.reset()
    }
  }
</script>

The a-input-with-validation component code (from veevalidate):

<template>
    <ValidationProvider
            :vid="vid"
            :name="nameAlt || name"
            :rules="rules"
            v-slot="{ errors, valid }"
    >
        <b-field
                :label="label"
                :prop="name"
                v-bind="$attrs"
                :auto-complete="autoComplete"
                :type="{ 'is-danger': errors[0], 'is-success': valid }"
                :message="errors"
        >
            <b-input
                    :name="name"
                    :type="type"
                    v-bind="$attrs"
                    :placeholder="placeholder"
                    v-model="innerValue"
                    :password-reveal="type === 'password'"
                    novalidate
            />
        </b-field>
    </ValidationProvider>
</template>

<style scoped>
    .AInputWithValidation {}
</style>

<script lang="ts">
  import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
  import { ValidationObserver, ValidationProvider } from 'vee-validate'

  @Component({
    components: {
      ValidationObserver,
      ValidationProvider
    }
  })
  export default class AInputWithValidation extends Vue {
    @Prop({ required: true })
    value!: any
    @Prop({ required: true })
    label!: string
    @Prop({ required: true })
    name!: string
    @Prop({ default: 'off' })
    autoComplete!: string
    @Prop({ default: 'text' })
    type!: string
    @Prop()
    nameAlt?: string
    @Prop()
    placeholder?: string
    @Prop()
    vid?: string
    @Prop()
    rules?: string

    innerValue = ''

    created () {
      if (this.value) {
        this.innerValue = this.value
      }
    }

    @Watch('innerValue')
    innerValueHandle (newVal) {
      this.$emit('child-output', newVal)
      this.$emit('input', newVal)
    }

    @Watch('value')
    valueValueHandle (newVal) {
      this.innerValue = newVal
    }

  }
</script>

The app compiles without errors but fails to reset the form after submission. How can I reset the form without triggering the validation errors?

(Even moving the ref="form" to the form tag did not resolve the issue.)

Answer №1

ValidationObserver does not reset form fields when reset() is called, only the validation state. To clear the form fields manually, you can refer to a form-reset demo. Alternatively, you can use HTMLFormElement.reset() on the <form> element to restore the fields to their initial values. Access the <form> element through the SubmitEvent's target:

export default class OItemCommentForm extends Vue {

  async onSubmit(e) {
    // Wait for microtasks to update models before resetting validation state
    await this.$nextTick()
    this.$refs.form.reset()

    // Reset form in the next event loop
    setTimeout(() => e.target.reset())
  }
}

To ensure the form is reset in the next event loop, use setTimeout with zero timeout.

https://codesandbox.io/s/reset-form-after-submit-230s0?fontsize=14&hidenavigation=1&module=%2Fsrc%2FDemo.vue&theme=dark

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

Access an object within the ngOnInit lifecycle hook

Is there a way to access an object from the ngOnInit function and use it outside the class in the same component? Let me explain: I am implementing an Angular Material table and want to dynamically populate it with data retrieved from Firebase. ngOnIn ...

Issue with nested checkbox v-model in Bootstrap-vue not functioning correctly

https://i.sstatic.net/RwzMn.png Could you please review this component code briefly? <template> <div> <b-form-checkbox id="checkbox-0" v-model="checkboxIsChecked" name="checkbox-1 ...

Overriding a generic property in Typescript allows for a more

I'm troubleshooting an issue with my code: class Base<T> {} class Test { prop: Base<any>; createProp<T>() { this.prop = new Base<T>(); } } const test = new Test(); test.createProp<{ a: number }>(); test.pr ...

It appears that using dedicated objects such as HttpParams or UrlSearchParams do not seem to work when dealing with Angular 5 and HTTP GET query parameters

I'm facing a perplexing issue that I just can’t seem to figure out. Below is the code snippet making a call to a REST endpoint: this.http.get<AllApplicationType[]>(environment.SUDS_API_SERVICE_URL + environment.SUDS_ALL_APPLICATIONS_URL, this ...

Is there a way to modify the antd TimePicker to display hours from 00 to 99 instead of the usual 00 to 23 range?

import React, { useState } from "react"; import "./index.css"; import { TimePicker } from "antd"; import type { Dayjs } from "dayjs"; const format = "HH:mm"; const Clock: React.FC = () =& ...

in Vue.js, extract the style of an element and apply it to a different element

Currently, I am using VUE.js 2 in my project. Here is my website's DOM structure: <aside :style="{height : height()}" class="col-sm-4 col-md-3 col-lg-3">...</aside> <main class="col-sm-8 col-md-9 col-lg-9" ref="userPanelMainContents" ...

When validation fails, all fields are highlighted in the Div containing the FormGroup

In my Angular application, I need to utilize two fields - produced date and expiry date. It is important to note that I must use <div [formGroup]...> since this component will be called within other forms. Using the form tag here is not an option. ...

Encountering a sign-in issue with credentials in next-auth. The credential authorization process is resulting in a

I am currently facing an issue with deploying my Next.js project on Vercel. While the login functionality works perfectly in a development environment, I encounter difficulties when trying to sign in with credentials in Production, receiving a 401 error st ...

Next.js's router.push method directs the user to the specified URL and refreshes the page

I am facing an issue with my page structure: pages [re] login [slug.tsx] When I navigate from http://localhost:3000/in/login/data1 to http://localhost:3000/in/login/data2 using router.push on button click, the route is updated but th ...

What is the best way to utilize the existing MUI state in order to calculate and show column totals?

I am currently in the process of developing an MUI web application to keep track of some personal data. Within this application, I have incorporated the MUI datagrid pro component to efficiently display the data with its robust filtering capabilities. In ...

Angular's DecimalPipe will truncate any strings that exceed 10 digits

Using the decimal pipe to format numbers in an input field value| number:'0.0-6': 'en-us' When working with numbers containing more than 10 digits, it displays as follows: For 11111111111.123456, it formats to 11,111,111,111.123455 ...

Executing a typescript class from a bash script: tips and tricks

Is it possible to invoke a TypeScript class and function from a bash script file? I have been unable to locate any relevant documentation on this topic. Below is the code snippet: TypeScript code: export class TestClass { constructor( public name ...

Is there a way to prevent IntelliJ from creating .js files when working with .ts source code?

Working on a mixed Java/Typescript project with Maven as the build tool, I utilize the frontend-maven-plugin to successfully build from the command line. However, I am encountering an issue with IntelliJ 2018.2 where it keeps transpiling .js files for my . ...

Troubleshooting Vue.js devtools not functioning correctly in an Electron Vue project

Whenever I launch the project using npm run electron:serve, I encounter an issue where the components tree of the Vue.js devtools and other tabs appear empty. It seems like the project is not being detected properly. Is there a solution to resolve this pr ...

Implementing Vuejs v-model with a dynamically named two-dimensional array

How can I create a dynamic v-model with two dynamic variables? Using only one dynamic variable like v-model="shirt_count[brand]" works fine, but when I try v-model="shirt_count[brand][color]", it does not work. See the code snippet belo ...

How can we dynamically showcase a table column/row containing data with varying sizes of nested arrays?

I am struggling to showcase the data retrieved from firestore on a table using Vue.js and Element UI. Most solutions I found are for displaying a fixed amount of data, but my case involves an uneven number of data entries. Here is the structure of my data ...

What could be causing the Google Sign-In functionality to fail in an Angular web application?

I'm currently working on implementing Google sign-in for my web app. I've been following this tutorial here. However, I'm facing an issue where the Google sign-in button is not appearing. I would like the authentication to happen at http://l ...

The srcSet functionality in the Image component seems to be malfunctioning in the next.js framework, as it is failing to display

Check out my Next.js code snippet below: import React from "react"; import style from "@/styles/Home.module.css"; import Image from "next/image"; function index() { return ( <> <div className="contai ...

Issue encountered: Vue js and d3 data visualization error - "d3 is not defined"

I am attempting to showcase a .json file as a treemap by using npm run dev. I thought I had everything set up correctly but it appears that an issue is arising. Below is my App.vue code: <template> <div id="app"> <title> { ...

Building a Search Object using Template String Types

Here is a type definition that allows for specific responses: type Response = 'n_a' | 'n_o' | 'yes' | 'no' I want to create a type that ensures underscores are replaced with slashes: type ReplaceUnderscoreWithSlash& ...