PluginProbe
RSVP and Event Management / 1.2.0
RSVP and Event Management v1.2.0
trunk 0.5.0 0.6.0 0.7.0 0.8.0 0.9.0 0.9.5 1.0.0 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.5.0 1.6.0 1.6.1 1.6.2 1.6.5 1.7.0 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 All 136 releases
rsvp / jquery-validate / lib / jquery.form.js

jquery.form.js in RSVP and Event Management 1.2.0, at jquery-validate/lib/jquery.form.js

820 lines 30.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 * jQuery Form Plugin
3 * @requires jQuery v1.1 or later
4 *
5 * Examples at: http://malsup.com/jquery/form/
6 * Dual licensed under the MIT and GPL licenses:
7 * http://www.opensource.org/licenses/mit-license.php
8 * http://www.gnu.org/licenses/gpl.html
9 *
10 * Revision: $Id: jquery.form.js 3028 2007-08-31 13:37:36Z joern.zaefferer $
11 */
12 (function($) {
13 /**
14 * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
15 *
16 * ajaxSubmit accepts a single argument which can be either a success callback function
17 * or an options Object. If a function is provided it will be invoked upon successful
18 * completion of the submit and will be passed the response from the server.
19 * If an options Object is provided, the following attributes are supported:
20 *
21 * target: Identifies the element(s) in the page to be updated with the server response.
22 * This value may be specified as a jQuery selection string, a jQuery object,
23 * or a DOM element.
24 * default value: null
25 *
26 * url: URL to which the form data will be submitted.
27 * default value: value of form's 'action' attribute
28 *
29 * type: The method in which the form data should be submitted, 'GET' or 'POST'.
30 * default value: value of form's 'method' attribute (or 'GET' if none found)
31 *
32 * data: Additional data to add to the request, specified as key/value pairs (see $.ajax).
33 *
34 * beforeSubmit: Callback method to be invoked before the form is submitted.
35 * default value: null
36 *
37 * success: Callback method to be invoked after the form has been successfully submitted
38 * and the response has been returned from the server
39 * default value: null
40 *
41 * dataType: Expected dataType of the response. One of: null, 'xml', 'script', or 'json'
42 * default value: null
43 *
44 * semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
45 * default value: false
46 *
47 * resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
48 *
49 * clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
50 *
51 *
52 * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
53 * validating the form data. If the 'beforeSubmit' callback returns false then the form will
54 * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
55 * in array format, the jQuery object, and the options object passed into ajaxSubmit.
56 * The form data array takes the following form:
57 *
58 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
59 *
60 * If a 'success' callback method is provided it is invoked after the response has been returned
61 * from the server. It is passed the responseText or responseXML value (depending on dataType).
62 * See jQuery.ajax for further details.
63 *
64 *
65 * The dataType option provides a means for specifying how the server response should be handled.
66 * This maps directly to the jQuery.httpData method. The following values are supported:
67 *
68 * 'xml': if dataType == 'xml' the server response is treated as XML and the 'success'
69 * callback method, if specified, will be passed the responseXML value
70 * 'json': if dataType == 'json' the server response will be evaluted and passed to
71 * the 'success' callback, if specified
72 * 'script': if dataType == 'script' the server response is evaluated in the global context
73 *
74 *
75 * Note that it does not make sense to use both the 'target' and 'dataType' options. If both
76 * are provided the target will be ignored.
77 *
78 * The semantic argument can be used to force form serialization in semantic order.
79 * This is normally true anyway, unless the form contains input elements of type='image'.
80 * If your form must be submitted with name/value pairs in semantic order and your form
81 * contains an input of type='image" then pass true for this arg, otherwise pass false
82 * (or nothing) to avoid the overhead for this logic.
83 *
84 *
85 * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
86 *
87 * $("#form-id").submit(function() {
88 * $(this).ajaxSubmit(options);
89 * return false; // cancel conventional submit
90 * });
91 *
92 * When using ajaxForm(), however, this is done for you.
93 *
94 * @example
95 * $('#myForm').ajaxSubmit(function(data) {
96 * alert('Form submit succeeded! Server returned: ' + data);
97 * });
98 * @desc Submit form and alert server response
99 *
100 *
101 * @example
102 * var options = {
103 * target: '#myTargetDiv'
104 * };
105 * $('#myForm').ajaxSubmit(options);
106 * @desc Submit form and update page element with server response
107 *
108 *
109 * @example
110 * var options = {
111 * success: function(responseText) {
112 * alert(responseText);
113 * }
114 * };
115 * $('#myForm').ajaxSubmit(options);
116 * @desc Submit form and alert the server response
117 *
118 *
119 * @example
120 * var options = {
121 * beforeSubmit: function(formArray, jqForm) {
122 * if (formArray.length == 0) {
123 * alert('Please enter data.');
124 * return false;
125 * }
126 * }
127 * };
128 * $('#myForm').ajaxSubmit(options);
129 * @desc Pre-submit validation which aborts the submit operation if form data is empty
130 *
131 *
132 * @example
133 * var options = {
134 * url: myJsonUrl.php,
135 * dataType: 'json',
136 * success: function(data) {
137 * // 'data' is an object representing the the evaluated json data
138 * }
139 * };
140 * $('#myForm').ajaxSubmit(options);
141 * @desc json data returned and evaluated
142 *
143 *
144 * @example
145 * var options = {
146 * url: myXmlUrl.php,
147 * dataType: 'xml',
148 * success: function(responseXML) {
149 * // responseXML is XML document object
150 * var data = $('myElement', responseXML).text();
151 * }
152 * };
153 * $('#myForm').ajaxSubmit(options);
154 * @desc XML data returned from server
155 *
156 *
157 * @example
158 * var options = {
159 * resetForm: true
160 * };
161 * $('#myForm').ajaxSubmit(options);
162 * @desc submit form and reset it if successful
163 *
164 * @example
165 * $('#myForm).submit(function() {
166 * $(this).ajaxSubmit();
167 * return false;
168 * });
169 * @desc Bind form's submit event to use ajaxSubmit
170 *
171 *
172 * @name ajaxSubmit
173 * @type jQuery
174 * @param options object literal containing options which control the form submission process
175 * @cat Plugins/Form
176 * @return jQuery
177 */
178 $.fn.ajaxSubmit = function(options) {
179 if (typeof options == 'function')
180 options = { success: options };
181
182 options = $.extend({
183 url: this.attr('action') || window.location,
184 type: this.attr('method') || 'GET'
185 }, options || {});
186
187 // hook for manipulating the form data before it is extracted;
188 // convenient for use with rich editors like tinyMCE or FCKEditor
189 var veto = {};
190 $.event.trigger('form.pre.serialize', [this, options, veto]);
191 if (veto.veto) return this;
192
193 var a = this.formToArray(options.semantic);
194 if (options.data) {
195 for (var n in options.data)
196 a.push( { name: n, value: options.data[n] } );
197 }
198
199 // give pre-submit callback an opportunity to abort the submit
200 if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;
201
202 // fire vetoable 'validate' event
203 $.event.trigger('form.submit.validate', [a, this, options, veto]);
204 if (veto.veto) return this;
205
206 var q = $.param(a);//.replace(/%20/g,'+');
207
208 if (options.type.toUpperCase() == 'GET') {
209 options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
210 options.data = null; // data is null for 'get'
211 }
212 else
213 options.data = q; // data is the query string for 'post'
214
215 var $form = this, callbacks = [];
216 if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
217 if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
218
219 // perform a load on the target only if dataType is not provided
220 if (!options.dataType && options.target) {
221 var oldSuccess = options.success || function(){};
222 callbacks.push(function(data) {
223 if (this.evalScripts)
224 $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments);
225 else // jQuery v1.1.4
226 $(options.target).html(data).each(oldSuccess, arguments);
227 });
228 }
229 else if (options.success)
230 callbacks.push(options.success);
231
232 options.success = function(data, status) {
233 for (var i=0, max=callbacks.length; i < max; i++)
234 callbacks[i](data, status, $form);
235 };
236
237 // are there files to upload?
238 var files = $('input:file', this).fieldValue();
239 var found = false;
240 for (var j=0; j < files.length; j++)
241 if (files[j])
242 found = true;
243
244 if (options.iframe || found) // options.iframe allows user to force iframe mode
245 fileUpload();
246 else
247 $.ajax(options);
248
249 // fire 'notify' event
250 $.event.trigger('form.submit.notify', [this, options]);
251 return this;
252
253
254 // private function for handling file uploads (hat tip to YAHOO!)
255 function fileUpload() {
256 var form = $form[0];
257 var opts = $.extend({}, $.ajaxSettings, options);
258
259 var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++;
260 var $io = $('<iframe id="' + id + '" name="' + id + '" />');
261 var io = $io[0];
262 var op8 = $.browser.opera && window.opera.version() < 9;
263 if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
264 $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
265
266 var xhr = { // mock object
267 responseText: null,
268 responseXML: null,
269 status: 0,
270 statusText: 'n/a',
271 getAllResponseHeaders: function() {},
272 getResponseHeader: function() {},
273 setRequestHeader: function() {}
274 };
275
276 var g = opts.global;
277 // trigger ajax global events so that activity/block indicators work like normal
278 if (g && ! $.active++) $.event.trigger("ajaxStart");
279 if (g) $.event.trigger("ajaxSend", [xhr, opts]);
280
281 var cbInvoked = 0;
282 var timedOut = 0;
283
284 // take a breath so that pending repaints get some cpu time before the upload starts
285 setTimeout(function() {
286 $io.appendTo('body');
287 // jQuery's event binding doesn't work for iframe events in IE
288 io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
289
290 // make sure form attrs are set
291 var encAttr = form.encoding ? 'encoding' : 'enctype';
292 var t = $form.attr('target');
293 $form.attr({
294 target: id,
295 method: 'POST',
296 action: opts.url
297 });
298 form[encAttr] = 'multipart/form-data';
299
300 // support timout
301 if (opts.timeout)
302 setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
303
304 form.submit();
305 $form.attr('target', t); // reset target
306 }, 10);
307
308 function cb() {
309 if (cbInvoked++) return;
310
311 io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
312
313 var ok = true;
314 try {
315 if (timedOut) throw 'timeout';
316 // extract the server response from the iframe
317 var data, doc;
318 doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
319 xhr.responseText = doc.body ? doc.body.innerHTML : null;
320 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
321
322 if (opts.dataType == 'json' || opts.dataType == 'script') {
323 var ta = doc.getElementsByTagName('textarea')[0];
324 data = ta ? ta.value : xhr.responseText;
325 if (opts.dataType == 'json')
326 eval("data = " + data);
327 else
328 $.globalEval(data);
329 }
330 else if (opts.dataType == 'xml') {
331 data = xhr.responseXML;
332 if (!data && xhr.responseText != null)
333 data = toXml(xhr.responseText);
334 }
335 else {
336 data = xhr.responseText;
337 }
338 }
339 catch(e){
340 ok = false;
341 $.handleError(opts, xhr, 'error', e);
342 }
343
344 // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
345 if (ok) {
346 opts.success(data, 'success');
347 if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
348 }
349 if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
350 if (g && ! --$.active) $.event.trigger("ajaxStop");
351 if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
352
353 // clean up
354 setTimeout(function() {
355 $io.remove();
356 xhr.responseXML = null;
357 }, 100);
358 };
359
360 function toXml(s, doc) {
361 if (window.ActiveXObject) {
362 doc = new ActiveXObject('Microsoft.XMLDOM');
363 doc.async = 'false';
364 doc.loadXML(s);
365 }
366 else
367 doc = (new DOMParser()).parseFromString(s, 'text/xml');
368 return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
369 };
370 };
371 };
372 $.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids
373
374 /**
375 * ajaxForm() provides a mechanism for fully automating form submission.
376 *
377 * The advantages of using this method instead of ajaxSubmit() are:
378 *
379 * 1: This method will include coordinates for <input type="image" /> elements (if the element
380 * is used to submit the form).
381 * 2. This method will include the submit element's name/value data (for the element that was
382 * used to submit the form).
383 * 3. This method binds the submit() method to the form for you.
384 *
385 * Note that for accurate x/y coordinates of image submit elements in all browsers
386 * you need to also use the "dimensions" plugin (this method will auto-detect its presence).
387 *
388 * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
389 * passes the options argument along after properly binding events for submit elements and
390 * the form itself. See ajaxSubmit for a full description of the options argument.
391 *
392 *
393 * @example
394 * var options = {
395 * target: '#myTargetDiv'
396 * };
397 * $('#myForm').ajaxSForm(options);
398 * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
399 * when the form is submitted.
400 *
401 *
402 * @example
403 * var options = {
404 * success: function(responseText) {
405 * alert(responseText);
406 * }
407 * };
408 * $('#myForm').ajaxSubmit(options);
409 * @desc Bind form's submit event so that server response is alerted after the form is submitted.
410 *
411 *
412 * @example
413 * var options = {
414 * beforeSubmit: function(formArray, jqForm) {
415 * if (formArray.length == 0) {
416 * alert('Please enter data.');
417 * return false;
418 * }
419 * }
420 * };
421 * $('#myForm').ajaxSubmit(options);
422 * @desc Bind form's submit event so that pre-submit callback is invoked before the form
423 * is submitted.
424 *
425 *
426 * @name ajaxForm
427 * @param options object literal containing options which control the form submission process
428 * @return jQuery
429 * @cat Plugins/Form
430 * @type jQuery
431 */
432 $.fn.ajaxForm = function(options) {
433 return this.ajaxFormUnbind().submit(submitHandler).each(function() {
434 // store options in hash
435 this.formPluginId = $.fn.ajaxForm.counter++;
436 $.fn.ajaxForm.optionHash[this.formPluginId] = options;
437 $(":submit,input:image", this).click(clickHandler);
438 });
439 };
440
441 $.fn.ajaxForm.counter = 1;
442 $.fn.ajaxForm.optionHash = {};
443
444 function clickHandler(e) {
445 var $form = this.form;
446 $form.clk = this;
447 if (this.type == 'image') {
448 if (e.offsetX != undefined) {
449 $form.clk_x = e.offsetX;
450 $form.clk_y = e.offsetY;
451 } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
452 var offset = $(this).offset();
453 $form.clk_x = e.pageX - offset.left;
454 $form.clk_y = e.pageY - offset.top;
455 } else {
456 $form.clk_x = e.pageX - this.offsetLeft;
457 $form.clk_y = e.pageY - this.offsetTop;
458 }
459 }
460 // clear form vars
461 setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
462 };
463
464 function submitHandler() {
465 // retrieve options from hash
466 var id = this.formPluginId;
467 var options = $.fn.ajaxForm.optionHash[id];
468 $(this).ajaxSubmit(options);
469 return false;
470 };
471
472 /**
473 * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
474 *
475 * @name ajaxFormUnbind
476 * @return jQuery
477 * @cat Plugins/Form
478 * @type jQuery
479 */
480 $.fn.ajaxFormUnbind = function() {
481 this.unbind('submit', submitHandler);
482 return this.each(function() {
483 $(":submit,input:image", this).unbind('click', clickHandler);
484 });
485
486 };
487
488 /**
489 * formToArray() gathers form element data into an array of objects that can
490 * be passed to any of the following ajax functions: $.get, $.post, or load.
491 * Each object in the array has both a 'name' and 'value' property. An example of
492 * an array for a simple login form might be:
493 *
494 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
495 *
496 * It is this array that is passed to pre-submit callback functions provided to the
497 * ajaxSubmit() and ajaxForm() methods.
498 *
499 * The semantic argument can be used to force form serialization in semantic order.
500 * This is normally true anyway, unless the form contains input elements of type='image'.
501 * If your form must be submitted with name/value pairs in semantic order and your form
502 * contains an input of type='image" then pass true for this arg, otherwise pass false
503 * (or nothing) to avoid the overhead for this logic.
504 *
505 * @example var data = $("#myForm").formToArray();
506 * $.post( "myscript.cgi", data );
507 * @desc Collect all the data from a form and submit it to the server.
508 *
509 * @name formToArray
510 * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
511 * @type Array<Object>
512 * @cat Plugins/Form
513 */
514 $.fn.formToArray = function(semantic) {
515 var a = [];
516 if (this.length == 0) return a;
517
518 var form = this[0];
519 var els = semantic ? form.getElementsByTagName('*') : form.elements;
520 if (!els) return a;
521 for(var i=0, max=els.length; i < max; i++) {
522 var el = els[i];
523 var n = el.name;
524 if (!n) continue;
525
526 if (semantic && form.clk && el.type == "image") {
527 // handle image inputs on the fly when semantic == true
528 if(!el.disabled && form.clk == el)
529 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
530 continue;
531 }
532
533 var v = $.fieldValue(el, true);
534 if (v && v.constructor == Array) {
535 for(var j=0, jmax=v.length; j < jmax; j++)
536 a.push({name: n, value: v[j]});
537 }
538 else if (v !== null && typeof v != 'undefined')
539 a.push({name: n, value: v});
540 }
541
542 if (!semantic && form.clk) {
543 // input type=='image' are not found in elements array! handle them here
544 var inputs = form.getElementsByTagName("input");
545 for(var i=0, max=inputs.length; i < max; i++) {
546 var input = inputs[i];
547 var n = input.name;
548 if(n && !input.disabled && input.type == "image" && form.clk == input)
549 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
550 }
551 }
552 return a;
553 };
554
555
556 /**
557 * Serializes form data into a 'submittable' string. This method will return a string
558 * in the format: name1=value1&amp;name2=value2
559 *
560 * The semantic argument can be used to force form serialization in semantic order.
561 * If your form must be submitted with name/value pairs in semantic order then pass
562 * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
563 * this logic (which can be significant for very large forms).
564 *
565 * @example var data = $("#myForm").formSerialize();
566 * $.ajax('POST', "myscript.cgi", data);
567 * @desc Collect all the data from a form into a single string
568 *
569 * @name formSerialize
570 * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
571 * @type String
572 * @cat Plugins/Form
573 */
574 $.fn.formSerialize = function(semantic) {
575 //hand off to jQuery.param for proper encoding
576 return $.param(this.formToArray(semantic));
577 };
578
579
580 /**
581 * Serializes all field elements in the jQuery object into a query string.
582 * This method will return a string in the format: name1=value1&amp;name2=value2
583 *
584 * The successful argument controls whether or not serialization is limited to
585 * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
586 * The default value of the successful argument is true.
587 *
588 * @example var data = $("input").formSerialize();
589 * @desc Collect the data from all successful input elements into a query string
590 *
591 * @example var data = $(":radio").formSerialize();
592 * @desc Collect the data from all successful radio input elements into a query string
593 *
594 * @example var data = $("#myForm :checkbox").formSerialize();
595 * @desc Collect the data from all successful checkbox input elements in myForm into a query string
596 *
597 * @example var data = $("#myForm :checkbox").formSerialize(false);
598 * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string
599 *
600 * @example var data = $(":input").formSerialize();
601 * @desc Collect the data from all successful input, select, textarea and button elements into a query string
602 *
603 * @name fieldSerialize
604 * @param successful true if only successful controls should be serialized (default is true)
605 * @type String
606 * @cat Plugins/Form
607 */
608 $.fn.fieldSerialize = function(successful) {
609 var a = [];
610 this.each(function() {
611 var n = this.name;
612 if (!n) return;
613 var v = $.fieldValue(this, successful);
614 if (v && v.constructor == Array) {
615 for (var i=0,max=v.length; i < max; i++)
616 a.push({name: n, value: v[i]});
617 }
618 else if (v !== null && typeof v != 'undefined')
619 a.push({name: this.name, value: v});
620 });
621 //hand off to jQuery.param for proper encoding
622 return $.param(a);
623 };
624
625
626 /**
627 * Returns the value(s) of the element in the matched set. For example, consider the following form:
628 *
629 * <form><fieldset>
630 * <input name="A" type="text" />
631 * <input name="A" type="text" />
632 * <input name="B" type="checkbox" value="B1" />
633 * <input name="B" type="checkbox" value="B2"/>
634 * <input name="C" type="radio" value="C1" />
635 * <input name="C" type="radio" value="C2" />
636 * </fieldset></form>
637 *
638 * var v = $(':text').fieldValue();
639 * // if no values are entered into the text inputs
640 * v == ['','']
641 * // if values entered into the text inputs are 'foo' and 'bar'
642 * v == ['foo','bar']
643 *
644 * var v = $(':checkbox').fieldValue();
645 * // if neither checkbox is checked
646 * v === undefined
647 * // if both checkboxes are checked
648 * v == ['B1', 'B2']
649 *
650 * var v = $(':radio').fieldValue();
651 * // if neither radio is checked
652 * v === undefined
653 * // if first radio is checked
654 * v == ['C1']
655 *
656 * The successful argument controls whether or not the field element must be 'successful'
657 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
658 * The default value of the successful argument is true. If this value is false the value(s)
659 * for each element is returned.
660 *
661 * Note: This method *always* returns an array. If no valid value can be determined the
662 * array will be empty, otherwise it will contain one or more values.
663 *
664 * @example var data = $("#myPasswordElement").fieldValue();
665 * alert(data[0]);
666 * @desc Alerts the current value of the myPasswordElement element
667 *
668 * @example var data = $("#myForm :input").fieldValue();
669 * @desc Get the value(s) of the form elements in myForm
670 *
671 * @example var data = $("#myForm :checkbox").fieldValue();
672 * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object.
673 *
674 * @example var data = $("#mySingleSelect").fieldValue();
675 * @desc Get the value(s) of the select control
676 *
677 * @example var data = $(':text').fieldValue();
678 * @desc Get the value(s) of the text input or textarea elements
679 *
680 * @example var data = $("#myMultiSelect").fieldValue();
681 * @desc Get the values for the select-multiple control
682 *
683 * @name fieldValue
684 * @param Boolean successful true if only the values for successful controls should be returned (default is true)
685 * @type Array<String>
686 * @cat Plugins/Form
687 */
688 $.fn.fieldValue = function(successful) {
689 for (var val=[], i=0, max=this.length; i < max; i++) {
690 var el = this[i];
691 var v = $.fieldValue(el, successful);
692 if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
693 continue;
694 v.constructor == Array ? $.merge(val, v) : val.push(v);
695 }
696 return val;
697 };
698
699 /**
700 * Returns the value of the field element.
701 *
702 * The successful argument controls whether or not the field element must be 'successful'
703 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
704 * The default value of the successful argument is true. If the given element is not
705 * successful and the successful arg is not false then the returned value will be null.
706 *
707 * Note: If the successful flag is true (default) but the element is not successful, the return will be null
708 * Note: The value returned for a successful select-multiple element will always be an array.
709 * Note: If the element has no value the return value will be undefined.
710 *
711 * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]);
712 * @desc Gets the current value of the myPasswordElement element
713 *
714 * @name fieldValue
715 * @param Element el The DOM element for which the value will be returned
716 * @param Boolean successful true if value returned must be for a successful controls (default is true)
717 * @type String or Array<String> or null or undefined
718 * @cat Plugins/Form
719 */
720 $.fieldValue = function(el, successful) {
721 var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
722 if (typeof successful == 'undefined') successful = true;
723
724 if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
725 (t == 'checkbox' || t == 'radio') && !el.checked ||
726 (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
727 tag == 'select' && el.selectedIndex == -1))
728 return null;
729
730 if (tag == 'select') {
731 var index = el.selectedIndex;
732 if (index < 0) return null;
733 var a = [], ops = el.options;
734 var one = (t == 'select-one');
735 var max = (one ? index+1 : ops.length);
736 for(var i=(one ? index : 0); i < max; i++) {
737 var op = ops[i];
738 if (op.selected) {
739 // extra pain for IE...
740 var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
741 if (one) return v;
742 a.push(v);
743 }
744 }
745 return a;
746 }
747 return el.value;
748 };
749
750
751 /**
752 * Clears the form data. Takes the following actions on the form's input fields:
753 * - input text fields will have their 'value' property set to the empty string
754 * - select elements will have their 'selectedIndex' property set to -1
755 * - checkbox and radio inputs will have their 'checked' property set to false
756 * - inputs of type submit, button, reset, and hidden will *not* be effected
757 * - button elements will *not* be effected
758 *
759 * @example $('form').clearForm();
760 * @desc Clears all forms on the page.
761 *
762 * @name clearForm
763 * @type jQuery
764 * @cat Plugins/Form
765 */
766 $.fn.clearForm = function() {
767 return this.each(function() {
768 $('input,select,textarea', this).clearFields();
769 });
770 };
771
772 /**
773 * Clears the selected form elements. Takes the following actions on the matched elements:
774 * - input text fields will have their 'value' property set to the empty string
775 * - select elements will have their 'selectedIndex' property set to -1
776 * - checkbox and radio inputs will have their 'checked' property set to false
777 * - inputs of type submit, button, reset, and hidden will *not* be effected
778 * - button elements will *not* be effected
779 *
780 * @example $('.myInputs').clearFields();
781 * @desc Clears all inputs with class myInputs
782 *
783 * @name clearFields
784 * @type jQuery
785 * @cat Plugins/Form
786 */
787 $.fn.clearFields = $.fn.clearInputs = function() {
788 return this.each(function() {
789 var t = this.type, tag = this.tagName.toLowerCase();
790 if (t == 'text' || t == 'password' || tag == 'textarea')
791 this.value = '';
792 else if (t == 'checkbox' || t == 'radio')
793 this.checked = false;
794 else if (tag == 'select')
795 this.selectedIndex = -1;
796 });
797 };
798
799
800 /**
801 * Resets the form data. Causes all form elements to be reset to their original value.
802 *
803 * @example $('form').resetForm();
804 * @desc Resets all forms on the page.
805 *
806 * @name resetForm
807 * @type jQuery
808 * @cat Plugins/Form
809 */
810 $.fn.resetForm = function() {
811 return this.each(function() {
812 // guard against an input with the name of 'reset'
813 // note that IE reports the reset function as an 'object'
814 if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
815 this.reset();
816 });
817 };
818
819 })(jQuery);
820