43

Just completed a todolist tutorial. When submitting the form the input field doesn't clear.

After trying both:

    document.getElementById("todo-field").reset();
    document.getElementById("#todo-field").value = "";

The input field properly clears but it also deletes the todo.

It seems to delete the input field before it has time to push the new todo in the todos.text array.

Would love some input guys! Thanks!!

<template>
  <form id="todo-field" v-on:submit="submitForm">
    <input type="text" v-model="text">
  </form>
     <ul>
       <li v-for="todo in todos">
        <input class="toggle" type="checkbox" v-model="todo.completed">
        <span :class="{completed: todo.completed}" class="col-md-6">
            <label @dblclick="deleteTodo(todo)">
                {{todo.text}}
            </label>
        </span>

       </li>
     </ul>

<script>
  export default {
    name: 'todos',
      data () {
        return {
          text: '',
          todos: [
          {
      text:'My Todo One',
      completed: false
    },
    {
      text:'My Todo Two',
      completed: false
    },
    {
      text:'My Todo Three',
      completed: false
    }
  ]// End of array
}
  },
    methods: {
    deleteTodo(todo){
        this.todos.splice(this.todos.indexOf(todo),1);
    },
    submitForm(e){
        this.todos.push(
            {
                text: this.text,
                completed: false
            }
        );
        //document.getElementById("todo-field").reset();
        document.getElementById("#todo-field").value = "";

        // To prevent the form from submitting
        e.preventDefault();
    }
}
}
</script>

10 Answers 10

54

These solutions are good but if you want to go for less work then you can use $refs

<form ref="anyName" @submit="submitForm">
</form>

<script>
   methods: {
      submitForm(){
         // Your form submission
         this.$refs.anyName.reset(); // This will clear that form
      }
   }
</script>
Sign up to request clarification or add additional context in comments.

3 Comments

This is the best answer here, in my opinion, but I wish there were a way to modify the behavior such that the form inputs are reverted to their initial state (when the DOM was first rendered), and not simply cleared outright. My use-case is that I want the user to be able to "undo" any changes made to the form since page-load, without completely resetting all inputs to "no selection". It seems I'll need a different approach, but thanks for sharing this technique!
@BenJohnson what about using defaultForm = Object.freeze({...}) when creating a form with default values, assigning this to a form using form = Object.assign({}, this.defaultForm) and then keeping the reset() like it's in that example? Wouldn't be what you want to achieve? The resetting would be then (by following my example) this.$refs.form.reset(). ref in html would be to form, like ref="form".
If you use vee-validate (currently in version 4.5.11) it's not reset() but resetForm(), hence this.$refs.anyName.resetForm()
44

What you need is to set this.text to an empty string in your submitForm function:

submitForm(e){
    this.todos.push(
        {
            text: this.text,
            completed: false
        }
    );
    this.text = "";

    // To prevent the form from submitting
    e.preventDefault();
}

Remember that binding works both ways: The (input) view can update the (string) model, or the model can update the view.

5 Comments

@TonyRositano: You're welcome. Can you please accept the answer if it did indeed work? Thanks.
@Tony Rositano: Welcome to Stack Overflow. Please note that the preferred way of saying 'thanks' around here is by up-voting good questions and helpful answers (once you have enough reputation to do so), and by accepting the most helpful answer to any question you ask (which also gives you a small boost to your reputation). In other words, if you accept the answer, please click the checkmark to the left of the answer.
Gotcha thanks! Cannot upvote yet...not enough credentials! Soon will do!
The problem with this manner is that validation is then triggered and in my case "The field cannot be null"
Same validation issue when giving an empty string value
30

Assuming that you have a form that is huge or simply you do not want to reset each form field one by one, you can reset all the fields of the form by iterating through the fields one by one

var self = this;
Object.keys(this.data.form).forEach(function(key,index) {
    self.data.form[key] = '';
});

The above will reset all fields of the given this.data.form object to empty string. Let's say there are one or two fields that you selectively want to set to a specific value in that case inside the above block you can easily put a condition based on field name

if(key === "country") 
   self.data.form[key] = 'Canada';
else 
   self.data.form[key] = ''; 

Or if you want to reset the field based on type and you have boolean and other field types in that case

if(typeof self.data.form[key] === "string") 
   self.data.form[key] = ''; 
else if (typeof self.data.form[key] === "boolean") 
   self.data.form[key] = false; 

For more type info see here

A basic vuejs template and script sample would look as follow

<template>
  <div>
    <form @submit.prevent="onSubmit">
      <input type="text" class="input" placeholder="User first name" v-model="data.form.firstName">
      <input type="text" class="input" placeholder="User last name" v-model="data.form.lastName">
      <input type="text" class="input" placeholder="User phone" v-model="data.form.phone">
      <input type="submit" class="button is-info" value="Add">
      <input type="button" class="button is-warning" @click="resetForm()" value="Reset Form">
    </form>
  </div>
</template>

