[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/jquery/multiplefileupload/ -> jquery.form.js (source)

   1  /*!

   2   * jQuery Form Plugin

   3   * version: 3.02 (07-MAR-2012)

   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  /*global ActiveXObject alert */

  12  ;(function($) {
  13  "use strict";
  14  
  15  /*

  16      Usage Note:

  17      -----------

  18      Do not use both ajaxSubmit and ajaxForm on the same form.  These

  19      functions are mutually 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(e) {

  24              e.preventDefault(); // <-- important

  25              $(this).ajaxSubmit({

  26                  target: '#output'

  27              });

  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      You can also use ajaxForm with delegation (requires jQuery v1.7+), so the

  41      form does not have to exist when you invoke ajaxForm:

  42  

  43      $('#myForm').ajaxForm({

  44          delegation: true,

  45          target: '#output'

  46      });

  47      

  48      When using ajaxForm, the ajaxSubmit function will be invoked for you

  49      at the appropriate time.

  50  */
  51  
  52  /**

  53   * Feature detection

  54   */
  55  var feature = {};
  56  feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
  57  feature.formdata = window.FormData !== undefined;
  58  
  59  /**

  60   * ajaxSubmit() provides a mechanism for immediately submitting

  61   * an HTML form using AJAX.

  62   */
  63  $.fn.ajaxSubmit = function(options) {
  64      /*jshint scripturl:true */

  65  
  66      // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)

  67      if (!this.length) {
  68          log('ajaxSubmit: skipping submit process - no element selected');
  69          return this;
  70      }
  71      
  72      var method, action, url, $form = this;
  73  
  74      if (typeof options == 'function') {
  75          options = { success: options };
  76      }
  77  
  78      method = this.attr('method');
  79      action = this.attr('action');
  80      url = (typeof action === 'string') ? $.trim(action) : '';
  81      url = url || window.location.href || '';
  82      if (url) {
  83          // clean url (don't include hash vaue)

  84          url = (url.match(/^([^#]+)/)||[])[1];
  85      }
  86  
  87      options = $.extend(true, {
  88          url:  url,
  89          success: $.ajaxSettings.success,
  90          type: method || 'GET',
  91          iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
  92      }, options);
  93  
  94      // hook for manipulating the form data before it is extracted;

  95      // convenient for use with rich editors like tinyMCE or FCKEditor

  96      var veto = {};
  97      this.trigger('form-pre-serialize', [this, options, veto]);
  98      if (veto.veto) {
  99          log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
 100          return this;
 101      }
 102  
 103      // provide opportunity to alter form data before it is serialized

 104      if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
 105          log('ajaxSubmit: submit aborted via beforeSerialize callback');
 106          return this;
 107      }
 108  
 109      var traditional = options.traditional;
 110      if ( traditional === undefined ) {
 111          traditional = $.ajaxSettings.traditional;
 112      }
 113      
 114      var qx, a = this.formToArray(options.semantic);
 115      if (options.data) {
 116          options.extraData = options.data;
 117          qx = $.param(options.data, traditional);
 118      }
 119  
 120      // give pre-submit callback an opportunity to abort the submit

 121      if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
 122          log('ajaxSubmit: submit aborted via beforeSubmit callback');
 123          return this;
 124      }
 125  
 126      // fire vetoable 'validate' event

 127      this.trigger('form-submit-validate', [a, this, options, veto]);
 128      if (veto.veto) {
 129          log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
 130          return this;
 131      }
 132  
 133      var q = $.param(a, traditional);
 134      if (qx) {
 135          q = ( q ? (q + '&' + qx) : qx );
 136      }    
 137      if (options.type.toUpperCase() == 'GET') {
 138          options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
 139          options.data = null;  // data is null for 'get'

 140      }
 141      else {
 142          options.data = q; // data is the query string for 'post'

 143      }
 144  
 145      var callbacks = [];
 146      if (options.resetForm) {
 147          callbacks.push(function() { $form.resetForm(); });
 148      }
 149      if (options.clearForm) {
 150          callbacks.push(function() { $form.clearForm(options.includeHidden); });
 151      }
 152  
 153      // perform a load on the target only if dataType is not provided

 154      if (!options.dataType && options.target) {
 155          var oldSuccess = options.success || function(){};
 156          callbacks.push(function(data) {
 157              var fn = options.replaceTarget ? 'replaceWith' : 'html';
 158              $(options.target)[fn](data).each(oldSuccess, arguments);
 159          });
 160      }
 161      else if (options.success) {
 162          callbacks.push(options.success);
 163      }
 164  
 165      options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
 166          var context = options.context || options;    // jQuery 1.4+ supports scope context 

 167          for (var i=0, max=callbacks.length; i < max; i++) {
 168              callbacks[i].apply(context, [data, status, xhr || $form, $form]);
 169          }
 170      };
 171  
 172      // are there files to upload?

 173      var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)

 174      var hasFileInputs = fileInputs.length > 0;
 175      var mp = 'multipart/form-data';
 176      var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
 177  
 178      var fileAPI = feature.fileapi && feature.formdata;
 179      log("fileAPI :" + fileAPI);
 180      var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
 181  
 182      // options.iframe allows user to force iframe mode

 183      // 06-NOV-09: now defaulting to iframe mode if file input is detected

 184      if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
 185          // hack to fix Safari hang (thanks to Tim Molendijk for this)

 186          // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d

 187          if (options.closeKeepAlive) {
 188              $.get(options.closeKeepAlive, function() {
 189                  fileUploadIframe(a);
 190              });
 191          }
 192            else {
 193              fileUploadIframe(a);
 194            }
 195      }
 196      else if ((hasFileInputs || multipart) && fileAPI) {
 197          fileUploadXhr(a);
 198      }
 199      else {
 200          $.ajax(options);
 201      }
 202  
 203       // fire 'notify' event

 204       this.trigger('form-submit-notify', [this, options]);
 205       return this;
 206  
 207       // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)

 208      function fileUploadXhr(a) {
 209          var formdata = new FormData();
 210  
 211          for (var i=0; i < a.length; i++) {
 212              formdata.append(a[i].name, a[i].value);
 213          }
 214  
 215          if (options.extraData) {
 216              for (var k in options.extraData)
 217                  if (options.extraData.hasOwnProperty(k))
 218                      formdata.append(k, options.extraData[k]);
 219          }
 220  
 221          options.data = null;
 222  
 223          var s = $.extend(true, {}, $.ajaxSettings, options, {
 224              contentType: false,
 225              processData: false,
 226              cache: false,
 227              type: 'POST'
 228          });
 229  
 230          if (options.uploadProgress) {
 231              // workaround because jqXHR does not expose upload property

 232              s.xhr = function() {
 233                  var xhr = jQuery.ajaxSettings.xhr();
 234                  if (xhr.upload) {
 235                      xhr.upload.onprogress = function(event) {
 236                          var percent = 0;
 237                          if (event.lengthComputable)
 238                              percent = parseInt((event.position / event.total) * 100, 10);
 239                          options.uploadProgress(event, event.position, event.total, percent);
 240                      }
 241                  }
 242                  return xhr;
 243              }
 244          }
 245  
 246            s.data = null;
 247            var beforeSend = s.beforeSend;
 248            s.beforeSend = function(xhr, o) {
 249                o.data = formdata;
 250              if(beforeSend)
 251                  beforeSend.call(o, xhr, options);
 252            };
 253            $.ajax(s);
 254          }
 255  
 256      // private function for handling file uploads (hat tip to YAHOO!)

 257      function fileUploadIframe(a) {
 258          var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
 259          var useProp = !!$.fn.prop;
 260  
 261          if (a) {
 262              if ( useProp ) {
 263                  // ensure that every serialized input is still enabled

 264                  for (i=0; i < a.length; i++) {
 265                      el = $(form[a[i].name]);
 266                      el.prop('disabled', false);
 267                  }
 268              } else {
 269                  for (i=0; i < a.length; i++) {
 270                      el = $(form[a[i].name]);
 271                      el.removeAttr('disabled');
 272                  }
 273              }
 274          }
 275  
 276          if ($(':input[name=submit],:input[id=submit]', form).length) {
 277              // if there is an input with a name or id of 'submit' then we won't be

 278              // able to invoke the submit fn on the form (at least not x-browser)

 279              alert('Error: Form elements must not have name or id of "submit".');
 280              return;
 281          }
 282          
 283          s = $.extend(true, {}, $.ajaxSettings, options);
 284          s.context = s.context || s;
 285          id = 'jqFormIO' + (new Date().getTime());
 286          if (s.iframeTarget) {
 287              $io = $(s.iframeTarget);
 288              n = $io.attr('name');
 289              if (!n)
 290                   $io.attr('name', id);
 291              else
 292                  id = n;
 293          }
 294          else {
 295              $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
 296              $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
 297          }
 298          io = $io[0];
 299  
 300  
 301          xhr = { // mock object
 302              aborted: 0,
 303              responseText: null,
 304              responseXML: null,
 305              status: 0,
 306              statusText: 'n/a',
 307              getAllResponseHeaders: function() {},
 308              getResponseHeader: function() {},
 309              setRequestHeader: function() {},
 310              abort: function(status) {
 311                  var e = (status === 'timeout' ? 'timeout' : 'aborted');
 312                  log('aborting upload... ' + e);
 313                  this.aborted = 1;
 314                  $io.attr('src', s.iframeSrc); // abort op in progress

 315                  xhr.error = e;
 316                  if (s.error)
 317                      s.error.call(s.context, xhr, e, status);
 318                  if (g)
 319                      $.event.trigger("ajaxError", [xhr, s, e]);
 320                  if (s.complete)
 321                      s.complete.call(s.context, xhr, e);
 322              }
 323          };
 324  
 325          g = s.global;
 326          // trigger ajax global events so that activity/block indicators work like normal

 327          if (g && 0 === $.active++) {
 328              $.event.trigger("ajaxStart");
 329          }
 330          if (g) {
 331              $.event.trigger("ajaxSend", [xhr, s]);
 332          }
 333  
 334          if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
 335              if (s.global) {
 336                  $.active--;
 337              }
 338              return;
 339          }
 340          if (xhr.aborted) {
 341              return;
 342          }
 343  
 344          // add submitting element to data if we know it

 345          sub = form.clk;
 346          if (sub) {
 347              n = sub.name;
 348              if (n && !sub.disabled) {
 349                  s.extraData = s.extraData || {};
 350                  s.extraData[n] = sub.value;
 351                  if (sub.type == "image") {
 352                      s.extraData[n+'.x'] = form.clk_x;
 353                      s.extraData[n+'.y'] = form.clk_y;
 354                  }
 355              }
 356          }
 357          
 358          var CLIENT_TIMEOUT_ABORT = 1;
 359          var SERVER_ABORT = 2;
 360  
 361          function getDoc(frame) {
 362              var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
 363              return doc;
 364          }
 365          
 366          // Rails CSRF hack (thanks to Yvan Barthelemy)

 367          var csrf_token = $('meta[name=csrf-token]').attr('content');
 368          var csrf_param = $('meta[name=csrf-param]').attr('content');
 369          if (csrf_param && csrf_token) {
 370              s.extraData = s.extraData || {};
 371              s.extraData[csrf_param] = csrf_token;
 372          }
 373  
 374          // take a breath so that pending repaints get some cpu time before the upload starts

 375          function doSubmit() {
 376              // make sure form attrs are set

 377              var t = $form.attr('target'), a = $form.attr('action');
 378  
 379              // update form attrs in IE friendly way

 380              form.setAttribute('target',id);
 381              if (!method) {
 382                  form.setAttribute('method', 'POST');
 383              }
 384              if (a != s.url) {
 385                  form.setAttribute('action', s.url);
 386              }
 387  
 388              // ie borks in some cases when setting encoding

 389              if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
 390                  $form.attr({
 391                      encoding: 'multipart/form-data',
 392                      enctype:  'multipart/form-data'
 393                  });
 394              }
 395  
 396              // support timout

 397              if (s.timeout) {
 398                  timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
 399              }
 400              
 401              // look for server aborts

 402              function checkState() {
 403                  try {
 404                      var state = getDoc(io).readyState;
 405                      log('state = ' + state);
 406                      if (state && state.toLowerCase() == 'uninitialized')
 407                          setTimeout(checkState,50);
 408                  }
 409                  catch(e) {
 410                      log('Server abort: ' , e, ' (', e.name, ')');
 411                      cb(SERVER_ABORT);
 412                      if (timeoutHandle)
 413                          clearTimeout(timeoutHandle);
 414                      timeoutHandle = undefined;
 415                  }
 416              }
 417  
 418              // add "extra" data to form if provided in options

 419              var extraInputs = [];
 420              try {
 421                  if (s.extraData) {
 422                      for (var n in s.extraData) {
 423                          if (s.extraData.hasOwnProperty(n)) {
 424                              extraInputs.push(
 425                                  $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
 426                                      .appendTo(form)[0]);
 427                          }
 428                      }
 429                  }
 430  
 431                  if (!s.iframeTarget) {
 432                      // add iframe to doc and submit the form

 433                      $io.appendTo('body');
 434                      if (io.attachEvent)
 435                          io.attachEvent('onload', cb);
 436                      else
 437                          io.addEventListener('load', cb, false);
 438                  }
 439                  setTimeout(checkState,15);
 440                  form.submit();
 441              }
 442              finally {
 443                  // reset attrs and remove "extra" input elements

 444                  form.setAttribute('action',a);
 445                  if(t) {
 446                      form.setAttribute('target', t);
 447                  } else {
 448                      $form.removeAttr('target');
 449                  }
 450                  $(extraInputs).remove();
 451              }
 452          }
 453  
 454          if (s.forceSync) {
 455              doSubmit();
 456          }
 457          else {
 458              setTimeout(doSubmit, 10); // this lets dom updates render

 459          }
 460  
 461          var data, doc, domCheckCount = 50, callbackProcessed;
 462  
 463          function cb(e) {
 464              if (xhr.aborted || callbackProcessed) {
 465                  return;
 466              }
 467              try {
 468                  doc = getDoc(io);
 469              }
 470              catch(ex) {
 471                  log('cannot access response document: ', ex);
 472                  e = SERVER_ABORT;
 473              }
 474              if (e === CLIENT_TIMEOUT_ABORT && xhr) {
 475                  xhr.abort('timeout');
 476                  return;
 477              }
 478              else if (e == SERVER_ABORT && xhr) {
 479                  xhr.abort('server abort');
 480                  return;
 481              }
 482  
 483              if (!doc || doc.location.href == s.iframeSrc) {
 484                  // response not received yet

 485                  if (!timedOut)
 486                      return;
 487              }
 488              if (io.detachEvent)
 489                  io.detachEvent('onload', cb);
 490              else    
 491                  io.removeEventListener('load', cb, false);
 492  
 493              var status = 'success', errMsg;
 494              try {
 495                  if (timedOut) {
 496                      throw 'timeout';
 497                  }
 498  
 499                  var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
 500                  log('isXml='+isXml);
 501                  if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
 502                      if (--domCheckCount) {
 503                          // in some browsers (Opera) the iframe DOM is not always traversable when

 504                          // the onload callback fires, so we loop a bit to accommodate

 505                          log('requeing onLoad callback, DOM not available');
 506                          setTimeout(cb, 250);
 507                          return;
 508                      }
 509                      // let this fall through because server response could be an empty document

 510                      //log('Could not access iframe DOM after mutiple tries.');

 511                      //throw 'DOMException: not available';

 512                  }
 513  
 514                  //log('response detected');

 515                  var docRoot = doc.body ? doc.body : doc.documentElement;
 516                  xhr.responseText = docRoot ? docRoot.innerHTML : null;
 517                  xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
 518                  if (isXml)
 519                      s.dataType = 'xml';
 520                  xhr.getResponseHeader = function(header){
 521                      var headers = {'content-type': s.dataType};
 522                      return headers[header];
 523                  };
 524                  // support for XHR 'status' & 'statusText' emulation :

 525                  if (docRoot) {
 526                      xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
 527                      xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
 528                  }
 529  
 530                  var dt = (s.dataType || '').toLowerCase();
 531                  var scr = /(json|script|text)/.test(dt);
 532                  if (scr || s.textarea) {
 533                      // see if user embedded response in textarea

 534                      var ta = doc.getElementsByTagName('textarea')[0];
 535                      if (ta) {
 536                          xhr.responseText = ta.value;
 537                          // support for XHR 'status' & 'statusText' emulation :

 538                          xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
 539                          xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
 540                      }
 541                      else if (scr) {
 542                          // account for browsers injecting pre around json response

 543                          var pre = doc.getElementsByTagName('pre')[0];
 544                          var b = doc.getElementsByTagName('body')[0];
 545                          if (pre) {
 546                              xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
 547                          }
 548                          else if (b) {
 549                              xhr.responseText = b.textContent ? b.textContent : b.innerText;
 550                          }
 551                      }
 552                  }
 553                  else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
 554                      xhr.responseXML = toXml(xhr.responseText);
 555                  }
 556  
 557                  try {
 558                      data = httpData(xhr, dt, s);
 559                  }
 560                  catch (e) {
 561                      status = 'parsererror';
 562                      xhr.error = errMsg = (e || status);
 563                  }
 564              }
 565              catch (e) {
 566                  log('error caught: ',e);
 567                  status = 'error';
 568                  xhr.error = errMsg = (e || status);
 569              }
 570  
 571              if (xhr.aborted) {
 572                  log('upload aborted');
 573                  status = null;
 574              }
 575  
 576              if (xhr.status) { // we've set xhr.status
 577                  status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
 578              }
 579  
 580              // ordering of these callbacks/triggers is odd, but that's how $.ajax does it

 581              if (status === 'success') {
 582                  if (s.success)
 583                      s.success.call(s.context, data, 'success', xhr);
 584                  if (g)
 585                      $.event.trigger("ajaxSuccess", [xhr, s]);
 586              }
 587              else if (status) {
 588                  if (errMsg === undefined)
 589                      errMsg = xhr.statusText;
 590                  if (s.error)
 591                      s.error.call(s.context, xhr, status, errMsg);
 592                  if (g)
 593                      $.event.trigger("ajaxError", [xhr, s, errMsg]);
 594              }
 595  
 596              if (g)
 597                  $.event.trigger("ajaxComplete", [xhr, s]);
 598  
 599              if (g && ! --$.active) {
 600                  $.event.trigger("ajaxStop");
 601              }
 602  
 603              if (s.complete)
 604                  s.complete.call(s.context, xhr, status);
 605  
 606              callbackProcessed = true;
 607              if (s.timeout)
 608                  clearTimeout(timeoutHandle);
 609  
 610              // clean up

 611              setTimeout(function() {
 612                  if (!s.iframeTarget)
 613                      $io.remove();
 614                  xhr.responseXML = null;
 615              }, 100);
 616          }
 617  
 618          var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
 619              if (window.ActiveXObject) {
 620                  doc = new ActiveXObject('Microsoft.XMLDOM');
 621                  doc.async = 'false';
 622                  doc.loadXML(s);
 623              }
 624              else {
 625                  doc = (new DOMParser()).parseFromString(s, 'text/xml');
 626              }
 627              return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
 628          };
 629          var parseJSON = $.parseJSON || function(s) {
 630              /*jslint evil:true */

 631              return window['eval']('(' + s + ')');
 632          };
 633  
 634          var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
 635  
 636              var ct = xhr.getResponseHeader('content-type') || '',
 637                  xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
 638                  data = xml ? xhr.responseXML : xhr.responseText;
 639  
 640              if (xml && data.documentElement.nodeName === 'parsererror') {
 641                  if ($.error)
 642                      $.error('parsererror');
 643              }
 644              if (s && s.dataFilter) {
 645                  data = s.dataFilter(data, type);
 646              }
 647              if (typeof data === 'string') {
 648                  if (type === 'json' || !type && ct.indexOf('json') >= 0) {
 649                      data = parseJSON(data);
 650                  } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
 651                      $.globalEval(data);
 652                  }
 653              }
 654              return data;
 655          };
 656      }
 657  };
 658  
 659  /**

 660   * ajaxForm() provides a mechanism for fully automating form submission.

 661   *

 662   * The advantages of using this method instead of ajaxSubmit() are:

 663   *

 664   * 1: This method will include coordinates for <input type="image" /> elements (if the element

 665   *    is used to submit the form).

 666   * 2. This method will include the submit element's name/value data (for the element that was

 667   *    used to submit the form).

 668   * 3. This method binds the submit() method to the form for you.

 669   *

 670   * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely

 671   * passes the options argument along after properly binding events for submit elements and

 672   * the form itself.

 673   */
 674  $.fn.ajaxForm = function(options) {
 675      options = options || {};
 676      options.delegation = options.delegation && $.isFunction($.fn.on);
 677      
 678      // in jQuery 1.3+ we can fix mistakes with the ready state

 679      if (!options.delegation && this.length === 0) {
 680          var o = { s: this.selector, c: this.context };
 681          if (!$.isReady && o.s) {
 682              log('DOM not ready, queuing ajaxForm');
 683              $(function() {
 684                  $(o.s,o.c).ajaxForm(options);
 685              });
 686              return this;
 687          }
 688          // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()

 689          log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
 690          return this;
 691      }
 692  
 693      if ( options.delegation ) {
 694          $(document)
 695              .off('submit.form-plugin', this.selector, doAjaxSubmit)
 696              .off('click.form-plugin', this.selector, captureSubmittingElement)
 697              .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
 698              .on('click.form-plugin', this.selector, options, captureSubmittingElement);
 699          return this;
 700      }
 701  
 702      return this.ajaxFormUnbind()
 703          .bind('submit.form-plugin', options, doAjaxSubmit)
 704          .bind('click.form-plugin', options, captureSubmittingElement);
 705  };
 706  
 707  // private event handlers    

 708  function doAjaxSubmit(e) {
 709      /*jshint validthis:true */

 710      var options = e.data;
 711      if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
 712          e.preventDefault();
 713          $(this).ajaxSubmit(options);
 714      }
 715  }
 716      
 717  function captureSubmittingElement(e) {
 718      /*jshint validthis:true */

 719      var target = e.target;
 720      var $el = $(target);
 721      if (!($el.is(":submit,input:image"))) {
 722          // is this a child element of the submit el?  (ex: a span within a button)

 723          var t = $el.closest(':submit');
 724          if (t.length === 0) {
 725              return;
 726          }
 727          target = t[0];
 728      }
 729      var form = this;
 730      form.clk = target;
 731      if (target.type == 'image') {
 732          if (e.offsetX !== undefined) {
 733              form.clk_x = e.offsetX;
 734              form.clk_y = e.offsetY;
 735          } else if (typeof $.fn.offset == 'function') {
 736              var offset = $el.offset();
 737              form.clk_x = e.pageX - offset.left;
 738              form.clk_y = e.pageY - offset.top;
 739          } else {
 740              form.clk_x = e.pageX - target.offsetLeft;
 741              form.clk_y = e.pageY - target.offsetTop;
 742          }
 743      }
 744      // clear form vars

 745      setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
 746  }
 747  
 748  
 749  // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm

 750  $.fn.ajaxFormUnbind = function() {
 751      return this.unbind('submit.form-plugin click.form-plugin');
 752  };
 753  
 754  /**

 755   * formToArray() gathers form element data into an array of objects that can

 756   * be passed to any of the following ajax functions: $.get, $.post, or load.

 757   * Each object in the array has both a 'name' and 'value' property.  An example of

 758   * an array for a simple login form might be:

 759   *

 760   * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]

 761   *

 762   * It is this array that is passed to pre-submit callback functions provided to the

 763   * ajaxSubmit() and ajaxForm() methods.

 764   */
 765  $.fn.formToArray = function(semantic) {
 766      var a = [];
 767      if (this.length === 0) {
 768          return a;
 769      }
 770  
 771      var form = this[0];
 772      var els = semantic ? form.getElementsByTagName('*') : form.elements;
 773      if (!els) {
 774          return a;
 775      }
 776  
 777      var i,j,n,v,el,max,jmax;
 778      for(i=0, max=els.length; i < max; i++) {
 779          el = els[i];
 780          n = el.name;
 781          if (!n) {
 782              continue;
 783          }
 784  
 785          if (semantic && form.clk && el.type == "image") {
 786              // handle image inputs on the fly when semantic == true

 787              if(!el.disabled && form.clk == el) {
 788                  a.push({name: n, value: $(el).val(), type: el.type });
 789                  a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
 790              }
 791              continue;
 792          }
 793  
 794          v = $.fieldValue(el, true);
 795          if (v && v.constructor == Array) {
 796              for(j=0, jmax=v.length; j < jmax; j++) {
 797                  a.push({name: n, value: v[j]});
 798              }
 799          }
 800          else if (feature.fileapi && el.type == 'file' && !el.disabled) {
 801              var files = el.files;
 802              for (j=0; j < files.length; j++) {
 803                  a.push({name: n, value: files[j], type: el.type});
 804              }
 805          }
 806          else if (v !== null && typeof v != 'undefined') {
 807              a.push({name: n, value: v, type: el.type});
 808          }
 809      }
 810  
 811      if (!semantic && form.clk) {
 812          // input type=='image' are not found in elements array! handle it here

 813          var $input = $(form.clk), input = $input[0];
 814          n = input.name;
 815          if (n && !input.disabled && input.type == 'image') {
 816              a.push({name: n, value: $input.val()});
 817              a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
 818          }
 819      }
 820      return a;
 821  };
 822  
 823  /**

 824   * Serializes form data into a 'submittable' string. This method will return a string

 825   * in the format: name1=value1&amp;name2=value2

 826   */
 827  $.fn.formSerialize = function(semantic) {
 828      //hand off to jQuery.param for proper encoding

 829      return $.param(this.formToArray(semantic));
 830  };
 831  
 832  /**

 833   * Serializes all field elements in the jQuery object into a query string.

 834   * This method will return a string in the format: name1=value1&amp;name2=value2

 835   */
 836  $.fn.fieldSerialize = function(successful) {
 837      var a = [];
 838      this.each(function() {
 839          var n = this.name;
 840          if (!n) {
 841              return;
 842          }
 843          var v = $.fieldValue(this, successful);
 844          if (v && v.constructor == Array) {
 845              for (var i=0,max=v.length; i < max; i++) {
 846                  a.push({name: n, value: v[i]});
 847              }
 848          }
 849          else if (v !== null && typeof v != 'undefined') {
 850              a.push({name: this.name, value: v});
 851          }
 852      });
 853      //hand off to jQuery.param for proper encoding

 854      return $.param(a);
 855  };
 856  
 857  /**

 858   * Returns the value(s) of the element in the matched set.  For example, consider the following form:

 859   *

 860   *  <form><fieldset>

 861   *      <input name="A" type="text" />

 862   *      <input name="A" type="text" />

 863   *      <input name="B" type="checkbox" value="B1" />

 864   *      <input name="B" type="checkbox" value="B2"/>

 865   *      <input name="C" type="radio" value="C1" />

 866   *      <input name="C" type="radio" value="C2" />

 867   *  </fieldset></form>

 868   *

 869   *  var v = $(':text').fieldValue();

 870   *  // if no values are entered into the text inputs

 871   *  v == ['','']

 872   *  // if values entered into the text inputs are 'foo' and 'bar'

 873   *  v == ['foo','bar']

 874   *

 875   *  var v = $(':checkbox').fieldValue();

 876   *  // if neither checkbox is checked

 877   *  v === undefined

 878   *  // if both checkboxes are checked

 879   *  v == ['B1', 'B2']

 880   *

 881   *  var v = $(':radio').fieldValue();

 882   *  // if neither radio is checked

 883   *  v === undefined

 884   *  // if first radio is checked

 885   *  v == ['C1']

 886   *

 887   * The successful argument controls whether or not the field element must be 'successful'

 888   * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).

 889   * The default value of the successful argument is true.  If this value is false the value(s)

 890   * for each element is returned.

 891   *

 892   * Note: This method *always* returns an array.  If no valid value can be determined the

 893   *    array will be empty, otherwise it will contain one or more values.

 894   */
 895  $.fn.fieldValue = function(successful) {
 896      for (var val=[], i=0, max=this.length; i < max; i++) {
 897          var el = this[i];
 898          var v = $.fieldValue(el, successful);
 899          if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
 900              continue;
 901          }
 902          if (v.constructor == Array)
 903              $.merge(val, v);
 904          else
 905              val.push(v);
 906      }
 907      return val;
 908  };
 909  
 910  /**

 911   * Returns the value of the field element.

 912   */
 913  $.fieldValue = function(el, successful) {
 914      var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
 915      if (successful === undefined) {
 916          successful = true;
 917      }
 918  
 919      if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
 920          (t == 'checkbox' || t == 'radio') && !el.checked ||
 921          (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
 922          tag == 'select' && el.selectedIndex == -1)) {
 923              return null;
 924      }
 925  
 926      if (tag == 'select') {
 927          var index = el.selectedIndex;
 928          if (index < 0) {
 929              return null;
 930          }
 931          var a = [], ops = el.options;
 932          var one = (t == 'select-one');
 933          var max = (one ? index+1 : ops.length);
 934          for(var i=(one ? index : 0); i < max; i++) {
 935              var op = ops[i];
 936              if (op.selected) {
 937                  var v = op.value;
 938                  if (!v) { // extra pain for IE...
 939                      v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
 940                  }
 941                  if (one) {
 942                      return v;
 943                  }
 944                  a.push(v);
 945              }
 946          }
 947          return a;
 948      }
 949      return $(el).val();
 950  };
 951  
 952  /**

 953   * Clears the form data.  Takes the following actions on the form's input fields:

 954   *  - input text fields will have their 'value' property set to the empty string

 955   *  - select elements will have their 'selectedIndex' property set to -1

 956   *  - checkbox and radio inputs will have their 'checked' property set to false

 957   *  - inputs of type submit, button, reset, and hidden will *not* be effected

 958   *  - button elements will *not* be effected

 959   */
 960  $.fn.clearForm = function(includeHidden) {
 961      return this.each(function() {
 962          $('input,select,textarea', this).clearFields(includeHidden);
 963      });
 964  };
 965  
 966  /**

 967   * Clears the selected form elements.

 968   */
 969  $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
 970      var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list

 971      return this.each(function() {
 972          var t = this.type, tag = this.tagName.toLowerCase();
 973          if (re.test(t) || tag == 'textarea' || (includeHidden && /hidden/.test(t)) ) {
 974              this.value = '';
 975          }
 976          else if (t == 'checkbox' || t == 'radio') {
 977              this.checked = false;
 978          }
 979          else if (tag == 'select') {
 980              this.selectedIndex = -1;
 981          }
 982      });
 983  };
 984  
 985  /**

 986   * Resets the form data.  Causes all form elements to be reset to their original value.

 987   */
 988  $.fn.resetForm = function() {
 989      return this.each(function() {
 990          // guard against an input with the name of 'reset'

 991          // note that IE reports the reset function as an 'object'

 992          if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
 993              this.reset();
 994          }
 995      });
 996  };
 997  
 998  /**

 999   * Enables or disables any matching elements.

1000   */
1001  $.fn.enable = function(b) {
1002      if (b === undefined) {
1003          b = true;
1004      }
1005      return this.each(function() {
1006          this.disabled = !b;
1007      });
1008  };
1009  
1010  /**

1011   * Checks/unchecks any matching checkboxes or radio buttons and

1012   * selects/deselects and matching option elements.

1013   */
1014  $.fn.selected = function(select) {
1015      if (select === undefined) {
1016          select = true;
1017      }
1018      return this.each(function() {
1019          var t = this.type;
1020          if (t == 'checkbox' || t == 'radio') {
1021              this.checked = select;
1022          }
1023          else if (this.tagName.toLowerCase() == 'option') {
1024              var $sel = $(this).parent('select');
1025              if (select && $sel[0] && $sel[0].type == 'select-one') {
1026                  // deselect all other options

1027                  $sel.find('option').selected(false);
1028              }
1029              this.selected = select;
1030          }
1031      });
1032  };
1033  
1034  // expose debug var

1035  $.fn.ajaxSubmit.debug = false;
1036  
1037  // helper fn for console logging

1038  function log() {
1039      if (!$.fn.ajaxSubmit.debug) 
1040          return;
1041      var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
1042      if (window.console && window.console.log) {
1043          window.console.log(msg);
1044      }
1045      else if (window.opera && window.opera.postError) {
1046          window.opera.postError(msg);
1047      }
1048  }
1049  
1050  })(jQuery);


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1