/*
* jQuery form plugin
* @requires jQuery v1.0.3
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id$
* Version: 0.9
*/
/**
* ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
*
* ajaxSubmit accepts a single argument which can be either a success callback function
* or an options Object. If a function is provided it will be invoked upon successful
* completion of the submit and will be passed the response from the server.
* If an options Object is provided, the following attributes are supported:
*
* target: Identifies the element(s) in the page to be updated with the server response.
* This value may be specified as a jQuery selection string, a jQuery object,
* or a DOM element.
* default value: null
*
* url: URL to which the form data will be submitted.
* default value: value of form's 'action' attribute
*
* method: @deprecated use 'type'
* type: The method in which the form data should be submitted, 'GET' or 'POST'.
* default value: value of form's 'method' attribute (or 'GET' if none found)
*
* before: @deprecated use 'beforeSubmit'
* beforeSubmit: Callback method to be invoked before the form is submitted.
* default value: null
*
* after: @deprecated use 'success'
* success: Callback method to be invoked after the form has been successfully submitted
* and the response has been returned from the server
* default value: null
*
* dataType: Expected dataType of the response. One of: null, 'xml', 'script', or 'json'
* default value: null
*
* semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
* default value: false
*
* resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
*
* clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
*
*
* The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
* validating the form data. If the 'beforeSubmit' callback returns false then the form will
* not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
* in array format, the jQuery object, and the options object passed into ajaxSubmit.
* The form data array takes the following form:
*
* [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
*
* If a 'success' callback method is provided it is invoked after the response has been returned
* from the server. It is passed the responseText or responseXML value (depending on dataType).
* See jQuery.ajax for further details.
*
*
* The dataType option provides a means for specifying how the server response should be handled.
* This maps directly to the jQuery.httpData method. The following values are supported:
*
* 'xml': if dataType == 'xml' the server response is treated as XML and the 'after'
* callback method, if specified, will be passed the responseXML value
* 'json': if dataType == 'json' the server response will be evaluted and passed to
* the 'after' callback, if specified
* 'script': if dataType == 'script' the server response is evaluated in the global context
*
*
* Note that it does not make sense to use both the 'target' and 'dataType' options. If both
* are provided the target will be ignored.
*
* The semantic argument can be used to force form serialization in semantic order.
* This is normally true anyway, unless the form contains input elements of type='image'.
* If your form must be submitted with name/value pairs in semantic order and your form
* contains an input of type='image" then pass true for this arg, otherwise pass false
* (or nothing) to avoid the overhead for this logic.
*
*
* When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
*
* $("#form-id").submit(function() {
* $(this).ajaxSubmit(options);
* return false; // cancel conventional submit
* });
*
* When using ajaxForm(), however, this is done for you.
*
* @example
* $('#myForm').ajaxSubmit(function(data) {
* alert('Form submit succeeded! Server returned: ' + data);
* });
* @desc Submit form and alert server response
*
*
* @example
* var options = {
* target: '#myTargetDiv'
* };
* $('#myForm').ajaxSubmit(options);
* @desc Submit form and update page element with server response
*
*
* @example
* var options = {
* success: function(responseText) {
* alert(responseText);
* }
* };
* $('#myForm').ajaxSubmit(options);
* @desc Submit form and alert the server response
*
*
* @example
* var options = {
* beforeSubmit: function(formArray, jqForm) {
* if (formArray.length == 0) {
* alert('Please enter data.');
* return false;
* }
* }
* };
* $('#myForm').ajaxSubmit(options);
* @desc Pre-submit validation which aborts the submit operation if form data is empty
*
*
* @example
* var options = {
* url: myJsonUrl.php,
* dataType: 'json',
* success: function(data) {
* // 'data' is an object representing the the evaluated json data
* }
* };
* $('#myForm').ajaxSubmit(options);
* @desc json data returned and evaluated
*
*
* @example
* var options = {
* url: myXmlUrl.php,
* dataType: 'xml',
* success: function(responseXML) {
* // responseXML is XML document object
* var data = $('myElement', responseXML).text();
* }
* };
* $('#myForm').ajaxSubmit(options);
* @desc XML data returned from server
*
*
* @example
* var options = {
* resetForm: true
* };
* $('#myForm').ajaxSubmit(options);
* @desc submit form and reset it if successful
*
* @example
* $('#myForm).submit(function() {
* $(this).ajaxSubmit();
* return false;
* });
* @desc Bind form's submit event to use ajaxSubmit
*
*
* @name ajaxSubmit
* @type jQuery
* @param options object literal containing options which control the form submission process
* @cat Plugins/Form
* @return jQuery
* @see formToArray
* @see ajaxForm
* @see $.ajax
* @author jQuery Community
*/
jQuery.fn.ajaxSubmit = function(options) {
if (typeof options == 'function')
options = { success: options };
options = jQuery.extend({
url: this.attr('action') || '',
method: this.attr('method') || 'GET'
}, options || {});
// remap deprecated options (temporarily)
options.success = options.success || options.after;
options.beforeSubmit = options.beforeSubmit || options.before;
options.type = options.type || options.method;
var a = this.formToArray(options.semantic);
// give pre-submit callback an opportunity to abort the submit
if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;
var q = jQuery.param(a);
if (options.type.toUpperCase() == 'GET') {
// if url already has a '?' then append args after '&'
options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
options.data = null; // data is null for 'get'
}
else
options.data = q; // data is the query string for 'post'
var $form = this, callbacks = [];
if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
// perform a load on the target only if dataType is not provided
if (!options.dataType && options.target) {
var oldSuccess = options.success || function(){};
callbacks.push(function(data, status) {
jQuery(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, [data, status]);
});
}
else if (options.success)
callbacks.push(options.success);
options.success = function(data, status) {
for (var i=0, max=callbacks.length; i < max; i++)
callbacks[i](data, status);
};
jQuery.ajax(options);
return this;
};
/**
* ajaxForm() provides a mechanism for fully automating form submission.
*
* The advantages of using this method instead of ajaxSubmit() are:
*
* 1: This method will include coordinates for elements (if the element
* is used to submit the form).
* 2. This method will include the submit element's name/value data (for the element that was
* used to submit the form).
* 3. This method binds the submit() method to the form for you.
*
* Note that for accurate x/y coordinates of image submit elements in all browsers
* you need to also use the "dimensions" plugin (this method will auto-detect its presence).
*
* The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
* passes the options argument along after properly binding events for submit elements and
* the form itself. See ajaxSubmit for a full description of the options argument.
*
*
* @example
* var options = {
* target: '#myTargetDiv'
* };
* $('#myForm').ajaxSForm(options);
* @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
* when the form is submitted.
*
*
* @example
* var options = {
* success: function(responseText) {
* alert(responseText);
* }
* };
* $('#myForm').ajaxSubmit(options);
* @desc Bind form's submit event so that server response is alerted after the form is submitted.
*
*
* @example
* var options = {
* beforeSubmit: function(formArray, jqForm) {
* if (formArray.length == 0) {
* alert('Please enter data.');
* return false;
* }
* }
* };
* $('#myForm').ajaxSubmit(options);
* @desc Bind form's submit event so that pre-submit callback is invoked before the form
* is submitted.
*
*
* @name ajaxForm
* @param options object literal containing options which control the form submission process
* @return jQuery
* @cat Plugins/Form
* @type jQuery
* @see ajaxSubmit
* @author jQuery Community
*/
jQuery.fn.ajaxForm = function(options) {
return this.each(function() {
jQuery("input:submit,input:image,button:submit", this).click(function(ev) {
var $form = this.form;
$form.clk = this;
if (this.type == 'image') {
if (ev.offsetX != undefined) {
$form.clk_x = ev.offsetX;
$form.clk_y = ev.offsetY;
} else if (typeof jQuery.fn.offset == 'function') { // try to use dimensions plugin
var offset = jQuery(this).offset();
$form.clk_x = ev.pageX - offset.left;
$form.clk_y = ev.pageY - offset.top;
} else {
$form.clk_x = ev.pageX - this.offsetLeft;
$form.clk_y = ev.pageY - this.offsetTop;
}
}
// clear form vars
setTimeout(function() {
$form.clk = $form.clk_x = $form.clk_y = null;
}, 10);
})
}).submit(function(e) {
jQuery(this).ajaxSubmit(options);
return false;
});
};
/**
* formToArray() gathers form element data into an array of objects that can
* be passed to any of the following ajax functions: $.get, $.post, or load.
* Each object in the array has both a 'name' and 'value' property. An example of
* an array for a simple login form might be:
*
* [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
*
* It is this array that is passed to pre-submit callback functions provided to the
* ajaxSubmit() and ajaxForm() methods.
*
* The semantic argument can be used to force form serialization in semantic order.
* This is normally true anyway, unless the form contains input elements of type='image'.
* If your form must be submitted with name/value pairs in semantic order and your form
* contains an input of type='image" then pass true for this arg, otherwise pass false
* (or nothing) to avoid the overhead for this logic.
*
* @example var data = $("#myForm").formToArray();
* $.post( "myscript.cgi", data );
* @desc Collect all the data from a form and submit it to the server.
*
* @name formToArray
* @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
* @type Array