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