MINOR Updated jquery.form.js plugin, and re-added it to standard includes (its handy for clearing out forms, and consistently getting form field values)

This commit is contained in:
Ingo Schommer 2012-03-02 13:42:15 +01:00
parent c7a301521d
commit 3659c63afe
2 changed files with 358 additions and 151 deletions

View File

@ -239,6 +239,7 @@ class LeftAndMain extends Controller {
THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js', THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js',
THIRDPARTY_DIR . '/jquery-cookie/jquery.cookie.js', THIRDPARTY_DIR . '/jquery-cookie/jquery.cookie.js',
THIRDPARTY_DIR . '/jquery-query/jquery.query.js', THIRDPARTY_DIR . '/jquery-query/jquery.query.js',
THIRDPARTY_DIR . '/jquery-form/jquery.form.js',
SAPPHIRE_ADMIN_DIR . '/thirdparty/jquery-notice/jquery.notice.js', SAPPHIRE_ADMIN_DIR . '/thirdparty/jquery-notice/jquery.notice.js',
SAPPHIRE_ADMIN_DIR . '/thirdparty/jsizes/lib/jquery.sizes.js', SAPPHIRE_ADMIN_DIR . '/thirdparty/jsizes/lib/jquery.sizes.js',
SAPPHIRE_ADMIN_DIR . '/thirdparty/jlayout/lib/jlayout.border.js', SAPPHIRE_ADMIN_DIR . '/thirdparty/jlayout/lib/jlayout.border.js',

View File

@ -1,6 +1,6 @@
/*! /*!
* jQuery Form Plugin * jQuery Form Plugin
* version: 2.63 (29-JAN-2011) * version: 2.96 (16-FEB-2012)
* @requires jQuery v1.3.2 or later * @requires jQuery v1.3.2 or later
* *
* Examples and documentation at: http://malsup.com/jquery/form/ * Examples and documentation at: http://malsup.com/jquery/form/
@ -14,7 +14,7 @@
Usage Note: Usage Note:
----------- -----------
Do not use both ajaxSubmit and ajaxForm on the same form. These Do not use both ajaxSubmit and ajaxForm on the same form. These
functions are intended to be exclusive. Use ajaxSubmit if you want functions are mutually exclusive. Use ajaxSubmit if you want
to bind your own submit handler to the form. For example, to bind your own submit handler to the form. For example,
$(document).ready(function() { $(document).ready(function() {
@ -35,6 +35,14 @@
}); });
}); });
You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
form does not have to exist when you invoke ajaxForm:
$('#myForm').ajaxForm({
delegation: true,
target: '#output'
});
When using ajaxForm, the ajaxSubmit function will be invoked for you When using ajaxForm, the ajaxSubmit function will be invoked for you
at the appropriate time. at the appropriate time.
*/ */
@ -50,21 +58,25 @@ $.fn.ajaxSubmit = function(options) {
return this; return this;
} }
var method, action, url, $form = this;
if (typeof options == 'function') { if (typeof options == 'function') {
options = { success: options }; options = { success: options };
} }
var action = this.attr('action'); method = this.attr('method');
var url = (typeof action === 'string') ? $.trim(action) : ''; action = this.attr('action');
url = (typeof action === 'string') ? $.trim(action) : '';
url = url || window.location.href || '';
if (url) { if (url) {
// clean url (don't include hash vaue) // clean url (don't include hash vaue)
url = (url.match(/^([^#]+)/)||[])[1]; url = (url.match(/^([^#]+)/)||[])[1];
} }
url = url || window.location.href || '';
options = $.extend(true, { options = $.extend(true, {
url: url, url: url,
type: this[0].getAttribute('method') || 'GET', // IE7 massage (see issue 57) success: $.ajaxSettings.success,
type: method || 'GET',
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
}, options); }, options);
@ -83,21 +95,15 @@ $.fn.ajaxSubmit = function(options) {
return this; return this;
} }
var n,v,a = this.formToArray(options.semantic); var traditional = options.traditional;
if ( traditional === undefined ) {
traditional = $.ajaxSettings.traditional;
}
var qx,n,v,a = this.formToArray(options.semantic);
if (options.data) { if (options.data) {
options.extraData = options.data; options.extraData = options.data;
for (n in options.data) { qx = $.param(options.data, traditional);
if(options.data[n] instanceof Array) {
for (var k in options.data[n]) {
a.push( { name: n, value: options.data[n][k] } );
}
}
else {
v = options.data[n];
v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
a.push( { name: n, value: v } );
}
}
} }
// give pre-submit callback an opportunity to abort the submit // give pre-submit callback an opportunity to abort the submit
@ -113,8 +119,10 @@ $.fn.ajaxSubmit = function(options) {
return this; return this;
} }
var q = $.param(a); var q = $.param(a, traditional);
if (qx) {
q = ( q ? (q + '&' + qx) : qx );
}
if (options.type.toUpperCase() == 'GET') { if (options.type.toUpperCase() == 'GET') {
options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
options.data = null; // data is null for 'get' options.data = null; // data is null for 'get'
@ -123,12 +131,12 @@ $.fn.ajaxSubmit = function(options) {
options.data = q; // data is the query string for 'post' options.data = q; // data is the query string for 'post'
} }
var $form = this, callbacks = []; var callbacks = [];
if (options.resetForm) { if (options.resetForm) {
callbacks.push(function() { $form.resetForm(); }); callbacks.push(function() { $form.resetForm(); });
} }
if (options.clearForm) { if (options.clearForm) {
callbacks.push(function() { $form.clearForm(); }); callbacks.push(function() { $form.clearForm(options.includeHidden); });
} }
// perform a load on the target only if dataType is not provided // perform a load on the target only if dataType is not provided
@ -151,22 +159,33 @@ $.fn.ajaxSubmit = function(options) {
}; };
// are there files to upload? // are there files to upload?
var fileInputs = $('input:file', this).length > 0; var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
var hasFileInputs = fileInputs.length > 0;
var mp = 'multipart/form-data'; var mp = 'multipart/form-data';
var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
var fileAPI = !!(hasFileInputs && fileInputs.get(0).files && window.FormData);
log("fileAPI :" + fileAPI);
var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
// options.iframe allows user to force iframe mode // options.iframe allows user to force iframe mode
// 06-NOV-09: now defaulting to iframe mode if file input is detected // 06-NOV-09: now defaulting to iframe mode if file input is detected
if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
// hack to fix Safari hang (thanks to Tim Molendijk for this) // hack to fix Safari hang (thanks to Tim Molendijk for this)
// see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
if (options.closeKeepAlive) { if (options.closeKeepAlive) {
$.get(options.closeKeepAlive, fileUpload); $.get(options.closeKeepAlive, function() {
fileUploadIframe(a);
});
} }
else { else {
fileUpload(); fileUploadIframe(a);
} }
} }
else if ((hasFileInputs || multipart) && fileAPI) {
options.progress = options.progress || $.noop;
fileUploadXhr(a);
}
else { else {
$.ajax(options); $.ajax(options);
} }
@ -175,10 +194,74 @@ $.fn.ajaxSubmit = function(options) {
this.trigger('form-submit-notify', [this, options]); this.trigger('form-submit-notify', [this, options]);
return this; return this;
// XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
function fileUploadXhr(a) {
var formdata = new FormData();
for (var i=0; i < a.length; i++) {
if (a[i].type == 'file')
continue;
formdata.append(a[i].name, a[i].value);
}
$form.find('input:file:enabled').each(function(){
var name = $(this).attr('name'), files = this.files;
if (name) {
for (var i=0; i < files.length; i++)
formdata.append(name, files[i]);
}
});
if (options.extraData) {
for (var k in options.extraData)
formdata.append(k, options.extraData[k])
}
options.data = null;
var s = $.extend(true, {}, $.ajaxSettings, options, {
contentType: false,
processData: false,
cache: false,
type: 'POST'
});
//s.context = s.context || s;
s.data = null;
var beforeSend = s.beforeSend;
s.beforeSend = function(xhr, o) {
o.data = formdata;
if(xhr.upload) { // unfortunately, jQuery doesn't expose this prop (http://bugs.jquery.com/ticket/10190)
xhr.upload.onprogress = function(event) {
o.progress(event.position, event.total);
};
}
if(beforeSend)
beforeSend.call(o, xhr, options);
};
$.ajax(s);
}
// private function for handling file uploads (hat tip to YAHOO!) // private function for handling file uploads (hat tip to YAHOO!)
function fileUpload() { function fileUploadIframe(a) {
var form = $form[0]; var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
var useProp = !!$.fn.prop;
if (a) {
if ( useProp ) {
// ensure that every serialized input is still enabled
for (i=0; i < a.length; i++) {
el = $(form[a[i].name]);
el.prop('disabled', false);
}
} else {
for (i=0; i < a.length; i++) {
el = $(form[a[i].name]);
el.removeAttr('disabled');
}
};
}
if ($(':input[name=submit],:input[id=submit]', form).length) { if ($(':input[name=submit],:input[id=submit]', form).length) {
// if there is an input with a name or id of 'submit' then we won't be // if there is an input with a name or id of 'submit' then we won't be
@ -187,15 +270,25 @@ $.fn.ajaxSubmit = function(options) {
return; return;
} }
var s = $.extend(true, {}, $.ajaxSettings, options); s = $.extend(true, {}, $.ajaxSettings, options);
s.context = s.context || s; s.context = s.context || s;
var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id; id = 'jqFormIO' + (new Date().getTime());
var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" />'); if (s.iframeTarget) {
var io = $io[0]; $io = $(s.iframeTarget);
n = $io.attr('name');
if (n == null)
$io.attr('name', id);
else
id = n;
}
else {
$io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
}
io = $io[0];
var xhr = { // mock object
xhr = { // mock object
aborted: 0, aborted: 0,
responseText: null, responseText: null,
responseXML: null, responseXML: null,
@ -204,13 +297,19 @@ $.fn.ajaxSubmit = function(options) {
getAllResponseHeaders: function() {}, getAllResponseHeaders: function() {},
getResponseHeader: function() {}, getResponseHeader: function() {},
setRequestHeader: function() {}, setRequestHeader: function() {},
abort: function() { abort: function(status) {
var e = (status === 'timeout' ? 'timeout' : 'aborted');
log('aborting upload... ' + e);
this.aborted = 1; this.aborted = 1;
$io.attr('src', s.iframeSrc); // abort op in progress $io.attr('src', s.iframeSrc); // abort op in progress
xhr.error = e;
s.error && s.error.call(s.context, xhr, e, status);
g && $.event.trigger("ajaxError", [xhr, s, e]);
s.complete && s.complete.call(s.context, xhr, e);
} }
}; };
var g = s.global; g = s.global;
// trigger ajax global events so that activity/block indicators work like normal // trigger ajax global events so that activity/block indicators work like normal
if (g && ! $.active++) { if (g && ! $.active++) {
$.event.trigger("ajaxStart"); $.event.trigger("ajaxStart");
@ -229,12 +328,10 @@ $.fn.ajaxSubmit = function(options) {
return; return;
} }
var timedOut = 0;
// add submitting element to data if we know it // add submitting element to data if we know it
var sub = form.clk; sub = form.clk;
if (sub) { if (sub) {
var n = sub.name; n = sub.name;
if (n && !sub.disabled) { if (n && !sub.disabled) {
s.extraData = s.extraData || {}; s.extraData = s.extraData || {};
s.extraData[n] = sub.value; s.extraData[n] = sub.value;
@ -245,6 +342,22 @@ $.fn.ajaxSubmit = function(options) {
} }
} }
var CLIENT_TIMEOUT_ABORT = 1;
var SERVER_ABORT = 2;
function getDoc(frame) {
var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
return doc;
}
// Rails CSRF hack (thanks to Yvan Barthelemy)
var csrf_token = $('meta[name=csrf-token]').attr('content');
var csrf_param = $('meta[name=csrf-param]').attr('content');
if (csrf_param && csrf_token) {
s.extraData = s.extraData || {};
s.extraData[csrf_param] = csrf_token;
}
// take a breath so that pending repaints get some cpu time before the upload starts // take a breath so that pending repaints get some cpu time before the upload starts
function doSubmit() { function doSubmit() {
// make sure form attrs are set // make sure form attrs are set
@ -252,15 +365,15 @@ $.fn.ajaxSubmit = function(options) {
// update form attrs in IE friendly way // update form attrs in IE friendly way
form.setAttribute('target',id); form.setAttribute('target',id);
if (form.getAttribute('method') != 'POST') { if (!method) {
form.setAttribute('method', 'POST'); form.setAttribute('method', 'POST');
} }
if (form.getAttribute('action') != s.url) { if (a != s.url) {
form.setAttribute('action', s.url); form.setAttribute('action', s.url);
} }
// ie borks in some cases when setting encoding // ie borks in some cases when setting encoding
if (! s.skipEncodingOverride) { if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
$form.attr({ $form.attr({
encoding: 'multipart/form-data', encoding: 'multipart/form-data',
enctype: 'multipart/form-data' enctype: 'multipart/form-data'
@ -269,7 +382,23 @@ $.fn.ajaxSubmit = function(options) {
// support timout // support timout
if (s.timeout) { if (s.timeout) {
setTimeout(function() { timedOut = true; cb(); }, s.timeout); timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
}
// look for server aborts
function checkState() {
try {
var state = getDoc(io).readyState;
log('state = ' + state);
if (state.toLowerCase() == 'uninitialized')
setTimeout(checkState,50);
}
catch(e) {
log('Server abort: ' , e, ' (', e.name, ')');
cb(SERVER_ABORT);
timeoutHandle && clearTimeout(timeoutHandle);
timeoutHandle = undefined;
}
} }
// add "extra" data to form if provided in options // add "extra" data to form if provided in options
@ -278,14 +407,17 @@ $.fn.ajaxSubmit = function(options) {
if (s.extraData) { if (s.extraData) {
for (var n in s.extraData) { for (var n in s.extraData) {
extraInputs.push( extraInputs.push(
$('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />') $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
.appendTo(form)[0]); .appendTo(form)[0]);
} }
} }
if (!s.iframeTarget) {
// add iframe to doc and submit the form // add iframe to doc and submit the form
$io.appendTo('body'); $io.appendTo('body');
io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
}
setTimeout(checkState,15);
form.submit(); form.submit();
} }
finally { finally {
@ -307,17 +439,36 @@ $.fn.ajaxSubmit = function(options) {
setTimeout(doSubmit, 10); // this lets dom updates render setTimeout(doSubmit, 10); // this lets dom updates render
} }
var data, doc, domCheckCount = 50; var data, doc, domCheckCount = 50, callbackProcessed;
function cb(e) {
if (xhr.aborted || callbackProcessed) {
return;
}
try {
doc = getDoc(io);
}
catch(ex) {
log('cannot access response document: ', ex);
e = SERVER_ABORT;
}
if (e === CLIENT_TIMEOUT_ABORT && xhr) {
xhr.abort('timeout');
return;
}
else if (e == SERVER_ABORT && xhr) {
xhr.abort('server abort');
return;
}
function cb() {
doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
if (!doc || doc.location.href == s.iframeSrc) { if (!doc || doc.location.href == s.iframeSrc) {
// response not received yet // response not received yet
if (!timedOut)
return; return;
} }
io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
var ok = true; var status = 'success', errMsg;
try { try {
if (timedOut) { if (timedOut) {
throw 'timeout'; throw 'timeout';
@ -339,56 +490,82 @@ $.fn.ajaxSubmit = function(options) {
} }
//log('response detected'); //log('response detected');
xhr.responseText = doc.body ? doc.body.innerHTML : doc.documentElement ? doc.documentElement.innerHTML : null; var docRoot = doc.body ? doc.body : doc.documentElement;
xhr.responseText = docRoot ? docRoot.innerHTML : null;
xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
if (isXml)
s.dataType = 'xml';
xhr.getResponseHeader = function(header){ xhr.getResponseHeader = function(header){
var headers = {'content-type': s.dataType}; var headers = {'content-type': s.dataType};
return headers[header]; return headers[header];
}; };
// support for XHR 'status' & 'statusText' emulation :
if (docRoot) {
xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
}
var scr = /(json|script)/.test(s.dataType); var dt = (s.dataType || '').toLowerCase();
var scr = /(json|script|text)/.test(dt);
if (scr || s.textarea) { if (scr || s.textarea) {
// see if user embedded response in textarea // see if user embedded response in textarea
var ta = doc.getElementsByTagName('textarea')[0]; var ta = doc.getElementsByTagName('textarea')[0];
if (ta) { if (ta) {
xhr.responseText = ta.value; xhr.responseText = ta.value;
// support for XHR 'status' & 'statusText' emulation :
xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
} }
else if (scr) { else if (scr) {
// account for browsers injecting pre around json response // account for browsers injecting pre around json response
var pre = doc.getElementsByTagName('pre')[0]; var pre = doc.getElementsByTagName('pre')[0];
var b = doc.getElementsByTagName('body')[0]; var b = doc.getElementsByTagName('body')[0];
if (pre) { if (pre) {
xhr.responseText = pre.textContent; xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
} }
else if (b) { else if (b) {
xhr.responseText = b.innerHTML; xhr.responseText = b.textContent ? b.textContent : b.innerText;
} }
} }
} }
else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { else if (dt == 'xml' && !xhr.responseXML && xhr.responseText != null) {
xhr.responseXML = toXml(xhr.responseText); xhr.responseXML = toXml(xhr.responseText);
} }
data = httpData(xhr, s.dataType, s); try {
data = httpData(xhr, dt, s);
}
catch (e) {
status = 'parsererror';
xhr.error = errMsg = (e || status);
}
} }
catch (e) { catch (e) {
log('error caught: ',e); log('error caught: ',e);
ok = false; status = 'error';
xhr.error = e; xhr.error = errMsg = (e || status);
s.error.call(s.context, xhr, 'error', e);
g && $.event.trigger("ajaxError", [xhr, s, e]);
} }
if (xhr.aborted) { if (xhr.aborted) {
log('upload aborted'); log('upload aborted');
ok = false; status = null;
}
if (xhr.status) { // we've set xhr.status
status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
} }
// ordering of these callbacks/triggers is odd, but that's how $.ajax does it // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
if (ok) { if (status === 'success') {
s.success.call(s.context, data, 'success', xhr); s.success && s.success.call(s.context, data, 'success', xhr);
g && $.event.trigger("ajaxSuccess", [xhr, s]); g && $.event.trigger("ajaxSuccess", [xhr, s]);
} }
else if (status) {
if (errMsg == undefined)
errMsg = xhr.statusText;
s.error && s.error.call(s.context, xhr, status, errMsg);
g && $.event.trigger("ajaxError", [xhr, s, errMsg]);
}
g && $.event.trigger("ajaxComplete", [xhr, s]); g && $.event.trigger("ajaxComplete", [xhr, s]);
@ -396,11 +573,15 @@ $.fn.ajaxSubmit = function(options) {
$.event.trigger("ajaxStop"); $.event.trigger("ajaxStop");
} }
s.complete && s.complete.call(s.context, xhr, ok ? 'success' : 'error'); s.complete && s.complete.call(s.context, xhr, status);
callbackProcessed = true;
if (s.timeout)
clearTimeout(timeoutHandle);
// clean up // clean up
setTimeout(function() { setTimeout(function() {
$io.removeData('form-plugin-onload'); if (!s.iframeTarget)
$io.remove(); $io.remove();
xhr.responseXML = null; xhr.responseXML = null;
}, 100); }, 100);
@ -422,6 +603,7 @@ $.fn.ajaxSubmit = function(options) {
}; };
var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4 var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
var ct = xhr.getResponseHeader('content-type') || '', var ct = xhr.getResponseHeader('content-type') || '',
xml = type === 'xml' || !type && ct.indexOf('xml') >= 0, xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
data = xml ? xhr.responseXML : xhr.responseText; data = xml ? xhr.responseXML : xhr.responseText;
@ -460,8 +642,11 @@ $.fn.ajaxSubmit = function(options) {
* the form itself. * the form itself.
*/ */
$.fn.ajaxForm = function(options) { $.fn.ajaxForm = function(options) {
options = options || {};
options.delegation = options.delegation && $.isFunction($.fn.on);
// in jQuery 1.3+ we can fix mistakes with the ready state // in jQuery 1.3+ we can fix mistakes with the ready state
if (this.length === 0) { if (!options.delegation && this.length === 0) {
var o = { s: this.selector, c: this.context }; var o = { s: this.selector, c: this.context };
if (!$.isReady && o.s) { if (!$.isReady && o.s) {
log('DOM not ready, queuing ajaxForm'); log('DOM not ready, queuing ajaxForm');
@ -475,12 +660,30 @@ $.fn.ajaxForm = function(options) {
return this; return this;
} }
return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) { if ( options.delegation ) {
$(document)
.off('submit.form-plugin', this.selector, doAjaxSubmit)
.off('click.form-plugin', this.selector, captureSubmittingElement)
.on('submit.form-plugin', this.selector, options, doAjaxSubmit)
.on('click.form-plugin', this.selector, options, captureSubmittingElement);
return this;
}
return this.ajaxFormUnbind()
.bind('submit.form-plugin', options, doAjaxSubmit)
.bind('click.form-plugin', options, captureSubmittingElement);
};
// private event handlers
function doAjaxSubmit(e) {
var options = e.data;
if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
e.preventDefault(); e.preventDefault();
$(this).ajaxSubmit(options); $(this).ajaxSubmit(options);
} }
}).bind('click.form-plugin', function(e) { }
function captureSubmittingElement(e) {
var target = e.target; var target = e.target;
var $el = $(target); var $el = $(target);
if (!($el.is(":submit,input:image"))) { if (!($el.is(":submit,input:image"))) {
@ -497,7 +700,7 @@ $.fn.ajaxForm = function(options) {
if (e.offsetX != undefined) { if (e.offsetX != undefined) {
form.clk_x = e.offsetX; form.clk_x = e.offsetX;
form.clk_y = e.offsetY; form.clk_y = e.offsetY;
} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin } else if (typeof $.fn.offset == 'function') {
var offset = $el.offset(); var offset = $el.offset();
form.clk_x = e.pageX - offset.left; form.clk_x = e.pageX - offset.left;
form.clk_y = e.pageY - offset.top; form.clk_y = e.pageY - offset.top;
@ -508,9 +711,9 @@ $.fn.ajaxForm = function(options) {
} }
// clear form vars // clear form vars
setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
});
}; };
// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() { $.fn.ajaxFormUnbind = function() {
return this.unbind('submit.form-plugin click.form-plugin'); return this.unbind('submit.form-plugin click.form-plugin');
@ -550,7 +753,7 @@ $.fn.formToArray = function(semantic) {
if (semantic && form.clk && el.type == "image") { if (semantic && form.clk && el.type == "image") {
// handle image inputs on the fly when semantic == true // handle image inputs on the fly when semantic == true
if(!el.disabled && form.clk == el) { if(!el.disabled && form.clk == el) {
a.push({name: n, value: $(el).val()}); a.push({name: n, value: $(el).val(), type: el.type });
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
} }
continue; continue;
@ -563,7 +766,7 @@ $.fn.formToArray = function(semantic) {
} }
} }
else if (v !== null && typeof v != 'undefined') { else if (v !== null && typeof v != 'undefined') {
a.push({name: n, value: v}); a.push({name: n, value: v, type: el.type});
} }
} }
@ -713,19 +916,20 @@ $.fieldValue = function(el, successful) {
* - inputs of type submit, button, reset, and hidden will *not* be effected * - inputs of type submit, button, reset, and hidden will *not* be effected
* - button elements will *not* be effected * - button elements will *not* be effected
*/ */
$.fn.clearForm = function() { $.fn.clearForm = function(includeHidden) {
return this.each(function() { return this.each(function() {
$('input,select,textarea', this).clearFields(); $('input,select,textarea', this).clearFields(includeHidden);
}); });
}; };
/** /**
* Clears the selected form elements. * Clears the selected form elements.
*/ */
$.fn.clearFields = $.fn.clearInputs = function() { $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
return this.each(function() { return this.each(function() {
var t = this.type, tag = this.tagName.toLowerCase(); var t = this.type, tag = this.tagName.toLowerCase();
if (t == 'text' || t == 'password' || tag == 'textarea') { if (re.test(t) || tag == 'textarea' || (includeHidden && /hidden/.test(t)) ) {
this.value = ''; this.value = '';
} }
else if (t == 'checkbox' || t == 'radio') { else if (t == 'checkbox' || t == 'radio') {
@ -786,10 +990,13 @@ $.fn.selected = function(select) {
}); });
}; };
// expose debug var
$.fn.ajaxSubmit.debug = false;
// helper fn for console logging // helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() { function log() {
if ($.fn.ajaxSubmit.debug) { if (!$.fn.ajaxSubmit.debug)
return;
var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
if (window.console && window.console.log) { if (window.console && window.console.log) {
window.console.log(msg); window.console.log(msg);
@ -797,7 +1004,6 @@ function log() {
else if (window.opera && window.opera.postError) { else if (window.opera && window.opera.postError) {
window.opera.postError(msg); window.opera.postError(msg);
} }
}
}; };
})(jQuery); })(jQuery);