See ow the @submit.prevent="onSubmit" is used in the form element. That would by default, prevent the form submission and call the onSubmit function.

Let's assume we have the following for the above

<script>
  export default {
    data() {
      return {
        data: {
          form: {
            firstName: '',
            lastName: '',
            phone: ''
          }
        }
      }
    },
    methods: {
      onSubmit: function() {
        console.log('Make API request.')
        this.resetForm(); //clear form automatically after successful request
      },
      resetForm() {
        console.log('Reseting the form')
        var self = this; //you need this because *this* will refer to Object.keys below`

        //Iterate through each object field, key is name of the object field`
        Object.keys(this.data.form).forEach(function(key,index) {
          self.data.form[key] = '';
        });
      }
    }
  }
</script>

You can call the resetForm from anywhere and it will reset your form fields.

1 Comment

One of my input fields is required and is getting marked after clearing the form. But the submit call is @submit.prevent
11

For reset all field in one form you can use event.target.reset()

const app = new Vue({
    el: '#app',    
    data(){
	return{        
            name : null,
	    lastname : null,
	    address : null
	}
    },
    methods: {
        submitForm : function(event){
            event.preventDefault(),
            //process...             
            event.target.reset()
        }
    }

});
form input[type=text]{border-radius:5px; padding:6px; border:1px solid #ddd}
form input[type=submit]{border-radius:5px; padding:8px; background:#060; color:#fff; cursor:pointer; border:none}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.6/vue.js"></script>
<div id="app">
<form id="todo-field" v-on:submit="submitForm">
        <input type="text" v-model="name"><br><br>
        <input type="text" v-model="lastname"><br><br>
        <input type="text" v-model="address"><br><br>
        <input type="submit" value="Send"><br>
    </form>
</div>

Comments

7

Markup

<template lang="pug">
  form
    input.input(type='text' v-model='formData.firstName')
    input.input(type='text' v-model='formData.lastName')
    button(@click='resetForm') Reset Form
</template>

Script

<script>
  const initFromData = { firstName: '', lastName: '' };
  
  export default {
    data() {
      return {
        formData: Object.assign({}, initFromData),
      };
    },
    methods: {
      resetForm() {
        // if shallow copy
        this.formData = Object.assign({}, initFromData);
  
        // if deep copy
        // this.formData = JSON.parse(JSON.stringify(this.initFromData));
      },
    },
  };
</script>

Read the difference between a deep copy and a shallow copy HERE.

Comments

1

I use this

this.$refs['refFormName'].resetFields();

this work fine for me.

Comments

0

This solution is only for components

If we toggle(show/hide) components using booleans then data is also removed. No need to clean the form fields.

I usually make components and initialize them using booleans. e.g.

<template>
    <button @click="show_create_form = true">Add New Record</button
    <create-form v-if="show_create_form" />
</template>


<script>
...
data(){
   return{
       show_create_form:false //making it false by default
   }
},
methods:{
    submitForm(){
      //...
      this.axios.post('/submit-form-url',data,config)
           .then((response) => {
               this.show_create_form= false; //hide it again after success.
               //if you now click on add new record button then it will show you empty form
           }).catch((error) => {
              //
           })
    }
}
...
</script>

When use clicks on edit button then this boolean becomes true and after successful submit I change it to false again.

Comments

0

I had a situation where i was working with a custom component and i needed to clear the form data.

But only if the page was in 'create' form state, and if the page was not being used to edit an existing item. So I made a method.

I called this method inside a watcher on custom component file, and not the vue page that uses the custom component. If that makes sense.

The entire form $ref was only available to me on the Base Custom Component.

<!-- Custom component HTML -->
<template>
  <v-form ref="form" v-model="valid" @submit.prevent>
    <slot v-bind="{ formItem, formState, valid }"></slot>
  </v-form>
</template>

watch: {
  value() {
    // Some other code here
    this.clearFormDataIfNotEdit(this)
    // Some other code here too
  }
}
... some other stuff ....

methods: {
  clearFormDataIfNotEdit(objct) {
    if (objct.formstate === 'create' && objct.formItem.id === undefined) {
       objct.$refs.form.reset()
    }
  },
}

Basically i checked to see if the form data had an ID, if it did not, and the state was on create, then call the obj.$ref.form.reset() if i did this directly in the watcher, then it would be this.$ref.form.reset() obvs.

But you can only call the $ref from the page which it's referenced. Which is what i wanted to call out with this answer.

Comments

0

This is how I do it in Vue 3.

html:

  <input type="text" v-model="state.name">

js:

import {reactive} from "vue";

const state = reactive({
    name: ""
})

axios.post('/contact', state)
    .then(res => {
        if (res.status == 200) {
            state.name = ""
        }
    })

Response status 200 being a successful submission of the form input. state.name is reactive and will be set to "" if the submission is successful.

1 Comment

This gives me validation errors since I'm giving the input an empty value
0

if your using vue.js v-form you can simply do like

this.form.reset()

Documentation Vform - Documentation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.