5

How can I run a piece of code as soon as a form has been reset?

The reset event fires before the form fields get reset to their default values. So, for example:

$('form').on('reset', function(e) {
    $('input').val('a value that should be set after the form has been reset');
});

This won't work. (Demo)

As the reset event fires before the browser handles the default form reset behavior, the code above simply sets the input's value right before the reset event's default action takes place, restoring the input's value to its default value. This makes sense, as so I'd be able to call e.preventDefault() to cancel the form resetting.

My use case requires executing code as soon as the form has been reset. In simple cases, a setTimeout would suffice:

$('form').on('reset', function(e) {
    setTimeout(function() {
        $('input').val('yay it works now');
    }, 0);
});

This works, as the setTimeout will execute sometime in the future, after the reset has finished bubbling and the browser has handled its default action.

However, this loses synchronicity. As soon as I have to programmatically reset the form and manipulate it from another place, everything goes down the drain.

$('form').on('reset', function(e) {
    setTimeout(function() {
        $('input').val("reset'd value");
    }, 0);
});

//somewhere in another module..
$('form').trigger('reset');
$('input').val('value after resetting the form');

(Demo)

Of course, everything is supposed to happen synchronously, but only my reset event handling is pushed to asynchronously run in the future, thus it ends up running after all the current synchronous pile of code has executed, when it was supposed to run right after the form has been reset.

Solutions I've thought about:

  • Use yet another setTimeout to run after the setTimeout. This is overly ugly and I refuse to jump into a setTimeout hell.
  • Implement a wrapper for resetting the form which either takes a callback function or returns a promise object. This seems a bit overkill though.

If only an afterreset event existed.. Well, did I overlook something or are the solutions above my only options?


I've came across these questions while searching:

But their titles are (imho) a bit misleading, seeing as those are actually very distant from my problem.

Community
  • 1
  • 1
Fabrício Matté
  • 69,329
  • 26
  • 129
  • 166
  • There's also no way to "handle" an event as soon as the browser has finished handling its default action, right? This is rather disheartening. – Fabrício Matté Jul 13 '13 at 08:18
  • Just out of curiosity, what use case prompts you to do this? – Blender Jul 13 '13 at 08:30
  • @Blender I have some [Select2](http://ivaynberg.github.io/select2/) instances. I want to set its data to my default values when the form is reset, however their corresponding `select` elements would have their selectedIndex reset after I've set the Select2 data. `:(` – Fabrício Matté Jul 13 '13 at 08:33
  • is this [question](http://stackoverflow.com/questions/10319289/how-to-execute-code-after-html-form-reset-with-jquery) similar to your question – Yogesh Jul 13 '13 at 08:50
  • @Yogesh Oh thank you, I've thought something similar with `.on('reset', fn)` but that'd get in an infinite loop (as a vanilla `form.reset()` does trigger a `.on('reset', fn)`, I've tested), the accepted answer uses a `click` handler for the reset button mhm I guess it may help. I'll experiment and mark this as dupe if it works otherwise I'll update the question. – Fabrício Matté Jul 13 '13 at 08:53
  • Yes, I'll have to replace the `form.reset()` calls by `$(resetButton).trigger('click')`. Not the perfect solution but it is as good as it gets I guess. Voting to close as dupe. – Fabrício Matté Jul 13 '13 at 08:59
  • I have tried the solution here ..please have a look at [Demo](http://jsfiddle.net/bRruD/34/) – Yogesh Jul 13 '13 at 09:07
  • @Yogesh Yeah but then the form `reset` is cancelled. Type something in the first box and press the reset button http://jsfiddle.net/bRruD/35/ Don't worry, your linked answer should suffice my needs. – Fabrício Matté Jul 13 '13 at 09:09
  • @FabrícioMatté My Bad. Sorry. I completely forgot the primary goal – Yogesh Jul 13 '13 at 09:12

1 Answers1

1

In your case, I think you just simply assign a default value to your textbox. As the form is reset, the browser will automatically reset it to the default value.

<form>
    <input value="Abc" type="text"/>
    <input type="reset" />
</form>

Check demo.

Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • Yes I've been thinking just about this. My use case is a tad bit more complex, but I'll try this out. – Fabrício Matté Jul 13 '13 at 08:36
  • @Fabrício Matté: actually, when you set a default value in your HTML, the browser assigns the value to a special `defaultValue` field instead of `value`. Check this link http://jsfiddle.net/5YKRk/1/ . Try setting to `document.getElementById("test").value = "Abc";` you will see a difference – Khanh TO Jul 13 '13 at 08:38
  • I'm aware of the `defaultValue` property for text inputs, my real issue is with `select` elements though. – Fabrício Matté Jul 13 '13 at 08:45
  • @Fabrício Matté: for select element, just set the `selected` for its option. See http://jsfiddle.net/5YKRk/2/ – Khanh TO Jul 13 '13 at 08:50
  • Thank you. I thought I'd not be able to use `selected` because my `option` elements are dynamically generated, but I just realized that I can set `.attr('selected', 'selected')` inside DOM ready (or even inside the `reset` handler) and it will work fine. Just a couple more tests and I'll accept the answer. – Fabrício Matté Jul 13 '13 at 09:14