-
+ D584535557858F772AF08191BBA535BC99899D7E742D8895B86516F3FEDE01D7AF3853C1EB985CF4DA6A42209C19C5370B56F0123A9D3441132832BB150F8191
mp-wp/wp-includes/js/jquery/jquery.form.js
(0 . 0)(1 . 872)
101338 /*
101339 * jQuery Form Plugin
101340 * version: 2.02 (12/16/2007)
101341 * @requires jQuery v1.1 or later
101342 *
101343 * Examples at: http://malsup.com/jquery/form/
101344 * Dual licensed under the MIT and GPL licenses:
101345 * http://www.opensource.org/licenses/mit-license.php
101346 * http://www.gnu.org/licenses/gpl.html
101347 *
101348 * Revision: $Id$
101349 */
101350 (function($) {
101351 /**
101352 * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
101353 *
101354 * ajaxSubmit accepts a single argument which can be either a success callback function
101355 * or an options Object. If a function is provided it will be invoked upon successful
101356 * completion of the submit and will be passed the response from the server.
101357 * If an options Object is provided, the following attributes are supported:
101358 *
101359 * target: Identifies the element(s) in the page to be updated with the server response.
101360 * This value may be specified as a jQuery selection string, a jQuery object,
101361 * or a DOM element.
101362 * default value: null
101363 *
101364 * url: URL to which the form data will be submitted.
101365 * default value: value of form's 'action' attribute
101366 *
101367 * type: The method in which the form data should be submitted, 'GET' or 'POST'.
101368 * default value: value of form's 'method' attribute (or 'GET' if none found)
101369 *
101370 * data: Additional data to add to the request, specified as key/value pairs (see $.ajax).
101371 *
101372 * beforeSubmit: Callback method to be invoked before the form is submitted.
101373 * default value: null
101374 *
101375 * success: Callback method to be invoked after the form has been successfully submitted
101376 * and the response has been returned from the server
101377 * default value: null
101378 *
101379 * dataType: Expected dataType of the response. One of: null, 'xml', 'script', or 'json'
101380 * default value: null
101381 *
101382 * semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
101383 * default value: false
101384 *
101385 * resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
101386 *
101387 * clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
101388 *
101389 *
101390 * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
101391 * validating the form data. If the 'beforeSubmit' callback returns false then the form will
101392 * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
101393 * in array format, the jQuery object, and the options object passed into ajaxSubmit.
101394 * The form data array takes the following form:
101395 *
101396 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
101397 *
101398 * If a 'success' callback method is provided it is invoked after the response has been returned
101399 * from the server. It is passed the responseText or responseXML value (depending on dataType).
101400 * See jQuery.ajax for further details.
101401 *
101402 *
101403 * The dataType option provides a means for specifying how the server response should be handled.
101404 * This maps directly to the jQuery.httpData method. The following values are supported:
101405 *
101406 * 'xml': if dataType == 'xml' the server response is treated as XML and the 'success'
101407 * callback method, if specified, will be passed the responseXML value
101408 * 'json': if dataType == 'json' the server response will be evaluted and passed to
101409 * the 'success' callback, if specified
101410 * 'script': if dataType == 'script' the server response is evaluated in the global context
101411 *
101412 *
101413 * Note that it does not make sense to use both the 'target' and 'dataType' options. If both
101414 * are provided the target will be ignored.
101415 *
101416 * The semantic argument can be used to force form serialization in semantic order.
101417 * This is normally true anyway, unless the form contains input elements of type='image'.
101418 * If your form must be submitted with name/value pairs in semantic order and your form
101419 * contains an input of type='image" then pass true for this arg, otherwise pass false
101420 * (or nothing) to avoid the overhead for this logic.
101421 *
101422 *
101423 * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
101424 *
101425 * $("#form-id").submit(function() {
101426 * $(this).ajaxSubmit(options);
101427 * return false; // cancel conventional submit
101428 * });
101429 *
101430 * When using ajaxForm(), however, this is done for you.
101431 *
101432 * @example
101433 * $('#myForm').ajaxSubmit(function(data) {
101434 * alert('Form submit succeeded! Server returned: ' + data);
101435 * });
101436 * @desc Submit form and alert server response
101437 *
101438 *
101439 * @example
101440 * var options = {
101441 * target: '#myTargetDiv'
101442 * };
101443 * $('#myForm').ajaxSubmit(options);
101444 * @desc Submit form and update page element with server response
101445 *
101446 *
101447 * @example
101448 * var options = {
101449 * success: function(responseText) {
101450 * alert(responseText);
101451 * }
101452 * };
101453 * $('#myForm').ajaxSubmit(options);
101454 * @desc Submit form and alert the server response
101455 *
101456 *
101457 * @example
101458 * var options = {
101459 * beforeSubmit: function(formArray, jqForm) {
101460 * if (formArray.length == 0) {
101461 * alert('Please enter data.');
101462 * return false;
101463 * }
101464 * }
101465 * };
101466 * $('#myForm').ajaxSubmit(options);
101467 * @desc Pre-submit validation which aborts the submit operation if form data is empty
101468 *
101469 *
101470 * @example
101471 * var options = {
101472 * url: myJsonUrl.php,
101473 * dataType: 'json',
101474 * success: function(data) {
101475 * // 'data' is an object representing the the evaluated json data
101476 * }
101477 * };
101478 * $('#myForm').ajaxSubmit(options);
101479 * @desc json data returned and evaluated
101480 *
101481 *
101482 * @example
101483 * var options = {
101484 * url: myXmlUrl.php,
101485 * dataType: 'xml',
101486 * success: function(responseXML) {
101487 * // responseXML is XML document object
101488 * var data = $('myElement', responseXML).text();
101489 * }
101490 * };
101491 * $('#myForm').ajaxSubmit(options);
101492 * @desc XML data returned from server
101493 *
101494 *
101495 * @example
101496 * var options = {
101497 * resetForm: true
101498 * };
101499 * $('#myForm').ajaxSubmit(options);
101500 * @desc submit form and reset it if successful
101501 *
101502 * @example
101503 * $('#myForm).submit(function() {
101504 * $(this).ajaxSubmit();
101505 * return false;
101506 * });
101507 * @desc Bind form's submit event to use ajaxSubmit
101508 *
101509 *
101510 * @name ajaxSubmit
101511 * @type jQuery
101512 * @param options object literal containing options which control the form submission process
101513 * @cat Plugins/Form
101514 * @return jQuery
101515 */
101516 $.fn.ajaxSubmit = function(options) {
101517 if (typeof options == 'function')
101518 options = { success: options };
101519
101520 options = $.extend({
101521 url: this.attr('action') || window.location.toString(),
101522 type: this.attr('method') || 'GET'
101523 }, options || {});
101524
101525 // hook for manipulating the form data before it is extracted;
101526 // convenient for use with rich editors like tinyMCE or FCKEditor
101527 var veto = {};
101528 $.event.trigger('form.pre.serialize', [this, options, veto]);
101529 if (veto.veto) return this;
101530
101531 var a = this.formToArray(options.semantic);
101532 if (options.data) {
101533 for (var n in options.data)
101534 a.push( { name: n, value: options.data[n] } );
101535 }
101536
101537 // give pre-submit callback an opportunity to abort the submit
101538 if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;
101539
101540 // fire vetoable 'validate' event
101541 $.event.trigger('form.submit.validate', [a, this, options, veto]);
101542 if (veto.veto) return this;
101543
101544 var q = $.param(a);//.replace(/%20/g,'+');
101545
101546 if (options.type.toUpperCase() == 'GET') {
101547 options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
101548 options.data = null; // data is null for 'get'
101549 }
101550 else
101551 options.data = q; // data is the query string for 'post'
101552
101553 var $form = this, callbacks = [];
101554 if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
101555 if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
101556
101557 // perform a load on the target only if dataType is not provided
101558 if (!options.dataType && options.target) {
101559 var oldSuccess = options.success || function(){};
101560 callbacks.push(function(data) {
101561 if (this.evalScripts)
101562 $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments);
101563 else // jQuery v1.1.4
101564 $(options.target).html(data).each(oldSuccess, arguments);
101565 });
101566 }
101567 else if (options.success)
101568 callbacks.push(options.success);
101569
101570 options.success = function(data, status) {
101571 for (var i=0, max=callbacks.length; i < max; i++)
101572 callbacks[i](data, status, $form);
101573 };
101574
101575 // are there files to upload?
101576 var files = $('input:file', this).fieldValue();
101577 var found = false;
101578 for (var j=0; j < files.length; j++)
101579 if (files[j])
101580 found = true;
101581
101582 // options.iframe allows user to force iframe mode
101583 if (options.iframe || found) {
101584 // hack to fix Safari hang (thanks to Tim Molendijk for this)
101585 // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
101586 if ($.browser.safari && options.closeKeepAlive)
101587 $.get(options.closeKeepAlive, fileUpload);
101588 else
101589 fileUpload();
101590 }
101591 else
101592 $.ajax(options);
101593
101594 // fire 'notify' event
101595 $.event.trigger('form.submit.notify', [this, options]);
101596 return this;
101597
101598
101599 // private function for handling file uploads (hat tip to YAHOO!)
101600 function fileUpload() {
101601 var form = $form[0];
101602 var opts = $.extend({}, $.ajaxSettings, options);
101603
101604 var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++;
101605 var $io = $('<iframe id="' + id + '" name="' + id + '" />');
101606 var io = $io[0];
101607 var op8 = $.browser.opera && window.opera.version() < 9;
101608 if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
101609 $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
101610
101611 var xhr = { // mock object
101612 responseText: null,
101613 responseXML: null,
101614 status: 0,
101615 statusText: 'n/a',
101616 getAllResponseHeaders: function() {},
101617 getResponseHeader: function() {},
101618 setRequestHeader: function() {}
101619 };
101620
101621 var g = opts.global;
101622 // trigger ajax global events so that activity/block indicators work like normal
101623 if (g && ! $.active++) $.event.trigger("ajaxStart");
101624 if (g) $.event.trigger("ajaxSend", [xhr, opts]);
101625
101626 var cbInvoked = 0;
101627 var timedOut = 0;
101628
101629 // take a breath so that pending repaints get some cpu time before the upload starts
101630 setTimeout(function() {
101631 // make sure form attrs are set
101632 var encAttr = form.encoding ? 'encoding' : 'enctype';
101633 var t = $form.attr('target');
101634 $form.attr({
101635 target: id,
101636 method: 'POST',
101637 action: opts.url
101638 });
101639 form[encAttr] = 'multipart/form-data';
101640
101641 // support timout
101642 if (opts.timeout)
101643 setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
101644
101645 // add iframe to doc and submit the form
101646 $io.appendTo('body');
101647 io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
101648 form.submit();
101649 $form.attr('target', t); // reset target
101650 }, 10);
101651
101652 function cb() {
101653 if (cbInvoked++) return;
101654
101655 io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
101656
101657 var ok = true;
101658 try {
101659 if (timedOut) throw 'timeout';
101660 // extract the server response from the iframe
101661 var data, doc;
101662 doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
101663 xhr.responseText = doc.body ? doc.body.innerHTML : null;
101664 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
101665
101666 if (opts.dataType == 'json' || opts.dataType == 'script') {
101667 var ta = doc.getElementsByTagName('textarea')[0];
101668 data = ta ? ta.value : xhr.responseText;
101669 if (opts.dataType == 'json')
101670 eval("data = " + data);
101671 else
101672 $.globalEval(data);
101673 }
101674 else if (opts.dataType == 'xml') {
101675 data = xhr.responseXML;
101676 if (!data && xhr.responseText != null)
101677 data = toXml(xhr.responseText);
101678 }
101679 else {
101680 data = xhr.responseText;
101681 }
101682 }
101683 catch(e){
101684 ok = false;
101685 $.handleError(opts, xhr, 'error', e);
101686 }
101687
101688 // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
101689 if (ok) {
101690 opts.success(data, 'success');
101691 if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
101692 }
101693 if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
101694 if (g && ! --$.active) $.event.trigger("ajaxStop");
101695 if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
101696
101697 // clean up
101698 setTimeout(function() {
101699 $io.remove();
101700 xhr.responseXML = null;
101701 }, 100);
101702 };
101703
101704 function toXml(s, doc) {
101705 if (window.ActiveXObject) {
101706 doc = new ActiveXObject('Microsoft.XMLDOM');
101707 doc.async = 'false';
101708 doc.loadXML(s);
101709 }
101710 else
101711 doc = (new DOMParser()).parseFromString(s, 'text/xml');
101712 return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
101713 };
101714 };
101715 };
101716 $.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids
101717
101718 /**
101719 * ajaxForm() provides a mechanism for fully automating form submission.
101720 *
101721 * The advantages of using this method instead of ajaxSubmit() are:
101722 *
101723 * 1: This method will include coordinates for <input type="image" /> elements (if the element
101724 * is used to submit the form).
101725 * 2. This method will include the submit element's name/value data (for the element that was
101726 * used to submit the form).
101727 * 3. This method binds the submit() method to the form for you.
101728 *
101729 * Note that for accurate x/y coordinates of image submit elements in all browsers
101730 * you need to also use the "dimensions" plugin (this method will auto-detect its presence).
101731 *
101732 * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
101733 * passes the options argument along after properly binding events for submit elements and
101734 * the form itself. See ajaxSubmit for a full description of the options argument.
101735 *
101736 *
101737 * @example
101738 * var options = {
101739 * target: '#myTargetDiv'
101740 * };
101741 * $('#myForm').ajaxSForm(options);
101742 * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
101743 * when the form is submitted.
101744 *
101745 *
101746 * @example
101747 * var options = {
101748 * success: function(responseText) {
101749 * alert(responseText);
101750 * }
101751 * };
101752 * $('#myForm').ajaxSubmit(options);
101753 * @desc Bind form's submit event so that server response is alerted after the form is submitted.
101754 *
101755 *
101756 * @example
101757 * var options = {
101758 * beforeSubmit: function(formArray, jqForm) {
101759 * if (formArray.length == 0) {
101760 * alert('Please enter data.');
101761 * return false;
101762 * }
101763 * }
101764 * };
101765 * $('#myForm').ajaxSubmit(options);
101766 * @desc Bind form's submit event so that pre-submit callback is invoked before the form
101767 * is submitted.
101768 *
101769 *
101770 * @name ajaxForm
101771 * @param options object literal containing options which control the form submission process
101772 * @return jQuery
101773 * @cat Plugins/Form
101774 * @type jQuery
101775 */
101776 $.fn.ajaxForm = function(options) {
101777 return this.ajaxFormUnbind().submit(submitHandler).each(function() {
101778 // store options in hash
101779 this.formPluginId = $.fn.ajaxForm.counter++;
101780 $.fn.ajaxForm.optionHash[this.formPluginId] = options;
101781 $(":submit,input:image", this).click(clickHandler);
101782 });
101783 };
101784
101785 $.fn.ajaxForm.counter = 1;
101786 $.fn.ajaxForm.optionHash = {};
101787
101788 function clickHandler(e) {
101789 var $form = this.form;
101790 $form.clk = this;
101791 if (this.type == 'image') {
101792 if (e.offsetX != undefined) {
101793 $form.clk_x = e.offsetX;
101794 $form.clk_y = e.offsetY;
101795 } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
101796 var offset = $(this).offset();
101797 $form.clk_x = e.pageX - offset.left;
101798 $form.clk_y = e.pageY - offset.top;
101799 } else {
101800 $form.clk_x = e.pageX - this.offsetLeft;
101801 $form.clk_y = e.pageY - this.offsetTop;
101802 }
101803 }
101804 // clear form vars
101805 setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
101806 };
101807
101808 function submitHandler() {
101809 // retrieve options from hash
101810 var id = this.formPluginId;
101811 var options = $.fn.ajaxForm.optionHash[id];
101812 $(this).ajaxSubmit(options);
101813 return false;
101814 };
101815
101816 /**
101817 * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
101818 *
101819 * @name ajaxFormUnbind
101820 * @return jQuery
101821 * @cat Plugins/Form
101822 * @type jQuery
101823 */
101824 $.fn.ajaxFormUnbind = function() {
101825 this.unbind('submit', submitHandler);
101826 return this.each(function() {
101827 $(":submit,input:image", this).unbind('click', clickHandler);
101828 });
101829
101830 };
101831
101832 /**
101833 * formToArray() gathers form element data into an array of objects that can
101834 * be passed to any of the following ajax functions: $.get, $.post, or load.
101835 * Each object in the array has both a 'name' and 'value' property. An example of
101836 * an array for a simple login form might be:
101837 *
101838 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
101839 *
101840 * It is this array that is passed to pre-submit callback functions provided to the
101841 * ajaxSubmit() and ajaxForm() methods.
101842 *
101843 * The semantic argument can be used to force form serialization in semantic order.
101844 * This is normally true anyway, unless the form contains input elements of type='image'.
101845 * If your form must be submitted with name/value pairs in semantic order and your form
101846 * contains an input of type='image" then pass true for this arg, otherwise pass false
101847 * (or nothing) to avoid the overhead for this logic.
101848 *
101849 * @example var data = $("#myForm").formToArray();
101850 * $.post( "myscript.cgi", data );
101851 * @desc Collect all the data from a form and submit it to the server.
101852 *
101853 * @name formToArray
101854 * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
101855 * @type Array<Object>
101856 * @cat Plugins/Form
101857 */
101858 $.fn.formToArray = function(semantic) {
101859 var a = [];
101860 if (this.length == 0) return a;
101861
101862 var form = this[0];
101863 var els = semantic ? form.getElementsByTagName('*') : form.elements;
101864 if (!els) return a;
101865 for(var i=0, max=els.length; i < max; i++) {
101866 var el = els[i];
101867 var n = el.name;
101868 if (!n) continue;
101869
101870 if (semantic && form.clk && el.type == "image") {
101871 // handle image inputs on the fly when semantic == true
101872 if(!el.disabled && form.clk == el)
101873 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
101874 continue;
101875 }
101876
101877 var v = $.fieldValue(el, true);
101878 if (v && v.constructor == Array) {
101879 for(var j=0, jmax=v.length; j < jmax; j++)
101880 a.push({name: n, value: v[j]});
101881 }
101882 else if (v !== null && typeof v != 'undefined')
101883 a.push({name: n, value: v});
101884 }
101885
101886 if (!semantic && form.clk) {
101887 // input type=='image' are not found in elements array! handle them here
101888 var inputs = form.getElementsByTagName("input");
101889 for(var i=0, max=inputs.length; i < max; i++) {
101890 var input = inputs[i];
101891 var n = input.name;
101892 if(n && !input.disabled && input.type == "image" && form.clk == input)
101893 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
101894 }
101895 }
101896 return a;
101897 };
101898
101899
101900 /**
101901 * Serializes form data into a 'submittable' string. This method will return a string
101902 * in the format: name1=value1&name2=value2
101903 *
101904 * The semantic argument can be used to force form serialization in semantic order.
101905 * If your form must be submitted with name/value pairs in semantic order then pass
101906 * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
101907 * this logic (which can be significant for very large forms).
101908 *
101909 * @example var data = $("#myForm").formSerialize();
101910 * $.ajax('POST', "myscript.cgi", data);
101911 * @desc Collect all the data from a form into a single string
101912 *
101913 * @name formSerialize
101914 * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
101915 * @type String
101916 * @cat Plugins/Form
101917 */
101918 $.fn.formSerialize = function(semantic) {
101919 //hand off to jQuery.param for proper encoding
101920 return $.param(this.formToArray(semantic));
101921 };
101922
101923
101924 /**
101925 * Serializes all field elements in the jQuery object into a query string.
101926 * This method will return a string in the format: name1=value1&name2=value2
101927 *
101928 * The successful argument controls whether or not serialization is limited to
101929 * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
101930 * The default value of the successful argument is true.
101931 *
101932 * @example var data = $("input").formSerialize();
101933 * @desc Collect the data from all successful input elements into a query string
101934 *
101935 * @example var data = $(":radio").formSerialize();
101936 * @desc Collect the data from all successful radio input elements into a query string
101937 *
101938 * @example var data = $("#myForm :checkbox").formSerialize();
101939 * @desc Collect the data from all successful checkbox input elements in myForm into a query string
101940 *
101941 * @example var data = $("#myForm :checkbox").formSerialize(false);
101942 * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string
101943 *
101944 * @example var data = $(":input").formSerialize();
101945 * @desc Collect the data from all successful input, select, textarea and button elements into a query string
101946 *
101947 * @name fieldSerialize
101948 * @param successful true if only successful controls should be serialized (default is true)
101949 * @type String
101950 * @cat Plugins/Form
101951 */
101952 $.fn.fieldSerialize = function(successful) {
101953 var a = [];
101954 this.each(function() {
101955 var n = this.name;
101956 if (!n) return;
101957 var v = $.fieldValue(this, successful);
101958 if (v && v.constructor == Array) {
101959 for (var i=0,max=v.length; i < max; i++)
101960 a.push({name: n, value: v[i]});
101961 }
101962 else if (v !== null && typeof v != 'undefined')
101963 a.push({name: this.name, value: v});
101964 });
101965 //hand off to jQuery.param for proper encoding
101966 return $.param(a);
101967 };
101968
101969
101970 /**
101971 * Returns the value(s) of the element in the matched set. For example, consider the following form:
101972 *
101973 * <form><fieldset>
101974 * <input name="A" type="text" />
101975 * <input name="A" type="text" />
101976 * <input name="B" type="checkbox" value="B1" />
101977 * <input name="B" type="checkbox" value="B2"/>
101978 * <input name="C" type="radio" value="C1" />
101979 * <input name="C" type="radio" value="C2" />
101980 * </fieldset></form>
101981 *
101982 * var v = $(':text').fieldValue();
101983 * // if no values are entered into the text inputs
101984 * v == ['','']
101985 * // if values entered into the text inputs are 'foo' and 'bar'
101986 * v == ['foo','bar']
101987 *
101988 * var v = $(':checkbox').fieldValue();
101989 * // if neither checkbox is checked
101990 * v === undefined
101991 * // if both checkboxes are checked
101992 * v == ['B1', 'B2']
101993 *
101994 * var v = $(':radio').fieldValue();
101995 * // if neither radio is checked
101996 * v === undefined
101997 * // if first radio is checked
101998 * v == ['C1']
101999 *
102000 * The successful argument controls whether or not the field element must be 'successful'
102001 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
102002 * The default value of the successful argument is true. If this value is false the value(s)
102003 * for each element is returned.
102004 *
102005 * Note: This method *always* returns an array. If no valid value can be determined the
102006 * array will be empty, otherwise it will contain one or more values.
102007 *
102008 * @example var data = $("#myPasswordElement").fieldValue();
102009 * alert(data[0]);
102010 * @desc Alerts the current value of the myPasswordElement element
102011 *
102012 * @example var data = $("#myForm :input").fieldValue();
102013 * @desc Get the value(s) of the form elements in myForm
102014 *
102015 * @example var data = $("#myForm :checkbox").fieldValue();
102016 * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object.
102017 *
102018 * @example var data = $("#mySingleSelect").fieldValue();
102019 * @desc Get the value(s) of the select control
102020 *
102021 * @example var data = $(':text').fieldValue();
102022 * @desc Get the value(s) of the text input or textarea elements
102023 *
102024 * @example var data = $("#myMultiSelect").fieldValue();
102025 * @desc Get the values for the select-multiple control
102026 *
102027 * @name fieldValue
102028 * @param Boolean successful true if only the values for successful controls should be returned (default is true)
102029 * @type Array<String>
102030 * @cat Plugins/Form
102031 */
102032 $.fn.fieldValue = function(successful) {
102033 for (var val=[], i=0, max=this.length; i < max; i++) {
102034 var el = this[i];
102035 var v = $.fieldValue(el, successful);
102036 if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
102037 continue;
102038 v.constructor == Array ? $.merge(val, v) : val.push(v);
102039 }
102040 return val;
102041 };
102042
102043 /**
102044 * Returns the value of the field element.
102045 *
102046 * The successful argument controls whether or not the field element must be 'successful'
102047 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
102048 * The default value of the successful argument is true. If the given element is not
102049 * successful and the successful arg is not false then the returned value will be null.
102050 *
102051 * Note: If the successful flag is true (default) but the element is not successful, the return will be null
102052 * Note: The value returned for a successful select-multiple element will always be an array.
102053 * Note: If the element has no value the return value will be undefined.
102054 *
102055 * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]);
102056 * @desc Gets the current value of the myPasswordElement element
102057 *
102058 * @name fieldValue
102059 * @param Element el The DOM element for which the value will be returned
102060 * @param Boolean successful true if value returned must be for a successful controls (default is true)
102061 * @type String or Array<String> or null or undefined
102062 * @cat Plugins/Form
102063 */
102064 $.fieldValue = function(el, successful) {
102065 var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
102066 if (typeof successful == 'undefined') successful = true;
102067
102068 if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
102069 (t == 'checkbox' || t == 'radio') && !el.checked ||
102070 (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
102071 tag == 'select' && el.selectedIndex == -1))
102072 return null;
102073
102074 if (tag == 'select') {
102075 var index = el.selectedIndex;
102076 if (index < 0) return null;
102077 var a = [], ops = el.options;
102078 var one = (t == 'select-one');
102079 var max = (one ? index+1 : ops.length);
102080 for(var i=(one ? index : 0); i < max; i++) {
102081 var op = ops[i];
102082 if (op.selected) {
102083 // extra pain for IE...
102084 var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
102085 if (one) return v;
102086 a.push(v);
102087 }
102088 }
102089 return a;
102090 }
102091 return el.value;
102092 };
102093
102094
102095 /**
102096 * Clears the form data. Takes the following actions on the form's input fields:
102097 * - input text fields will have their 'value' property set to the empty string
102098 * - select elements will have their 'selectedIndex' property set to -1
102099 * - checkbox and radio inputs will have their 'checked' property set to false
102100 * - inputs of type submit, button, reset, and hidden will *not* be effected
102101 * - button elements will *not* be effected
102102 *
102103 * @example $('form').clearForm();
102104 * @desc Clears all forms on the page.
102105 *
102106 * @name clearForm
102107 * @type jQuery
102108 * @cat Plugins/Form
102109 */
102110 $.fn.clearForm = function() {
102111 return this.each(function() {
102112 $('input,select,textarea', this).clearFields();
102113 });
102114 };
102115
102116 /**
102117 * Clears the selected form elements. Takes the following actions on the matched elements:
102118 * - input text fields will have their 'value' property set to the empty string
102119 * - select elements will have their 'selectedIndex' property set to -1
102120 * - checkbox and radio inputs will have their 'checked' property set to false
102121 * - inputs of type submit, button, reset, and hidden will *not* be effected
102122 * - button elements will *not* be effected
102123 *
102124 * @example $('.myInputs').clearFields();
102125 * @desc Clears all inputs with class myInputs
102126 *
102127 * @name clearFields
102128 * @type jQuery
102129 * @cat Plugins/Form
102130 */
102131 $.fn.clearFields = $.fn.clearInputs = function() {
102132 return this.each(function() {
102133 var t = this.type, tag = this.tagName.toLowerCase();
102134 if (t == 'text' || t == 'password' || tag == 'textarea')
102135 this.value = '';
102136 else if (t == 'checkbox' || t == 'radio')
102137 this.checked = false;
102138 else if (tag == 'select')
102139 this.selectedIndex = -1;
102140 });
102141 };
102142
102143
102144 /**
102145 * Resets the form data. Causes all form elements to be reset to their original value.
102146 *
102147 * @example $('form').resetForm();
102148 * @desc Resets all forms on the page.
102149 *
102150 * @name resetForm
102151 * @type jQuery
102152 * @cat Plugins/Form
102153 */
102154 $.fn.resetForm = function() {
102155 return this.each(function() {
102156 // guard against an input with the name of 'reset'
102157 // note that IE reports the reset function as an 'object'
102158 if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
102159 this.reset();
102160 });
102161 };
102162
102163
102164 /**
102165 * Enables or disables any matching elements.
102166 *
102167 * @example $(':radio').enabled(false);
102168 * @desc Disables all radio buttons
102169 *
102170 * @name select
102171 * @type jQuery
102172 * @cat Plugins/Form
102173 */
102174 $.fn.enable = function(b) {
102175 if (b == undefined) b = true;
102176 return this.each(function() {
102177 this.disabled = !b
102178 });
102179 };
102180
102181 /**
102182 * Checks/unchecks any matching checkboxes or radio buttons and
102183 * selects/deselects and matching option elements.
102184 *
102185 * @example $(':checkbox').selected();
102186 * @desc Checks all checkboxes
102187 *
102188 * @name select
102189 * @type jQuery
102190 * @cat Plugins/Form
102191 */
102192 $.fn.select = function(select) {
102193 if (select == undefined) select = true;
102194 return this.each(function() {
102195 var t = this.type;
102196 if (t == 'checkbox' || t == 'radio')
102197 this.checked = select;
102198 else if (this.tagName.toLowerCase() == 'option') {
102199 var $sel = $(this).parent('select');
102200 if (select && $sel[0] && $sel[0].type == 'select-one') {
102201 // deselect all other options
102202 $sel.find('option').select(false);
102203 }
102204 this.selected = select;
102205 }
102206 });
102207 };
102208
102209 })(jQuery);