Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does form.reset() not work from a reset handler?

document.forms[0].addEventListener("reset", resetHandler, false);

function resetHandler (evt)
{
    evt.preventDefault();
    document.forms[0].reset();  // this does nothing
}

In this example, reset() has no effect (tested in Firefox and Chrome).
The exact same thing works as expected for the "submit" event.
Why?

Fiddle: http://jsfiddle.net/wcLLtkaL/

like image 345
Zilk Avatar asked Sep 20 '25 07:09

Zilk


2 Answers

The HTML spec says:

When a form element form is reset, the user agent must fire a simple event named reset, that bubbles and is cancelable, at form, and then, if that event is not canceled, must invoke the reset algorithm of each resettable element whose form owner is form.

When the reset algorithm is invoked by the reset() method, the reset event fired by the reset algorithm must not be trusted.

This is exactly what happens when button is pressed or f.reset() is called: An event is created. But since you cancel the event (evt.preventDefault()), the "reset algorithm of each resettable element" step is not performed.

This looks like it should go into an infinite loop (reset() methods triggers reset event, which calls reset() method with triggers...), however, there seem to be additional steps taken to prevent that.

You can easily verify that f.reset() triggers the reset event by moving the call outside the method:

document.forms[0].addEventListener("reset", resetHandler, false);

function resetHandler (evt)
{
    console.log('reset');
    evt.preventDefault();
}

document.forms[0].reset();

This will log "reset", indicating that all .reset() does is triggering the event. And only if the event is not canceled the form is actually reset.


But why does submit() behave differently?

Calling the submit() method does not actually trigger a submit event and therefore the action to be taken is not canceled.

like image 67
Felix Kling Avatar answered Sep 22 '25 22:09

Felix Kling


The "evt.preventDefault();" is preventing the default action of "reset". Updated fiddle with "evt.preventDefault();" commented out, showing it working.

var f = document.forms[0];

f.addEventListener("reset", resetHandler, false);
f.addEventListener("submit", submitHandler, false);

function resetHandler (evt)
{
    //evt.preventDefault();
    f.reset();  // this does nothing
}

function submitHandler (evt)
{
    evt.preventDefault();
    f.submit();  // this works fine
}
like image 36
t1nr2y Avatar answered Sep 22 '25 22:09

t1nr2y