whole_func_string: function fileUpload() {
      var form = $form[0];
  
      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;
      }
      
      var s = $.extend(true, {}, $.ajaxSettings, options);
      s.context = s.context || s;
      var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
      window[fn] = function() {
        var f = $io.data('form-plugin-onload');
        if (f) {
          f();
          window[fn] = undefined;
          try { delete window[fn]; } catch(e){}
        }
      }
      var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" onload="window[\'_\'+this.id]()" />');
      var io = $io[0];
  
      $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
  
      var xhr = { // mock object
        aborted: 0,
        responseText: null,
        responseXML: null,
        status: 0,
        statusText: 'n/a',
        getAllResponseHeaders: function() {},
        getResponseHeader: function() {},
        setRequestHeader: function() {},
        abort: function() {
          this.aborted = 1;
          $io.attr('src', s.iframeSrc); // abort op in progress
        }
      };
  
      var g = s.global;
      // trigger ajax global events so that activity/block indicators work like normal
      if (g && ! $.active++) {
        $.event.trigger("ajaxStart");
      }
      if (g) {
        $.event.trigger("ajaxSend", [xhr, s]);
      }
  
      if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
        if (s.global) { 
          $.active--;
        }
        return;
      }
      if (xhr.aborted) {
        return;
      }
  
      var cbInvoked = false;
      var timedOut = 0;
  
      // add submitting element to data if we know it
      var sub = form.clk;
      if (sub) {
        var n = sub.name;
        if (n && !sub.disabled) {
          s.extraData = s.extraData || {};
          s.extraData[n] = sub.value;
          if (sub.type == "image") {
            s.extraData[n+'.x'] = form.clk_x;
            s.extraData[n+'.y'] = form.clk_y;
          }
        }
      }
  
      // take a breath so that pending repaints get some cpu time before the upload starts
      function doSubmit() {
        // make sure form attrs are set
        var t = $form.attr('target'), a = $form.attr('action');
  
        // update form attrs in IE friendly way
        form.setAttribute('target',id);
        if (form.getAttribute('method') != 'POST') {
          form.setAttribute('method', 'POST');
        }
        if (form.getAttribute('action') != s.url) {
          form.setAttribute('action', s.url);
        }
  
        // ie borks in some cases when setting encoding
        if (! s.skipEncodingOverride) {
          $form.attr({
            encoding: 'multipart/form-data',
            enctype:  'multipart/form-data'
          });
        }
  
        // support timout
        if (s.timeout) {
          setTimeout(function() { timedOut = true; cb(); }, s.timeout);
        }
  
        // add "extra" data to form if provided in options
        var extraInputs = [];
        try {
          if (s.extraData) {
            for (var n in s.extraData) {
              extraInputs.push(
                $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
                  .appendTo(form)[0]);
            }
          }
  
          // add iframe to doc and submit the form
          $io.appendTo('body');
          $io.data('form-plugin-onload', cb);
          form.submit();
        }
        finally {
          // reset attrs and remove "extra" input elements
          form.setAttribute('action',a);
          if(t) {
            form.setAttribute('target', t);
          } else {
            $form.removeAttr('target');
          }
          $(extraInputs).remove();
        }
      }
  
      if (s.forceSync) {
        doSubmit();
      }
      else {
        setTimeout(doSubmit, 10); // this lets dom updates render
      }
    
      var data, doc, domCheckCount = 50;
  
      function cb() {
        if (cbInvoked) {
          return;
        }
  
        $io.removeData('form-plugin-onload');
        
        var ok = true;
        try {
          if (timedOut) {
            throw 'timeout';
          }
          // extract the server response from the iframe
          doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
          
          var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
          log('isXml='+isXml);
          if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
            if (--domCheckCount) {
              // in some browsers (Opera) the iframe DOM is not always traversable when
              // the onload callback fires, so we loop a bit to accommodate
              log('requeing onLoad callback, DOM not available');
              setTimeout(cb, 250);
              return;
            }
            // let this fall through because server response could be an empty document
            //log('Could not access iframe DOM after mutiple tries.');
            //throw 'DOMException: not available';
          }
  
          //log('response detected');
          cbInvoked = true;
          xhr.responseText = doc.documentElement ? doc.documentElement.innerHTML : null; 
          xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
          xhr.getResponseHeader = function(header){
            var headers = {'content-type': s.dataType};
            return headers[header];
          };
  
          var scr = /(json|script)/.test(s.dataType);
          if (scr || s.textarea) {
            // see if user embedded response in textarea
            var ta = doc.getElementsByTagName('textarea')[0];
            if (ta) {
              xhr.responseText = ta.value;
            }
            else if (scr) {
              // account for browsers injecting pre around json response
              var pre = doc.getElementsByTagName('pre')[0];
              if (pre) {
                xhr.responseText = pre.innerHTML;
              }
            }        
          }
          else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
            xhr.responseXML = toXml(xhr.responseText);
          }
          data = $.httpData(xhr, s.dataType);
        }
        catch(e){
          log('error caught:',e);
          ok = false;
          xhr.error = e;
          $.handleError(s, xhr, 'error', e);
        }
  
        // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
        if (ok) {
          s.success.call(s.context, data, 'success', xhr);
          if (g) {
            $.event.trigger("ajaxSuccess", [xhr, s]);
          }
        }
        if (g) {
          $.event.trigger("ajaxComplete", [xhr, s]);
        }
        if (g && ! --$.active) {
          $.event.trigger("ajaxStop");
        }
        if (s.complete) {
          s.complete.call(s.context, xhr, ok ? 'success' : 'error');
        }
  
        // clean up
        setTimeout(function() {
          $io.removeData('form-plugin-onload');
          $io.remove();
          xhr.responseXML = null;
        }, 100);
      }
  
      function toXml(s, doc) {
        if (window.ActiveXObject) {
          doc = new ActiveXObject('Microsoft.XMLDOM');
          doc.async = 'false';
          doc.loadXML(s);
        }
        else {
          doc = (new DOMParser()).parseFromString(s, 'text/xml');
        }
        return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
      }
    }
