Vue: Submit a form with javascript doesn't trigger event modifier.

Created on 6 Jun 2016  ·  8Comments  ·  Source: vuejs/vue

Vue.js version

1.0.23

Reproduction Link

http://jsbin.com/pevimajuro/edit?html,js,output

Steps to reproduce

Submit a form with javascript document.forms[0].submit(); doesn't trigger event modifier v-on:submit.prevent

What is actually happening?

The event modifier is not triggered. The default event is.

Is this a bug ?

Some web extension auto login after filling form, but don't seems to work with a vuejs form.

Most helpful comment

I had a scenario where i wanted to submit the form outside of the form and calling this.$refs.form.submit() wouldn't fire my saveData() function so this is my workaround...

Form HTML

<form ref="form" v-on:submit.prevent='saveData()' v-on:reset.prevent>
    <!-- form inputs --->
</form>
<button @click="saveData()">Save</button>

Vue component method

saveData: function () {
    // Manually trigger validation
    if (!this.$refs.form.checkValidity()) {
        // Try focus on the error 
        this.$refs.form.reportValidity()
        return
    }

    // Actually save code
}

Hopefully this helps someone. Still can be submitted via $refs.form.submit() but I can still manually trigger the Validity (although I'm not sure if reportValidity() is reliable).

All 8 comments

Hello,

This is not a bug.

Please see cloned jsbin with modifications. http://jsbin.com/desade/edit?html,js,console,output

You will notice if you do vm.$el.submit() with a console.log inside of _onSubmit_, the log will not be triggered. However, direct communication to vm.onSubmit() should resolve your use case. Programmatic execution of form interaction will not call onSubmit method. See http://wayback.archive.org/web/20090323062817/http://blogs.vertigosoftware.com/snyholm/archive/2006/09/27/3788.aspx

Hey,

So, this mean that even if we use a v-on:submit.prevent="whatever" on any form, if someone decide to submit the given form with a JS-line typed in the console, the whatever callback will not be called?

And we have to add a plain-JS eventListener, additionally to the VM, in order to catch this event?

@flo-sch yes, or you valid the form with the submit button

Hey @guillaumevincent, thanks for your answer,

My concern is not about a way to submit the form itself (I perfectly know how to do that),
But rather about preventing people to submit it in a way I do not want them too, for instance, without a validation process.

I would have prefered not to have to worry about someone typing documents.forms[0].submit() in the console, for instance.

I expected a submit event-listener to be actually executed on any submit event.

Even though, it is easily solvable :
https://jsfiddle.net/FloSchieldBobby/a5gmdd62/

<form id='my-form' v-on:submit='onFormSubmit'>
    <input v-model='someFieldToValidate' name='some-field' type='text'>
    <button type='submit'>Submit</button>
</form>

var form = new Vue({
    el: '#my-form',
    data: {
        someFieldToValidate: '',
        isSubmitAllowed: false
    },
    methods: {
        validate: function () {
            // Validate some fields, execute XHR-requests etc.
            // [...]

            this.isSubmitAllowed = !!this.someFieldToValidate;
        },
        onFormSubmit: function (event) {
            this.validate();

            if (!this.isSubmitAllowed) {
                event.preventDefault();
            }
        }
    }
});

// Then we have to add a non-Vuejs event-listener to ensure the form will not be submitted by another way,
// Such as typing `document.forms[0].submit()` in the console.
form.$el.addEventListener('submit', form.onFormSubmit.bind(form));

@flo-sch adding plain listener won't help, the problem is that programmatic form.submit() does not fire event at all.

I had a scenario where i wanted to submit the form outside of the form and calling this.$refs.form.submit() wouldn't fire my saveData() function so this is my workaround...

Form HTML

<form ref="form" v-on:submit.prevent='saveData()' v-on:reset.prevent>
    <!-- form inputs --->
</form>
<button @click="saveData()">Save</button>

Vue component method

saveData: function () {
    // Manually trigger validation
    if (!this.$refs.form.checkValidity()) {
        // Try focus on the error 
        this.$refs.form.reportValidity()
        return
    }

    // Actually save code
}

Hopefully this helps someone. Still can be submitted via $refs.form.submit() but I can still manually trigger the Validity (although I'm not sure if reportValidity() is reliable).

@GarethTIGFreight Golly G man, you saved my night :DDD

@GarethTIGFreight joder amigo, tardé prácticamente 2 días buscando solución hasta que te encontré a ti. ¡Mil gracias!

Was this page helpful?
0 / 5 - 0 ratings