PageSourceSearch

https://vancouverplays.com/js-plugin/neko-contact-ajax-plugin/js/jquery.form.js

js vancouverplays.com collected 2026-10-02 08:02:02 UTC 27,136 bytes, 919 lines download raw bytes

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