thomasfrank.se
Undo & redo in forms
Februari 14, 2007
It seems I'm in a undo/redo mode right now. Two weeks ago I wrote an article about how to remember different states of an object. This is a good swiss army knife when working with normal javascript objects.
But here's another script optimized to make form input undoable/redoable. It's really simply to apply.
Form state
Download formState.js (3 kB) and embed it in the head section of your web page:
<head>
<script type="text/javascript" src="formState.js"></script>
...
</head>
How to use
First you must tell formState that form input should be undoable for a certain form. You do this by adding "_undoable" to the id of the form. (The "_undoable" part will be removed, so the actual id of the form below will still be "cool".)
<form id="cool_undoable">
This will make every element change in the form undoable. For a closer shave you could use "_undoable_keystroke" which will make every key stroke undoable. Obviously this will eat more memory and might give a sluggish performance.
<form id="cool_undoable_keystroke">
Two methods - undo and redo
You can now call two methods in formState to undo and redo changes in your form:
- formState.undo(formObject) will perform an undo action.
- formState.redo(formObject) will perform a redo action.
For convenience you can pass any form child object as a parameter instead of the form object itself.
So a simple way to run these methods would be to attach them to buttons in your form:
<input type="button" onFocus="this.blur()"
onClick="formState.undo(this)" name="Undo" value="Undo">
<input type="button" onFocus="this.blur()"
onClick="formState.redo(this)" name="Redo" value="Redo">
Please note: To name your buttons "Undo" and "Redo" is optional but will add the benefit that formState will disable/enable them depending on whether there are user actions to undo/redo.
Let's try it out
Here are two forms that will give you an example of how formState works. The first one is set to "_undoable" and the one to the right to "_undoable_keystroke".
Some extras you can use if you want to
Now let's go through som optional adjustments you can make to formState.
Handling event handlers
When you apply formState to a form it will modify the following event handlers:
- onchange
- onclick
- onkeyup (if you use the "keystroke" option).
If you have events attached to these event handlers they will still trigger, before formState stores the changes in the form. You can change this so that your events will trigger after storage instead. Set the following flag:
formState.eventsBeforeStore=false
Do something on state change
You can add a event handler/method to formState that will trigger each time a new state is stored. This method will receive three parameters - they will tell you which form we're dealing with and if any undoing or redoing is currently possible.
formState.onStateChange=function(formObject,undoable,redoable){
/*
formObject - the actual form
undoable - true/false (true if there's something the user can undo)
redoable - true/false (true if there's something the user can redo)
*/
/*
your code here
*/
}
That's about it. Happy undoing!