PageSourceSearch

https://npo-ecofood.ru/local/js/basic/jquery.form.js?152302668827128

js npo-ecofood.ru collected 2026-10-10 02:25:48 UTC 27,128 bytes, 923 lines download raw bytes

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