[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 /*! 2 * jQuery Form Plugin 3 * version: 2.94 (13-DEC-2011) 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(e) { 22 e.preventDefault(); // <-- important 23 $(this).ajaxSubmit({ 24 target: '#output' 25 }); 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 var method, action, url, $form = this; 54 55 if (typeof options == 'function') { 56 options = { success: options }; 57 } 58 59 method = this.attr('method'); 60 action = this.attr('action'); 61 url = (typeof action === 'string') ? $.trim(action) : ''; 62 url = url || window.location.href || ''; 63 if (url) { 64 // clean url (don't include hash vaue) 65 url = (url.match(/^([^#]+)/)||[])[1]; 66 } 67 68 options = $.extend(true, { 69 url: url, 70 success: $.ajaxSettings.success, 71 type: method || 'GET', 72 iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' 73 }, options); 74 75 // hook for manipulating the form data before it is extracted; 76 // convenient for use with rich editors like tinyMCE or FCKEditor 77 var veto = {}; 78 this.trigger('form-pre-serialize', [this, options, veto]); 79 if (veto.veto) { 80 log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); 81 return this; 82 } 83 84 // provide opportunity to alter form data before it is serialized 85 if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { 86 log('ajaxSubmit: submit aborted via beforeSerialize callback'); 87 return this; 88 } 89 90 var traditional = options.traditional; 91 if ( traditional === undefined ) { 92 traditional = $.ajaxSettings.traditional; 93 } 94 95 var qx,n,v,a = this.formToArray(options.semantic); 96 if (options.data) { 97 options.extraData = options.data; 98 qx = $.param(options.data, traditional); 99 } 100 101 // give pre-submit callback an opportunity to abort the submit 102 if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { 103 log('ajaxSubmit: submit aborted via beforeSubmit callback'); 104 return this; 105 } 106 107 // fire vetoable 'validate' event 108 this.trigger('form-submit-validate', [a, this, options, veto]); 109 if (veto.veto) { 110 log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); 111 return this; 112 } 113 114 var q = $.param(a, traditional); 115 if (qx) { 116 q = ( q ? (q + '&' + qx) : qx ); 117 } 118 if (options.type.toUpperCase() == 'GET') { 119 options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; 120 options.data = null; // data is null for 'get' 121 } 122 else { 123 options.data = q; // data is the query string for 'post' 124 } 125 126 var callbacks = []; 127 if (options.resetForm) { 128 callbacks.push(function() { $form.resetForm(); }); 129 } 130 if (options.clearForm) { 131 callbacks.push(function() { $form.clearForm(options.includeHidden); }); 132 } 133 134 // perform a load on the target only if dataType is not provided 135 if (!options.dataType && options.target) { 136 var oldSuccess = options.success || function(){}; 137 callbacks.push(function(data) { 138 var fn = options.replaceTarget ? 'replaceWith' : 'html'; 139 $(options.target)[fn](data).each(oldSuccess, arguments); 140 }); 141 } 142 else if (options.success) { 143 callbacks.push(options.success); 144 } 145 146 options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg 147 var context = options.context || options; // jQuery 1.4+ supports scope context 148 for (var i=0, max=callbacks.length; i < max; i++) { 149 callbacks[i].apply(context, [data, status, xhr || $form, $form]); 150 } 151 }; 152 153 // are there files to upload? 154 var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113) 155 var hasFileInputs = fileInputs.length > 0; 156 var mp = 'multipart/form-data'; 157 var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); 158 159 var fileAPI = !!(hasFileInputs && fileInputs.get(0).files && window.FormData); 160 log("fileAPI :" + fileAPI); 161 var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI; 162 163 // options.iframe allows user to force iframe mode 164 // 06-NOV-09: now defaulting to iframe mode if file input is detected 165 if (options.iframe !== false && (options.iframe || shouldUseFrame)) { 166 // hack to fix Safari hang (thanks to Tim Molendijk for this) 167 // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d 168 if (options.closeKeepAlive) { 169 $.get(options.closeKeepAlive, function() { 170 fileUploadIframe(a); 171 }); 172 } 173 else { 174 fileUploadIframe(a); 175 } 176 } 177 else if ((hasFileInputs || multipart) && fileAPI) { 178 options.progress = options.progress || $.noop; 179 fileUploadXhr(a); 180 } 181 else { 182 $.ajax(options); 183 } 184 185 // fire 'notify' event 186 this.trigger('form-submit-notify', [this, options]); 187 return this; 188 189 // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz) 190 function fileUploadXhr(a) { 191 var formdata = new FormData(); 192 193 for (var i=0; i < a.length; i++) { 194 if (a[i].type == 'file') 195 continue; 196 formdata.append(a[i].name, a[i].value); 197 } 198 199 $form.find('input:file:enabled').each(function(){ 200 var name = $(this).attr('name'), files = this.files; 201 if (name) { 202 for (var i=0; i < files.length; i++) 203 formdata.append(name, files[i]); 204 } 205 }); 206 207 if (options.extraData) { 208 for (var k in options.extraData) 209 formdata.append(k, options.extraData[k]) 210 } 211 212 options.data = null; 213 214 var s = $.extend(true, {}, $.ajaxSettings, options, { 215 contentType: false, 216 processData: false, 217 cache: false, 218 type: 'POST' 219 }); 220 221 s.context = s.context || s; 222 223 s.data = null; 224 var beforeSend = s.beforeSend; 225 s.beforeSend = function(xhr, o) { 226 o.data = formdata; 227 if(xhr.upload) { // unfortunately, jQuery doesn't expose this prop (http://bugs.jquery.com/ticket/10190) 228 xhr.upload.onprogress = function(event) { 229 o.progress(event.position, event.total); 230 }; 231 } 232 if(beforeSend) 233 beforeSend.call(o, xhr, options); 234 }; 235 $.ajax(s); 236 } 237 238 // private function for handling file uploads (hat tip to YAHOO!) 239 function fileUploadIframe(a) { 240 var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; 241 var useProp = !!$.fn.prop; 242 243 if (a) { 244 if ( useProp ) { 245 // ensure that every serialized input is still enabled 246 for (i=0; i < a.length; i++) { 247 el = $(form[a[i].name]); 248 el.prop('disabled', false); 249 } 250 } else { 251 for (i=0; i < a.length; i++) { 252 el = $(form[a[i].name]); 253 el.removeAttr('disabled'); 254 } 255 }; 256 } 257 258 if ($(':input[name=submit],:input[id=submit]', form).length) { 259 // if there is an input with a name or id of 'submit' then we won't be 260 // able to invoke the submit fn on the form (at least not x-browser) 261 alert('Error: Form elements must not have name or id of "submit".'); 262 return; 263 } 264 265 s = $.extend(true, {}, $.ajaxSettings, options); 266 s.context = s.context || s; 267 id = 'jqFormIO' + (new Date().getTime()); 268 if (s.iframeTarget) { 269 $io = $(s.iframeTarget); 270 n = $io.attr('name'); 271 if (n == null) 272 $io.attr('name', id); 273 else 274 id = n; 275 } 276 else { 277 $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />'); 278 $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); 279 } 280 io = $io[0]; 281 282 283 xhr = { // mock object 284 aborted: 0, 285 responseText: null, 286 responseXML: null, 287 status: 0, 288 statusText: 'n/a', 289 getAllResponseHeaders: function() {}, 290 getResponseHeader: function() {}, 291 setRequestHeader: function() {}, 292 abort: function(status) { 293 var e = (status === 'timeout' ? 'timeout' : 'aborted'); 294 log('aborting upload... ' + e); 295 this.aborted = 1; 296 $io.attr('src', s.iframeSrc); // abort op in progress 297 xhr.error = e; 298 s.error && s.error.call(s.context, xhr, e, status); 299 g && $.event.trigger("ajaxError", [xhr, s, e]); 300 s.complete && s.complete.call(s.context, xhr, e); 301 } 302 }; 303 304 g = s.global; 305 // trigger ajax global events so that activity/block indicators work like normal 306 if (g && ! $.active++) { 307 $.event.trigger("ajaxStart"); 308 } 309 if (g) { 310 $.event.trigger("ajaxSend", [xhr, s]); 311 } 312 313 if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) { 314 if (s.global) { 315 $.active--; 316 } 317 return; 318 } 319 if (xhr.aborted) { 320 return; 321 } 322 323 // add submitting element to data if we know it 324 sub = form.clk; 325 if (sub) { 326 n = sub.name; 327 if (n && !sub.disabled) { 328 s.extraData = s.extraData || {}; 329 s.extraData[n] = sub.value; 330 if (sub.type == "image") { 331 s.extraData[n+'.x'] = form.clk_x; 332 s.extraData[n+'.y'] = form.clk_y; 333 } 334 } 335 } 336 337 var CLIENT_TIMEOUT_ABORT = 1; 338 var SERVER_ABORT = 2; 339 340 function getDoc(frame) { 341 var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document; 342 return doc; 343 } 344 345 // Rails CSRF hack (thanks to Yvan Barthelemy) 346 var csrf_token = $('meta[name=csrf-token]').attr('content'); 347 var csrf_param = $('meta[name=csrf-param]').attr('content'); 348 if (csrf_param && csrf_token) { 349 s.extraData = s.extraData || {}; 350 s.extraData[csrf_param] = csrf_token; 351 } 352 353 // take a breath so that pending repaints get some cpu time before the upload starts 354 function doSubmit() { 355 // make sure form attrs are set 356 var t = $form.attr('target'), a = $form.attr('action'); 357 358 // update form attrs in IE friendly way 359 form.setAttribute('target',id); 360 if (!method) { 361 form.setAttribute('method', 'POST'); 362 } 363 if (a != s.url) { 364 form.setAttribute('action', s.url); 365 } 366 367 // ie borks in some cases when setting encoding 368 if (! s.skipEncodingOverride && (!method || /post/i.test(method))) { 369 $form.attr({ 370 encoding: 'multipart/form-data', 371 enctype: 'multipart/form-data' 372 }); 373 } 374 375 // support timout 376 if (s.timeout) { 377 timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout); 378 } 379 380 // look for server aborts 381 function checkState() { 382 try { 383 var state = getDoc(io).readyState; 384 log('state = ' + state); 385 if (state.toLowerCase() == 'uninitialized') 386 setTimeout(checkState,50); 387 } 388 catch(e) { 389 log('Server abort: ' , e, ' (', e.name, ')'); 390 cb(SERVER_ABORT); 391 timeoutHandle && clearTimeout(timeoutHandle); 392 timeoutHandle = undefined; 393 } 394 } 395 396 // add "extra" data to form if provided in options 397 var extraInputs = []; 398 try { 399 if (s.extraData) { 400 for (var n in s.extraData) { 401 extraInputs.push( 402 $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n]) 403 .appendTo(form)[0]); 404 } 405 } 406 407 if (!s.iframeTarget) { 408 // add iframe to doc and submit the form 409 $io.appendTo('body'); 410 io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); 411 } 412 setTimeout(checkState,15); 413 form.submit(); 414 } 415 finally { 416 // reset attrs and remove "extra" input elements 417 form.setAttribute('action',a); 418 if(t) { 419 form.setAttribute('target', t); 420 } else { 421 $form.removeAttr('target'); 422 } 423 $(extraInputs).remove(); 424 } 425 } 426 427 if (s.forceSync) { 428 doSubmit(); 429 } 430 else { 431 setTimeout(doSubmit, 10); // this lets dom updates render 432 } 433 434 var data, doc, domCheckCount = 50, callbackProcessed; 435 436 function cb(e) { 437 if (xhr.aborted || callbackProcessed) { 438 return; 439 } 440 try { 441 doc = getDoc(io); 442 } 443 catch(ex) { 444 log('cannot access response document: ', ex); 445 e = SERVER_ABORT; 446 } 447 if (e === CLIENT_TIMEOUT_ABORT && xhr) { 448 xhr.abort('timeout'); 449 return; 450 } 451 else if (e == SERVER_ABORT && xhr) { 452 xhr.abort('server abort'); 453 return; 454 } 455 456 if (!doc || doc.location.href == s.iframeSrc) { 457 // response not received yet 458 if (!timedOut) 459 return; 460 } 461 io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); 462 463 var status = 'success', errMsg; 464 try { 465 if (timedOut) { 466 throw 'timeout'; 467 } 468 469 var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); 470 log('isXml='+isXml); 471 if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) { 472 if (--domCheckCount) { 473 // in some browsers (Opera) the iframe DOM is not always traversable when 474 // the onload callback fires, so we loop a bit to accommodate 475 log('requeing onLoad callback, DOM not available'); 476 setTimeout(cb, 250); 477 return; 478 } 479 // let this fall through because server response could be an empty document 480 //log('Could not access iframe DOM after mutiple tries.'); 481 //throw 'DOMException: not available'; 482 } 483 484 //log('response detected'); 485 var docRoot = doc.body ? doc.body : doc.documentElement; 486 xhr.responseText = docRoot ? docRoot.innerHTML : null; 487 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; 488 if (isXml) 489 s.dataType = 'xml'; 490 xhr.getResponseHeader = function(header){ 491 var headers = {'content-type': s.dataType}; 492 return headers[header]; 493 }; 494 // support for XHR 'status' & 'statusText' emulation : 495 if (docRoot) { 496 xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status; 497 xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText; 498 } 499 500 var dt = (s.dataType || '').toLowerCase(); 501 var scr = /(json|script|text)/.test(dt); 502 if (scr || s.textarea) { 503 // see if user embedded response in textarea 504 var ta = doc.getElementsByTagName('textarea')[0]; 505 if (ta) { 506 xhr.responseText = ta.value; 507 // support for XHR 'status' & 'statusText' emulation : 508 xhr.status = Number( ta.getAttribute('status') ) || xhr.status; 509 xhr.statusText = ta.getAttribute('statusText') || xhr.statusText; 510 } 511 else if (scr) { 512 // account for browsers injecting pre around json response 513 var pre = doc.getElementsByTagName('pre')[0]; 514 var b = doc.getElementsByTagName('body')[0]; 515 if (pre) { 516 xhr.responseText = pre.textContent ? pre.textContent : pre.innerText; 517 } 518 else if (b) { 519 xhr.responseText = b.textContent ? b.textContent : b.innerText; 520 } 521 } 522 } 523 else if (dt == 'xml' && !xhr.responseXML && xhr.responseText != null) { 524 xhr.responseXML = toXml(xhr.responseText); 525 } 526 527 try { 528 data = httpData(xhr, dt, s); 529 } 530 catch (e) { 531 status = 'parsererror'; 532 xhr.error = errMsg = (e || status); 533 } 534 } 535 catch (e) { 536 log('error caught: ',e); 537 status = 'error'; 538 xhr.error = errMsg = (e || status); 539 } 540 541 if (xhr.aborted) { 542 log('upload aborted'); 543 status = null; 544 } 545 546 if (xhr.status) { // we've set xhr.status 547 status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error'; 548 } 549 550 // ordering of these callbacks/triggers is odd, but that's how $.ajax does it 551 if (status === 'success') { 552 s.success && s.success.call(s.context, data, 'success', xhr); 553 g && $.event.trigger("ajaxSuccess", [xhr, s]); 554 } 555 else if (status) { 556 if (errMsg == undefined) 557 errMsg = xhr.statusText; 558 s.error && s.error.call(s.context, xhr, status, errMsg); 559 g && $.event.trigger("ajaxError", [xhr, s, errMsg]); 560 } 561 562 g && $.event.trigger("ajaxComplete", [xhr, s]); 563 564 if (g && ! --$.active) { 565 $.event.trigger("ajaxStop"); 566 } 567 568 s.complete && s.complete.call(s.context, xhr, status); 569 570 callbackProcessed = true; 571 if (s.timeout) 572 clearTimeout(timeoutHandle); 573 574 // clean up 575 setTimeout(function() { 576 if (!s.iframeTarget) 577 $io.remove(); 578 xhr.responseXML = null; 579 }, 100); 580 } 581 582 var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+) 583 if (window.ActiveXObject) { 584 doc = new ActiveXObject('Microsoft.XMLDOM'); 585 doc.async = 'false'; 586 doc.loadXML(s); 587 } 588 else { 589 doc = (new DOMParser()).parseFromString(s, 'text/xml'); 590 } 591 return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null; 592 }; 593 var parseJSON = $.parseJSON || function(s) { 594 return window['eval']('(' + s + ')'); 595 }; 596 597 var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4 598 599 var ct = xhr.getResponseHeader('content-type') || '', 600 xml = type === 'xml' || !type && ct.indexOf('xml') >= 0, 601 data = xml ? xhr.responseXML : xhr.responseText; 602 603 if (xml && data.documentElement.nodeName === 'parsererror') { 604 $.error && $.error('parsererror'); 605 } 606 if (s && s.dataFilter) { 607 data = s.dataFilter(data, type); 608 } 609 if (typeof data === 'string') { 610 if (type === 'json' || !type && ct.indexOf('json') >= 0) { 611 data = parseJSON(data); 612 } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) { 613 $.globalEval(data); 614 } 615 } 616 return data; 617 }; 618 } 619 }; 620 621 /** 622 * ajaxForm() provides a mechanism for fully automating form submission. 623 * 624 * The advantages of using this method instead of ajaxSubmit() are: 625 * 626 * 1: This method will include coordinates for <input type="image" /> elements (if the element 627 * is used to submit the form). 628 * 2. This method will include the submit element's name/value data (for the element that was 629 * used to submit the form). 630 * 3. This method binds the submit() method to the form for you. 631 * 632 * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely 633 * passes the options argument along after properly binding events for submit elements and 634 * the form itself. 635 */ 636 $.fn.ajaxForm = function(options) { 637 // in jQuery 1.3+ we can fix mistakes with the ready state 638 if (this.length === 0) { 639 var o = { s: this.selector, c: this.context }; 640 if (!$.isReady && o.s) { 641 log('DOM not ready, queuing ajaxForm'); 642 $(function() { 643 $(o.s,o.c).ajaxForm(options); 644 }); 645 return this; 646 } 647 // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready() 648 log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); 649 return this; 650 } 651 652 return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) { 653 if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed 654 e.preventDefault(); 655 $(this).ajaxSubmit(options); 656 } 657 }).bind('click.form-plugin', function(e) { 658 var target = e.target; 659 var $el = $(target); 660 if (!($el.is(":submit,input:image"))) { 661 // is this a child element of the submit el? (ex: a span within a button) 662 var t = $el.closest(':submit'); 663 if (t.length == 0) { 664 return; 665 } 666 target = t[0]; 667 } 668 var form = this; 669 form.clk = target; 670 if (target.type == 'image') { 671 if (e.offsetX != undefined) { 672 form.clk_x = e.offsetX; 673 form.clk_y = e.offsetY; 674 } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin 675 var offset = $el.offset(); 676 form.clk_x = e.pageX - offset.left; 677 form.clk_y = e.pageY - offset.top; 678 } else { 679 form.clk_x = e.pageX - target.offsetLeft; 680 form.clk_y = e.pageY - target.offsetTop; 681 } 682 } 683 // clear form vars 684 setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); 685 }); 686 }; 687 688 // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm 689 $.fn.ajaxFormUnbind = function() { 690 return this.unbind('submit.form-plugin click.form-plugin'); 691 }; 692 693 /** 694 * formToArray() gathers form element data into an array of objects that can 695 * be passed to any of the following ajax functions: $.get, $.post, or load. 696 * Each object in the array has both a 'name' and 'value' property. An example of 697 * an array for a simple login form might be: 698 * 699 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] 700 * 701 * It is this array that is passed to pre-submit callback functions provided to the 702 * ajaxSubmit() and ajaxForm() methods. 703 */ 704 $.fn.formToArray = function(semantic) { 705 var a = []; 706 if (this.length === 0) { 707 return a; 708 } 709 710 var form = this[0]; 711 var els = semantic ? form.getElementsByTagName('*') : form.elements; 712 if (!els) { 713 return a; 714 } 715 716 var i,j,n,v,el,max,jmax; 717 for(i=0, max=els.length; i < max; i++) { 718 el = els[i]; 719 n = el.name; 720 if (!n) { 721 continue; 722 } 723 724 if (semantic && form.clk && el.type == "image") { 725 // handle image inputs on the fly when semantic == true 726 if(!el.disabled && form.clk == el) { 727 a.push({name: n, value: $(el).val(), type: el.type }); 728 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 729 } 730 continue; 731 } 732 733 v = $.fieldValue(el, true); 734 if (v && v.constructor == Array) { 735 for(j=0, jmax=v.length; j < jmax; j++) { 736 a.push({name: n, value: v[j]}); 737 } 738 } 739 else if (v !== null && typeof v != 'undefined') { 740 a.push({name: n, value: v, type: el.type}); 741 } 742 } 743 744 if (!semantic && form.clk) { 745 // input type=='image' are not found in elements array! handle it here 746 var $input = $(form.clk), input = $input[0]; 747 n = input.name; 748 if (n && !input.disabled && input.type == 'image') { 749 a.push({name: n, value: $input.val()}); 750 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 751 } 752 } 753 return a; 754 }; 755 756 /** 757 * Serializes form data into a 'submittable' string. This method will return a string 758 * in the format: name1=value1&name2=value2 759 */ 760 $.fn.formSerialize = function(semantic) { 761 //hand off to jQuery.param for proper encoding 762 return $.param(this.formToArray(semantic)); 763 }; 764 765 /** 766 * Serializes all field elements in the jQuery object into a query string. 767 * This method will return a string in the format: name1=value1&name2=value2 768 */ 769 $.fn.fieldSerialize = function(successful) { 770 var a = []; 771 this.each(function() { 772 var n = this.name; 773 if (!n) { 774 return; 775 } 776 var v = $.fieldValue(this, successful); 777 if (v && v.constructor == Array) { 778 for (var i=0,max=v.length; i < max; i++) { 779 a.push({name: n, value: v[i]}); 780 } 781 } 782 else if (v !== null && typeof v != 'undefined') { 783 a.push({name: this.name, value: v}); 784 } 785 }); 786 //hand off to jQuery.param for proper encoding 787 return $.param(a); 788 }; 789 790 /** 791 * Returns the value(s) of the element in the matched set. For example, consider the following form: 792 * 793 * <form><fieldset> 794 * <input name="A" type="text" /> 795 * <input name="A" type="text" /> 796 * <input name="B" type="checkbox" value="B1" /> 797 * <input name="B" type="checkbox" value="B2"/> 798 * <input name="C" type="radio" value="C1" /> 799 * <input name="C" type="radio" value="C2" /> 800 * </fieldset></form> 801 * 802 * var v = $(':text').fieldValue(); 803 * // if no values are entered into the text inputs 804 * v == ['',''] 805 * // if values entered into the text inputs are 'foo' and 'bar' 806 * v == ['foo','bar'] 807 * 808 * var v = $(':checkbox').fieldValue(); 809 * // if neither checkbox is checked 810 * v === undefined 811 * // if both checkboxes are checked 812 * v == ['B1', 'B2'] 813 * 814 * var v = $(':radio').fieldValue(); 815 * // if neither radio is checked 816 * v === undefined 817 * // if first radio is checked 818 * v == ['C1'] 819 * 820 * The successful argument controls whether or not the field element must be 'successful' 821 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 822 * The default value of the successful argument is true. If this value is false the value(s) 823 * for each element is returned. 824 * 825 * Note: This method *always* returns an array. If no valid value can be determined the 826 * array will be empty, otherwise it will contain one or more values. 827 */ 828 $.fn.fieldValue = function(successful) { 829 for (var val=[], i=0, max=this.length; i < max; i++) { 830 var el = this[i]; 831 var v = $.fieldValue(el, successful); 832 if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) { 833 continue; 834 } 835 v.constructor == Array ? $.merge(val, v) : val.push(v); 836 } 837 return val; 838 }; 839 840 /** 841 * Returns the value of the field element. 842 */ 843 $.fieldValue = function(el, successful) { 844 var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); 845 if (successful === undefined) { 846 successful = true; 847 } 848 849 if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || 850 (t == 'checkbox' || t == 'radio') && !el.checked || 851 (t == 'submit' || t == 'image') && el.form && el.form.clk != el || 852 tag == 'select' && el.selectedIndex == -1)) { 853 return null; 854 } 855 856 if (tag == 'select') { 857 var index = el.selectedIndex; 858 if (index < 0) { 859 return null; 860 } 861 var a = [], ops = el.options; 862 var one = (t == 'select-one'); 863 var max = (one ? index+1 : ops.length); 864 for(var i=(one ? index : 0); i < max; i++) { 865 var op = ops[i]; 866 if (op.selected) { 867 var v = op.value; 868 if (!v) { // extra pain for IE... 869 v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; 870 } 871 if (one) { 872 return v; 873 } 874 a.push(v); 875 } 876 } 877 return a; 878 } 879 return $(el).val(); 880 }; 881 882 /** 883 * Clears the form data. Takes the following actions on the form's input fields: 884 * - input text fields will have their 'value' property set to the empty string 885 * - select elements will have their 'selectedIndex' property set to -1 886 * - checkbox and radio inputs will have their 'checked' property set to false 887 * - inputs of type submit, button, reset, and hidden will *not* be effected 888 * - button elements will *not* be effected 889 */ 890 $.fn.clearForm = function(includeHidden) { 891 return this.each(function() { 892 $('input,select,textarea', this).clearFields(includeHidden); 893 }); 894 }; 895 896 /** 897 * Clears the selected form elements. 898 */ 899 $.fn.clearFields = $.fn.clearInputs = function(includeHidden) { 900 var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list 901 return this.each(function() { 902 var t = this.type, tag = this.tagName.toLowerCase(); 903 if (re.test(t) || tag == 'textarea' || (includeHidden && /hidden/.test(t)) ) { 904 this.value = ''; 905 } 906 else if (t == 'checkbox' || t == 'radio') { 907 this.checked = false; 908 } 909 else if (tag == 'select') { 910 this.selectedIndex = -1; 911 } 912 }); 913 }; 914 915 /** 916 * Resets the form data. Causes all form elements to be reset to their original value. 917 */ 918 $.fn.resetForm = function() { 919 return this.each(function() { 920 // guard against an input with the name of 'reset' 921 // note that IE reports the reset function as an 'object' 922 if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) { 923 this.reset(); 924 } 925 }); 926 }; 927 928 /** 929 * Enables or disables any matching elements. 930 */ 931 $.fn.enable = function(b) { 932 if (b === undefined) { 933 b = true; 934 } 935 return this.each(function() { 936 this.disabled = !b; 937 }); 938 }; 939 940 /** 941 * Checks/unchecks any matching checkboxes or radio buttons and 942 * selects/deselects and matching option elements. 943 */ 944 $.fn.selected = function(select) { 945 if (select === undefined) { 946 select = true; 947 } 948 return this.each(function() { 949 var t = this.type; 950 if (t == 'checkbox' || t == 'radio') { 951 this.checked = select; 952 } 953 else if (this.tagName.toLowerCase() == 'option') { 954 var $sel = $(this).parent('select'); 955 if (select && $sel[0] && $sel[0].type == 'select-one') { 956 // deselect all other options 957 $sel.find('option').selected(false); 958 } 959 this.selected = select; 960 } 961 }); 962 }; 963 964 // expose debug var 965 $.fn.ajaxSubmit.debug = false; 966 967 // helper fn for console logging 968 function log() { 969 if (!$.fn.ajaxSubmit.debug) 970 return; 971 var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); 972 if (window.console && window.console.log) { 973 window.console.log(msg); 974 } 975 else if (window.opera && window.opera.postError) { 976 window.opera.postError(msg); 977 } 978 }; 979 980 })(jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |