jQuery: The Write Less, Do More JavaScript Library

Changeset 5522

Show
Ignore:
Timestamp:
05/08/08 21:00:21 (4 days ago)
Author:
malsup
Message:

- Fix event timing issue in Opera 9.2x
- Dump 13k worth of comments

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/plugins/form/jquery.form.js

    r5359 r5522  
    11/* 
    22 * jQuery Form Plugin 
    3  * version: 2.08 (04/29/2008) 
     3 * version: 2.10 (05/08/2008) 
    44 * @requires jQuery v1.2.2 or later 
    55 * 
    6  * Examples at: http://malsup.com/jquery/form/ 
     6 * Examples and documentation at: http://malsup.com/jquery/form/ 
    77 * Dual licensed under the MIT and GPL licenses: 
    88 *   http://www.opensource.org/licenses/mit-license.php 
     
    1313(function($) { 
    1414 
    15 /** 
    16  * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX. 
    17  * 
    18  * ajaxSubmit accepts a single argument which can be either a success callback function 
    19  * or an options Object.  If a function is provided it will be invoked upon successful 
    20  * completion of the submit and will be passed the response from the server. 
    21  * If an options Object is provided, the following attributes are supported: 
    22  * 
    23  *  target:   Identifies the element(s) in the page to be updated with the server response. 
    24  *            This value may be specified as a jQuery selection string, a jQuery object, 
    25  *            or a DOM element. 
    26  *            default value: null 
    27  * 
    28  *  url:      URL to which the form data will be submitted. 
    29  *            default value: value of form's 'action' attribute 
    30  * 
    31  *  type:     The method in which the form data should be submitted, 'GET' or 'POST'. 
    32  *            default value: value of form's 'method' attribute (or 'GET' if none found) 
    33  * 
    34  *  data:     Additional data to add to the request, specified as key/value pairs (see $.ajax). 
    35  * 
    36  *  beforeSubmit:  Callback method to be invoked before the form is submitted. 
    37  *            default value: null 
    38  * 
    39  *  success:  Callback method to be invoked after the form has been successfully submitted 
    40  *            and the response has been returned from the server 
    41  *            default value: null 
    42  * 
    43  *  dataType: Expected dataType of the response.  One of: null, 'xml', 'script', or 'json' 
    44  *            default value: null 
    45  * 
    46  *  semantic: Boolean flag indicating whether data must be submitted in semantic order (slower). 
    47  *            default value: false 
    48  * 
    49  *  resetForm: Boolean flag indicating whether the form should be reset if the submit is successful 
    50  * 
    51  *  clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful 
    52  * 
    53  * 
    54  * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for 
    55  * validating the form data.  If the 'beforeSubmit' callback returns false then the form will 
    56  * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data 
    57  * in array format, the jQuery object, and the options object passed into ajaxSubmit. 
    58  * The form data array takes the following form: 
    59  * 
    60  *     [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] 
    61  * 
    62  * If a 'success' callback method is provided it is invoked after the response has been returned 
    63  * from the server.  It is passed the responseText or responseXML value (depending on dataType). 
    64  * See jQuery.ajax for further details. 
    65  * 
    66  * 
    67  * The dataType option provides a means for specifying how the server response should be handled. 
    68  * This maps directly to the jQuery.httpData method.  The following values are supported: 
    69  * 
    70  *      'xml':    if dataType == 'xml' the server response is treated as XML and the 'success' 
    71  *                   callback method, if specified, will be passed the responseXML value 
    72  *      'json':   if dataType == 'json' the server response will be evaluted and passed to 
    73  *                   the 'success' callback, if specified 
    74  *      'script': if dataType == 'script' the server response is evaluated in the global context 
    75  * 
    76  * 
    77  * Note that it does not make sense to use both the 'target' and 'dataType' options.  If both 
    78  * are provided the target will be ignored. 
    79  * 
    80  * The semantic argument can be used to force form serialization in semantic order. 
    81  * This is normally true anyway, unless the form contains input elements of type='image'. 
    82  * If your form must be submitted with name/value pairs in semantic order and your form 
    83  * contains an input of type='image" then pass true for this arg, otherwise pass false 
    84  * (or nothing) to avoid the overhead for this logic. 
    85  * 
    86  * 
    87  * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this: 
    88  * 
    89  * $("#form-id").submit(function() { 
    90  *     $(this).ajaxSubmit(options); 
    91  *     return false; // cancel conventional submit 
    92  * }); 
    93  * 
    94  * When using ajaxForm(), however, this is done for you. 
    95  * 
    96  * @example 
    97  * $('#myForm').ajaxSubmit(function(data) { 
    98  *     alert('Form submit succeeded! Server returned: ' + data); 
    99  * }); 
    100  * @desc Submit form and alert server response 
    101  * 
    102  * 
    103  * @example 
    104  * var options = { 
    105  *     target: '#myTargetDiv' 
    106  * }; 
    107  * $('#myForm').ajaxSubmit(options); 
    108  * @desc Submit form and update page element with server response 
    109  * 
    110  * 
    111  * @example 
    112  * var options = { 
    113  *     success: function(responseText) { 
    114  *         alert(responseText); 
    115  *     } 
    116  * }; 
    117  * $('#myForm').ajaxSubmit(options); 
    118  * @desc Submit form and alert the server response 
    119  * 
    120  * 
    121  * @example 
    122  * var options = { 
    123  *     beforeSubmit: function(formArray, jqForm) { 
    124  *         if (formArray.length == 0) { 
    125  *             alert('Please enter data.'); 
    126  *             return false; 
    127  *         } 
    128  *     } 
    129  * }; 
    130  * $('#myForm').ajaxSubmit(options); 
    131  * @desc Pre-submit validation which aborts the submit operation if form data is empty 
    132  * 
    133  * 
    134  * @example 
    135  * var options = { 
    136  *     url: myJsonUrl.php, 
    137  *     dataType: 'json', 
    138  *     success: function(data) { 
    139  *        // 'data' is an object representing the the evaluated json data 
    140  *     } 
    141  * }; 
    142  * $('#myForm').ajaxSubmit(options); 
    143  * @desc json data returned and evaluated 
    144  * 
    145  * 
    146  * @example 
    147  * var options = { 
    148  *     url: myXmlUrl.php, 
    149  *     dataType: 'xml', 
    150  *     success: function(responseXML) { 
    151  *        // responseXML is XML document object 
    152  *        var data = $('myElement', responseXML).text(); 
    153  *     } 
    154  * }; 
    155  * $('#myForm').ajaxSubmit(options); 
    156  * @desc XML data returned from server 
    157  * 
    158  * 
    159  * @example 
    160  * var options = { 
    161  *     resetForm: true 
    162  * }; 
    163  * $('#myForm').ajaxSubmit(options); 
    164  * @desc submit form and reset it if successful 
    165  * 
    166  * @example 
    167  * $('#myForm).submit(function() { 
    168  *    $(this).ajaxSubmit(); 
    169  *    return false; 
    170  * }); 
    171  * @desc Bind form's submit event to use ajaxSubmit 
    172  * 
    173  * 
    174  * @name ajaxSubmit 
    175  * @type jQuery 
    176  * @param options  object literal containing options which control the form submission process 
    177  * @cat Plugins/Form 
    178  * @return jQuery 
     15/* 
     16    Usage Note:   
     17    ----------- 
     18    Do not use both ajaxSubmit and ajaxForm on the same form.  These 
     19    functions are intended to be exclusive.  Use ajaxSubmit if you want 
     20    to bind your own submit handler to the form.  For example, 
     21 
     22    $(document).ready(function() { 
     23        $('#myForm').bind('submit', function() { 
     24            $(this).ajaxSubmit({ 
     25                target: '#output' 
     26            }); 
     27            return false; // <-- important! 
     28        }); 
     29    }); 
     30 
     31    Use ajaxForm when you want the plugin to manage all the event binding 
     32    for you.  For example, 
     33 
     34    $(document).ready(function() { 
     35        $('#myForm').ajaxForm({ 
     36            target: '#output' 
     37        }); 
     38    }); 
     39         
     40    When using ajaxForm, the ajaxSubmit function will be invoked for you 
     41    at the appropriate time.   
     42*/ 
     43 
     44/** 
     45 * ajaxSubmit() provides a mechanism for immediately submitting  
     46 * an HTML form using AJAX. 
    17947 */ 
    18048$.fn.ajaxSubmit = function(options) { 
     
    282150        var $io = $('<iframe id="' + id + '" name="' + id + '" />'); 
    283151        var io = $io[0]; 
    284         var op8 = $.browser.opera && window.opera.version() < 9; 
    285         if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");'; 
     152 
     153        if ($.browser.msie || $.browser.opera)  
     154            io.src = 'javascript:false;document.write("");'; 
    286155        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); 
    287156 
     
    344213        function cb() { 
    345214            if (cbInvoked++) return; 
    346  
     215             
    347216            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); 
    348217 
     218            var operaHack = 0; 
    349219            var ok = true; 
    350220            try { 
     
    352222                // extract the server response from the iframe 
    353223                var data, doc; 
     224 
    354225                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; 
     226                 
     227                if (doc.body == null && !operaHack && $.browser.opera) { 
     228                    // In Opera 9.2.x the iframe DOM is not always traversable when 
     229                    // the onload callback fires so we give Opera 100ms to right itself 
     230                    operaHack = 1; 
     231                    cbInvoked--; 
     232                    setTimeout(cb, 100); 
     233                    return; 
     234                } 
     235                 
    355236                xhr.responseText = doc.body ? doc.body.innerHTML : null; 
    356237                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; 
     
    414295 * 3. This method binds the submit() method to the form for you. 
    415296 * 
    416  * Note that for accurate x/y coordinates of image submit elements in all browsers 
    417  * you need to also use the "dimensions" plugin (this method will auto-detect its presence). 
    418  * 
    419297 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely 
    420298 * passes the options argument along after properly binding events for submit elements and 
    421  * the form itself.  See ajaxSubmit for a full description of the options argument. 
    422  * 
    423  * 
    424  * @example 
    425  * var options = { 
    426  *     target: '#myTargetDiv' 
    427  * }; 
    428  * $('#myForm').ajaxSForm(options); 
    429  * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response 
    430  *       when the form is submitted. 
    431  * 
    432  * 
    433  * @example 
    434  * var options = { 
    435  *     success: function(responseText) { 
    436  *         alert(responseText); 
    437  *     } 
    438  * }; 
    439  * $('#myForm').ajaxSubmit(options); 
    440  * @desc Bind form's submit event so that server response is alerted after the form is submitted. 
    441  * 
    442  * 
    443  * @example 
    444  * var options = { 
    445  *     beforeSubmit: function(formArray, jqForm) { 
    446  *         if (formArray.length == 0) { 
    447  *             alert('Please enter data.'); 
    448  *             return false; 
    449  *         } 
    450  *     } 
    451  * }; 
    452  * $('#myForm').ajaxSubmit(options); 
    453  * @desc Bind form's submit event so that pre-submit callback is invoked before the form 
    454  *       is submitted. 
    455  * 
    456  * 
    457  * @name   ajaxForm 
    458  * @param  options  object literal containing options which control the form submission process 
    459  * @return jQuery 
    460  * @cat    Plugins/Form 
    461  * @type   jQuery 
    462  */ 
     299 * the form itself. 
     300 */  
    463301$.fn.ajaxForm = function(options) { 
    464302    return this.ajaxFormUnbind().bind('submit.form-plugin',function() { 
     
    489327}; 
    490328 
    491  
    492 /** 
    493  * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm 
    494  * 
    495  * @name   ajaxFormUnbind 
    496  * @return jQuery 
    497  * @cat    Plugins/Form 
    498  * @type   jQuery 
    499  */ 
     329// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm 
    500330$.fn.ajaxFormUnbind = function() { 
    501331    this.unbind('submit.form-plugin'); 
     
    516346 * It is this array that is passed to pre-submit callback functions provided to the 
    517347 * ajaxSubmit() and ajaxForm() methods. 
    518  * 
    519  * The semantic argument can be used to force form serialization in semantic order. 
    520  * This is normally true anyway, unless the form contains input elements of type='image'. 
    521  * If your form must be submitted with name/value pairs in semantic order and your form 
    522  * contains an input of type='image" then pass true for this arg, otherwise pass false 
    523  * (or nothing) to avoid the overhead for this logic. 
    524  * 
    525  * @example var data = $("#myForm").formToArray(); 
    526  * $.post( "myscript.cgi", data ); 
    527  * @desc Collect all the data from a form and submit it to the server. 
    528  * 
    529  * @name formToArray 
    530  * @param semantic true if serialization must maintain strict semantic ordering of elements (slower) 
    531  * @type Array<Object> 
    532  * @cat Plugins/Form 
    533348 */ 
    534349$.fn.formToArray = function(semantic) { 
     
    573388}; 
    574389 
    575  
    576390/** 
    577391 * Serializes form data into a 'submittable' string. This method will return a string 
    578392 * in the format: name1=value1&amp;name2=value2 
    579  * 
    580  * The semantic argument can be used to force form serialization in semantic order. 
    581  * If your form must be submitted with name/value pairs in semantic order then pass 
    582  * true for this arg, otherwise pass false (or nothing) to avoid the overhead for 
    583  * this logic (which can be significant for very large forms). 
    584  * 
    585  * @example var data = $("#myForm").formSerialize(); 
    586  * $.ajax('POST', "myscript.cgi", data); 
    587  * @desc Collect all the data from a form into a single string 
    588  * 
    589  * @name formSerialize 
    590  * @param semantic true if serialization must maintain strict semantic ordering of elements (slower) 
    591  * @type String 
    592  * @cat Plugins/Form 
    593393 */ 
    594394$.fn.formSerialize = function(semantic) { 
     
    597397}; 
    598398 
    599  
    600399/** 
    601400 * Serializes all field elements in the jQuery object into a query string. 
    602401 * This method will return a string in the format: name1=value1&amp;name2=value2 
    603  * 
    604  * The successful argument controls whether or not serialization is limited to 
    605  * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 
    606  * The default value of the successful argument is true. 
    607  * 
    608  * @example var data = $("input").fieldSerialize(); 
    609  * @desc Collect the data from all successful input elements into a query string 
    610  * 
    611  * @example var data = $(":radio").fieldSerialize(); 
    612  * @desc Collect the data from all successful radio input elements into a query string 
    613  * 
    614  * @example var data = $("#myForm :checkbox").fieldSerialize(); 
    615  * @desc Collect the data from all successful checkbox input elements in myForm into a query string 
    616  * 
    617  * @example var data = $("#myForm :checkbox").fieldSerialize(false); 
    618  * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string 
    619  * 
    620  * @example var data = $(":input").fieldSerialize(); 
    621  * @desc Collect the data from all successful input, select, textarea and button elements into a query string 
    622  * 
    623  * @name fieldSerialize 
    624  * @param successful true if only successful controls should be serialized (default is true) 
    625  * @type String 
    626  * @cat Plugins/Form 
    627402 */ 
    628403$.fn.fieldSerialize = function(successful) { 
     
    643418}; 
    644419 
    645  
    646420/** 
    647421 * Returns the value(s) of the element in the matched set.  For example, consider the following form: 
     
    681455 * Note: This method *always* returns an array.  If no valid value can be determined the 
    682456 *       array will be empty, otherwise it will contain one or more values. 
    683  * 
    684  * @example var data = $("#myPasswordElement").fieldValue(); 
    685  * alert(data[0]); 
    686  * @desc Alerts the current value of the myPasswordElement element 
    687  * 
    688  * @example var data = $("#myForm :input").fieldValue(); 
    689  * @desc Get the value(s) of the form elements in myForm 
    690  * 
    691  * @example var data = $("#myForm :checkbox").fieldValue(); 
    692  * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object. 
    693  * 
    694  * @example var data = $("#mySingleSelect").fieldValue(); 
    695  * @desc Get the value(s) of the select control 
    696  * 
    697  * @example var data = $(':text').fieldValue(); 
    698  * @desc Get the value(s) of the text input or textarea elements 
    699  * 
    700  * @example var data = $("#myMultiSelect").fieldValue(); 
    701  * @desc Get the values for the select-multiple control 
    702  * 
    703  * @name fieldValue 
    704  * @param Boolean successful true if only the values for successful controls should be returned (default is true) 
    705  * @type Array<String> 
    706  * @cat Plugins/Form 
    707457 */ 
    708458$.fn.fieldValue = function(successful) { 
     
    719469/** 
    720470 * Returns the value of the field element. 
    721  * 
    722  * The successful argument controls whether or not the field element must be 'successful' 
    723  * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 
    724  * The default value of the successful argument is true.  If the given element is not 
    725  * successful and the successful arg is not false then the returned value will be null. 
    726  * 
    727  * Note: If the successful flag is true (default) but the element is not successful, the return will be null 
    728  * Note: The value returned for a successful select-multiple element will always be an array. 
    729  * Note: If the element has no value the return value will be undefined. 
    730  * 
    731  * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]); 
    732  * @desc Gets the current value of the myPasswordElement element 
    733  * 
    734  * @name fieldValue 
    735  * @param Element el The DOM element for which the value will be returned 
    736  * @param Boolean successful true if value returned must be for a successful controls (default is true) 
    737  * @type String or Array<String> or null or undefined 
    738  * @cat Plugins/Form 
    739471 */ 
    740472$.fieldValue = function(el, successful) { 
     
    768500}; 
    769501 
    770  
    771502/** 
    772503 * Clears the form data.  Takes the following actions on the form's input fields: 
     
    776507 *  - inputs of type submit, button, reset, and hidden will *not* be effected 
    777508 *  - button elements will *not* be effected 
    778  * 
    779  * @example $('form').clearForm(); 
    780  * @desc Clears all forms on the page. 
    781  * 
    782  * @name clearForm 
    783  * @type jQuery 
    784  * @cat Plugins/Form 
    785509 */ 
    786510$.fn.clearForm = function() { 
     
    791515 
    792516/** 
    793  * Clears the selected form elements.  Takes the following actions on the matched elements: 
    794  *  - input text fields will have their 'value' property set to the empty string 
    795  *  - select elements will have their 'selectedIndex' property set to -1 
    796  *  - checkbox and radio inputs will have their 'checked' property set to false 
    797  *  - inputs of type submit, button, reset, and hidden will *not* be effected 
    798  *  - button elements will *not* be effected 
    799  * 
    800  * @example $('.myInputs').clearFields(); 
    801  * @desc Clears all inputs with class myInputs 
    802  * 
    803  * @name clearFields 
    804  * @type jQuery 
    805  * @cat Plugins/Form 
     517 * Clears the selected form elements. 
    806518 */ 
    807519$.fn.clearFields = $.fn.clearInputs = function() { 
     
    817529}; 
    818530 
    819  
    820531/** 
    821532 * Resets the form data.  Causes all form elements to be reset to their original value. 
    822  * 
    823  * @example $('form').resetForm(); 
    824  * @desc Resets all forms on the page. 
    825  * 
    826  * @name resetForm 
    827  * @type jQuery 
    828  * @cat Plugins/Form 
    829533 */ 
    830534$.fn.resetForm = function() { 
     
    837541}; 
    838542 
    839  
    840543/** 
    841544 * Enables or disables any matching elements. 
    842  * 
    843  * @example $(':radio').enabled(false); 
    844  * @desc Disables all radio buttons 
    845  * 
    846  * @name select 
    847  * @type jQuery 
    848  * @cat Plugins/Form 
    849545 */ 
    850546$.fn.enable = function(b) {  
     
    858554 * Checks/unchecks any matching checkboxes or radio buttons and 
    859555 * selects/deselects and matching option elements. 
    860  * 
    861  * @example $(':checkbox').select(); 
    862  * @desc Checks all checkboxes 
    863  * 
    864  * @name select 
    865  * @type jQuery 
    866  * @cat Plugins/Form 
    867556 */ 
    868557$.fn.select = function(select) {