? drupal_ahah2.patch
? misc/jquery113.js
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.214
diff -u -p -r1.214 form.inc
--- includes/form.inc 4 Jul 2007 15:45:37 -0000 1.214
+++ includes/form.inc 8 Jul 2007 20:57:41 -0000
@@ -1469,15 +1469,16 @@ function form_expand_ahah($element) {
// Adding the same javascript settings twice will cause a recursion error,
// we avoid the problem by checking if the javascript has already been added.
if (!isset($js_added[$element['#id']]) && isset($element['#ahah_event']) && isset($element['#ahah_path'])) {
+ drupal_add_js('misc/jquery.form.js');
drupal_add_js('misc/ahah.js');
drupal_add_js('misc/progress.js');
$ahah_binding = array(
- 'id' => $element['#id'],
- 'uri' => url($element['#ahah_path']),
+ 'uri' => url($element['#ahah_path']),
'event' => $element['#ahah_event'],
- 'effect' => empty($element['#ahah_effect']) ? 'none' : $element['#ahah_effect'],
- 'method' => empty($element['#ahah_method']) ? 'replace' : $element['#ahah_method'],
+ 'selector' => empty($element['#ahah_selector']) ? '#'. $element['#id'] : $element['#ahah_selector'],
+ 'effect' => empty($element['#ahah_effect']) ? 'none' : $element['#ahah_effect'],
+ 'method' => empty($element['#ahah_method']) ? 'replace' : $element['#ahah_method'],
);
if (!empty($element['#ahah_wrapper'])) {
Index: misc/ahah.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/ahah.js,v
retrieving revision 1.1
diff -u -p -r1.1 ahah.js
--- misc/ahah.js 4 Jul 2007 15:42:38 -0000 1.1
+++ misc/ahah.js 8 Jul 2007 20:57:41 -0000
@@ -31,6 +31,7 @@ Drupal.behaviors.ahah = function(context
Drupal.ahah = function(base, element) {
// Set the properties for this object.
this.id = '#' + base;
+ this.selector = element.selector;
this.event = element.event;
this.uri = element.uri;
this.wrapper = '#'+ element.wrapper;
@@ -39,47 +40,73 @@ Drupal.ahah = function(base, element) {
if (this.effect == 'none') {
this.showEffect = 'show';
this.hideEffect = 'hide';
+ this.showSpeed = '';
}
else if (this.effect == 'fade') {
this.showEffect = 'fadeIn';
this.hideEffect = 'fadeOut';
+ this.showSpeed = 'slow';
}
else {
this.showEffect = this.effect + 'Toggle';
this.hideEffect = this.effect + 'Toggle';
+ this.showSpeed = 'slow';
}
- Drupal.redirectFormButton(this.uri, $(this.id).get(0), this);
+
+ // Set the options for the ajaxSubmit function.
+ // The 'this' variable will not persist inside of the options object.
+ var ahah = this;
+ var options = {
+ url: ahah.uri,
+ beforeSubmit: function(form_values, element, options) {
+ return ahah.onsubmit(form_values, element, options);
+ },
+ success: function(response, status) {
+ return ahah.oncomplete(response, status);
+ },
+ complete: function(response, status) {
+ if (status == 'error') {
+ return ahah.onerror(response.responseText);
+ }
+ },
+ dataType: 'json',
+ type: 'POST'
+ };
+
+ // Bind the ajaxSubmit function to the element event.
+ $(ahah.selector).bind(ahah.event, function() {
+ options.element = this;
+ $(ahah.id).parents('form').ajaxSubmit(options);
+ return false;
+ });
+
};
/**
* Handler for the form redirection submission.
*/
-Drupal.ahah.prototype.onsubmit = function () {
+Drupal.ahah.prototype.onsubmit = function (form_values, element, options) {
// Insert progressbar and stretch to take the same space.
this.progress = new Drupal.progressBar('ahah_progress');
this.progress.setProgress(-1, Drupal.t('Please wait...'));
var wrapper = $(this.wrapper);
- var button = $(this.id);
+ var element = $(options.element);
var progress_element = $(this.progress.element);
- progress_element.css('float', 'left').css({
- display: 'none',
- width: '10em',
- margin: '0 0 0 20px'
- });
- button.css('float', 'left').attr('disabled', true).after(progress_element);
- eval('progress_element.' + this.showEffect + '()');
+ progress_element.css('float', 'left').css('display', 'none');
+ element.css('float', 'left').attr('disabled', true).after(progress_element);
+ progress_element.show();
};
/**
* Handler for the form redirection completion.
*/
-Drupal.ahah.prototype.oncomplete = function (data) {
+Drupal.ahah.prototype.oncomplete = function (response, status) {
var wrapper = $(this.wrapper);
var button = $(this.id);
var progress_element = $(this.progress.element);
- var new_content = $('
' + data + '
');
+ var new_content = $('
' + response.data + '
');
Drupal.freezeHeight();
@@ -89,14 +116,24 @@ Drupal.ahah.prototype.oncomplete = funct
// Hide the new content before adding to page.
new_content.hide();
- // Add the form and re-attach behavior.
+ // Add the new content to the page.
if (this.method == 'replace') {
wrapper.empty().append(new_content);
}
else {
eval('wrapper.' + this.method + '(new_content)');
}
- eval('new_content.' + this.showEffect + '()');
+
+ // Determine what effect use and what content will receive the effect,
+ // then show the new content.
+ if ($('.ahah-new-content', new_content).size() > 0) {
+ $('.ahah-new-content', new_content).hide();
+ new_content.show();
+ eval('$(".ahah-new-content", new_content).' + this.showEffect + '("' + this.showSpeed +'")');
+ }
+ else {
+ eval('new_content.' + this.showEffect + '("' + this.showSpeed +'")');
+ }
button.css('float', 'none').attr('disabled', false);
Drupal.attachBehaviors(new_content);
Index: misc/drupal.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/drupal.js,v
retrieving revision 1.35
diff -u -p -r1.35 drupal.js
--- misc/drupal.js 1 Jul 2007 15:37:08 -0000 1.35
+++ misc/drupal.js 8 Jul 2007 20:57:42 -0000
@@ -195,69 +195,6 @@ Drupal.theme = function(func) {
};
/**
- * Redirects a button's form submission to a hidden iframe and displays the result
- * in a given wrapper. The iframe should contain a call to
- * window.parent.iframeHandler() after submission.
- */
-Drupal.redirectFormButton = function (uri, button, handler) {
- // Trap the button
- button.onmouseover = button.onfocus = function() {
- button.onclick = function() {
- // Create target iframe
- Drupal.createIframe();
-
- // Prepare variables for use in anonymous function.
- var button = this;
- var action = button.form.action;
- var target = button.form.target;
-
- // Redirect form submission to iframe
- this.form.action = uri;
- this.form.target = 'redirect-target';
-
- handler.onsubmit();
-
- // Set iframe handler for later
- window.iframeHandler = function () {
- var iframe = $('#redirect-target').get(0);
- // Restore form submission
- button.form.action = action;
- button.form.target = target;
-
- // Get response from iframe body
- try {
- response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML;
- // Firefox 1.0.x hack: Remove (corrupted) control characters
- response = response.replace(/[\f\n\r\t]/g, ' ');
- if (window.opera) {
- // Opera-hack: it returns innerHTML sanitized.
- response = response.replace(/"/g, '"');
- }
- }
- catch (e) {
- response = null;
- }
-
- response = Drupal.parseJson(response);
- // Check response code
- if (response.status == 0) {
- handler.onerror(response.data);
- return;
- }
- handler.oncomplete(response.data);
-
- return true;
- };
-
- return true;
- };
- };
- button.onmouseout = button.onblur = function() {
- button.onclick = null;
- };
-};
-
-/**
* Retrieves the absolute position of an element on the screen
*/
Drupal.absolutePosition = function (el) {
@@ -305,41 +242,6 @@ Drupal.parseJson = function (data) {
};
/**
- * Create an invisible iframe for form submissions.
- */
-Drupal.createIframe = function () {
- if ($('#redirect-holder').size()) {
- return;
- }
- // Note: some browsers require the literal name/id attributes on the tag,
- // some want them set through JS. We do both.
- window.iframeHandler = function () {};
- var div = document.createElement('div');
- div.id = 'redirect-holder';
- $(div).html('');
- var iframe = div.firstChild;
- $(iframe)
- .attr({
- name: 'redirect-target',
- id: 'redirect-target'
- })
- .css({
- position: 'absolute',
- height: '1px',
- width: '1px',
- visibility: 'hidden'
- });
- $('body').append(div);
-};
-
-/**
- * Delete the invisible iframe
- */
-Drupal.deleteIframe = function () {
- $('#redirect-holder').remove();
-};
-
-/**
* Freeze the current body height (as minimum height). Used to prevent
* unnecessary upwards scrolling when doing DOM manipulations.
*/
Index: misc/jquery.form.js
===================================================================
RCS file: misc/jquery.form.js
diff -N misc/jquery.form.js
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ misc/jquery.form.js 8 Jul 2007 20:57:42 -0000
@@ -0,0 +1,804 @@
+/*
+ * jQuery form plugin
+ * @requires jQuery v1.1 or later
+ *
+ * Examples at: http://malsup.com/jquery/form/
+ * 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: 1.0 Jul-04-2007
+ */
+ (function($) {
+/**
+ * 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
+ *
+ * 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)
+ *
+ * beforeSubmit: Callback method to be invoked before the form is submitted.
+ * default value: null
+ *
+ * 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
+ */
+$.fn.ajaxSubmit = function(options) {
+ if (typeof options == 'function')
+ options = { success: options };
+
+ options = $.extend({
+ url: this.attr('action') || window.location,
+ type: this.attr('method') || 'GET'
+ }, options || {});
+
+ 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;
+
+ // fire vetoable 'validate' event
+ var veto = {};
+ $.event.trigger('form.submit.validate', [a, this, options, veto]);
+ if (veto.veto)
+ return this;
+
+ var q = $.param(a);//.replace(/%20/g,'+');
+
+ if (options.type.toUpperCase() == 'GET') {
+ 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) {
+ $(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);
+ };
+
+ // are there files to upload?
+ var files = $('input:file', this).fieldValue();
+ var found = false;
+ for (var j=0; j < files.length; j++)
+ if (files[j])
+ found = true;
+
+ if (options.iframe || found) // options.iframe allows user to force iframe mode
+ fileUpload();
+ else
+ $.ajax(options);
+
+ // fire 'notify' event
+ $.event.trigger('form.submit.notify', [this, options]);
+ return this;
+
+
+ // private function for handling file uploads (hat tip to YAHOO!)
+ function fileUpload() {
+ var form = $form[0];
+ var opts = $.extend({}, $.ajaxSettings, options);
+
+ var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++;
+ var $io = $('');
+ var io = $io[0];
+ var op8 = $.browser.opera && window.opera.version() < 9;
+ if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
+ $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
+
+ // make sure form attrs are set
+ form.method = 'POST';
+ form.encoding ? form.encoding = 'multipart/form-data' : form.enctype = 'multipart/form-data';
+
+ var xhr = { // mock object
+ responseText: null,
+ responseXML: null,
+ status: 0,
+ statusText: 'n/a',
+ getAllResponseHeaders: function() {},
+ getResponseHeader: function() {},
+ setRequestHeader: function() {}
+ };
+
+ var g = opts.global;
+ // trigger ajax global events so that activity/block indicators work like normal
+ if (g && ! $.active++) $.event.trigger("ajaxStart");
+ if (g) $.event.trigger("ajaxSend", [xhr, opts]);
+
+ var cbInvoked = 0;
+ var timedOut = 0;
+
+ // take a breath so that pending repaints get some cpu time before the upload starts
+ setTimeout(function() {
+ $io.appendTo('body');
+ // jQuery's event binding doesn't work for iframe events in IE
+ io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
+ form.action = opts.url;
+ var t = form.target;
+ form.target = id;
+
+ // support timout
+ if (opts.timeout)
+ setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
+
+ form.submit();
+ form.target = t; // reset
+ }, 10);
+
+ function cb() {
+ if (cbInvoked++) return;
+
+ io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
+
+ var ok = true;
+ try {
+ if (timedOut) throw 'timeout';
+ // extract the server response from the iframe
+ var data, doc;
+ doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
+ xhr.responseText = doc.body ? doc.body.innerHTML : null;
+ xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
+
+ if (opts.dataType == 'json' || opts.dataType == 'script') {
+ var ta = doc.getElementsByTagName('textarea')[0];
+ data = ta ? ta.value : xhr.responseText;
+ if (opts.dataType == 'json')
+ eval("data = " + data);
+ else
+ $.globalEval(data);
+ }
+ else if (opts.dataType == 'xml') {
+ data = xhr.responseXML;
+ if (!data && xhr.responseText != null)
+ data = toXml(xhr.responseText);
+ }
+ else {
+ data = xhr.responseText;
+ }
+ }
+ catch(e){
+ ok = false;
+ $.handleError(opts, xhr, 'error', e);
+ }
+
+ // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
+ if (ok) {
+ opts.success(data, 'success');
+ if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
+ }
+ if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
+ if (g && ! --$.active) $.event.trigger("ajaxStop");
+ if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
+
+ // clean up
+ setTimeout(function() {
+ $io.remove();
+ xhr.responseXML = null;
+ }, 100);
+ };
+
+ function toXml(s, doc) {
+ if (window.ActiveXObject) {
+ doc = new ActiveXObject('Microsoft.XMLDOM');
+ doc.async = 'false';
+ doc.loadXML(s);
+ }
+ else
+ doc = (new DOMParser()).parseFromString(s, 'text/xml');
+ return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
+ }
+ };
+};
+$.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids
+
+/**
+ * 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
+ */
+$.fn.ajaxForm = function(options) {
+ return this.ajaxFormUnbind().submit(submitHandler).each(function() {
+ // store options in hash
+ this.formPluginId = $.fn.ajaxForm.counter++;
+ $.fn.ajaxForm.optionHash[this.formPluginId] = options;
+ $(":submit,input:image", this).click(clickHandler);
+ });
+};
+
+$.fn.ajaxForm.counter = 1;
+$.fn.ajaxForm.optionHash = {};
+
+function clickHandler(e) {
+ var $form = this.form;
+ $form.clk = this;
+ if (this.type == 'image') {
+ if (e.offsetX != undefined) {
+ $form.clk_x = e.offsetX;
+ $form.clk_y = e.offsetY;
+ } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
+ var offset = $(this).offset();
+ $form.clk_x = e.pageX - offset.left;
+ $form.clk_y = e.pageY - offset.top;
+ } else {
+ $form.clk_x = e.pageX - this.offsetLeft;
+ $form.clk_y = e.pageY - this.offsetTop;
+ }
+ }
+ // clear form vars
+ setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
+};
+
+function submitHandler() {
+ // retrieve options from hash
+ var id = this.formPluginId;
+ var options = $.fn.ajaxForm.optionHash[id];
+ $(this).ajaxSubmit(options);
+ return false;
+};
+
+/**
+ * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
+ *
+ * @name ajaxFormUnbind
+ * @return jQuery
+ * @cat Plugins/Form
+ * @type jQuery
+ */
+$.fn.ajaxFormUnbind = function() {
+ this.unbind('submit', submitHandler);
+ return this.each(function() {
+ $(":submit,input:image", this).unbind('click', clickHandler);
+ });
+
+};
+
+/**
+ * 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