func_code_string: function fileUpload() {
      var form = $form[0];
  
      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;
      }
      
      var s = $.extend(true, {}, $.ajaxSettings, options);
      s.context = s.context || s;
      var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
      window[fn] = function() {
        var f = $io.data('form-plugin-onload');
        if (f) {
          f();
          window[fn] = undefined;
          try { delete window[fn]; } catch(e){}
        }
      }
      var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" onload="window[\'_\'+this.id]()" />');
      var io = $io[0];
  
      $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
  
      var xhr = { // mock object
        aborted: 0,
        responseText: null,
        responseXML: null,
        status: 0,
        statusText: 'n/a',
        getAllResponseHeaders: function() {},
        getResponseHeader: function() {},
        setRequestHeader: function() {},
        abort: function() {
          this.aborted = 1;
          $io.attr('src', s.iframeSrc); // abort op in progress
        }
      };
  
      var g = s.global;
      // trigger ajax global events so that activity/block indicators work like normal
      if (g && ! $.active++) {
        $.event.trigger("ajaxStart");
      }
      if (g) {
        $.event.trigger("ajaxSend", [xhr, s]);
      }
  
      if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
        if (s.global) { 
          $.active--;
        }
        return;
      }
      if (xhr.aborted) {
        return;
      }
  
      var cbInvoked = false;
      var timedOut = 0;
  
      // add submitting element to data if we know it
      var sub = form.clk;
      if (sub) {
        var n = sub.name;
        if (n && !sub.disabled) {
          s.extraData = s.extraData || {};
          s.extraData[n] = sub.value;
          if (sub.type == "image") {
            s.extraData[n+'.x'] = form.clk_x;
            s.extraData[n+'.y'] = form.clk_y;
          }
        }
      }
  
      // take a breath so that pending repaints get some cpu time before the upload starts
      function doSubmit() {
        // make sure form attrs are set
        var t = $form.attr('target'), a = $form.attr('action');
  
        // update form attrs in IE friendly way
        form.setAttribute('target',id);
        if (form.getAttribute('method') != 'POST') {
          form.setAttribute('method', 'POST');
        }
        if (form.getAttribute('action') != s.url) {
          form.setAttribute('action', s.url);
        }
  
        // ie borks in some cases when setting encoding
        if (! s.skipEncodingOverride) {
          $form.attr({
            encoding: 'multipart/form-data',
            enctype:  'multipart/form-data'
          });
        }
  
        // support timout
        if (s.timeout) {
          setTimeout(function() { timedOut = true; cb(); }, s.timeout);
        }
  
        // add "extra" data to form if provided in options
        var extraInputs = [];
        try {
          if (s.extraData) {
            for (var n in s.extraData) {
              extraInputs.push(
                $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
                  .appendTo(form)[0]);
            }
          }
  
          // add iframe to doc and submit the form
          $io.appendTo('body');
          $io.data('form-plugin-onload', cb);
          form.submit();
        }
        finally {
          // reset attrs and remove "extra" input elements
          form.setAttribute('action',a);
          if(t) {
            form.setAttribute('target', t);
          } else {
            $form.removeAttr('target');
          }
          $(extraInputs).remove();
        }
      }
  
      if (s.forceSync) {
        doSubmit();
      }
      else {
        setTimeout(doSubmit, 10); // this lets dom updates render
      }
    
      var data, doc, domCheckCount = 50;
  
      function cb() {
        if (cbInvoked) {
          return;
        }
  
        $io.removeData('form-plugin-onload');
        
        var ok = true;
        try {
          if (timedOut) {
            throw 'timeout';
          }
          // extract the server response from the iframe
          doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
          
          var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
          log('isXml='+isXml);
          if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
            if (--domCheckCount) {
              // in some browsers (Opera) the iframe DOM is not always traversable when
              // the onload callback fires, so we loop a bit to accommodate
              log('requeing onLoad callback, DOM not available');
              setTimeout(cb, 250);
              return;
            }
            // let this fall through because server response could be an empty document
            //log('Could not access iframe DOM after mutiple tries.');
            //throw 'DOMException: not available';
          }
  
          //log('response detected');
          cbInvoked = true;
          xhr.responseText = doc.documentElement ? doc.documentElement.innerHTML : null; 
          xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
          xhr.getResponseHeader = function(header){
            var headers = {'content-type': s.dataType};
            return headers[header];
          };
  
          var scr = /(json|script)/.test(s.dataType);
          if (scr || s.textarea) {
            // see if user embedded response in textarea
            var ta = doc.getElementsByTagName('textarea')[0];
            if (ta) {
              xhr.responseText = ta.value;
            }
            else if (scr) {
              // account for browsers injecting pre around json response
              var pre = doc.getElementsByTagName('pre')[0];
              if (pre) {
                xhr.responseText = pre.innerHTML;
              }
            }        
          }
          else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
            xhr.responseXML = toXml(xhr.responseText);
          }
          data = $.httpData(xhr, s.dataType);
        }
        catch(e){
          log('error caught:',e);
          ok = false;
          xhr.error = e;
          $.handleError(s, xhr, 'error', e);
        }
  
        // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
        if (ok) {
          s.success.call(s.context, data, 'success', xhr);
          if (g) {
            $.event.trigger("ajaxSuccess", [xhr, s]);
          }
        }
        if (g) {
          $.event.trigger("ajaxComplete", [xhr, s]);
        }
        if (g && ! --$.active) {
          $.event.trigger("ajaxStop");
        }
        if (s.complete) {
          s.complete.call(s.context, xhr, ok ? 'success' : 'error');
        }
  
        // clean up
        setTimeout(function() {
          $io.removeData('form-plugin-onload');
          $io.remove();
          xhr.responseXML = null;
        }, 100);
      }
  
      function toXml(s, doc) {
        if (window.ActiveXObject) {
          doc = new ActiveXObject('Microsoft.XMLDOM');
          doc.async = 'false';
          doc.loadXML(s);
        }
        else {
          doc = (new DOMParser()).parseFromString(s, 'text/xml');
        }
        return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
      }
    }
func_documentation_string: private function for handling file uploads (hat tip to YAHOO!)