[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/jquery/ -> jquery.form.dev.js (source)

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


Generated: Fri May 25 03:56:23 2012 Hosted by follow the white rabbit.