981 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			981 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * jQuery Form Plugin
							 | 
						||
| 
								 | 
							
								 * version: 2.94 (13-DEC-2011)
							 | 
						||
| 
								 | 
							
								 * @requires jQuery v1.3.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
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								;(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(e) {
							 | 
						||
| 
								 | 
							
											e.preventDefault(); // <-- important
							 | 
						||
| 
								 | 
							
											$(this).ajaxSubmit({
							 | 
						||
| 
								 | 
							
												target: '#output'
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var method, action, url, $form = this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (typeof options == 'function') {
							 | 
						||
| 
								 | 
							
										options = { success: options };
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									method = this.attr('method');
							 | 
						||
| 
								 | 
							
									action = this.attr('action');
							 | 
						||
| 
								 | 
							
									url = (typeof action === 'string') ? $.trim(action) : '';
							 | 
						||
| 
								 | 
							
									url = url || window.location.href || '';
							 | 
						||
| 
								 | 
							
									if (url) {
							 | 
						||
| 
								 | 
							
										// clean url (don't include hash vaue)
							 | 
						||
| 
								 | 
							
										url = (url.match(/^([^#]+)/)||[])[1];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									options = $.extend(true, {
							 | 
						||
| 
								 | 
							
										url:  url,
							 | 
						||
| 
								 | 
							
										success: $.ajaxSettings.success,
							 | 
						||
| 
								 | 
							
										type: method || 'GET',
							 | 
						||
| 
								 | 
							
										iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
							 | 
						||
| 
								 | 
							
									}, 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 traditional = options.traditional;
							 | 
						||
| 
								 | 
							
									if ( traditional === undefined ) {
							 | 
						||
| 
								 | 
							
										traditional = $.ajaxSettings.traditional;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var qx,n,v,a = this.formToArray(options.semantic);
							 | 
						||
| 
								 | 
							
									if (options.data) {
							 | 
						||
| 
								 | 
							
										options.extraData = options.data;
							 | 
						||
| 
								 | 
							
										qx = $.param(options.data, traditional);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// 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, traditional);
							 | 
						||
| 
								 | 
							
									if (qx) {
							 | 
						||
| 
								 | 
							
										q = ( q ? (q + '&' + qx) : qx );
							 | 
						||
| 
								 | 
							
									}	
							 | 
						||
| 
								 | 
							
									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 callbacks = [];
							 | 
						||
| 
								 | 
							
									if (options.resetForm) {
							 | 
						||
| 
								 | 
							
										callbacks.push(function() { $form.resetForm(); });
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (options.clearForm) {
							 | 
						||
| 
								 | 
							
										callbacks.push(function() { $form.clearForm(options.includeHidden); });
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// 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) {
							 | 
						||
| 
								 | 
							
											var fn = options.replaceTarget ? 'replaceWith' : 'html';
							 | 
						||
| 
								 | 
							
											$(options.target)[fn](data).each(oldSuccess, arguments);
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if (options.success) {
							 | 
						||
| 
								 | 
							
										callbacks.push(options.success);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
							 | 
						||
| 
								 | 
							
										var context = options.context || options;	// jQuery 1.4+ supports scope context 
							 | 
						||
| 
								 | 
							
										for (var i=0, max=callbacks.length; i < max; i++) {
							 | 
						||
| 
								 | 
							
											callbacks[i].apply(context, [data, status, xhr || $form, $form]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// are there files to upload?
							 | 
						||
| 
								 | 
							
									var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
							 | 
						||
| 
								 | 
							
									var hasFileInputs = fileInputs.length > 0;
							 | 
						||
| 
								 | 
							
									var mp = 'multipart/form-data';
							 | 
						||
| 
								 | 
							
									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
							 | 
						||
| 
								 | 
							
									// 06-NOV-09: now defaulting to iframe mode if file input is detected
							 | 
						||
| 
								 | 
							
									if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
							 | 
						||
| 
								 | 
							
										// hack to fix Safari hang (thanks to Tim Molendijk for this)
							 | 
						||
| 
								 | 
							
										// see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
							 | 
						||
| 
								 | 
							
										if (options.closeKeepAlive) {
							 | 
						||
| 
								 | 
							
											$.get(options.closeKeepAlive, function() {
							 | 
						||
| 
								 | 
							
												fileUploadIframe(a);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								  		else {
							 | 
						||
| 
								 | 
							
											fileUploadIframe(a);
							 | 
						||
| 
								 | 
							
								  		}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if ((hasFileInputs || multipart) && fileAPI) {
							 | 
						||
| 
								 | 
							
										options.progress = options.progress || $.noop;
							 | 
						||
| 
								 | 
							
										fileUploadXhr(a);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										$.ajax(options);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									 // fire 'notify' event
							 | 
						||
| 
								 | 
							
									 this.trigger('form-submit-notify', [this, options]);
							 | 
						||
| 
								 | 
							
									 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!)
							 | 
						||
| 
								 | 
							
									function fileUploadIframe(a) {
							 | 
						||
| 
								 | 
							
										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 there is an input with a name or id of 'submit' then we won't be
							 | 
						||
| 
								 | 
							
											// able to invoke the submit fn on the form (at least not x-browser)
							 | 
						||
| 
								 | 
							
											alert('Error: Form elements must not have name or id of "submit".');
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										s = $.extend(true, {}, $.ajaxSettings, options);
							 | 
						||
| 
								 | 
							
										s.context = s.context || s;
							 | 
						||
| 
								 | 
							
										id = 'jqFormIO' + (new Date().getTime());
							 | 
						||
| 
								 | 
							
										if (s.iframeTarget) {
							 | 
						||
| 
								 | 
							
											$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 = $io[0];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										xhr = { // mock object
							 | 
						||
| 
								 | 
							
											aborted: 0,
							 | 
						||
| 
								 | 
							
											responseText: null,
							 | 
						||
| 
								 | 
							
											responseXML: null,
							 | 
						||
| 
								 | 
							
											status: 0,
							 | 
						||
| 
								 | 
							
											statusText: 'n/a',
							 | 
						||
| 
								 | 
							
											getAllResponseHeaders: function() {},
							 | 
						||
| 
								 | 
							
											getResponseHeader: function() {},
							 | 
						||
| 
								 | 
							
											setRequestHeader: function() {},
							 | 
						||
| 
								 | 
							
											abort: function(status) {
							 | 
						||
| 
								 | 
							
												var e = (status === 'timeout' ? 'timeout' : 'aborted');
							 | 
						||
| 
								 | 
							
												log('aborting upload... ' + e);
							 | 
						||
| 
								 | 
							
												this.aborted = 1;
							 | 
						||
| 
								 | 
							
												$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);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										g = s.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, s]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
							 | 
						||
| 
								 | 
							
											if (s.global) {
							 | 
						||
| 
								 | 
							
												$.active--;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (xhr.aborted) {
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// add submitting element to data if we know it
							 | 
						||
| 
								 | 
							
										sub = form.clk;
							 | 
						||
| 
								 | 
							
										if (sub) {
							 | 
						||
| 
								 | 
							
											n = sub.name;
							 | 
						||
| 
								 | 
							
											if (n && !sub.disabled) {
							 | 
						||
| 
								 | 
							
												s.extraData = s.extraData || {};
							 | 
						||
| 
								 | 
							
												s.extraData[n] = sub.value;
							 | 
						||
| 
								 | 
							
												if (sub.type == "image") {
							 | 
						||
| 
								 | 
							
													s.extraData[n+'.x'] = form.clk_x;
							 | 
						||
| 
								 | 
							
													s.extraData[n+'.y'] = form.clk_y;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										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
							 | 
						||
| 
								 | 
							
										function doSubmit() {
							 | 
						||
| 
								 | 
							
											// make sure form attrs are set
							 | 
						||
| 
								 | 
							
											var t = $form.attr('target'), a = $form.attr('action');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// update form attrs in IE friendly way
							 | 
						||
| 
								 | 
							
											form.setAttribute('target',id);
							 | 
						||
| 
								 | 
							
											if (!method) {
							 | 
						||
| 
								 | 
							
												form.setAttribute('method', 'POST');
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (a != s.url) {
							 | 
						||
| 
								 | 
							
												form.setAttribute('action', s.url);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// ie borks in some cases when setting encoding
							 | 
						||
| 
								 | 
							
											if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
							 | 
						||
| 
								 | 
							
												$form.attr({
							 | 
						||
| 
								 | 
							
													encoding: 'multipart/form-data',
							 | 
						||
| 
								 | 
							
													enctype:  'multipart/form-data'
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// support timout
							 | 
						||
| 
								 | 
							
											if (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
							 | 
						||
| 
								 | 
							
											var extraInputs = [];
							 | 
						||
| 
								 | 
							
											try {
							 | 
						||
| 
								 | 
							
												if (s.extraData) {
							 | 
						||
| 
								 | 
							
													for (var n in s.extraData) {
							 | 
						||
| 
								 | 
							
														extraInputs.push(
							 | 
						||
| 
								 | 
							
															$('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
							 | 
						||
| 
								 | 
							
																.appendTo(form)[0]);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if (!s.iframeTarget) {
							 | 
						||
| 
								 | 
							
													// add iframe to doc and submit the form
							 | 
						||
| 
								 | 
							
													$io.appendTo('body');
							 | 
						||
| 
								 | 
							
													io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												setTimeout(checkState,15);
							 | 
						||
| 
								 | 
							
												form.submit();
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											finally {
							 | 
						||
| 
								 | 
							
												// reset attrs and remove "extra" input elements
							 | 
						||
| 
								 | 
							
												form.setAttribute('action',a);
							 | 
						||
| 
								 | 
							
												if(t) {
							 | 
						||
| 
								 | 
							
													form.setAttribute('target', t);
							 | 
						||
| 
								 | 
							
												} else {
							 | 
						||
| 
								 | 
							
													$form.removeAttr('target');
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												$(extraInputs).remove();
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (s.forceSync) {
							 | 
						||
| 
								 | 
							
											doSubmit();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											setTimeout(doSubmit, 10); // this lets dom updates render
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										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;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (!doc || doc.location.href == s.iframeSrc) {
							 | 
						||
| 
								 | 
							
												// response not received yet
							 | 
						||
| 
								 | 
							
												if (!timedOut)
							 | 
						||
| 
								 | 
							
													return;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var status = 'success', errMsg;
							 | 
						||
| 
								 | 
							
											try {
							 | 
						||
| 
								 | 
							
												if (timedOut) {
							 | 
						||
| 
								 | 
							
													throw 'timeout';
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
							 | 
						||
| 
								 | 
							
												log('isXml='+isXml);
							 | 
						||
| 
								 | 
							
												if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
							 | 
						||
| 
								 | 
							
													if (--domCheckCount) {
							 | 
						||
| 
								 | 
							
														// in some browsers (Opera) the iframe DOM is not always traversable when
							 | 
						||
| 
								 | 
							
														// the onload callback fires, so we loop a bit to accommodate
							 | 
						||
| 
								 | 
							
														log('requeing onLoad callback, DOM not available');
							 | 
						||
| 
								 | 
							
														setTimeout(cb, 250);
							 | 
						||
| 
								 | 
							
														return;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													// let this fall through because server response could be an empty document
							 | 
						||
| 
								 | 
							
													//log('Could not access iframe DOM after mutiple tries.');
							 | 
						||
| 
								 | 
							
													//throw 'DOMException: not available';
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												//log('response detected');
							 | 
						||
| 
								 | 
							
												var docRoot = doc.body ? doc.body : doc.documentElement;
							 | 
						||
| 
								 | 
							
												xhr.responseText = docRoot ? docRoot.innerHTML : null;
							 | 
						||
| 
								 | 
							
												xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
							 | 
						||
| 
								 | 
							
												if (isXml)
							 | 
						||
| 
								 | 
							
													s.dataType = 'xml';
							 | 
						||
| 
								 | 
							
												xhr.getResponseHeader = function(header){
							 | 
						||
| 
								 | 
							
													var headers = {'content-type': s.dataType};
							 | 
						||
| 
								 | 
							
													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 dt = (s.dataType || '').toLowerCase();
							 | 
						||
| 
								 | 
							
												var scr = /(json|script|text)/.test(dt);
							 | 
						||
| 
								 | 
							
												if (scr || s.textarea) {
							 | 
						||
| 
								 | 
							
													// see if user embedded response in textarea
							 | 
						||
| 
								 | 
							
													var ta = doc.getElementsByTagName('textarea')[0];
							 | 
						||
| 
								 | 
							
													if (ta) {
							 | 
						||
| 
								 | 
							
														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) {
							 | 
						||
| 
								 | 
							
														// account for browsers injecting pre around json response
							 | 
						||
| 
								 | 
							
														var pre = doc.getElementsByTagName('pre')[0];
							 | 
						||
| 
								 | 
							
														var b = doc.getElementsByTagName('body')[0];
							 | 
						||
| 
								 | 
							
														if (pre) {
							 | 
						||
| 
								 | 
							
															xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else if (b) {
							 | 
						||
| 
								 | 
							
															xhr.responseText = b.textContent ? b.textContent : b.innerText;
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else if (dt == 'xml' && !xhr.responseXML && xhr.responseText != null) {
							 | 
						||
| 
								 | 
							
													xhr.responseXML = toXml(xhr.responseText);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												try {
							 | 
						||
| 
								 | 
							
													data = httpData(xhr, dt, s);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												catch (e) {
							 | 
						||
| 
								 | 
							
													status = 'parsererror';
							 | 
						||
| 
								 | 
							
													xhr.error = errMsg = (e || status);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											catch (e) {
							 | 
						||
| 
								 | 
							
												log('error caught: ',e);
							 | 
						||
| 
								 | 
							
												status = 'error';
							 | 
						||
| 
								 | 
							
												xhr.error = errMsg = (e || status);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (xhr.aborted) {
							 | 
						||
| 
								 | 
							
												log('upload aborted');
							 | 
						||
| 
								 | 
							
												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
							 | 
						||
| 
								 | 
							
											if (status === 'success') {
							 | 
						||
| 
								 | 
							
												s.success && s.success.call(s.context, data, 'success', xhr);
							 | 
						||
| 
								 | 
							
												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]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (g && ! --$.active) {
							 | 
						||
| 
								 | 
							
												$.event.trigger("ajaxStop");
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											s.complete && s.complete.call(s.context, xhr, status);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											callbackProcessed = true;
							 | 
						||
| 
								 | 
							
											if (s.timeout)
							 | 
						||
| 
								 | 
							
												clearTimeout(timeoutHandle);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// clean up
							 | 
						||
| 
								 | 
							
											setTimeout(function() {
							 | 
						||
| 
								 | 
							
												if (!s.iframeTarget)
							 | 
						||
| 
								 | 
							
													$io.remove();
							 | 
						||
| 
								 | 
							
												xhr.responseXML = null;
							 | 
						||
| 
								 | 
							
											}, 100);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
							 | 
						||
| 
								 | 
							
											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.nodeName != 'parsererror') ? doc : null;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
										var parseJSON = $.parseJSON || function(s) {
							 | 
						||
| 
								 | 
							
											return window['eval']('(' + s + ')');
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var ct = xhr.getResponseHeader('content-type') || '',
							 | 
						||
| 
								 | 
							
												xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
							 | 
						||
| 
								 | 
							
												data = xml ? xhr.responseXML : xhr.responseText;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (xml && data.documentElement.nodeName === 'parsererror') {
							 | 
						||
| 
								 | 
							
												$.error && $.error('parsererror');
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (s && s.dataFilter) {
							 | 
						||
| 
								 | 
							
												data = s.dataFilter(data, type);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (typeof data === 'string') {
							 | 
						||
| 
								 | 
							
												if (type === 'json' || !type && ct.indexOf('json') >= 0) {
							 | 
						||
| 
								 | 
							
													data = parseJSON(data);
							 | 
						||
| 
								 | 
							
												} else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
							 | 
						||
| 
								 | 
							
													$.globalEval(data);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return data;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * 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) {
							 | 
						||
| 
								 | 
							
									// in jQuery 1.3+ we can fix mistakes with the ready state
							 | 
						||
| 
								 | 
							
									if (this.length === 0) {
							 | 
						||
| 
								 | 
							
										var o = { s: this.selector, c: this.context };
							 | 
						||
| 
								 | 
							
										if (!$.isReady && o.s) {
							 | 
						||
| 
								 | 
							
											log('DOM not ready, queuing ajaxForm');
							 | 
						||
| 
								 | 
							
											$(function() {
							 | 
						||
| 
								 | 
							
												$(o.s,o.c).ajaxForm(options);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
											return this;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										// is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
							 | 
						||
| 
								 | 
							
										log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
							 | 
						||
| 
								 | 
							
										return this;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
							 | 
						||
| 
								 | 
							
										if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
							 | 
						||
| 
								 | 
							
											e.preventDefault();
							 | 
						||
| 
								 | 
							
											$(this).ajaxSubmit(options);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}).bind('click.form-plugin', function(e) {
							 | 
						||
| 
								 | 
							
										var target = e.target;
							 | 
						||
| 
								 | 
							
										var $el = $(target);
							 | 
						||
| 
								 | 
							
										if (!($el.is(":submit,input:image"))) {
							 | 
						||
| 
								 | 
							
											// is this a child element of the submit el?  (ex: a span within a button)
							 | 
						||
| 
								 | 
							
											var t = $el.closest(':submit');
							 | 
						||
| 
								 | 
							
											if (t.length == 0) {
							 | 
						||
| 
								 | 
							
												return;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											target = t[0];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										var form = this;
							 | 
						||
| 
								 | 
							
										form.clk = target;
							 | 
						||
| 
								 | 
							
										if (target.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 = $el.offset();
							 | 
						||
| 
								 | 
							
												form.clk_x = e.pageX - offset.left;
							 | 
						||
| 
								 | 
							
												form.clk_y = e.pageY - offset.top;
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												form.clk_x = e.pageX - target.offsetLeft;
							 | 
						||
| 
								 | 
							
												form.clk_y = e.pageY - target.offsetTop;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										// clear form vars
							 | 
						||
| 
								 | 
							
										setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
							 | 
						||
| 
								 | 
							
									});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
							 | 
						||
| 
								 | 
							
								$.fn.ajaxFormUnbind = function() {
							 | 
						||
| 
								 | 
							
									return this.unbind('submit.form-plugin 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;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var i,j,n,v,el,max,jmax;
							 | 
						||
| 
								 | 
							
									for(i=0, max=els.length; i < max; i++) {
							 | 
						||
| 
								 | 
							
										el = els[i];
							 | 
						||
| 
								 | 
							
										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, value: $(el).val(), type: el.type });
							 | 
						||
| 
								 | 
							
												a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											continue;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										v = $.fieldValue(el, true);
							 | 
						||
| 
								 | 
							
										if (v && v.constructor == Array) {
							 | 
						||
| 
								 | 
							
											for(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, type: el.type});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (!semantic && form.clk) {
							 | 
						||
| 
								 | 
							
										// input type=='image' are not found in elements array! handle it here
							 | 
						||
| 
								 | 
							
										var $input = $(form.clk), input = $input[0];
							 | 
						||
| 
								 | 
							
										n = input.name;
							 | 
						||
| 
								 | 
							
										if (n && !input.disabled && input.type == 'image') {
							 | 
						||
| 
								 | 
							
											a.push({name: n, value: $input.val()});
							 | 
						||
| 
								 | 
							
											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 (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) {
							 | 
						||
| 
								 | 
							
												var v = op.value;
							 | 
						||
| 
								 | 
							
												if (!v) { // extra pain for IE...
							 | 
						||
| 
								 | 
							
													v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if (one) {
							 | 
						||
| 
								 | 
							
													return v;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												a.push(v);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return a;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return $(el).val();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * 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(includeHidden) {
							 | 
						||
| 
								 | 
							
									return this.each(function() {
							 | 
						||
| 
								 | 
							
										$('input,select,textarea', this).clearFields(includeHidden);
							 | 
						||
| 
								 | 
							
									});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Clears the selected form elements.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								$.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() {
							 | 
						||
| 
								 | 
							
										var t = this.type, tag = this.tagName.toLowerCase();
							 | 
						||
| 
								 | 
							
										if (re.test(t) || tag == 'textarea' || (includeHidden && /hidden/.test(t)) ) {
							 | 
						||
| 
								 | 
							
											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;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// expose debug var
							 | 
						||
| 
								 | 
							
								$.fn.ajaxSubmit.debug = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// helper fn for console logging
							 | 
						||
| 
								 | 
							
								function log() {
							 | 
						||
| 
								 | 
							
									if (!$.fn.ajaxSubmit.debug) 
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
							 | 
						||
| 
								 | 
							
									if (window.console && window.console.log) {
							 | 
						||
| 
								 | 
							
										window.console.log(msg);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if (window.opera && window.opera.postError) {
							 | 
						||
| 
								 | 
							
										window.opera.postError(msg);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								})(jQuery);
							 |