PageSourceSearch

https://www.stagesafety.or.kr/public/common/plugins/jquery/jquery.form.js

js stagesafety.or.kr collected 2026-10-08 02:11:23 UTC 28,152 bytes, 969 lines download raw bytes

1/*!
2 * jQuery Form Plugin
3 * version: 2.93 (30-NOV-2011)
4 * @requires jQuery v1.3.2 or later
5 *
6 * Examples and documentation at: http://malsup.com/jquery/form/
7 * Dual licensed under the MIT and GPL licenses:
8 *	http://www.opensource.org/licenses/mit-license.php
9 *	http://www.gnu.org/licenses/gpl.html
10 */
11;(function($) {
12
13/*
14	Usage Note:
15	-----------
16	Do not use both ajaxSubmit and ajaxForm on the same form.  These
17	functions are intended to be exclusive.  Use ajaxSubmit if you want
18	to bind your own submit handler to the form.  For example,
19
20	$(document).ready(function() {
21		$('#myForm').bind('submit', function(e) {
22			e.preventDefault(); // <-- important
23			$(this).ajaxSubmit({
24				target: '#output'
25			});
26		});
27	});
28
29	Use ajaxForm when you want the plugin to manage all the event binding
30	for you.  For example,
31
32	$(document).ready(function() {
33		$('#myForm').ajaxForm({
34			target: '#output'
35		});
36	});
37
38	When using ajaxForm, the ajaxSubmit function will be invoked for you
39	at the appropriate time.
40*/
41
42/**
43 * ajaxSubmit() provides a mechanism for immediately submitting
44 * an HTML form using AJAX.
45 */
46$.fn.ajaxSubmit = function(options) {
47	// fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
48	if (!this.length) {
49		log('ajaxSubmit: skipping submit process - no element selected');
50		return this;
51	}
52	
53	var method, action, url, $form = this;
54
55	if (typeof options == 'function') {
56		options = { success: options };
57	}
58
59	method = this.attr('method');
60	action = this.attr('action');
61	url = (typeof action === 'string') ? $.trim(action) : '';
62	url = url || window.location.href || '';
63	if (url) {
64		// clean url (don't include hash vaue)
65		url = (url.match(/^([^#]+)/)||[])[1];
66	}
67
68	options = $.extend(true, {
69		url:  url,
70		success: $.ajaxSettings.success,
71		type: method || 'GET',
72		iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
73	}, options);
74
75	// hook for manipulating the form data before it is extracted;
76	// convenient for use with rich editors like tinyMCE or FCKEditor
77	var veto = {};
78	this.trigger('form-pre-serialize', [this, options, veto]);
79	if (veto.veto) {
80		log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
81		return this;
82	}
83
84	// provide opportunity to alter form data before it is serialized
85	if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
86		log('ajaxSubmit: submit aborted via beforeSerialize callback');
87		return this;
88	}
89
90	var traditional = options.traditional;
91	if ( traditional === undefined ) {
92		traditional = $.ajaxSettings.traditional;
93	}
94	
95	var qx,n,v,a = this.formToArray(options.semantic);
96	if (options.data) {
97		options.extraData = options.data;
98		qx = $.param(options.data, traditional);
99	}
100
101	// give pre-submit callback an opportunity to abort the submit
102	if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
103		log('ajaxSubmit: submit aborted via beforeSubmit callback');
104		return this;
105	}
106
107	// fire vetoable 'validate' event
108	this.trigger('form-submit-validate', [a, this, options, veto]);
109	if (veto.veto) {
110		log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
111		return this;
112	}
113
114	var q = $.param(a, traditional);
115	if (qx) {
116		q = ( q ? (q + '&' + qx) : qx );
117	}	
118	if (options.type.toUpperCase() == 'GET') {
119		options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
120		options.data = null;  // data is null for 'get'
121	}
122	else {
123		options.data = q; // data is the query string for 'post'
124	}
125
126	var callbacks = [];
127	if (options.resetForm) {
128		callbacks.push(function() { $form.resetForm(); });
129	}
130	if (options.clearForm) {
131		callbacks.push(function() { $form.clearForm(options.includeHidden); });
132	}
133
134	// perform a load on the target only if dataType is not provided
135	if (!options.dataType && options.target) {
136		var oldSuccess = options.success || function(){};
137		callbacks.push(function(data) {
138			var fn = options.replaceTarget ? 'replaceWith' : 'html';
139			$(options.target)[fn](data).each(oldSuccess, arguments);
140		});
141	}
142	else if (options.success) {
143		callbacks.push(options.success);
144	}
145
146	options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
147		var context = options.context || options;	// jQuery 1.4+ supports scope context 
148		for (var i=0, max=callbacks.length; i < max; i++) {
149			callbacks[i].apply(context, [data, status, xhr || $form, $form]);
150		}
151	};
152
153	// are there files to upload?
154	var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
155	var hasFileInputs = fileInputs.length > 0;
156	var mp = 'multipart/form-data';
157	var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
158
159	var fileAPI = !!(hasFileInputs && fileInputs.get(0).files && window.FormData);
160	log("fileAPI :" + fileAPI);
161	var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
162
163	// options.iframe allows user to force iframe mode
164	// 06-NOV-09: now defaulting to iframe mode if file input is detected
165	if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
166		// hack to fix Safari hang (thanks to Tim Molendijk for this)
167		// see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
168		if (options.closeKeepAlive) {
169			$.get(options.closeKeepAlive, function() {
170				fileUploadIframe(a);
171			});
172		}
173  		else {
174			fileUploadIframe(a);
175  		}
176	}
177	else if ((hasFileInputs || multipart) && fileAPI) {
178		options.progress = options.progress || $.noop;
179		fileUploadXhr(a);
180	}
181	else {
182		$.ajax(options);
183	}
184
185	 // fire 'notify' event
186	 this.trigger('form-submit-notify', [this, options]);
187	 return this;
188
189	 // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
190	function fileUploadXhr(a) {
191		var formdata = new FormData();
192
193		for (var i=0; i < a.length; i++) {
194			if (a[i].type == 'file')
195				continue;
196			formdata.append(a[i].name, a[i].value);
197		}
198
199		$form.find('input:file:enabled').each(function(){
200			var name = $(this).attr('name'), files = this.files;
201			if (name) {
202				for (var i=0; i < files.length; i++)
203					formdata.append(name, files[i]);
204			}
205		});
206
207		if (options.extraData) {
208			for (var k in options.extraData)
209				formdata.append(k, options.extraData[k])
210		}
211
212		options.data = null;
213		var _beforeSend = options.beforeSend;
214		options.beforeSend = function(xhr, options) {
215			options.data = formdata;
216			if (xhr.upload) { // unfortunately, jQuery doesn't expose this prop (http://bugs.jquery.com/ticket/10190)
217				xhr.upload.onprogress = function(event) {
218					options.progress(event.position, event.total);
219				}
220			}
221			if (_beforeSend)
222				_beforeSend.call(options, xhr, options);
223		}
224		$.ajax(options);
225	}
226
227	// private function for handling file uploads (hat tip to YAHOO!)
228	function fileUploadIframe(a) {
229		var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
230		var useProp = !!$.fn.prop;
231
232		if (a) {
233			if ( useProp ) {
234				// ensure that every serialized input is still enabled
235				for (i=0; i < a.length; i++) {
236					el = $(form[a[i].name]);
237					el.prop('disabled', false);
238				}
239			} else {
240				for (i=0; i < a.length; i++) {
241					el = $(form[a[i].name]);
242					el.removeAttr('disabled');
243				}
244			};
245		}
246
247		if ($(':input[name=submit],:input[id=submit]', form).length) {
248			// if there is an input with a name or id of 'submit' then we won't be
249			// able to invoke the submit fn on the form (at least not x-browser)
250			alert('Error: Form elements must not have name or id of "submit".');
251			return;
252		}
253		
254		s = $.extend(true, {}, $.ajaxSettings, options);
255		s.context = s.context || s;
256		id = 'jqFormIO' + (new Date().getTime());
257		if (s.iframeTarget) {
258			$io = $(s.iframeTarget);
259			n = $io.attr('name');
260			if (n == null)
261			 	$io.attr('name', id);
262			else
263				id = n;
264		}
265		else {
266			$io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
267			$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
268		}
269		io = $io[0];
270
271
272		xhr = { // mock object
273			aborted: 0,
274			responseText: null,
275			responseXML: null,
276			status: 0,
277			statusText: 'n/a',
278			getAllResponseHeaders: function() {},
279			getResponseHeader: function() {},
280			setRequestHeader: function() {},
281			abort: function(status) {
282				var e = (status === 'timeout' ? 'timeout' : 'aborted');
283				log('aborting upload... ' + e);
284				this.aborted = 1;
285				$io.attr('src', s.iframeSrc); // abort op in progress
286				xhr.error = e;
287				s.error && s.error.call(s.context, xhr, e, status);
288				g && $.event.trigger("ajaxError", [xhr, s, e]);
289				s.complete && s.complete.call(s.context, xhr, e);
290			}
291		};
292
293		g = s.global;
294		// trigger ajax global events so that activity/block indicators work like normal
295		if (g && ! $.active++) {
296			$.event.trigger("ajaxStart");
297		}
298		if (g) {
299			$.event.trigger("ajaxSend", [xhr, s]);
300		}
301
302		if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
303			if (s.global) {
304				$.active--;
305			}
306			return;
307		}
308		if (xhr.aborted) {
309			return;
310		}
311
312		// add submitting element to data if we know it
313		sub = form.clk;
314		if (sub) {
315			n = sub.name;
316			if (n && !sub.disabled) {
317				s.extraData = s.extraData || {};
318				s.extraData[n] = sub.value;
319				if (sub.type == "image") {
320					s.extraData[n+'.x'] = form.clk_x;
321					s.extraData[n+'.y'] = form.clk_y;
322				}
323			}
324		}
325		
326		var CLIENT_TIMEOUT_ABORT = 1;
327		var SERVER_ABORT = 2;
328
329		function getDoc(frame) {
330			var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
331			return doc;
332		}
333		
334		// Rails CSRF hack (thanks to Yvan BARTH긌EMY)
335		var csrf_token = $('meta[name=csrf-token]').attr('content');
336		var csrf_param = $('meta[name=csrf-param]').attr('content');
337		if (csrf_param && csrf_token) {
338			s.extraData = s.extraData || {};
339			s.extraData[csrf_param] = csrf_token;
340		}
341
342		// take a breath so that pending repaints get some cpu time before the upload starts
343		function doSubmit() {
344			// make sure form attrs are set
345			var t = $form.attr('target'), a = $form.attr('action');
346
347			// update form attrs in IE friendly way
348			form.setAttribute('target',id);
349			if (!method) {
350				form.setAttribute('method', 'POST');
351			}
352			if (a != s.url) {
353				form.setAttribute('action', s.url);
354			}
355
356			// ie borks in some cases when setting encoding
357			if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
358				$form.attr({
359					encoding: 'multipart/form-data',
360					enctype:  'multipart/form-data'
361				});
362			}
363
364			// support timout
365			if (s.timeout) {
366				timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
367			}
368			
369			// look for server aborts
370			function checkState() {
371				try {
372					var state = getDoc(io).readyState;
373					log('state = ' + state);
374					if (state.toLowerCase() == 'uninitialized')
375						setTimeout(checkState,50);
376				}
377				catch(e) {
378					log('Server abort: ' , e, ' (', e.name, ')');
379					cb(SERVER_ABORT);
380					timeoutHandle && clearTimeout(timeoutHandle);
381					timeoutHandle = undefined;
382				}
383			}
384
385			// add "extra" data to form if provided in options
386			var extraInputs = [];
387			try {
388				if (s.extraData) {
389					for (var n in s.extraData) {
390						extraInputs.push(
391							$('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
392								.appendTo(form)[0]);
393					}
394				}
395
396				if (!s.iframeTarget) {
397					// add iframe to doc and submit the form
398					$io.appendTo('body');
399					io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
400				}
401				setTimeout(checkState,15);
402				form.submit();
403			}
404			finally {
405				// reset attrs and remove "extra" input elements
406				form.setAttribute('action',a);
407				if(t) {
408					form.setAttribute('target', t);
409				} else {
410					$form.removeAttr('target');
411				}
412				$(extraInputs).remove();
413			}
414		}
415
416		if (s.forceSync) {
417			doSubmit();
418		}
419		else {
420			setTimeout(doSubmit, 10); // this lets dom updates render
421		}
422
423		var data, doc, domCheckCount = 50, callbackProcessed;
424
425		function cb(e) {
426			if (xhr.aborted || callbackProcessed) {
427				return;
428			}
429			try {
430				doc = getDoc(io);
431			}
432			catch(ex) {
433				log('cannot access response document: ', ex);
434				e = SERVER_ABORT;
435			}
436			if (e === CLIENT_TIMEOUT_ABORT && xhr) {
437				xhr.abort('timeout');
438				return;
439			}
440			else if (e == SERVER_ABORT && xhr) {
441				xhr.abort('server abort');
442				return;
443			}
444
445			if (!doc || doc.location.href == s.iframeSrc) {
446				// response not received yet
447				if (!timedOut)
448					return;
449			}
450			io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
451
452			var status = 'success', errMsg;
453			try {
454				if (timedOut) {
455					throw 'timeout';
456				}
457
458				var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
459				log('isXml='+isXml);
460				if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
461					if (--domCheckCount) {
462						// in some browsers (Opera) the iframe DOM is not always traversable when
463						// the onload callback fires, so we loop a bit to accommodate
464						log('requeing onLoad callback, DOM not available');
465						setTimeout(cb, 250);
466						return;
467					}
468					// let this fall through because server response could be an empty document
469					//log('Could not access iframe DOM after mutiple tries.');
470					//throw 'DOMException: not available';
471				}
472
473				//log('response detected');
474				var docRoot = doc.body ? doc.body : doc.documentElement;
475				xhr.responseText = docRoot ? docRoot.innerHTML : null;
476				xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
477				if (isXml)
478					s.dataType = 'xml';
479				xhr.getResponseHeader = function(header){
480					var headers = {'content-type': s.dataType};
481					return headers[header];
482				};
483				// support for XHR 'status' & 'statusText' emulation :
484				if (docRoot) {
485					xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
486					xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
487				}
488
489				var dt = (s.dataType || '').toLowerCase();
490				var scr = /(json|script|text)/.test(dt);
491				if (scr || s.textarea) {
492					// see if user embedded response in textarea
493					var ta = doc.getElementsByTagName('textarea')[0];
494					if (ta) {
495						xhr.responseText = ta.value;
496						// support for XHR 'status' & 'statusText' emulation :
497						xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
498						xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
499					}
500					else if (scr) {
501						// account for browsers injecting pre around json response
502						var pre = doc.getElementsByTagName('pre')[0];
503						var b = doc.getElementsByTagName('body')[0];
504						if (pre) {
505							xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
506						}
507						else if (b) {
508							xhr.responseText = b.textContent ? b.textContent : b.innerText;
509						}
510					}
511				}
512				else if (dt == 'xml' && !xhr.responseXML && xhr.responseText != null) {
513					xhr.responseXML = toXml(xhr.responseText);
514				}
515
516				try {
517					data = httpData(xhr, dt, s);
518				}
519				catch (e) {
520					status = 'parsererror';
521					xhr.error = errMsg = (e || status);
522				}
523			}
524			catch (e) {
525				log('error caught: ',e);
526				status = 'error';
527				xhr.error = errMsg = (e || status);
528			}
529
530			if (xhr.aborted) {
531				log('upload aborted');
532				status = null;
533			}
534
535			if (xhr.status) { // we've set xhr.status
536				status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
537			}
538
539			// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
540			if (status === 'success') {
541				s.success && s.success.call(s.context, data, 'success', xhr);
542				g && $.event.trigger("ajaxSuccess", [xhr, s]);
543			}
544			else if (status) {
545				if (errMsg == undefined)
546					errMsg = xhr.statusText;
547				s.error && s.error.call(s.context, xhr, status, errMsg);
548				g && $.event.trigger("ajaxError", [xhr, s, errMsg]);
549			}
550
551			g && $.event.trigger("ajaxComplete", [xhr, s]);
552
553			if (g && ! --$.active) {
554				$.event.trigger("ajaxStop");
555			}
556
557			s.complete && s.complete.call(s.context, xhr, status);
558
559			callbackProcessed = true;
560			if (s.timeout)
561				clearTimeout(timeoutHandle);
562
563			// clean up
564			setTimeout(function() {
565				if (!s.iframeTarget)
566					$io.remove();
567				xhr.responseXML = null;
568			}, 100);
569		}
570
571		var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
572			if (window.ActiveXObject) {
573				doc = new ActiveXObject('Microsoft.XMLDOM');
574				doc.async = 'false';
575				doc.loadXML(s);
576			}
577			else {
578				doc = (new DOMParser()).parseFromString(s, 'text/xml');
579			}
580			return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
581		};
582		var parseJSON = $.parseJSON || function(s) {
583			return window['eval']('(' + s + ')');
584		};
585
586		var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
587
588			var ct = xhr.getResponseHeader('content-type') || '',
589				xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
590				data = xml ? xhr.responseXML : xhr.responseText;
591
592			if (xml && data.documentElement.nodeName === 'parsererror') {
593				$.error && $.error('parsererror');
594			}
595			if (s && s.dataFilter) {
596				data = s.dataFilter(data, type);
597			}
598			if (typeof data === 'string') {
599				if (type === 'json' || !type && ct.indexOf('json') >= 0) {
600					data = parseJSON(data);
601				} else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
602					$.globalEval(data);
603				}
604			}
605			return data;
606		};
607	}
608};
609
610/**
611 * ajaxForm() provides a mechanism for fully automating form submission.
612 *
613 * The advantages of using this method instead of ajaxSubmit() are:
614 *
615 * 1: This method will include coordinates for <input type="image" /> elements (if the element
616 *	is used to submit the form).
617 * 2. This method will include the submit element's name/value data (for the element that was
618 *	used to submit the form).
619 * 3. This method binds the submit() method to the form for you.
620 *
621 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
622 * passes the options argument along after properly binding events for submit elements and
623 * the form itself.
624 */
625$.fn.ajaxForm = function(options) {
626	// in jQuery 1.3+ we can fix mistakes with the ready state
627	if (this.length === 0) {
628		var o = { s: this.selector, c: this.context };
629		if (!$.isReady && o.s) {
630			log('DOM not ready, queuing ajaxForm');
631			$(function() {
632				$(o.s,o.c).ajaxForm(options);
633			});
634			return this;
635		}
636		// is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
637		log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
638		return this;
639	}
640
641	return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
642		if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
643			e.preventDefault();
644			$(this).ajaxSubmit(options);
645		}
646	}).bind('click.form-plugin', function(e) {
647		var target = e.target;
648		var $el = $(target);
649		if (!($el.is(":submit,input:image"))) {
650			// is this a child element of the submit el?  (ex: a span within a button)
651			var t = $el.closest(':submit');
652			if (t.length == 0) {
653				return;
654			}
655			target = t[0];
656		}
657		var form = this;
658		form.clk = target;
659		if (target.type == 'image') {
660			if (e.offsetX != undefined) {
661				form.clk_x = e.offsetX;
662				form.clk_y = e.offsetY;
663			} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
664				var offset = $el.offset();
665				form.clk_x = e.pageX - offset.left;
666				form.clk_y = e.pageY - offset.top;
667			} else {
668				form.clk_x = e.pageX - target.offsetLeft;
669				form.clk_y = e.pageY - target.offsetTop;
670			}
671		}
672		// clear form vars
673		setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
674	});
675};
676
677// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
678$.fn.ajaxFormUnbind = function() {
679	return this.unbind('submit.form-plugin click.form-plugin');
680};
681
682/**
683 * formToArray() gathers form element data into an array of objects that can
684 * be passed to any of the following ajax functions: $.get, $.post, or load.
685 * Each object in the array has both a 'name' and 'value' property.  An example of
686 * an array for a simple login form might be:
687 *
688 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
689 *
690 * It is this array that is passed to pre-submit callback functions provided to the
691 * ajaxSubmit() and ajaxForm() methods.
692 */
693$.fn.formToArray = function(semantic) {
694	var a = [];
695	if (this.length === 0) {
696		return a;
697	}
698
699	var form = this[0];
700	var els = semantic ? form.getElementsByTagName('*') : form.elements;
701	if (!els) {
702		return a;
703	}
704
705	var i,j,n,v,el,max,jmax;
706	for(i=0, max=els.length; i < max; i++) {
707		el = els[i];
708		n = el.name;
709		if (!n) {
710			continue;
711		}
712
713		if (semantic && form.clk && el.type == "image") {
714			// handle image inputs on the fly when semantic == true
715			if(!el.disabled && form.clk == el) {
716				a.push({name: n, value: $(el).val(), type: el.type });
717				a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
718			}
719			continue;
720		}
721
722		v = $.fieldValue(el, true);
723		if (v && v.constructor == Array) {
724			for(j=0, jmax=v.length; j < jmax; j++) {
725				a.push({name: n, value: v[j]});
726			}
727		}
728		else if (v !== null && typeof v != 'undefined') {
729			a.push({name: n, value: v, type: el.type});
730		}
731	}
732
733	if (!semantic && form.clk) {
734		// input type=='image' are not found in elements array! handle it here
735		var $input = $(form.clk), input = $input[0];
736		n = input.name;
737		if (n && !input.disabled && input.type == 'image') {
738			a.push({name: n, value: $input.val()});
739			a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
740		}
741	}
742	return a;
743};
744
745/**
746 * Serializes form data into a 'submittable' string. This method will return a string
747 * in the format: name1=value1&amp;name2=value2
748 */
749$.fn.formSerialize = function(semantic) {
750	//hand off to jQuery.param for proper encoding
751	return $.param(this.formToArray(semantic));
752};
753
754/**
755 * Serializes all field elements in the jQuery object into a query string.
756 * This method will return a string in the format: name1=value1&amp;name2=value2
757 */
758$.fn.fieldSerialize = function(successful) {
759	var a = [];
760	this.each(function() {
761		var n = this.name;
762		if (!n) {
763			return;
764		}
765		var v = $.fieldValue(this, successful);
766		if (v && v.constructor == Array) {
767			for (var i=0,max=v.length; i < max; i++) {
768				a.push({name: n, value: v[i]});
769			}
770		}
771		else if (v !== null && typeof v != 'undefined') {
772			a.push({name: this.name, value: v});
773		}
774	});
775	//hand off to jQuery.param for proper encoding
776	return $.param(a);
777};
778
779/**
780 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
781 *
782 *  <form><fieldset>
783 *	  <input name="A" type="text" />
784 *	  <input name="A" type="text" />
785 *	  <input name="B" type="checkbox" value="B1" />
786 *	  <input name="B" type="checkbox" value="B2"/>
787 *	  <input name="C" type="radio" value="C1" />
788 *	  <input name="C" type="radio" value="C2" />
789 *  </fieldset></form>
790 *
791 *  var v = $(':text').fieldValue();
792 *  // if no values are entered into the text inputs
793 *  v == ['','']
794 *  // if values entered into the text inputs are 'foo' and 'bar'
795 *  v == ['foo','bar']
796 *
797 *  var v = $(':checkbox').fieldValue();
798 *  // if neither checkbox is checked
799 *  v === undefined
800 *  // if both checkboxes are checked
801 *  v == ['B1', 'B2']
802 *
803 *  var v = $(':radio').fieldValue();
804 *  // if neither radio is checked
805 *  v === undefined
806 *  // if first radio is checked
807 *  v == ['C1']
808 *
809 * The successful argument controls whether or not the field element must be 'successful'
810 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
811 * The default value of the successful argument is true.  If this value is false the value(s)
812 * for each element is returned.
813 *
814 * Note: This method *always* returns an array.  If no valid value can be determined the
815 *	array will be empty, otherwise it will contain one or more values.
816 */
817$.fn.fieldValue = function(successful) {
818	for (var val=[], i=0, max=this.length; i < max; i++) {
819		var el = this[i];
820		var v = $.fieldValue(el, successful);
821		if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
822			continue;
823		}
824		v.constructor == Array ? $.merge(val, v) : val.push(v);
825	}
826	return val;
827};
828
829/**
830 * Returns the value of the field element.
831 */
832$.fieldValue = function(el, successful) {
833	var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
834	if (successful === undefined) {
835		successful = true;
836	}
837
838	if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
839		(t == 'checkbox' || t == 'radio') && !el.checked ||
840		(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
841		tag == 'select' && el.selectedIndex == -1)) {
842			return null;
843	}
844
845	if (tag == 'select') {
846		var index = el.selectedIndex;
847		if (index < 0) {
848			return null;
849		}
850		var a = [], ops = el.options;
851		var one = (t == 'select-one');
852		var max = (one ? index+1 : ops.length);
853		for(var i=(one ? index : 0); i < max; i++) {
854			var op = ops[i];
855			if (op.selected) {
856				var v = op.value;
857				if (!v) { // extra pain for IE...
858					v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
859				}
860				if (one) {
861					return v;
862				}
863				a.push(v);
864			}
865		}
866		return a;
867	}
868	return $(el).val();
869};
870
871/**
872 * Clears the form data.  Takes the following actions on the form's input fields:
873 *  - input text fields will have their 'value' property set to the empty string
874 *  - select elements will have their 'selectedIndex' property set to -1
875 *  - checkbox and radio inputs will have their 'checked' property set to false
876 *  - inputs of type submit, button, reset, and hidden will *not* be effected
877 *  - button elements will *not* be effected
878 */
879$.fn.clearForm = function(includeHidden) {
880	return this.each(function() {
881		$('input,select,textarea', this).clearFields(includeHidden);
882	});
883};
884
885/**
886 * Clears the selected form elements.
887 */
888$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
889	var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
890	return this.each(function() {
891		var t = this.type, tag = this.tagName.toLowerCase();
892		if (re.test(t) || tag == 'textarea' || (includeHidden && /hidden/.test(t)) ) {
893			this.value = '';
894		}
895		else if (t == 'checkbox' || t == 'radio') {
896			this.checked = false;
897		}
898		else if (tag == 'select') {
899			this.selectedIndex = -1;
900		}
901	});
902};
903
904/**
905 * Resets the form data.  Causes all form elements to be reset to their original value.
906 */
907$.fn.resetForm = function() {
908	return this.each(function() {
909		// guard against an input with the name of 'reset'
910		// note that IE reports the reset function as an 'object'
911		if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
912			this.reset();
913		}
914	});
915};
916
917/**
918 * Enables or disables any matching elements.
919 */
920$.fn.enable = function(b) {
921	if (b === undefined) {
922		b = true;
923	}
924	return this.each(function() {
925		this.disabled = !b;
926	});
927};
928
929/**
930 * Checks/unchecks any matching checkboxes or radio buttons and
931 * selects/deselects and matching option elements.
932 */
933$.fn.selected = function(select) {
934	if (select === undefined) {
935		select = true;
936	}
937	return this.each(function() {
938		var t = this.type;
939		if (t == 'checkbox' || t == 'radio') {
940			this.checked = select;
941		}
942		else if (this.tagName.toLowerCase() == 'option') {
943			var $sel = $(this).parent('select');
944			if (select && $sel[0] && $sel[0].type == 'select-one') {
945				// deselect all other options
946				$sel.find('option').selected(false);
947			}
948			this.selected = select;
949		}
950	});
951};
952
953// expose debug var
954$.fn.ajaxSubmit.debug = false;
955
956// helper fn for console logging
957function log() {
958	if (!$.fn.ajaxSubmit.debug) 
959		return;
960	var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
961	if (window.console && window.console.log) {
962		window.console.log(msg);
963	}
964	else if (window.opera && window.opera.postError) {
965		window.opera.postError(msg);
966	}
967};
968
969})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.