| 
									
										
										
										
											2010-02-25 00:10:36 +01:00
										 |  |  | /* | 
					
						
							|  |  |  |  * jQuery Form Plugin | 
					
						
							|  |  |  |  * version: 2.17 (06-NOV-2008) | 
					
						
							|  |  |  |  * @requires jQuery v1.2.2 or later | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Examples and documentation 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$ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | ;(function($) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |     Usage Note:   | 
					
						
							|  |  |  |     ----------- | 
					
						
							|  |  |  |     Do not use both ajaxSubmit and ajaxForm on the same form.  These | 
					
						
							|  |  |  |     functions are intended to be exclusive.  Use ajaxSubmit if you want | 
					
						
							|  |  |  |     to bind your own submit handler to the form.  For example, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $(document).ready(function() { | 
					
						
							|  |  |  |         $('#myForm').bind('submit', function() { | 
					
						
							|  |  |  |             $(this).ajaxSubmit({ | 
					
						
							|  |  |  |                 target: '#output' | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |             return false; // <-- important!
 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Use ajaxForm when you want the plugin to manage all the event binding | 
					
						
							|  |  |  |     for you.  For example, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $(document).ready(function() { | 
					
						
							|  |  |  |         $('#myForm').ajaxForm({ | 
					
						
							|  |  |  |             target: '#output' | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     When using ajaxForm, the ajaxSubmit function will be invoked for you | 
					
						
							|  |  |  |     at the appropriate time.   | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * ajaxSubmit() provides a mechanism for immediately submitting  | 
					
						
							|  |  |  |  * an HTML form using AJAX. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.ajaxSubmit = function(options) { | 
					
						
							|  |  |  |     // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
 | 
					
						
							|  |  |  |     if (!this.length) { | 
					
						
							|  |  |  |         log('ajaxSubmit: skipping submit process - no element selected'); | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (typeof options == 'function') | 
					
						
							|  |  |  |         options = { success: options }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     options = $.extend({ | 
					
						
							|  |  |  |         url:  this.attr('action') || window.location.toString(), | 
					
						
							|  |  |  |         type: this.attr('method') || 'GET' | 
					
						
							|  |  |  |     }, options || {}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // hook for manipulating the form data before it is extracted;
 | 
					
						
							|  |  |  |     // convenient for use with rich editors like tinyMCE or FCKEditor
 | 
					
						
							|  |  |  |     var veto = {}; | 
					
						
							|  |  |  |     this.trigger('form-pre-serialize', [this, options, veto]); | 
					
						
							|  |  |  |     if (veto.veto) { | 
					
						
							|  |  |  |         log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // provide opportunity to alter form data before it is serialized
 | 
					
						
							|  |  |  |     if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { | 
					
						
							|  |  |  |         log('ajaxSubmit: submit aborted via beforeSerialize callback'); | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |     }     | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |     var a = this.formToArray(options.semantic); | 
					
						
							|  |  |  |     if (options.data) { | 
					
						
							|  |  |  |         options.extraData = options.data; | 
					
						
							|  |  |  |         for (var n in options.data) { | 
					
						
							|  |  |  |           if(options.data[n] instanceof Array) { | 
					
						
							|  |  |  |             for (var k in options.data[n]) | 
					
						
							|  |  |  |               a.push( { name: n, value: options.data[n][k] } ) | 
					
						
							|  |  |  |           }   | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |              a.push( { name: n, value: options.data[n] } ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // give pre-submit callback an opportunity to abort the submit
 | 
					
						
							|  |  |  |     if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { | 
					
						
							|  |  |  |         log('ajaxSubmit: submit aborted via beforeSubmit callback'); | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |     }     | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // fire vetoable 'validate' event
 | 
					
						
							|  |  |  |     this.trigger('form-submit-validate', [a, this, options, veto]); | 
					
						
							|  |  |  |     if (veto.veto) { | 
					
						
							|  |  |  |         log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |     }     | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var q = $.param(a); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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) { | 
					
						
							|  |  |  |             $(options.target).html(data).each(oldSuccess, arguments); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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].apply(options, [data, status, $form]); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // options.iframe allows user to force iframe mode
 | 
					
						
							|  |  |  |    if (options.iframe || found) {  | 
					
						
							|  |  |  |        // hack to fix Safari hang (thanks to Tim Molendijk for this)
 | 
					
						
							|  |  |  |        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
 | 
					
						
							|  |  |  |        if ($.browser.safari && options.closeKeepAlive) | 
					
						
							|  |  |  |            $.get(options.closeKeepAlive, fileUpload); | 
					
						
							|  |  |  |        else | 
					
						
							|  |  |  |            fileUpload(); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |    else | 
					
						
							|  |  |  |        $.ajax(options); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // fire 'notify' event
 | 
					
						
							|  |  |  |     this.trigger('form-submit-notify', [this, options]); | 
					
						
							|  |  |  |     return this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // private function for handling file uploads (hat tip to YAHOO!)
 | 
					
						
							|  |  |  |     function fileUpload() { | 
					
						
							|  |  |  |         var form = $form[0]; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if ($(':input[name=submit]', form).length) { | 
					
						
							|  |  |  |             alert('Error: Form elements must not be named "submit".'); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         var opts = $.extend({}, $.ajaxSettings, options); | 
					
						
							|  |  |  | 		var s = jQuery.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var id = 'jqFormIO' + (new Date().getTime()); | 
					
						
							|  |  |  |         var $io = $('<iframe id="' + id + '" name="' + id + '" />'); | 
					
						
							|  |  |  |         var io = $io[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($.browser.msie || $.browser.opera)  | 
					
						
							|  |  |  |             io.src = 'javascript:false;document.write("");'; | 
					
						
							|  |  |  |         $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var xhr = { // mock object
 | 
					
						
							|  |  |  |             aborted: 0, | 
					
						
							|  |  |  |             responseText: null, | 
					
						
							|  |  |  |             responseXML: null, | 
					
						
							|  |  |  |             status: 0, | 
					
						
							|  |  |  |             statusText: 'n/a', | 
					
						
							|  |  |  |             getAllResponseHeaders: function() {}, | 
					
						
							|  |  |  |             getResponseHeader: function() {}, | 
					
						
							|  |  |  |             setRequestHeader: function() {}, | 
					
						
							|  |  |  |             abort: function() {  | 
					
						
							|  |  |  |                 this.aborted = 1;  | 
					
						
							|  |  |  |                 $io.attr('src','about:blank'); // abort op in progress
 | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (s.beforeSend && s.beforeSend(xhr, s) === false) { | 
					
						
							|  |  |  | 			s.global && jQuery.active--; | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (xhr.aborted) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         var cbInvoked = 0; | 
					
						
							|  |  |  |         var timedOut = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // add submitting element to data if we know it
 | 
					
						
							|  |  |  |         var sub = form.clk; | 
					
						
							|  |  |  |         if (sub) { | 
					
						
							|  |  |  |             var n = sub.name; | 
					
						
							|  |  |  |             if (n && !sub.disabled) { | 
					
						
							|  |  |  |                 options.extraData = options.extraData || {}; | 
					
						
							|  |  |  |                 options.extraData[n] = sub.value; | 
					
						
							|  |  |  |                 if (sub.type == "image") { | 
					
						
							|  |  |  |                     options.extraData[name+'.x'] = form.clk_x; | 
					
						
							|  |  |  |                     options.extraData[name+'.y'] = form.clk_y; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // take a breath so that pending repaints get some cpu time before the upload starts
 | 
					
						
							|  |  |  |         setTimeout(function() { | 
					
						
							|  |  |  |             // make sure form attrs are set
 | 
					
						
							|  |  |  |             var t = $form.attr('target'), a = $form.attr('action'); | 
					
						
							|  |  |  |             $form.attr({ | 
					
						
							|  |  |  |                 target:   id, | 
					
						
							|  |  |  |                 method:   'POST', | 
					
						
							|  |  |  |                 action:   opts.url | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             // ie borks in some cases when setting encoding
 | 
					
						
							|  |  |  |             if (! options.skipEncodingOverride) { | 
					
						
							|  |  |  |                 $form.attr({ | 
					
						
							|  |  |  |                     encoding: 'multipart/form-data', | 
					
						
							|  |  |  |                     enctype:  'multipart/form-data' | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // support timout
 | 
					
						
							|  |  |  |             if (opts.timeout) | 
					
						
							|  |  |  |                 setTimeout(function() { timedOut = true; cb(); }, opts.timeout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // add "extra" data to form if provided in options
 | 
					
						
							|  |  |  |             var extraInputs = []; | 
					
						
							|  |  |  |             try { | 
					
						
							|  |  |  |                 if (options.extraData) | 
					
						
							|  |  |  |                     for (var n in options.extraData) | 
					
						
							|  |  |  |                         extraInputs.push( | 
					
						
							|  |  |  |                             $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />') | 
					
						
							|  |  |  |                                 .appendTo(form)[0]); | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |                 // add iframe to doc and submit the form
 | 
					
						
							|  |  |  |                 $io.appendTo('body'); | 
					
						
							|  |  |  |                 io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); | 
					
						
							|  |  |  |                 form.submit(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             finally { | 
					
						
							|  |  |  |                 // reset attrs and remove "extra" input elements
 | 
					
						
							|  |  |  |                 $form.attr('action', a); | 
					
						
							|  |  |  |                 t ? $form.attr('target', t) : $form.removeAttr('target'); | 
					
						
							|  |  |  |                 $(extraInputs).remove(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function cb() { | 
					
						
							|  |  |  |             if (cbInvoked++) return; | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var operaHack = 0; | 
					
						
							|  |  |  |             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; | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |                 if (doc.body == null && !operaHack && $.browser.opera) { | 
					
						
							|  |  |  |                     // In Opera 9.2.x the iframe DOM is not always traversable when
 | 
					
						
							|  |  |  |                     // the onload callback fires so we give Opera 100ms to right itself
 | 
					
						
							|  |  |  |                     operaHack = 1; | 
					
						
							|  |  |  |                     cbInvoked--; | 
					
						
							|  |  |  |                     setTimeout(cb, 100); | 
					
						
							|  |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |                 xhr.responseText = doc.body ? doc.body.innerHTML : null; | 
					
						
							|  |  |  |                 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; | 
					
						
							|  |  |  |                 xhr.getResponseHeader = function(header){ | 
					
						
							|  |  |  |                     var headers = {'content-type': opts.dataType}; | 
					
						
							|  |  |  |                     return headers[header]; | 
					
						
							|  |  |  |                 }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (opts.dataType == 'json' || opts.dataType == 'script') { | 
					
						
							|  |  |  |                     var ta = doc.getElementsByTagName('textarea')[0]; | 
					
						
							|  |  |  |                     xhr.responseText = ta ? ta.value : xhr.responseText; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { | 
					
						
							|  |  |  |                     xhr.responseXML = toXml(xhr.responseText); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 data = $.httpData(xhr, opts.dataType); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             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; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * 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 <input type="image" /> 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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */  | 
					
						
							|  |  |  | $.fn.ajaxForm = function(options) { | 
					
						
							|  |  |  |     return this.ajaxFormUnbind().bind('submit.form-plugin',function() { | 
					
						
							|  |  |  |         $(this).ajaxSubmit(options); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     }).each(function() { | 
					
						
							|  |  |  |         // store options in hash
 | 
					
						
							|  |  |  |         $(":submit,input:image", this).bind('click.form-plugin',function(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); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
 | 
					
						
							|  |  |  | $.fn.ajaxFormUnbind = function() { | 
					
						
							|  |  |  |     this.unbind('submit.form-plugin'); | 
					
						
							|  |  |  |     return this.each(function() { | 
					
						
							|  |  |  |         $(":submit,input:image", this).unbind('click.form-plugin'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.formToArray = function(semantic) { | 
					
						
							|  |  |  |     var a = []; | 
					
						
							|  |  |  |     if (this.length == 0) return a; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var form = this[0]; | 
					
						
							|  |  |  |     var els = semantic ? form.getElementsByTagName('*') : form.elements; | 
					
						
							|  |  |  |     if (!els) return a; | 
					
						
							|  |  |  |     for(var i=0, max=els.length; i < max; i++) { | 
					
						
							|  |  |  |         var el = els[i]; | 
					
						
							|  |  |  |         var n = el.name; | 
					
						
							|  |  |  |         if (!n) continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (semantic && form.clk && el.type == "image") { | 
					
						
							|  |  |  |             // handle image inputs on the fly when semantic == true
 | 
					
						
							|  |  |  |             if(!el.disabled && form.clk == el) | 
					
						
							|  |  |  |                 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var v = $.fieldValue(el, true); | 
					
						
							|  |  |  |         if (v && v.constructor == Array) { | 
					
						
							|  |  |  |             for(var j=0, jmax=v.length; j < jmax; j++) | 
					
						
							|  |  |  |                 a.push({name: n, value: v[j]}); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (v !== null && typeof v != 'undefined') | 
					
						
							|  |  |  |             a.push({name: n, value: v}); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!semantic && form.clk) { | 
					
						
							|  |  |  |         // input type=='image' are not found in elements array! handle them here
 | 
					
						
							|  |  |  |         var inputs = form.getElementsByTagName("input"); | 
					
						
							|  |  |  |         for(var i=0, max=inputs.length; i < max; i++) { | 
					
						
							|  |  |  |             var input = inputs[i]; | 
					
						
							|  |  |  |             var n = input.name; | 
					
						
							|  |  |  |             if(n && !input.disabled && input.type == "image" && form.clk == input) | 
					
						
							|  |  |  |                 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return a; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Serializes form data into a 'submittable' string. This method will return a string | 
					
						
							|  |  |  |  * in the format: name1=value1&name2=value2 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.formSerialize = function(semantic) { | 
					
						
							|  |  |  |     //hand off to jQuery.param for proper encoding
 | 
					
						
							|  |  |  |     return $.param(this.formToArray(semantic)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Serializes all field elements in the jQuery object into a query string. | 
					
						
							|  |  |  |  * This method will return a string in the format: name1=value1&name2=value2 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.fieldSerialize = function(successful) { | 
					
						
							|  |  |  |     var a = []; | 
					
						
							|  |  |  |     this.each(function() { | 
					
						
							|  |  |  |         var n = this.name; | 
					
						
							|  |  |  |         if (!n) return; | 
					
						
							|  |  |  |         var v = $.fieldValue(this, successful); | 
					
						
							|  |  |  |         if (v && v.constructor == Array) { | 
					
						
							|  |  |  |             for (var i=0,max=v.length; i < max; i++) | 
					
						
							|  |  |  |                 a.push({name: n, value: v[i]}); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (v !== null && typeof v != 'undefined') | 
					
						
							|  |  |  |             a.push({name: this.name, value: v}); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     //hand off to jQuery.param for proper encoding
 | 
					
						
							|  |  |  |     return $.param(a); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Returns the value(s) of the element in the matched set.  For example, consider the following form: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  <form><fieldset> | 
					
						
							|  |  |  |  *      <input name="A" type="text" /> | 
					
						
							|  |  |  |  *      <input name="A" type="text" /> | 
					
						
							|  |  |  |  *      <input name="B" type="checkbox" value="B1" /> | 
					
						
							|  |  |  |  *      <input name="B" type="checkbox" value="B2"/> | 
					
						
							|  |  |  |  *      <input name="C" type="radio" value="C1" /> | 
					
						
							|  |  |  |  *      <input name="C" type="radio" value="C2" /> | 
					
						
							|  |  |  |  *  </fieldset></form> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  var v = $(':text').fieldValue(); | 
					
						
							|  |  |  |  *  // if no values are entered into the text inputs
 | 
					
						
							|  |  |  |  *  v == ['',''] | 
					
						
							|  |  |  |  *  // if values entered into the text inputs are 'foo' and 'bar'
 | 
					
						
							|  |  |  |  *  v == ['foo','bar'] | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  var v = $(':checkbox').fieldValue(); | 
					
						
							|  |  |  |  *  // if neither checkbox is checked
 | 
					
						
							|  |  |  |  *  v === undefined | 
					
						
							|  |  |  |  *  // if both checkboxes are checked
 | 
					
						
							|  |  |  |  *  v == ['B1', 'B2'] | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  var v = $(':radio').fieldValue(); | 
					
						
							|  |  |  |  *  // if neither radio is checked
 | 
					
						
							|  |  |  |  *  v === undefined | 
					
						
							|  |  |  |  *  // if first radio is checked
 | 
					
						
							|  |  |  |  *  v == ['C1'] | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The successful argument controls whether or not the field element must be 'successful' | 
					
						
							|  |  |  |  * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 | 
					
						
							|  |  |  |  * The default value of the successful argument is true.  If this value is false the value(s) | 
					
						
							|  |  |  |  * for each element is returned. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Note: This method *always* returns an array.  If no valid value can be determined the | 
					
						
							|  |  |  |  *       array will be empty, otherwise it will contain one or more values. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.fieldValue = function(successful) { | 
					
						
							|  |  |  |     for (var val=[], i=0, max=this.length; i < max; i++) { | 
					
						
							|  |  |  |         var el = this[i]; | 
					
						
							|  |  |  |         var v = $.fieldValue(el, successful); | 
					
						
							|  |  |  |         if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         v.constructor == Array ? $.merge(val, v) : val.push(v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return val; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Returns the value of the field element. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fieldValue = function(el, successful) { | 
					
						
							|  |  |  |     var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); | 
					
						
							|  |  |  |     if (typeof successful == 'undefined') successful = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || | 
					
						
							|  |  |  |         (t == 'checkbox' || t == 'radio') && !el.checked || | 
					
						
							|  |  |  |         (t == 'submit' || t == 'image') && el.form && el.form.clk != el || | 
					
						
							|  |  |  |         tag == 'select' && el.selectedIndex == -1)) | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tag == 'select') { | 
					
						
							|  |  |  |         var index = el.selectedIndex; | 
					
						
							|  |  |  |         if (index < 0) return null; | 
					
						
							|  |  |  |         var a = [], ops = el.options; | 
					
						
							|  |  |  |         var one = (t == 'select-one'); | 
					
						
							|  |  |  |         var max = (one ? index+1 : ops.length); | 
					
						
							|  |  |  |         for(var i=(one ? index : 0); i < max; i++) { | 
					
						
							|  |  |  |             var op = ops[i]; | 
					
						
							|  |  |  |             if (op.selected) { | 
					
						
							|  |  |  |                 // extra pain for IE...
 | 
					
						
							|  |  |  |                 var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value; | 
					
						
							|  |  |  |                 if (one) return v; | 
					
						
							|  |  |  |                 a.push(v); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return a; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return el.value; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Clears the form data.  Takes the following actions on the form's input fields: | 
					
						
							|  |  |  |  *  - input text fields will have their 'value' property set to the empty string | 
					
						
							|  |  |  |  *  - select elements will have their 'selectedIndex' property set to -1 | 
					
						
							|  |  |  |  *  - checkbox and radio inputs will have their 'checked' property set to false | 
					
						
							|  |  |  |  *  - inputs of type submit, button, reset, and hidden will *not* be effected | 
					
						
							|  |  |  |  *  - button elements will *not* be effected | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.clearForm = function() { | 
					
						
							|  |  |  |     return this.each(function() { | 
					
						
							|  |  |  |         $('input,select,textarea', this).clearFields(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Clears the selected form elements. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.clearFields = $.fn.clearInputs = function() { | 
					
						
							|  |  |  |     return this.each(function() { | 
					
						
							|  |  |  |         var t = this.type, tag = this.tagName.toLowerCase(); | 
					
						
							|  |  |  |         if (t == 'file' || t == 'text' || t == 'password' || tag == 'textarea') | 
					
						
							|  |  |  |             this.value = ''; | 
					
						
							|  |  |  |         else if (t == 'checkbox' || t == 'radio') | 
					
						
							|  |  |  |             this.checked = false; | 
					
						
							|  |  |  |         else if (tag == 'select') | 
					
						
							|  |  |  |             this.selectedIndex = -1; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Resets the form data.  Causes all form elements to be reset to their original value. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.resetForm = function() { | 
					
						
							|  |  |  |     return this.each(function() { | 
					
						
							|  |  |  |         // guard against an input with the name of 'reset'
 | 
					
						
							|  |  |  |         // note that IE reports the reset function as an 'object'
 | 
					
						
							|  |  |  |         if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) | 
					
						
							|  |  |  |             this.reset(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Enables or disables any matching elements. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.enable = function(b) {  | 
					
						
							|  |  |  |     if (b == undefined) b = true; | 
					
						
							|  |  |  |     return this.each(function() {  | 
					
						
							|  |  |  |         this.disabled = !b  | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Checks/unchecks any matching checkboxes or radio buttons and | 
					
						
							|  |  |  |  * selects/deselects and matching option elements. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | $.fn.selected = function(select) { | 
					
						
							|  |  |  |     if (select == undefined) select = true; | 
					
						
							|  |  |  |     return this.each(function() {  | 
					
						
							|  |  |  |         var t = this.type; | 
					
						
							|  |  |  |         if (t == 'checkbox' || t == 'radio') | 
					
						
							|  |  |  |             this.checked = select; | 
					
						
							|  |  |  |         else if (this.tagName.toLowerCase() == 'option') { | 
					
						
							|  |  |  |             var $sel = $(this).parent('select'); | 
					
						
							|  |  |  |             if (select && $sel[0] && $sel[0].type == 'select-one') { | 
					
						
							|  |  |  |                 // deselect all other options
 | 
					
						
							|  |  |  |                 $sel.find('option').selected(false); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             this.selected = select; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // helper fn for console logging
 | 
					
						
							|  |  |  | // set $.fn.ajaxSubmit.debug to true to enable debug logging
 | 
					
						
							|  |  |  | function log() { | 
					
						
							|  |  |  |     if ($.fn.ajaxSubmit.debug && window.console && window.console.log) | 
					
						
							|  |  |  |         window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,'')); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | })(jQuery); |