Revision: 7816
Updated Code
at August 19, 2008 16:18 by dom111
Updated Code
//
// submitEvent 0.2
// 19/08/2008
//
// Version History:
//
// 0.2
// Slightly better fix, using .bind(this) instead of a temporary
// window.submitFormData var
//
// 0.11
// Hacky fix for IE6
//
// 0.1
// Initial release
//
//
// A small class for easily implementing many submit events including
// displaying a confirmation dialog, disabling the submit button and
// displaying an informative div so that the users stay informed.
//
// Please see example.html for some examples
//
// All the options are detailed below, and the defaults can be easily
// changed to suit your needs.
//
// Requires mootools 1.2 (I don't think it'll work with lower) although
// I may also make a prototype/scriptaculous version if required.
//
// This software is released under the Creative Commons Share Alike
// license.
//
// Dom
//
// http://www.dom111.co.uk/
//
var submitEvent = new Class({
Implements: [Options],
// options
//
// the default options
// these can be overridden here if you use the same
// settings often, to save yourself time
//
options: {
// confirmation
//
// enabled: boolean
// text: text to display on said dialog box
// confirmed: used internally to make sure the
// confirmation isn't displayed again if there's a
// timeout
confirmation: {
enabled: false,
text: 'Are you sure?',
confirmed: false
},
// submitButton
//
// object: the object (or id as string) that is the
// primary submit button for f
// changeText: whether or not to change the button's
// text on submit
// newText: text to change the button to
//
submitButton: {
object: null,
disable: true,
changeText: true,
text: 'Please wait...'
},
// informationDiv
//
// display: whether or not to diplay an information
// div
// className: CSS class to apply to the div
// centered: whether to horizontally center the div
// (uses left: xxpx so class must add position absolute)
// text: text (or HTML to populate the div with
// inject: element to inject the div into (this.form
// is used if this is left as null/false)
// injectTo: position to inject element to eg. bottom,
// top, before, after defaults to after
//
informationDiv: {
enabled: true,
className: '',
centered: true,
text: 'Loading...',
inject: null,
injectTo: 'after'
},
//
// undo
// enabled: boolean
// timeout: in seconds to run specified undo tasks
//
// submitButton:
// enabled: re-enable the submit button
// newText: text to display on the newly enabled
// submit button
//
// informationDiv
// text: updated text to display
// className: updated CSS class to apply
undo: {
enabled: true,
timeOut: 30,
submitButton: {
enabled: true,
newText: 'Try Again'
},
informationDiv: {
enabled: true,
text: 'Sorry, there was a problem.',
className: ''
}
},
//
// ajax
//
// makes the form submission use ajax
//
// enabled: boolean
// update: the dom node, or a string id of the element
// to update, if not set, defaults to this.form
// appendUrl: a query string to append to the ajax request
// (could be used to surpress header/footer or just distinguish
// between ajax/normal requests)
//
ajax: {
enabled: false,
udpate: null,
appendUrl: 'ajax=1'
}
},
initialize: function(f, o) {
// if f is a string, look for that element id...
if ($type(f) == 'string') {
f = $(f);
}
// if f still isn't an object, give up...
if ($type(f) != 'object' && $type(f) != 'element') {
return true; // ... and submit the form, because we can't do anything...
}
// store the form object as this.form
this.form = f;
// save the old onsubmit function
this.preservedOnSubmit = this.form.onsubmit || function() {};
// merge the options...
this.setOptions(o || {});
if (!(this.options.submitButton.object)) {
this.options.submitButton.object = this.findSubmitButton(this.form);
if (!(this.options.submitButton.object.id)) {
this.options.submitButton.object.id = 'submitEventSubmitButton_' + new Date().getTime();
}
}
this.options.submitButton.oldText = this.options.submitButton.object.value;
this.informationDiv = false;
this.submitButtonFunctionTimeout = false;
this.informationDivFunctionTimeout = false;
},
// process
//
// do the magic!
process: function() {
// carry out functions in order:
//
// check for a confirmation message first, as if the user
// wants to cancel we could save ourselves some time
if ((this.options.confirmation.enabled) && !(this.options.confirmation.confirmed)) {
// if the text is blank or it's not a string
if (!(this.options.confirmation.text) || $type(this.options.confirmation.text) != 'string') {
// set it to some default text
this.options.confirmation.text = 'Are you sure?'
}
// set c to true/false from the user box
var c = confirm(this.options.confirmation.text);
// if it's true
if (c) {
// set the confirmed variable to true so the dialog isn't displayed again
this.options.confirmation.confirmed = true;
} else {
// else stop processing anything
return false;
}
}
// next, change the submit button if required
if ((this.options.submitButton.changeText) || (this.options.submitButton.disable)) {
// if the object, isn't an object, make it one
if ($type(this.options.submitButton.object) == 'string') {
this.options.submitButton.object = $(this.options.submitButton.object);
}
// create a variable for the button, of the object
var button = this.options.submitButton.object;
// make sure it's not null or false
if (button) {
// if we're supposed to change the text, do...
if (this.options.submitButton.changeText) {
button.value = this.options.submitButton.text || 'Please wait...';
}
// if we're supposed to disable it, do!
if (this.options.submitButton.disable) {
button.disabled = true;
}
}
}
// information div... display if required
if ((this.informationDiv) || (this.options.informationDiv.enabled)) {
if ((this.options.informationDiv.text) && $type(this.options.informationDiv.text) == 'string') {
// check the text is a string and nothing else
if (!this.informationDiv) {
// create a div element
this.informationDiv = new Element('div', {
'id': 'submitEventInformationDiv_' + new Date().getTime()
});
} else {
if (this.options.undo.informationDiv.className) {
this.informationDiv.removeClass(this.options.undo.informationDiv.className);
}
}
// set the innerHTML to the specified 'text', or default
this.informationDiv.set('html', this.options.informationDiv.text || 'Loading...');
// add the className if set
this.informationDiv.addClass(this.options.informationDiv.className || '')
// inject the element into the specified element, or this.form if not specified
this.informationDiv.inject(this.options.informationDiv.inject || this.form, this.options.informationDiv.injectTo || 'after');
if (this.options.informationDiv.centered) {
this.informationDiv.setStyle('left', this.getCenter(this.informationDiv) + 'px');
}
}
}
// undo, the best bit...
//
// if we can run undo tasks and at least one is enabled...
if (this.options.undo.enabled && (this.options.undo.submitButton.enabled || this.options.undo.informationDiv.enabled)) {
// set the timeout variable to seconds * 1000 (milliseconds)
var timeOut = (this.options.undo.timeOut || 30) * 1000;
// if we can run the undo on the button
if (this.options.undo.submitButton.enabled) {
// build the function to re-enable it and change the text
submitButtonFunction = function() {
var button = this.options.submitButton.object;
button.disabled = false;
button.value = this.options.undo.submitButton.newText || this.options.submitButton.oldText;
}
// use mootools timeout function, which allows this to be used
this.submitButtonFunctionTimeout = submitButtonFunction.delay(timeOut, this);
}
// if we can do the same magic with the information div...
if (this.options.undo.informationDiv.enabled) {
// build a function to change the text
informationDivFunction = function() {
if (this.options.undo.informationDiv.text) {
this.informationDiv.set('html', this.options.undo.informationDiv.text || 'Sorry, there was a problem.');
}
// and add the new class
if (this.options.undo.informationDiv.className) {
this.informationDiv.removeClass(this.options.informationDiv.className || '');
this.informationDiv.addClass(this.options.undo.informationDiv.className);
}
if (this.options.informationDiv.centered) {
this.informationDiv.set('styles', {
'left': this.getCenter(this.informationDiv) + 'px'
})
}
}
// another lovely timeout function
this.informationDivFunctionTimeout = informationDivFunction.delay(timeOut, this);
}
}
// if we're ajaxing it up...
if (this.options.ajax.enabled) {
// create a mootools request object
this.ajaxRequest = new Request.HTML({
// populate it with all the details from the HTML form
method: this.form.method,
url: this.appendQueryString(this.form.action),
// data: this.form.toQueryString(), // fails in IE 6?
data: this.formToQueryString(this.form),
update: this.options.ajax.update || this.form,
// add an oncomplete function to remove the additions
onComplete: function() {
$clear(this.submitButtonFunctionTimeout);
$clear(this.informationDivFunctionTimeout);
if ($(this.informationDiv.id)) {
$(this.informationDiv.id).destroy();
}
if ($(this.options.submitButton.object.id)) {
$(this.options.submitButton.object.id).value = this.options.submitButton.oldText;
$(this.options.submitButton.object.id).disabled = false;
}
}.bind(this)
}).send();
// make sure the main form isn't submitted
return false;
} else {
return true; // post the form
}
},
// findSubmitButton
//
// returns the first submit button on a form
//
findSubmitButton: function(f) {
// if f fails use document
f = f || document;
// loop through all input elements in f
var i = f.getElementsByTagName('input');
for (var x = i.length - 1; x >= 0; x--) {
if (i[x].type == 'submit' || i[x].type == 'image') {
return i[x];
}
}
// loop through all button elements in f
var i = f.getElementsByTagName('button');
for (var x = i.length - 1; x >= 0; x--) {
if (i[x].type == 'submit') {
return i[x];
}
}
// we didn't find anything, so return null
return null;
},
// getCenter
//
// returns the width of the screen / 2 or the width
// of the screen - el.width / 2 for centering elements
//
getCenter: function(el) {
// w contains w.x and w.y
var w = window.getSize();
// if el is a string, make it an element
if ($type(el) == 'string') {
el = $(el);
}
// if el is all working
if (el) {
// get the sizes of it
var e = el.getSize();
// return the screen size minus the elements width / 2
return (w.x - e.x) / 2;
} else {
// just return the screen size / 2
return w.x / 2;
}
},
// appendQueryString
//
// returns the url with the extra query string correctly
// appended
//
appendQueryString: function(u) {
if (q = this.options.ajax.appendUrl) {
return (u.match(/\?/)) ? u + '&' + q : u + '?' + q;
} else {
return u;
}
},
// formToQueryString
//
// Ripped and modified from mooTools as form.toObject() was failing.
//
formToQueryString: function(form) {
var obj = {};
var inputs = form.getElementsByTagName('input');
var selects = form.getElementsByTagName('select');
var textareas = form.getElementsByTagName('textarea');
var els = [];
els[els.length] = inputs;
els[els.length] = selects;
els[els.length] = textareas;
for (var i = 0; i < els.length; i++) {
for (var j = 0; j < els[i].length; j++) {
var name = els[i][j].name;
var value = els[i][j].value;
if ((value !== false) && name) obj[name] = value;
}
}
var s = '';
$each(obj, function(value, name) {
s += name + '=' + value + '&';
});
return s;
}
});
Examples:
<?php
if (!empty($_POST)) {
sleep(5);
var_dump($_POST);
die();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>submitEvents</title>
<script src="/js/mootools1.2.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/submitEvent.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<form action="examples.php" method="post" onsubmit="return new submitEvent(this).process();">
<p>This form is using the default options</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.php" method="post" onsubmit="return new submitEvent(this, { ajax: { enabled: true, update: $('test1') }, undo: { timeOut: 3 } } ).process();">
<p>This form is using the default options with ajax (and a very low undo wait, to test the return to normality...)</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<div id="test1"></div>
<form action="examples.php" method="post" onsubmit="return new submitEvent(this, { confirmation: { enabled: true, text: 'Sure you\'re ready to submit?' } } ).process();">
<p>This form is using the default options with a confirmation dialog</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.php" method="post" onsubmit="return new submitEvent(this, { confirmation: { enabled: false }, ajax: { enabled: false }, informationDiv: { enabled: false } } ).process();">
<p>This form is only going to disable the submit button</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.php" method="post" id="totallyJavascriptForm">
<p>This form is using the default options, but specified directly, and the event is added via javascript</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<script type="text/javascript" charset="utf-8">
$('totallyJavascriptForm').addEvent('submit', function() {
return new submitEvent(this, {
confirmation: {
confirmation: {
enabled: false,
text: 'Are you sure?',
confirmed: false
},
submitButton: {
object: null,
disable: true,
changeText: true,
text: 'Please wait...'
},
informationDiv: {
enabled: true,
className: '',
centered: true,
text: 'Loading...',
inject: null,
injectTo: 'after'
},
undo: {
enabled: true,
timeOut: 30,
submitButton: {
enabled: true,
newText: 'Try Again'
},
informationDiv: {
enabled: true,
text: 'Sorry, there was a problem.',
className: ''
}
},
ajax: {
enabled: false,
udpate: null,
appendUrl: 'ajax=1'
}
}
}).process()
});
</script>
</body>
</html>
Revision: 7815
Updated Code
at August 14, 2008 09:37 by dom111
Updated Code
//
// submitEvent 0.1
// 14/08/2008
//
// A small class for easily implementing many submit events including
// displaying a confirmation dialog, disabling the submit button and
// displaying an informative div so that the users stay informed.
//
// Please see example.html for some examples
//
// All the options are detailed below, and the defaults can be easily
// changed to suit your needs.
//
// Requires mootools 1.2 (I don't think it'll work with lower) although
// I may also make a prototype/scriptaculous version if required.
//
// This software is released under the Creative Commons Share Alike
// license.
//
// Dom
//
// http://www.dom111.co.uk/
//
var submitEvent = new Class({
Implements: [Options],
// options
//
// the default options
// these can be overridden here if you use the same
// settings often, to save yourself time
//
options: {
// confirmation
//
// enabled: boolean
// text: text to display on said dialog box
// confirmed: used internally to make sure the
// confirmation isn't displayed again if there's a
// timeout
confirmation: {
enabled: false,
text: 'Are you sure?',
confirmed: false
},
// submitButton
//
// object: the object (or id as string) that is the
// primary submit button for f
// changeText: whether or not to change the button's
// text on submit
// newText: text to change the button to
//
submitButton: {
object: null,
disable: true,
changeText: true,
text: 'Please wait...'
},
// informationDiv
//
// display: whether or not to diplay an information
// div
// className: CSS class to apply to the div
// centered: whether to horizontally center the div
// (uses left: xxpx so class must add position absolute)
// text: text (or HTML to populate the div with
// inject: element to inject the div into (this.form
// is used if this is left as null/false)
// injectTo: position to inject element to eg. bottom,
// top, before, after defaults to after
//
informationDiv: {
enabled: true,
className: '',
centered: true,
text: 'Loading...',
inject: null,
injectTo: 'after'
},
//
// undo
// enabled: boolean
// timeout: in seconds to run specified undo tasks
//
// submitButton:
// enabled: re-enable the submit button
// newText: text to display on the newly enabled
// submit button
//
// informationDiv
// text: updated text to display
// className: updated CSS class to apply
undo: {
enabled: true,
timeOut: 30,
submitButton: {
enabled: true,
newText: 'Try Again'
},
informationDiv: {
enabled: true,
text: 'Sorry, there was a problem.',
className: ''
}
},
//
// ajax
//
// makes the form submission use ajax
//
// enabled: boolean
// update: the dom node, or a string id of the element
// to update, if not set, defaults to this.form
// appendUrl: a query string to append to the ajax request
// (could be used to surpress header/footer or just distinguish
// between ajax/normal requests)
//
ajax: {
enabled: false,
udpate: null,
appendUrl: 'ajax=1'
}
},
initialize: function(f, o) {
// if f is a string, look for that element id...
if ($type(f) == 'string') {
f = $(f);
}
// if f still isn't an object, give up...
if ($type(f) != 'object' && $type(f) != 'element') {
return true; // ... and submit the form, because we can't do anything...
}
// store the form object as this.form
this.form = f;
// save the old onsubmit function
this.preservedOnSubmit = this.form.onsubmit || function() {};
// merge the options...
this.setOptions(o || {});
if (!(this.options.submitButton.object)) {
this.options.submitButton.object = this.findSubmitButton(this.form);
if (!(this.options.submitButton.object.id)) {
this.options.submitButton.object.id = 'submitEventSubmitButton_' + new Date().getTime();
}
}
this.options.submitButton.oldText = this.options.submitButton.object.value;
this.informationDiv = false;
this.submitButtonFunctionTimeout = false;
this.informationDivFunctionTimeout = false;
},
// process
//
// do the magic!
process: function() {
// carry out functions in order:
//
// check for a confirmation message first, as if the user
// wants to cancel we could save ourselves some time
if ((this.options.confirmation.enabled) && !(this.options.confirmation.confirmed)) {
// if the text is blank or it's not a string
if (!(this.options.confirmation.text) || $type(this.options.confirmation.text) != 'string') {
// set it to some default text
this.options.confirmation.text = 'Are you sure?'
}
// set c to true/false from the user box
var c = confirm(this.options.confirmation.text);
// if it's true
if (c) {
// set the confirmed variable to true so the dialog isn't displayed again
this.options.confirmation.confirmed = true;
} else {
// else stop processing anything
return false;
}
}
// next, change the submit button if required
if ((this.options.submitButton.changeText) || (this.options.submitButton.disable)) {
// if the object, isn't an object, make it one
if ($type(this.options.submitButton.object) == 'string') {
this.options.submitButton.object = $(this.options.submitButton.object);
}
// create a variable for the button, of the object
var button = this.options.submitButton.object;
// make sure it's not null or false
if (button) {
// if we're supposed to change the text, do...
if (this.options.submitButton.changeText) {
button.value = this.options.submitButton.text || 'Please wait...';
}
// if we're supposed to disable it, do!
if (this.options.submitButton.disable) {
button.disabled = true;
}
}
}
// information div... display if required
if ((this.informationDiv) || (this.options.informationDiv.enabled)) {
if ((this.options.informationDiv.text) && $type(this.options.informationDiv.text) == 'string') {
// check the text is a string and nothing else
if (!this.informationDiv) {
// create a div element
this.informationDiv = new Element('div', {
'id': 'submitEventInformationDiv_' + new Date().getTime()
});
} else {
if (this.options.undo.informationDiv.className) {
this.informationDiv.removeClass(this.options.undo.informationDiv.className);
}
}
// set the innerHTML to the specified 'text', or default
this.informationDiv.set('html', this.options.informationDiv.text || 'Loading...');
// add the className if set
this.informationDiv.addClass(this.options.informationDiv.className || '')
// inject the element into the specified element, or this.form if not specified
this.informationDiv.inject(this.options.informationDiv.inject || this.form, this.options.informationDiv.injectTo || 'after');
if (this.options.informationDiv.centered) {
this.informationDiv.setStyle('left', this.getCenter(this.informationDiv) + 'px');
}
}
}
// undo, the best bit...
//
// if we can run undo tasks and at least one is enabled...
if (this.options.undo.enabled && (this.options.undo.submitButton.enabled || this.options.undo.informationDiv.enabled)) {
// set the timeout variable to seconds * 1000 (milliseconds)
var timeOut = (this.options.undo.timeOut || 30) * 1000;
// if we can run the undo on the button
if (this.options.undo.submitButton.enabled) {
// build the function to re-enable it and change the text
submitButtonFunction = function() {
var button = this.options.submitButton.object;
button.disabled = false;
button.value = this.options.undo.submitButton.newText || this.options.submitButton.oldText;
}
// use mootools timeout function, which allows this to be used
this.submitButtonFunctionTimeout = submitButtonFunction.delay(timeOut, this);
}
// if we can do the same magic with the information div...
if (this.options.undo.informationDiv.enabled) {
// build a function to change the text
informationDivFunction = function() {
if (this.options.undo.informationDiv.text) {
this.informationDiv.set('html', this.options.undo.informationDiv.text || 'Sorry, there was a problem.');
}
// and add the new class
if (this.options.undo.informationDiv.className) {
this.informationDiv.removeClass(this.options.informationDiv.className || '');
this.informationDiv.addClass(this.options.undo.informationDiv.className);
}
if (this.options.informationDiv.centered) {
this.informationDiv.set('styles', {
'left': this.getCenter(this.informationDiv) + 'px'
})
}
}
// another lovely timeout function
this.informationDivFunctionTimeout = informationDivFunction.delay(timeOut, this);
}
}
// if we're ajaxing it up...
if (this.options.ajax.enabled) {
// quick dirty fix to return all states to normality after AJAX send...
window.submitEventsData = this;
// create a mootools request object
this.ajaxRequest = new Request.HTML({
// populate it with all the details from the HTML form
method: this.form.method,
url: this.appendQueryString(this.form.action),
// data: this.form.toQueryString(), // fails in IE 6?
data: window.formToQueryString(this.form),
update: this.options.ajax.update || this.form,
// add an oncomplete function to remove the additions
onComplete: function() {
$clear(window.submitEventsData.submitButtonFunctionTimeout);
$clear(window.submitEventsData.informationDivFunctionTimeout);
if ($(window.submitEventsData.informationDiv.id)) {
$(window.submitEventsData.informationDiv.id).destroy();
}
if ($(window.submitEventsData.options.submitButton.object.id)) {
$(window.submitEventsData.options.submitButton.object.id).value = window.submitEventsData.options.submitButton.oldText;
$(window.submitEventsData.options.submitButton.object.id).disabled = false;
}
window.submitEventsData = null;
}
}).send();
return false;
} else {
return true; // post the form
}
},
// findSubmitButton
//
// returns the first submit button on a form
//
findSubmitButton: function(f) {
// if f fails use document
f = f || document;
// loop through all input elements in f
var i = f.getElementsByTagName('input');
for (var x = i.length - 1; x >= 0; x--) {
if (i[x].type == 'submit' || i[x].type == 'image') {
return i[x];
}
}
// loop through all button elements in f
var i = f.getElementsByTagName('button');
for (var x = i.length - 1; x >= 0; x--) {
if (i[x].type == 'submit') {
return i[x];
}
}
// we didn't find anything, so return null
return null;
},
// getCenter
//
// returns the width of the screen / 2 or the width
// of the screen - el.width / 2 for centering elements
//
getCenter: function(el) {
// w contains w.x and w.y
var w = window.getSize();
// if el is a string, make it an element
if ($type(el) == 'string') {
el = $(el);
}
// if el is all working
if (el) {
// get the sizes of it
var e = el.getSize();
// return the screen size minus the elements width / 2
return (w.x - e.x) / 2;
} else {
// just return the screen size / 2
return w.x / 2;
}
},
// appendQueryString
//
// returns the url with the extra query string correctly
// appended
//
appendQueryString: function(u) {
if (q = this.options.ajax.appendUrl) {
return (u.match(/\?/)) ? u + '&' + q : u + '?' + q;
} else {
return u;
}
}
});
// formToQueryString
//
// Ripped and modified from mooTools as form.toObject() was failing.
//
window.formToQueryString = function(form) {
var obj = {};
var inputs = form.getElementsByTagName('input');
var selects = form.getElementsByTagName('select');
var textareas = form.getElementsByTagName('textarea');
var els = [];
els[els.length] = inputs;
els[els.length] = selects;
els[els.length] = textareas;
for (var i = 0; i < els.length; i++) {
for (var j = 0; j < els[i].length; j++) {
var name = els[i][j].name;
var value = els[i][j].value;
if ((value !== false) && name) obj[name] = value;
}
}
var s = '';
$each(obj, function(value, name) {
s += name + '=' + value + '&';
});
return s;
}
Examples:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>submitEvents</title>
<script src="/js/mootools1.2.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/submitEvent.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<form action="examples.html" method="post" onsubmit="return new submitEvent(this).process();">
<p>This form is using the default options</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.html" method="post" onsubmit="return new submitEvent(this, { ajax: { enabled: true, update: $('test1') } } ).process();">
<p>This form is using the default options with ajax</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<div id="test1"></div>
<form action="examples.html" method="post" onsubmit="return new submitEvent(this, { confirmation: { enabled: true, text: 'Sure you\'re ready to submit?' } } ).process();">
<p>This form is using the default options with a confirmation dialog</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.html" method="post" onsubmit="return new submitEvent(this, { confirmation: { enabled: false }, ajax: { enabled: false }, informationDiv: { enabled: false } } ).process();">
<p>This form is only going to disable the submit button</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.html" method="post" id="totallyJavascriptForm">
<p>This form is using the default options, but specified directly, and the form is added via javascript</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<script type="text/javascript" charset="utf-8">
$('totallyJavascriptForm').addEvent('submit', function() {
return new submitEvent(this, {
confirmation: {
confirmation: {
enabled: false,
text: 'Are you sure?',
confirmed: false
},
submitButton: {
object: null,
disable: true,
changeText: true,
text: 'Please wait...'
},
informationDiv: {
enabled: true,
className: '',
centered: true,
text: 'Loading...',
inject: null,
injectTo: 'after'
},
undo: {
enabled: true,
timeOut: 30,
submitButton: {
enabled: true,
newText: 'Try Again'
},
informationDiv: {
enabled: true,
text: 'Sorry, there was a problem.',
className: ''
}
},
ajax: {
enabled: false,
udpate: null,
appendUrl: 'ajax=1'
}
}
}).process()
});
</script>
</body>
</html>
Revision: 7814
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at August 13, 2008 21:10 by dom111
Initial Code
//
// submitEvent 0.1
// 14/08/2008
//
// A small class for easily implementing many submit events including
// displaying a confirmation dialog, disabling the submit button and
// displaying an informative div so that the users stay informed.
//
// Please see example.html for some examples
//
// All the options are detailed below, and the defaults can be easily
// changed to suit your needs.
//
// Requires mootools 1.2 (I don't think it'll work with lower) although
// I may also make a prototype/scriptaculous version if required.
//
// This software is released under the Creative Commons Share Alike
// license.
//
// Dom
//
// http://www.dom111.co.uk/
//
var submitEvent = new Class({
Implements: [Options],
// options
//
// the default options
// these can be overridden here if you use the same
// settings often, to save yourself time
//
options: {
// confirmation
//
// enabled: boolean
// text: text to display on said dialog box
// confirmed: used internally to make sure the
// confirmation isn't displayed again if there's a
// timeout
confirmation: {
enabled: false,
text: 'Are you sure?',
confirmed: false
},
// submitButton
//
// object: the object (or id as string) that is the
// primary submit button for f
// changeText: whether or not to change the button's
// text on submit
// newText: text to change the button to
//
submitButton: {
object: null,
disable: true,
changeText: true,
text: 'Please wait...'
},
// informationDiv
//
// display: whether or not to diplay an information
// div
// className: CSS class to apply to the div
// centered: whether to horizontally center the div
// (uses left: xxpx so class must add position absolute)
// text: text (or HTML to populate the div with
// inject: element to inject the div into (this.form
// is used if this is left as null/false)
// injectTo: position to inject element to eg. bottom,
// top, before, after defaults to after
//
informationDiv: {
enabled: true,
className: '',
centered: true,
text: 'Loading...',
inject: null,
injectTo: 'after'
},
//
// undo
// enabled: boolean
// timeout: in seconds to run specified undo tasks
//
// submitButton:
// enabled: re-enable the submit button
// newText: text to display on the newly enabled
// submit button
//
// informationDiv
// text: updated text to display
// className: updated CSS class to apply
undo: {
enabled: true,
timeOut: 30,
submitButton: {
enabled: true,
newText: 'Try Again'
},
informationDiv: {
enabled: true,
text: 'Sorry, there was a problem.',
className: ''
}
},
//
// ajax
//
// makes the form submission use ajax
//
// enabled: boolean
// update: the dom node, or a string id of the element
// to update, if not set, defaults to this.form
// appendUrl: a query string to append to the ajax request
// (could be used to surpress header/footer or just distinguish
// between ajax/normal requests)
//
ajax: {
enabled: false,
udpate: null,
appendUrl: 'ajax=1'
}
},
initialize: function(f, o) {
// if f is a string, look for that element id...
if ($type(f) == 'string') {
f = $(f);
}
// if f still isn't an object, give up...
if ($type(f) != 'object' && $type(f) != 'element') {
return true; // ... and submit the form, because we can't do anything...
}
// store the form object as this.form
this.form = f;
// save the old onsubmit function
this.preservedOnSubmit = this.form.onsubmit || function() {};
// merge the options...
this.setOptions(o || {});
if (!(this.options.submitButton.object)) {
this.options.submitButton.object = this.findSubmitButton(this.form);
if (!(this.options.submitButton.object.id)) {
this.options.submitButton.object.id = 'submitEventSubmitButton_' + new Date().getTime();
}
}
this.options.submitButton.oldText = this.options.submitButton.object.value;
this.informationDiv = false;
this.submitButtonFunctionTimeout = false;
this.informationDivFunctionTimeout = false;
},
// process
//
// do the magic!
process: function() {
// carry out functions in order:
//
// check for a confirmation message first, as if the user
// wants to cancel we could save ourselves some time
if ((this.options.confirmation.enabled) && !(this.options.confirmation.confirmed)) {
// if the text is blank or it's not a string
if (!(this.options.confirmation.text) || $type(this.options.confirmation.text) != 'string') {
// set it to some default text
this.options.confirmation.text = 'Are you sure?'
}
// set c to true/false from the user box
var c = confirm(this.options.confirmation.text);
// if it's true
if (c) {
// set the confirmed variable to true so the dialog isn't displayed again
this.options.confirmation.confirmed = true;
} else {
// else stop processing anything
return false;
}
}
// next, change the submit button if required
if ((this.options.submitButton.changeText) || (this.options.submitButton.disable)) {
// if the object, isn't an object, make it one
if ($type(this.options.submitButton.object) == 'string') {
this.options.submitButton.object = $(this.options.submitButton.object);
}
// create a variable for the button, of the object
var button = this.options.submitButton.object;
// make sure it's not null or false
if (button) {
// if we're supposed to change the text, do...
if (this.options.submitButton.changeText) {
button.value = this.options.submitButton.text || 'Please wait...';
}
// if we're supposed to disable it, do!
if (this.options.submitButton.disable) {
button.disabled = true;
}
}
}
// information div... display if required
if ((this.informationDiv) || (this.options.informationDiv.enabled)) {
if ((this.options.informationDiv.text) && $type(this.options.informationDiv.text) == 'string') {
// check the text is a string and nothing else
if (!this.informationDiv) {
// create a div element
this.informationDiv = new Element('div', {
'id': 'submitEventInformationDiv_' + new Date().getTime()
});
} else {
if (this.options.undo.informationDiv.className) {
this.informationDiv.removeClass(this.options.undo.informationDiv.className);
}
}
// set the innerHTML to the specified 'text', or default
this.informationDiv.set('html', this.options.informationDiv.text || 'Loading...');
// add the className if set
this.informationDiv.addClass(this.options.informationDiv.className || '')
// inject the element into the specified element, or this.form if not specified
this.informationDiv.inject(this.options.informationDiv.inject || this.form, this.options.informationDiv.injectTo || 'after');
if (this.options.informationDiv.centered) {
this.informationDiv.setStyle('left', this.getCenter(this.informationDiv) + 'px');
}
}
}
// undo, the best bit...
//
// if we can run undo tasks and at least one is enabled...
if (this.options.undo.enabled && (this.options.undo.submitButton.enabled || this.options.undo.informationDiv.enabled)) {
// set the timeout variable to seconds * 1000 (milliseconds)
var timeOut = (this.options.undo.timeOut || 30) * 1000;
// if we can run the undo on the button
if (this.options.undo.submitButton.enabled) {
// build the function to re-enable it and change the text
submitButtonFunction = function() {
var button = this.options.submitButton.object;
button.disabled = false;
button.value = this.options.undo.submitButton.newText || this.options.submitButton.oldText;
}
// use mootools timeout function, which allows this to be used
this.submitButtonFunctionTimeout = submitButtonFunction.delay(timeOut, this);
}
// if we can do the same magic with the information div...
if (this.options.undo.informationDiv.enabled) {
// build a function to change the text
informationDivFunction = function() {
if (this.options.undo.informationDiv.text) {
this.informationDiv.set('html', this.options.undo.informationDiv.text || 'Sorry, there was a problem.');
}
// and add the new class
if (this.options.undo.informationDiv.className) {
this.informationDiv.removeClass(this.options.informationDiv.className || '');
this.informationDiv.addClass(this.options.undo.informationDiv.className);
}
if (this.options.informationDiv.centered) {
this.informationDiv.set('styles', {
'left': this.getCenter(this.informationDiv) + 'px'
})
}
}
// another lovely timeout function
this.informationDivFunctionTimeout = informationDivFunction.delay(timeOut, this);
}
}
// if we're ajaxing it up...
if (this.options.ajax.enabled) {
// quick dirty fix to return all states to normality after AJAX send...
var restore = eval('function() { $clear(' + this.submitButtonFunctionTimeout + '); $clear(' + this.informationDivFunctionTimeout + '); if ($(\'' + this.informationDiv.id + '\')) { $(\'' + this.informationDiv.id + '\').destroy(); } if ($(\'' + this.options.submitButton.object.id + '\')) { $(\'' + this.options.submitButton.object.id + '\').value = \'' + this.options.submitButton.oldText + '\'; $(\'' + this.options.submitButton.object.id + '\').disabled = false; } }');
// create a mootools request object
this.ajaxRequest = new Request.HTML({
// populate it with all the details from the HTML form
method: this.form.method,
url: this.appendQueryString(this.form.action),
data: this.form.toQueryString(),
update: this.options.ajax.update || this.form,
// add an oncomplete function to remove the additions
onComplete: function() {
restore();
}
}).send();
return false;
} else {
return true; // post the form
}
},
// findSubmitButton
//
// returns the first submit button on a form
//
findSubmitButton: function(f) {
// if f fails use document
f = f || document;
// loop through all input elements in f
var i = f.getElementsByTagName('input');
for (var x = i.length - 1; x >= 0; x--) {
if (i[x].type == 'submit' || i[x].type == 'image') {
return i[x];
}
}
// loop through all button elements in f
var i = f.getElementsByTagName('button');
for (var x = i.length - 1; x >= 0; x--) {
if (i[x].type == 'submit') {
return i[x];
}
}
// we didn't find anything, so return null
return null;
},
// getCenter
//
// returns the width of the screen / 2 or the width
// of the screen - el.width / 2 for centering elements
//
getCenter: function(el) {
// w contains w.x and w.y
var w = window.getSize();
// if el is a string, make it an element
if ($type(el) == 'string') {
el = $(el);
}
// if el is all working
if (el) {
// get the sizes of it
var e = el.getSize();
// return the screen size minus the elements width / 2
return (w.x - e.x) / 2;
} else {
// just return the screen size / 2
return w.x / 2;
}
},
// appendQueryString
//
// returns the url with the extra query string correctly
// appended
//
appendQueryString: function(u) {
if (q = this.options.ajax.appendUrl) {
return (u.match(/\?/)) ? u + '&' + q : u + '?' + q;
} else {
return u;
}
}
});
Examples:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>submitEvents</title>
<script src="/js/mootools1.2.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/submitEvent.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="/css/style.css" type="text/css"/>
</head>
<body>
<form action="examples.html" method="post" onsubmit="return new submitEvent(this).process();">
<p>This form is using the default options</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.html" method="post" onsubmit="return new submitEvent(this, { ajax: { enabled: true, update: $('test') } } ).process();">
<p>This form is using the default options with ajax</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<div id="test1"></div>
<form action="examples.html" method="post" onsubmit="return new submitEvent(this, { confirmation: { enabled: true, text: 'Sure you\'re ready to submit?' } } ).process();">
<p>This form is using the default options with a confirmation dialog</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.html" method="post" onsubmit="return new submitEvent(this, { confirmation: { enabled: false }, ajax: { enabled: false }, informationDiv: { enabled: false } } ).process();">
<p>This form is only going to disable the submit button</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<form action="examples.html" method="post" id="totallyJavascriptForm">
<p>This form is using the default options, but specified directly, and the form is added via javascript</p>
<p><input type="text" name="name" value="" id="name"/></p>
<p><input type="text" name="email" value="" id="email"/></p>
<p><input type="submit" name="submitButton" value="Submit"/></p>
</form>
<script type="text/javascript" charset="utf-8">
$('totallyJavascriptForm').addEvent('submit', function() {
return new submitEvent(this, {
confirmation: {
confirmation: {
enabled: false,
text: 'Are you sure?',
confirmed: false
},
submitButton: {
object: null,
disable: true,
changeText: true,
text: 'Please wait...'
},
informationDiv: {
enabled: true,
className: '',
centered: true,
text: 'Loading...',
inject: null,
injectTo: 'after'
},
undo: {
enabled: true,
timeOut: 30,
submitButton: {
enabled: true,
newText: 'Try Again'
},
informationDiv: {
enabled: true,
text: 'Sorry, there was a problem.',
className: ''
}
},
ajax: {
enabled: false,
udpate: null,
appendUrl: 'ajax=1'
}
}
}).process()
});
</script>
</body>
</html>
Initial URL
http://www.dom111.co.uk/blog/coding/submitevents-javascript-form-submission-handler/20
Initial Description
Requires Mootools 1.2<br/> http://mootools.net/download Based on the mootools javascript framework a re-usable class for easily implementing an array of on submit events. * Confirmation - Provides an Ok, Cancel input box before proceeding further * Submit Button - Disable and change the text on a submit button * Information Div - Display a div that lets the user know something is happening * Undo - Undo the changes (re-enable a previously disabled submit button, change the information div) that have been carried out by the class * AJAX - Submit the form using AJAX instead of the ‘old fashioned’ way This work is released under the creative commons share alike license. Requires Mootools 1.2<br/> http://mootools.net/download
Initial Title
submitEvents - Javascript form submission handler
Initial Tags
form, ajax, javascript, forms
Initial Language
JavaScript