ajaxform 원본 해독

45445 단어
define(function(require, exports) {
  require('tipsy/tipsy');
  var validDate = require('validate/validate');
  /*!
   * jQuery Form Plugin
   * version: 3.02 (07-MAR-2012)
   * @requires jQuery v1.3.2 or later
   *
   * Examples and documentation at: http://malsup.com/jquery/form/
   * Dual licensed under the MIT and GPL licenses:
   *    http://www.opensource.org/licenses/mit-license.php
   *    http://www.gnu.org/licenses/gpl.html
   */
  /*global ActiveXObject alert */
  (function($) {
    "use strict";

    /**
      Usage Note:
      -----------
      Do not use both ajaxSubmit and ajaxForm on the same form.  These
      functions are mutually exclusive.  Use ajaxSubmit if you want
      to bind your own submit handler to the form.  For example,

      $(document).ready(function() {
          $('#myForm').bind('submit', function(e) {
              e.preventDefault(); // ").get(0).files !== undefined;
    feature.formdata = window.FormData !== undefined;

    /**
     * ajaxSubmit() provides a mechanism for immediately submitting
     * an HTML form using AJAX.
     */
    $.fn.ajaxSubmit = function(options) {
      /*jshint scripturl:true */

      // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
      if (!this.length) {
        log('ajaxSubmit: skipping submit process - no element selected');
        return this;
      }

      var method, action, url, $form = this;

      if (typeof options == 'function') {
        options = {
          success: options
        };
      }

      method = this.attr('method');
      action = this.attr('action');
      url = (typeof action === 'string') ? $.trim(action) : '';
      url = url || window.location.href || '';
      if (url) {
        // clean url (don't include hash vaue)
        url = (url.match(/^([^#]+)/) || [])[1];
      }

      options = $.extend(true, {
        url: url,
        success: $.ajaxSettings.success,
        type: method || 'GET',
        dataType: "json",
        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
      }, options);

      // hook for manipulating the form data before it is extracted;
      // convenient for use with rich editors like tinyMCE or FCKEditor
      var veto = {};
      this.trigger('form-pre-serialize', [this, options, veto]);
      if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
        return this;
      }

      // provide opportunity to alter form data before it is serialized
      if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
        log('ajaxSubmit: submit aborted via beforeSerialize callback');
        return this;
      }

      var traditional = options.traditional;
      if (traditional === undefined) {
        traditional = $.ajaxSettings.traditional;
      }

      var qx, a = this.formToArray(options.semantic);
      if (options.data) {
        options.extraData = options.data;
        qx = $.param(options.data, traditional);
      }

      // give pre-submit callback an opportunity to abort the submit
      if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
        log('ajaxSubmit: submit aborted via beforeSubmit callback');
        return this;
      }

      // fire vetoable 'validate' event
      this.trigger('form-submit-validate', [a, this, options, veto]);
      if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
        return this;
      }

      var q = $.param(a, traditional);
      if (qx) {
        q = (q ? (q + '&' + qx) : qx);
      }
      if (options.type.toUpperCase() == 'GET') {
        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
        options.data = null; // data is null for 'get'
      } else {
        options.data = q; // data is the query string for 'post'
      }

      var callbacks = [];
      if (options.resetForm) {
        callbacks.push(function() {
          $form.resetForm();
        });
      }
      if (options.clearForm) {
        callbacks.push(function() {
          $form.clearForm(options.includeHidden);
        });
      }

      // perform a load on the target only if dataType is not provided
      if (!options.dataType && options.target) {
        var oldSuccess = options.success || function() {};
        callbacks.push(function(data) {
          var fn = options.replaceTarget ? 'replaceWith' : 'html';
          $(options.target)[fn](data).each(oldSuccess, arguments);
        });
      } else if (options.success) {
        callbacks.push(options.success);
      }

      options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
        var context = options.context || options; // jQuery 1.4+ supports scope context 
        for (var i = 0, max = callbacks.length; i < max; i++) {
          callbacks[i].apply(context, [data, status, xhr || $form, $form]);
        }
      };

      // are there files to upload?
      var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
      var hasFileInputs = fileInputs.length > 0;
      var mp = 'multipart/form-data';
      var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);

      var fileAPI = feature.fileapi && feature.formdata;
      log("fileAPI :" + fileAPI);
      var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;

      // options.iframe allows user to force iframe mode
      // 06-NOV-09: now defaulting to iframe mode if file input is detected
      if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
        // hack to fix Safari hang (thanks to Tim Molendijk for this)
        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
        if (options.closeKeepAlive) {
          $.get(options.closeKeepAlive, function() {
            fileUploadIframe(a);
          });
        } else {
          fileUploadIframe(a);
        }
      } else if ((hasFileInputs || multipart) && fileAPI) {
        fileUploadXhr(a);
      } else {
        $.ajax(options);
      }

      // fire 'notify' event
      this.trigger('form-submit-notify', [this, options]);
      return this;

      // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)

      function fileUploadXhr(a) {
        var formdata = new FormData();

        for (var i = 0; i < a.length; i++) {
          formdata.append(a[i].name, a[i].value);
        }

        if (options.extraData) {
          for (var k in options.extraData)
            if (options.extraData.hasOwnProperty(k))
              formdata.append(k, options.extraData[k]);
        }

        options.data = null;

        var s = $.extend(true, {}, $.ajaxSettings, options, {
          contentType: false,
          processData: false,
          cache: false,
          type: 'POST'
        });

        if (options.uploadProgress) {
          // workaround because jqXHR does not expose upload property
          s.xhr = function() {
            var xhr = jQuery.ajaxSettings.xhr();
            if (xhr.upload) {
              xhr.upload.onprogress = function(event) {
                var percent = 0;
                if (event.lengthComputable)
                  percent = parseInt((event.position / event.total) * 100, 10);
                options.uploadProgress(event, event.position, event.total, percent);
              }
            }
            return xhr;
          }
        }

        s.data = null;
        var beforeSend = s.beforeSend;
        s.beforeSend = function(xhr, o) {
          o.data = formdata;
          if (beforeSend)
            beforeSend.call(o, xhr, options);
        };
        $.ajax(s);
      }

      // private function for handling file uploads (hat tip to YAHOO!)

      function fileUploadIframe(a) {
        var form = $form[0],
          el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
        var useProp = !! $.fn.prop;

        if (a) {
          if (useProp) {
            // ensure that every serialized input is still enabled
            for (i = 0; i < a.length; i++) {
              el = $(form[a[i].name]);
              el.prop('disabled', false);
            }
          } else {
            for (i = 0; i < a.length; i++) {
              el = $(form[a[i].name]);
              el.removeAttr('disabled');
            }
          }
        }

        if ($(':input[name=submit],:input[id=submit]', form).length) {
          // if there is an input with a name or id of 'submit' then we won't be
          // able to invoke the submit fn on the form (at least not x-browser)
          alert('Error: Form elements must not have name or id of "submit".');
          return;
        }

        s = $.extend(true, {}, $.ajaxSettings, options);
        s.context = s.context || s;
        id = 'jqFormIO' + (new Date().getTime());
        if (s.iframeTarget) {
          $io = $(s.iframeTarget);
          n = $io.attr('name');
          if (!n)
            $io.attr('name', id);
          else
            id = n;
        } else {
          $io = $('

좋은 웹페이지 즐겨찾기