20

I need to submit a form programmatically, but I need it to preventDefault as well.

Right now I have the following:

submit() {
  this.$refs.form.submit()
}

It is working fine, but I cannot prevent default on the submit which in the end, refreshes the page.

4
  • How are you calling the submit() function? Not the $refs, but the outer function? Commented Aug 7, 2018 at 17:13
  • I am calling it as a @click="submit". I know it sounds weird why I do that, but it is because I am creating a wrapper for my form, where I wan't to submit the form. So I have something like: <vue-form @submit="doSomething"><vue-input></vue-input><button type="submit"></button></vue-form>. So basically I need the button to submit the form, which can be done with a slot within the form, if I can get the form to submit correctly programmatically. Commented Aug 7, 2018 at 17:16
  • And you need preventDefault because you want to "doSomething" before the form is submitted? And when this "something" is done, then you want to submit it programatically? Commented Aug 7, 2018 at 18:01
  • This question is similar to: v-on:submit.prevent not stopping form submission. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Nov 7, 2024 at 13:34

5 Answers 5

43

Short answer

You can add the .prevent modifier to the @submit (or any other v-on you're using), like this:

<form @submit.prevent="myMethod">
  <button type="submit"></button>
</form>

In the case of submitting a form, this will prevent the default behavior of refreshing the page.

Long answer

There are several ways to modify events.

From the Vue 3 docs:

It is a very common need to call event.preventDefault() or event.stopPropagation() inside event handlers. Although we can do this easily inside methods, it would be better if the methods can be purely about data logic rather than having to deal with DOM event details.

To address this problem, Vue provides event modifiers for v-on. Recall that modifiers are directive postfixes denoted by a dot.

<!-- the click event's propagation will be stopped -->
<a @click.stop="doThis"></a>

<!-- the submit event will no longer reload the page -->
<form @submit.prevent="onSubmit"></form>

<!-- modifiers can be chained -->
<a @click.stop.prevent="doThat"></a>

<!-- just the modifier -->
<form @submit.prevent></form>

<!-- use capture mode when adding the event listener -->
<!-- i.e. an event targeting an inner element is handled here before being handled by that element -->
<div @click.capture="doThis">...</div>

<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div @click.self="doThat">...</div>

Another option:

Sometimes we also need to access the original DOM event in an inline statement handler. You can pass it into a method using the special $event variable:

<button @click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
// ...
methods: {
  warn: function (message, event) {
    // now we have access to the native event
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

Cheers :)

Sign up to request clarification or add additional context in comments.

Comments

9

Didn't quite understand @Armin Ayari's answer, for instance why the code would have to be in the methods object? Anyway in Vue this is what worked for me:

<form ref="form" @submit.prevent="myMethod">
  <button type="submit"></button>
</form>

This blocked the page from refreshing and called myMethod instead.

You don't even need the ref. Understood this is an old question, but I found myself here after debugging, and found my form tags were simply mis-placed.

Comments

6

After some proper investigation with not a single answer here being related to the original question.

I have found your solution, however it isn't VueJS specific, referencing this article: Javascript e.preventDefault(); not working on submit()

Answer

Your programmatic way to execute submit this.$refs.form.submit() isn't correct if you want to properly preventDefault() or even run other functions.

You need to run this.$refs.form.requestSubmit(), this replicates the functionality as if you would've had a child <button> run the clicked event.

3 Comments

This is the correct answer to this question. Idk if other answers read the same question as as we did...
I agree with @Fanoflix. This answer solved my problem.
Solved my problem, which was to trigger form submission in a child component. @submit.prevent was being ignored when using formRef.submit()
1

I don't know if I understood your question correctly but you can prevent the default behavior of your form like this:

this.$refs.form.addEventListener("submit", (event) => {
    event.preventDefault()
});

Maybe this can help you:

new Vue({
  el: '#app',
  data: {},
  methods: {
    submit () {
      this.$refs.form.addEventListener('submit', event => {
        event.preventDefault()
      })
    },
    alert () {
      alert('hello')
    }
  }
})
<body>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <div id='app'>
    <div class="form-wrapper" @click='submit'>
      <form ref='form' @submit='alert'>
        <input type="text">
        <button type='submit'>Submit</button>
      </form>
    </div>
  </div>
</body>

2 Comments

Armin thank you! This is where I am going. I need the form to submit, but not to refresh the page, as it will when I just submit the form normally. I need this functionality because I need to emit an event, that the form has been submitted and I wan't the browser functionality of validating (ex. required).
@MaltheBjerregaardPetersen So is this answer you were looking for?
0

I think it's dona help!!

<form method="POST" action="http::localhost:8080/" @submit.prevent="submit_login($event)">
    // enter yours inputs here
</form>


submit_login(e) {
    if (true) {
        e.target.submit();
    },
},

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.