1/*! 2 * jQuery Form Plugin 3 * version: 2.47 (04-SEP-2010) 4 * @requires jQuery v1.3.2 or later 5 * 6 * Examples and documentation at: http://malsup.com/jquery/form/ 7 * Dual licensed under the MIT and GPL licenses: 8 * http://www.opensource.org/licenses/mit-license.php 9 * http://www.gnu.org/licenses/gpl.html 10 */ 11;(function($) { 12 13/* 14 Usage Note: 15 ----------- 16 Do not use both ajaxSubmit and ajaxForm on the same form. These 17 functions are intended to be exclusive. Use ajaxSubmit if you want 18 to bind your own submit handler to the form. For example, 19 20 $(document).ready(function() { 21 $('#myForm').bind('submit', function() { 22 $(this).ajaxSubmit({ 23 target: '#output' 24 }); 25 return false; // <-- important! 26 }); 27 }); 28 29 Use ajaxForm when you want the plugin to manage all the event binding 30 for you. For example, 31 32 $(document).ready(function() { 33 $('#myForm').ajaxForm({ 34 target: '#output' 35 }); 36 }); 37 38 When using ajaxForm, the ajaxSubmit function will be invoked for you 39 at the appropriate time. 40*/ 41 42/** 43 * ajaxSubmit() provides a mechanism for immediately submitting 44 * an HTML form using AJAX. 45 */ 46$.fn.ajaxSubmit = function(options) { 47 // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) 48 if (!this.length) { 49 log('ajaxSubmit: skipping submit process - no element selected'); 50 return this; 51 } 52 53 if (typeof options == 'function') { 54 options = { success: options }; 55 } 56 57 var url = $.trim(this.attr('action')); 58 if (url) { 59 // clean url (don't include hash vaue) 60 url = (url.match(/^([^#]+)/)||[])[1]; 61 } 62 url = url || window.location.href || ''; 63 64 options = $.extend(true, { 65 url: url, 66 type: this.attr('method') || 'GET', 67 iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' 68 }, options); 69 70 // hook for manipulating the form data before it is extracted; 71 // convenient for use with rich editors like tinyMCE or FCKEditor 72 var veto = {}; 73 this.trigger('form-pre-serialize', [this, options, veto]); 74 if (veto.veto) { 75 log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); 76 return this; 77 } 78 79 // provide opportunity to alter form data before it is serialized 80 if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { 81 log('ajaxSubmit: submit aborted via beforeSerialize callback'); 82 return this; 83 } 84 85 var n,v,a = this.formToArray(options.semantic); 86 if (options.data) { 87 options.extraData = options.data; 88 for (n in options.data) { 89 if(options.data[n] instanceof Array) { 90 for (var k in options.data[n]) { 91 a.push( { name: n, value: options.data[n][k] } ); 92 } 93 } 94 else { 95 v = options.data[n]; 96 v = $.isFunction(v) ? v() : v; // if value is fn, invoke it 97 a.push( { name: n, value: v } ); 98 } 99 } 100 } 101 102 // give pre-submit callback an opportunity to abort the submit 103 if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { 104 log('ajaxSubmit: submit aborted via beforeSubmit callback'); 105 return this; 106 } 107 108 // fire vetoable 'validate' event 109 this.trigger('form-submit-validate', [a, this, options, veto]); 110 if (veto.veto) { 111 log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); 112 return this; 113 } 114 115 var q = $.param(a); 116 117 if (options.type.toUpperCase() == 'GET') { 118 options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; 119 options.data = null; // data is null for 'get' 120 } 121 else { 122 options.data = q; // data is the query string for 'post' 123 } 124 125 var $form = this, callbacks = []; 126 if (options.resetForm) { 127 callbacks.push(function() { $form.resetForm(); }); 128 } 129 if (options.clearForm) { 130 callbacks.push(function() { $form.clearForm(); }); 131 } 132 133 // perform a load on the target only if dataType is not provided 134 if (!options.dataType && options.target) { 135 var oldSuccess = options.success || function(){}; 136 callbacks.push(function(data) { 137 var fn = options.replaceTarget ? 'replaceWith' : 'html'; 138 $(options.target)[fn](data).each(oldSuccess, arguments); 139 }); 140 } 141 else if (options.success) { 142 callbacks.push(options.success); 143 } 144 145 options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg 146 var context = options.context || options; // jQuery 1.4+ supports scope context 147 for (var i=0, max=callbacks.length; i < max; i++) { 148 callbacks[i].apply(context, [data, status, xhr || $form, $form]); 149 } 150 }; 151 152 // are there files to upload? 153 var fileInputs = $('input:file', this).length > 0; 154 var mp = 'multipart/form-data'; 155 var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); 156 157 // options.iframe allows user to force iframe mode 158 // 06-NOV-09: now defaulting to iframe mode if file input is detected 159 if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { 160 // hack to fix Safari hang (thanks to Tim Molendijk for this) 161 // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d 162 if (options.closeKeepAlive) { 163 $.get(options.closeKeepAlive, fileUpload); 164 } 165 else { 166 fileUpload(); 167 } 168 } 169 else { 170 $.ajax(options); 171 } 172 173 // fire 'notify' event 174 this.trigger('form-submit-notify', [this, options]); 175 return this; 176 177 178 // private function for handling file uploads (hat tip to YAHOO!) 179 function fileUpload() { 180 var form = $form[0]; 181 182 if ($(':input[name=submit],:input[id=submit]', form).length) { 183 // if there is an input with a name or id of 'submit' then we won't be 184 // able to invoke the submit fn on the form (at least not x-browser) 185 alert('Error: Form elements must not have name or id of "submit".'); 186 return; 187 } 188 189 var s = $.extend(true, {}, $.ajaxSettings, options); 190 s.context = s.context || s; 191 var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id; 192 window[fn] = function() { 193 var f = $io.data('form-plugin-onload'); 194 if (f) { 195 f(); 196 window[fn] = undefined;
197 try { delete window[fn]; } catch(e){} 198 } 199 } 200 var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" onload="window[\'_\'+this.id]()" />'); 201 var io = $io[0]; 202 203 $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); 204 205 var xhr = { // mock object 206 aborted: 0, 207 responseText: null, 208 responseXML: null, 209 status: 0, 210 statusText: 'n/a', 211 getAllResponseHeaders: function() {}, 212 getResponseHeader: function() {}, 213 setRequestHeader: function() {}, 214 abort: function() { 215 this.aborted = 1; 216 $io.attr('src', s.iframeSrc); // abort op in progress 217 } 218 }; 219 220 var g = s.global; 221 // trigger ajax global events so that activity/block indicators work like normal 222 if (g && ! $.active++) { 223 $.event.trigger("ajaxStart"); 224 } 225 if (g) { 226 $.event.trigger("ajaxSend", [xhr, s]); 227 } 228 229 if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) { 230 if (s.global) { 231 $.active--; 232 } 233 return; 234 } 235 if (xhr.aborted) { 236 return; 237 } 238 239 var cbInvoked = false; 240 var timedOut = 0; 241 242 // add submitting element to data if we know it 243 var sub = form.clk; 244 if (sub) { 245 var n = sub.name; 246 if (n && !sub.disabled) { 247 s.extraData = s.extraData || {}; 248 s.extraData[n] = sub.value; 249 if (sub.type == "image") { 250 s.extraData[n+'.x'] = form.clk_x; 251 s.extraData[n+'.y'] = form.clk_y; 252 } 253 } 254 } 255 256 // take a breath so that pending repaints get some cpu time before the upload starts 257 function doSubmit() { 258 // make sure form attrs are set 259 var t = $form.attr('target'), a = $form.attr('action'); 260 261 // update form attrs in IE friendly way 262 form.setAttribute('target',id); 263 if (form.getAttribute('method') != 'POST') { 264 form.setAttribute('method', 'POST'); 265 } 266 if (form.getAttribute('action') != s.url) { 267 form.setAttribute('action', s.url); 268 } 269 270 // ie borks in some cases when setting encoding 271 if (! s.skipEncodingOverride) { 272 $form.attr({ 273 encoding: 'multipart/form-data', 274 enctype: 'multipart/form-data' 275 }); 276 } 277 278 // support timout 279 if (s.timeout) { 280 setTimeout(function() { timedOut = true; cb(); }, s.timeout); 281 } 282 283 // add "extra" data to form if provided in options 284 var extraInputs = []; 285 try { 286 if (s.extraData) { 287 for (var n in s.extraData) { 288 extraInputs.push( 289 $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />') 290 .appendTo(form)[0]); 291 } 292 } 293 294 // add iframe to doc and submit the form 295 $io.appendTo('body'); 296 $io.data('form-plugin-onload', cb); 297 form.submit(); 298 } 299 finally { 300 // reset attrs and remove "extra" input elements 301 form.setAttribute('action',a); 302 if(t) { 303 form.setAttribute('target', t); 304 } else { 305 $form.removeAttr('target'); 306 } 307 $(extraInputs).remove(); 308 } 309 } 310 311 if (s.forceSync) { 312 doSubmit(); 313 } 314 else { 315 setTimeout(doSubmit, 10); // this lets dom updates render 316 } 317 318 var data, doc, domCheckCount = 50; 319 320 function cb() { 321 if (cbInvoked) { 322 return; 323 } 324 325 $io.removeData('form-plugin-onload'); 326 327 var ok = true; 328 try { 329 if (timedOut) { 330 throw 'timeout'; 331 } 332 // extract the server response from the iframe 333 doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; 334 335 var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); 336 log('isXml='+isXml); 337 if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) { 338 if (--domCheckCount) { 339 // in some browsers (Opera) the iframe DOM is not always traversable when 340 // the onload callback fires, so we loop a bit to accommodate 341 log('requeing onLoad callback, DOM not available'); 342 setTimeout(cb, 250); 343 return; 344 } 345 // let this fall through because server response could be an empty document 346 //log('Could not access iframe DOM after mutiple tries.'); 347 //throw 'DOMException: not available'; 348 } 349 350 //log('response detected'); 351 cbInvoked = true; 352 xhr.responseText = doc.documentElement ? doc.documentElement.innerHTML : null; 353 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; 354 xhr.getResponseHeader = function(header){ 355 var headers = {'content-type': s.dataType}; 356 return headers[header]; 357 }; 358 359 var scr = /(json|script)/.test(s.dataType); 360 if (scr || s.textarea) { 361 // see if user embedded response in textarea 362 var ta = doc.getElementsByTagName('textarea')[0]; 363 if (ta) { 364 xhr.responseText = ta.value; 365 } 366 else if (scr) { 367 // account for browsers injecting pre around json response 368 var pre = doc.getElementsByTagName('pre')[0]; 369 if (pre) { 370 xhr.responseText = pre.innerHTML; 371 } 372 } 373 } 374 else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { 375 xhr.responseXML = toXml(xhr.responseText); 376 } 377 data = $.httpData(xhr, s.dataType); 378 } 379 catch(e){ 380 log('error caught:',e); 381 ok = false;
382 xhr.error = e; 383 $.handleError(s, xhr, 'error', e); 384 } 385 386 // ordering of these callbacks/triggers is odd, but that's how $.ajax does it 387 if (ok) { 388 s.success.call(s.context, data, 'success', xhr); 389 if (g) { 390 $.event.trigger("ajaxSuccess", [xhr, s]); 391 } 392 } 393 if (g) { 394 $.event.trigger("ajaxComplete", [xhr, s]); 395 } 396 if (g && ! --$.active) { 397 $.event.trigger("ajaxStop"); 398 } 399 if (s.complete) { 400 s.complete.call(s.context, xhr, ok ? 'success' : 'error'); 401 } 402 403 // clean up 404 setTimeout(function() { 405 $io.removeData('form-plugin-onload'); 406 $io.remove(); 407 xhr.responseXML = null; 408 }, 100); 409 } 410 411 function toXml(s, doc) { 412 if (window.ActiveXObject) { 413 doc = new ActiveXObject('Microsoft.XMLDOM'); 414 doc.async = 'false'; 415 doc.loadXML(s); 416 } 417 else { 418 doc = (new DOMParser()).parseFromString(s, 'text/xml'); 419 } 420 return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null; 421 } 422 } 423}; 424 425/** 426 * ajaxForm() provides a mechanism for fully automating form submission. 427 * 428 * The advantages of using this method instead of ajaxSubmit() are: 429 * 430 * 1: This method will include coordinates for <input type="image" /> elements (if the element 431 * is used to submit the form). 432 * 2. This method will include the submit element's name/value data (for the element that was 433 * used to submit the form). 434 * 3. This method binds the submit() method to the form for you. 435 * 436 * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely 437 * passes the options argument along after properly binding events for submit elements and 438 * the form itself. 439 */ 440$.fn.ajaxForm = function(options) { 441 // in jQuery 1.3+ we can fix mistakes with the ready state 442 if (this.length === 0) { 443 var o = { s: this.selector, c: this.context }; 444 if (!$.isReady && o.s) { 445 log('DOM not ready, queuing ajaxForm'); 446 $(function() { 447 $(o.s,o.c).ajaxForm(options); 448 }); 449 return this; 450 } 451 // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready() 452 log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); 453 return this; 454 } 455 456 return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) { 457 if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed 458 e.preventDefault(); 459 $(this).ajaxSubmit(options); 460 } 461 }).bind('click.form-plugin', function(e) { 462 var target = e.target; 463 var $el = $(target); 464 if (!($el.is(":submit,input:image"))) { 465 // is this a child element of the submit el? (ex: a span within a button) 466 var t = $el.closest(':submit'); 467 if (t.length == 0) { 468 return; 469 } 470 target = t[0]; 471 } 472 var form = this; 473 form.clk = target; 474 if (target.type == 'image') { 475 if (e.offsetX != undefined) { 476 form.clk_x = e.offsetX; 477 form.clk_y = e.offsetY; 478 } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin 479 var offset = $el.offset(); 480 form.clk_x = e.pageX - offset.left; 481 form.clk_y = e.pageY - offset.top; 482 } else { 483 form.clk_x = e.pageX - target.offsetLeft; 484 form.clk_y = e.pageY - target.offsetTop; 485 } 486 } 487 // clear form vars 488 setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); 489 }); 490}; 491 492// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm 493$.fn.ajaxFormUnbind = function() { 494 return this.unbind('submit.form-plugin click.form-plugin'); 495}; 496 497/** 498 * formToArray() gathers form element data into an array of objects that can 499 * be passed to any of the following ajax functions: $.get, $.post, or load. 500 * Each object in the array has both a 'name' and 'value' property. An example of 501 * an array for a simple login form might be: 502 * 503 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] 504 * 505 * It is this array that is passed to pre-submit callback functions provided to the 506 * ajaxSubmit() and ajaxForm() methods. 507 */ 508$.fn.formToArray = function(semantic) { 509 var a = []; 510 if (this.length === 0) { 511 return a; 512 } 513 514 var form = this[0]; 515 var els = semantic ? form.getElementsByTagName('*') : form.elements; 516 if (!els) { 517 return a; 518 } 519 520 var i,j,n,v,el; 521 for(i=0, max=els.length; i < max; i++) { 522 el = els[i]; 523 n = el.name; 524 if (!n) { 525 continue; 526 } 527 528 if (semantic && form.clk && el.type == "image") { 529 // handle image inputs on the fly when semantic == true 530 if(!el.disabled && form.clk == el) { 531 a.push({name: n, value: $(el).val()}); 532 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 533 } 534 continue; 535 } 536 537 v = $.fieldValue(el, true); 538 if (v && v.constructor == Array) { 539 for(j=0, jmax=v.length; j < jmax; j++) { 540 a.push({name: n, value: v[j]}); 541 } 542 } 543 else if (v !== null && typeof v != 'undefined') { 544 a.push({name: n, value: v}); 545 } 546 } 547 548 if (!semantic && form.clk) { 549 // input type=='image' are not found in elements array! handle it here 550 var $input = $(form.clk), input = $input[0]; 551 n = input.name; 552 if (n && !input.disabled && input.type == 'image') { 553 a.push({name: n, value: $input.val()}); 554 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 555 } 556 } 557 return a; 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$.fn.formSerialize = function(semantic) { 565 //hand off to jQuery.param for proper encoding 566 return $.param(this.formToArray(semantic)); 567}; 568 569/** 570 * Serializes all field elements in the jQuery object into a query string. 571 * This method will return a string in the format: name1=value1&name2=value2 572 */ 573$.fn.fieldSerialize = function(successful) { 574 var a = []; 575 this.each(function() { 576 var n = this.name; 577 if (!n) { 578 return; 579 } 580 var v = $.fieldValue(this, successful); 581 if (v && v.constructor == Array) { 582 for (var i=0,max=v.length; i < max; i++) { 583 a.push({name: n, value: v[i]}); 584 } 585 } 586 else if (v !== null && typeof v != 'undefined') { 587 a.push({name: this.name, value: v}); 588 } 589 }); 590 //hand off to jQuery.param for proper encoding 591 return $.param(a); 592}; 593 594/** 595 * Returns the value(s) of the element in the matched set. For example, consider the following form: 596 * 597 * <form><fieldset> 598 * <input name="A" type="text" /> 599 * <input name="A" type="text" /> 600 * <input name="B" type="checkbox" value="B1" /> 601 * <input name="B" type="checkbox" value="B2"/> 602 * <input name="C" type="radio" value="C1" /> 603 * <input name="C" type="radio" value="C2" /> 604 * </fieldset></form> 605 * 606 * var v = $(':text').fieldValue(); 607 * // if no values are entered into the text inputs 608 * v == ['',''] 609 * // if values entered into the text inputs are 'foo' and 'bar' 610 * v == ['foo','bar'] 611 * 612 * var v = $(':checkbox').fieldValue(); 613 * // if neither checkbox is checked 614 * v === undefined 615 * // if both checkboxes are checked 616 * v == ['B1', 'B2'] 617 * 618 * var v = $(':radio').fieldValue(); 619 * // if neither radio is checked 620 * v === undefined 621 * // if first radio is checked 622 * v == ['C1'] 623 * 624 * The successful argument controls whether or not the field element must be 'successful' 625 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 626 * The default value of the successful argument is true. If this value is false the value(s) 627 * for each element is returned. 628 * 629 * Note: This method *always* returns an array. If no valid value can be determined the 630 * array will be empty, otherwise it will contain one or more values. 631 */ 632$.fn.fieldValue = function(successful) { 633 for (var val=[], i=0, max=this.length; i < max; i++) { 634 var el = this[i]; 635 var v = $.fieldValue(el, successful); 636 if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) { 637 continue; 638 } 639 v.constructor == Array ? $.merge(val, v) : val.push(v); 640 } 641 return val; 642}; 643 644/** 645 * Returns the value of the field element. 646 */ 647$.fieldValue = function(el, successful) { 648 var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); 649 if (successful === undefined) { 650 successful = true; 651 } 652 653 if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || 654 (t == 'checkbox' || t == 'radio') && !el.checked || 655 (t == 'submit' || t == 'image') && el.form && el.form.clk != el || 656 tag == 'select' && el.selectedIndex == -1)) { 657 return null; 658 } 659 660 if (tag == 'select') { 661 var index = el.selectedIndex; 662 if (index < 0) { 663 return null; 664 } 665 var a = [], ops = el.options; 666 var one = (t == 'select-one'); 667 var max = (one ? index+1 : ops.length); 668 for(var i=(one ? index : 0); i < max; i++) { 669 var op = ops[i]; 670 if (op.selected) { 671 var v = op.value; 672 if (!v) { // extra pain for IE... 673 v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; 674 } 675 if (one) { 676 return v; 677 } 678 a.push(v); 679 } 680 } 681 return a; 682 } 683 return $(el).val(); 684}; 685 686/** 687 * Clears the form data. Takes the following actions on the form's input fields: 688 * - input text fields will have their 'value' property set to the empty string 689 * - select elements will have their 'selectedIndex' property set to -1 690 * - checkbox and radio inputs will have their 'checked' property set to false 691 * - inputs of type submit, button, reset, and hidden will *not* be effected 692 * - button elements will *not* be effected 693 */ 694$.fn.clearForm = function() { 695 return this.each(function() { 696 $('input,select,textarea', this).clearFields(); 697 }); 698}; 699 700/** 701 * Clears the selected form elements. 702 */ 703$.fn.clearFields = $.fn.clearInputs = function() { 704 return this.each(function() { 705 var t = this.type, tag = this.tagName.toLowerCase(); 706 if (t == 'text' || t == 'password' || tag == 'textarea') { 707 this.value = ''; 708 } 709 else if (t == 'checkbox' || t == 'radio') { 710 this.checked = false;
711 } 712 else if (tag == 'select') { 713 this.selectedIndex = -1; 714 } 715 }); 716}; 717 718/** 719 * Resets the form data. Causes all form elements to be reset to their original value. 720 */ 721$.fn.resetForm = function() { 722 return this.each(function() { 723 // guard against an input with the name of 'reset' 724 // note that IE reports the reset function as an 'object' 725 if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) { 726 this.reset(); 727 } 728 }); 729}; 730 731/** 732 * Enables or disables any matching elements. 733 */ 734$.fn.enable = function(b) { 735 if (b === undefined) { 736 b = true; 737 } 738 return this.each(function() { 739 this.disabled = !b; 740 }); 741}; 742 743/** 744 * Checks/unchecks any matching checkboxes or radio buttons and 745 * selects/deselects and matching option elements. 746 */ 747$.fn.selected = function(select) { 748 if (select === undefined) { 749 select = true; 750 } 751 return this.each(function() { 752 var t = this.type; 753 if (t == 'checkbox' || t == 'radio') { 754 this.checked = select; 755 } 756 else if (this.tagName.toLowerCase() == 'option') { 757 var $sel = $(this).parent('select'); 758 if (select && $sel[0] && $sel[0].type == 'select-one') { 759 // deselect all other options 760 $sel.find('option').selected(false); 761 } 762 this.selected = select; 763 } 764 }); 765}; 766 767// helper fn for console logging 768// set $.fn.ajaxSubmit.debug to true to enable debug logging 769function log() { 770 if ($.fn.ajaxSubmit.debug) { 771 var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); 772 if (window.console && window.console.log) { 773 window.console.log(msg); 774 } 775 else if (window.opera && window.opera.postError) { 776 window.opera.postError(msg); 777 } 778 } 779}; 780 781})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.