Apart from below information, one additional information.

We have used the jQuery form plugin js in our project. This handles the form 
and request submit. The code is as attached here.




________________________________________
From: Rahul Singh <rksing...@hotmail.com>
Sent: Tuesday, January 19, 2016 11:30 AM
To: Tomcat Users List
Subject: Re: File size >= 2GB not uploaded in application [Tomcat 7.0.54 
Struts: 2.3.24 JAVA: openJDK 1.7.79]

Hi Christopher ,


>>So... what makes you sure that the browser actually made the request?
>>I'd like to see some kind of confirmation using a tool you didn't
>>write. Perhaps something like Firebug, LiveHttpHeaders, Fiddler, or
>>even Wireshark showing that the request was made, what headers it had,
>>etc.

OK,
We have used HTTP Analayzer for file upload via Internet Explorer-8. Following 
are the scenario observed.

For lesser than 2gb file uploads : The request header shows the correct 
content-length value of the file.The uploads works fine further also.

For more than 2gb file uploads: The file length is 2151533567 bytes(which is 
roughly 2.15 Gb).  The request is aborted in this case and the request header 
shows the content length
as -214343325 bytes (which is rougly 214 Mb).The upload process does not 
proceed further in this case.

both cases request headers are attached in screenshot.
________________________________________
From: Christopher Schultz <ch...@christopherschultz.net>
Sent: Monday, January 18, 2016 11:17 AM
To: Tomcat Users List
Subject: Re: File size >= 2GB not uploaded in application [Tomcat 7.0.54 
Struts: 2.3.24 JAVA: openJDK 1.7.79]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Rahul,

On 1/17/16 11:28 PM, Rahul Singh wrote:
> Code flow is attached, forgot to attach in trailing mail.
>
> ----------------------------------------------------------------------
- --
>
>
*From:* Rahul Singh <rksing...@hotmail.com>
> *Sent:* Monday, January 18, 2016 8:39 AM *To:* Tomcat Users List
> *Subject:* Re: File size >= 2GB not uploaded in application
> [Tomcat 7.0.54 Struts: 2.3.24 JAVA: openJDK 1.7.79]
>
> Hello Christopher, thanks for your prompt response !!
>
>> Why didn't you come to the Tomcat community first?
> Sorry for the delay, we wanted to make sure about the component
> causing the problem.
>
>
>>> I don't have a test-case in front of me, but I'm fairly
>>> confident that Tomcat allows file uploads of greater than 2GiB.
>>> I suspect the problem
> is another component.
>>> Are you using Servlet 3.0-based file upload, or are you
>>> allowing Struts to handle the file-upload for you? If you use
>>> Servlet-3.0 file-upload, then you'll have code that deals with
>>> Multipart classes and configuration in web.xml. If you are
>>> using Struts's file-upload, then you'll mostly just be calling
>>> getFile or getInputStream or however Struts 2 does things (I
>>> can't remember how it all works off the top of my head).
>
>
> In our case the filter class implements the javax.servlet.flter
> and imports javax.servlet.* The Filter class mentioned in the
> previous threads is the first one as declared in the web.xml
> (followed by other struts filters). All (url) requests are mapped
> to this filter. So this is where our file upload request goes. It
> is only in greater than 2 gb file upload request that the
> dofilter() fails to get any request. So we feel servlet 3.0 being
> used in our case the Filter is not being able to handle greater
> than 2 gb requests.
>
>
>>> The point is, if you are using Struts, then Tomcat will not
>>> touch the request and Struts is handling the whole thing. If
>>> Struts is the problem, you'll need to talk to the Struts
>>> team[1].
>
>>> If you are using Servlet-3.0 file-upload, then Struts is just a
>>> red herring and this is the right place to get your issue
>>> solved.
>
> As mentioned above Servlet 3.0 is being used. So request the
> tomcat community to please look into our issue.
>
>>> So far, you have posted some configuration for Struts and some
>>> JSP tablib-filled code, plus some Java code for a Filter. You
>>> didn't say where the Filter was in the filter chain (before or
>>> after Struts filter). You also mentioned that the form is
>>> actually posted using XMLHttpRequest and not through a standard
>>> form, but you didn't explain what component is doing that or
>>> how it actually works.
>
>>> There isn't enough information here to make any sense of the
>>> situation. Can you please address all of the questions I've
>>> posed above and maybe we can then help you?
>
>
> <<<Code model >>>> We need to model the following code to be told:
> jsp submit of the form How the .js submit it further in
> XmlHttpRequest How the Filter is declared How the web.xml is
> declared
>
>
>> Are you sure the request is even made to the server in these
>> cases?What if the Javascript upload component is failing before
>> it even starts?
>
> Yes the request is made in these cases. We have compared the
> scenario for greater than 2gb and lesser size file uploads and
> drawn the following inference from it.We have checked the request
> and content length for dofilter() method in our logs. The
> JavaScript is not the culprit in this case. The JavaScript sets the
> AJAX field to success after sending request and thereafter waits
> for response(which is not received in our case). Our application
> works fine for lesser than 2 gb fie uploads but fails for greater
> size files as the request fails to reach the dofilter() method
> after which the request can be forwarded to the requested method.
>
>
>
> Regards, Rahul
>
> ________________________________________ From: Christopher Schultz
> <ch...@christopherschultz.net> Sent: Saturday, January 16, 2016
> 9:33 AM To: Tomcat Users List Subject: Re: File size >= 2GB not
> uploaded in application [Tomcat 7.0.54 Struts: 2.3.24 JAVA: openJDK
> 1.7.79]
>
> Rahul,
>
> On 1/15/16 1:02 AM, Rahul Singh wrote:
>> Thanks for your guidelines, we have big hope from Apache Tomcat
>> Team to solve this problem as this is show stopper for our
>> application, we have also raise this question on various forum
>> like stack overflow and other, but no relevant reply till now.
>
> Why didn't you come to the Tomcat community first?
>
>> Hope you understand my situation,
>
>> please refer the below stackoverflow reference for more detail
>> about this issue.
>
>> http://stackoverflow.com/questions/34783438/dofilter-fails-to-get-any
- -
>
>>
<http://stackoverflow.com/questions/34783438/dofilter-fails-to-get-any->
>  doFilter() fails to get any request for the file upload > 2gb
> <http://stackoverflow.com/questions/34783438/dofilter-fails-to-get-any
- ->
>
>
stackoverflow.com
> For my struts project the doFilter() fails to get any request from
> the file upload form in cases the size of the file is greater than
> 2gb. Below is the code fragment: Filter (class is FilterUp) is...
>
>
>
> request-for-the-file-upload-2gb?noredirect=1#comment57315528_34783438
>
>
>
>
> for more information:
>
>> -No error are printed in tomcat logs. - how to configure "call
>> HttpServletRequest.getHeader("Content-Length") as a String and
>> parse it yourself."
>
> I don't have a test-case in front of my, but I'm fairly confident
> that Tomcat allows file uploads of greater than 2GiB. I suspect the
> problem is another component.
>
> Are you using Servlet 3.0-based file upload, or are you allowing
> Struts to handle the file-upload for you? If you use Servlet-3.0
> file-upload, then you'll have code that deals with Multipart
> classes and configuration in web.xml. If you are using Struts's
> file-upload, then you'll mostly just be calling getFile or
> getInputStream or however Struts 2 does things (I can't remember
> how it all works off the top of my head).
>
> The point is, if you are using Struts, then Tomcat will not touch
> the request and Struts is handling the whole thing. If Struts is
> the problem, you'll need to talk to the Struts team[1].
>
> If you are using Servlet-3.0 file-upload, then Struts is just a
> red herring and this is the right place to get your issue solved.
>
> So far, you have posted some configuration for Struts and some JSP
> tablib-filled code, plus some Java code for a Filter. You didn't
> say where the Filter was in the filter chain (before or after
> Struts filter).  You also mentioned that the form is actually
> posted using XMLHttpRequest and not through a standard form, but
> you didn't explain what component is doing that or how it actually
> works.
>
> There isn't enough information here to make any sense of the
> situation. Can you please address all of the questions I've posed
> above and maybe we can then help you?
>
> Are you sure the request is even made to the server in these
> cases? What if the Javascript upload component is failing before it
> even starts ?
>
> -chris
>
> [1] http://struts.apache.org/mail.html
>
>> ________________________________________ From: Christopher
>> Schultz <ch...@christopherschultz.net> Sent: Thursday, January
>> 14, 2016 8:43 PM To: Tomcat Users List Subject: Re: File size >=
>> 2GB not uploaded in application [Tomcat 7.0.54 Struts: 2.3.24
>> JAVA: openJDK 1.7.79]
>
>> André,
>
>> On 1/14/16 5:02 AM, André Warnier (tomcat) wrote:
>>> I have not followed this thread in details, but did you check
>>> this :
>>>
>>> http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Common_Attr
i
>
>>>
butes
>>>
>>>
>>>
> --> maxPostSize
>
>> +1
>
>>> The maximum size in bytes of the POST which will be handled by
>>> the container FORM URL parameter parsing. The limit can be
>>> disabled by setting this attribute to a value less than zero.
>>> If not specified, this attribute is set to 2097152 (2
>>> megabytes). Note that the FailedRequestFilter can be used to
>>> reject requests that exceed this limit.
>>>
>>> Note: the size above might relate to the *encoded* size of the
>>> file, as it is transmitted over the WWW (possibly encoded as
>>> Base64 e.g.), which may mean that an original 1 MB file
>>> translates to more than 1 MB bytes while being uploaded.
>>>
>>> Note also : maybe "Struts" is setting this to some other
>>> default value..
>>>
>>> Another question : did you check the Tomcat logs ?
>
>> IIRC, Tomcat doesn't log anything in these cases. You have to
>> use the FailedRequestFilter to detect and report the condition.
>> I wouldn't use that Filter in productio, but it would be good as
>> a simple test to see if this is the error that is occurring.
>
>> When Tomcat refuses to allow a file upload that it too large, it
>> simply does not parse the parameters, but the request continues
>> to process as usual (but the servlet doesn't end up getting any
>> of the parameters). I'm surprised that Struts isn't getting the
>> request in these cases.
>
>> -chris

So... what makes you sure that the browser actually made the request?
I'd like to see some kind of confirmation using a tool you didn't
write. Perhaps something like Firebug, LiveHttpHeaders, Fiddler, or
even Wireshark showing that the request was made, what headers it had,
etc.

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iEYEARECAAYFAlacfGwACgkQ9CaO5/Lv0PDZ9wCgk9toUxcJpCosg5Nx5sKDF6lB
MQ4AnimyBJlk2kFmNj/Kiolfd8WQUYLR
=TuoH
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org
/*!
 * jQuery Form Plugin
 * version: 2.52 (07-DEC-2010)
 * @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
 */

;(function($) {

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

        $(document).ready(function() {
                $('#myForm').bind('submit', function() {
                        $(this).ajaxSubmit({
                                target: '#output'
                        });
                        return false; // <-- important!
                });
        });

        Use ajaxForm when you want the plugin to manage all the event binding
        for you.  For example,

        $(document).ready(function() {
                $('#myForm').ajaxForm({
                        target: '#output'
                });
        });

        When using ajaxForm, the ajaxSubmit function will be invoked for you
        at the appropriate time.
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
        // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
        if (!this.length) {
                log('ajaxSubmit: skipping submit process - no element 
selected');
                return this;
        }

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

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

        options = $.extend({
                url:  url,
                type: this.attr('method') || 'GET',
                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 a = this.formToArray(options.semantic);
        if (options.data) {
                options.extraData = options.data;
                for (var n in options.data) {
                  if(options.data[n] instanceof Array) {
                        for (var k in options.data[n])
                          a.push( { name: n, value: options.data[n][k] } );
                  }
                  else
                         a.push( { name: n, value: options.data[n] } );
                }
        }

        // 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);

        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 $form = this, callbacks = [];
        if (options.resetForm) callbacks.push(function() { $form.resetForm(); 
});
        if (options.clearForm) callbacks.push(function() { $form.clearForm(); 
});

        // 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) {
                        $(options.target).html(data).each(oldSuccess, 
arguments);
                });
        }
        else if (options.success)
                callbacks.push(options.success);

        options.success = function(data, status) {
                for (var i=0, max=callbacks.length; i < max; i++)
                        callbacks[i].apply(options, [data, status, $form]);
        };

        // are there files to upload?
        var files = $('input:file', this).fieldValue();
        var found = false;
        for (var j=0; j < files.length; j++)
                if (files[j])
                        found = true;

        var multipart = false;
//      var mp = 'multipart/form-data';
//      multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == 
mp);

        // options.iframe allows user to force iframe mode
        // 06-NOV-09: now defaulting to iframe mode if file input is detected
   if ((files.length && options.iframe !== false) || options.iframe || found || 
multipart) {
           // 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, fileUpload);
           else
                   fileUpload();
           }
   else
           $.ajax(options);

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


        // private function for handling file uploads (hat tip to YAHOO!)
        function fileUpload() {
                var form = $form[0];

                if ($(':input[name=submit]', form).length) {
                        alert('Error: Form elements must not be named 
"submit".');
                        return;
                }

                var opts = $.extend({}, $.ajaxSettings, options);
                var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), 
opts);

                var id = 'jqFormIO' + (new Date().getTime());
                var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ 
opts.iframeSrc +'" />');
                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', opts.iframeSrc); // abort op in 
progress
                        }
                };

                var g = opts.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, opts]);

                if (s.beforeSend && s.beforeSend(xhr, s) === false) {
                        s.global && $.active--;
                        return;
                }
                if (xhr.aborted)
                        return;

                var cbInvoked = 0;
                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) {
                                options.extraData = options.extraData || {};
                                options.extraData[n] = sub.value;
                                if (sub.type == "image") {
                                        options.extraData[name+'.x'] = 
form.clk_x;
                                        options.extraData[name+'.y'] = 
form.clk_y;
                                }
                        }
                }

                // take a breath so that pending repaints get some cpu time 
before the upload starts
                setTimeout(function() {
                        // 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') != opts.url)
                                form.setAttribute('action', opts.url);

                        // ie borks in some cases when setting encoding
                        if (! options.skipEncodingOverride) {
                                $form.attr({
                                        encoding: 'multipart/form-data',
                                        enctype:  'multipart/form-data'
                                });
                        }

                        // support timout
                        if (opts.timeout)
                                setTimeout(function() { timedOut = true; cb(); 
}, opts.timeout);

                        // add "extra" data to form if provided in options
                        var extraInputs = [];
                        try {
                                if (options.extraData)
                                        for (var n in options.extraData)
                                                extraInputs.push(
                                                        $('<input type="hidden" 
name="'+n+'" value="'+options.extraData[n]+'" />')
                                                                
.appendTo(form)[0]);

                                // add iframe to doc and submit the form
                                $io.appendTo('body');
                                io.attachEvent ? io.attachEvent('onload', cb) : 
io.addEventListener('load', cb, false);
                                form.submit();
                        }
                        finally {
                                // reset attrs and remove "extra" input elements
                                form.setAttribute('action',a);
                                t ? form.setAttribute('target', t) : 
$form.removeAttr('target');
                                $(extraInputs).remove();
                        }
                }, 10);

                var domCheckCount = 50;

                function cb() {
                        if (cbInvoked++) return;

                        io.detachEvent ? io.detachEvent('onload', cb) : 
io.removeEventListener('load', cb, false);

                        var ok = true;
                        try {
                                if (timedOut) throw 'timeout';
                                // extract the server response from the iframe
                                var data, doc;

                                doc = io.contentWindow ? 
io.contentWindow.document : io.contentDocument ? io.contentDocument : 
io.document;
                                
                                var isXml = opts.dataType == 'xml' || 
doc.XMLDocument || $.isXMLDoc(doc);
                                log('isXml='+isXml);
                                if (!isXml && (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
                                                cbInvoked = 0;
                                                setTimeout(cb, 100);
                                                return;
                                        }
                                        log('Could not access iframe DOM after 
50 tries.');
                                        return;
                                }

                                xhr.responseText = doc.body ? 
doc.body.innerHTML : null;
                                xhr.responseXML = doc.XMLDocument ? 
doc.XMLDocument : doc;
                                xhr.getResponseHeader = function(header){
                                        var headers = {'content-type': 
opts.dataType};
                                        return headers[header];
                                };

                                if (opts.dataType == 'json' || opts.dataType == 
'script') {
                                        // see if user embedded response in 
textarea
                                        var ta = 
doc.getElementsByTagName('textarea')[0];
                                        if (ta)
                                                xhr.responseText = ta.value;
                                        else {
                                                // account for browsers 
injecting pre around json response
                                                var pre = 
doc.getElementsByTagName('pre')[0];
                                                if (pre)
                                                        xhr.responseText = 
pre.innerHTML;
                                        }                         
                                }
                                else if (opts.dataType == 'xml' && 
!xhr.responseXML && xhr.responseText != null) {
                                        xhr.responseXML = 
toXml(xhr.responseText);
                                }
                                data = $.httpData(xhr, opts.dataType);
                        }
                        catch(e){
                                ok = false;
                                $.handleError(opts, xhr, 'error', e);
                        }

                        // ordering of these callbacks/triggers is odd, but 
that's how $.ajax does it
                        if (ok) {
                                opts.success(data, 'success');
                                if (g) $.event.trigger("ajaxSuccess", [xhr, 
opts]);
                        }
                        if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
                        if (g && ! --$.active) $.event.trigger("ajaxStop");
                        if (opts.complete) opts.complete(xhr, ok ? 'success' : 
'error');

                        // clean up
                        setTimeout(function() {
                                $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;
                };
        };
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements 
(if the element
 *      is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the 
element that was
 *      used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  
ajaxForm merely
 * passes the options argument along after properly binding events for submit 
elements and
 * the form itself.
 */
$.fn.ajaxForm = function(options) {
        return this.ajaxFormUnbind().bind('submit.form-plugin', function() {
                $(this).ajaxSubmit(options);
                return false;
        }).bind('click.form-plugin', function(e) {
                var target = e.target;
                var $el = $(target);
                if (!($el.is(":submit,input:image"))) {
                        // is this a child element of the submit el?  (ex: a 
span within a button)
                        var t = $el.closest(':submit');
                        if (t.length == 0)
                                return;
                        target = t[0];
                }
                var form = this;
                form.clk = target;
                if (target.type == 'image') {
                        if (e.offsetX != undefined) {
                                form.clk_x = e.offsetX;
                                form.clk_y = e.offsetY;
                        } else if (typeof $.fn.offset == 'function') { // try 
to use dimensions plugin
                                var offset = $el.offset();
                                form.clk_x = e.pageX - offset.left;
                                form.clk_y = e.pageY - offset.top;
                        } else {
                                form.clk_x = e.pageX - target.offsetLeft;
                                form.clk_y = e.pageY - target.offsetTop;
                        }
                }
                // clear form vars
                setTimeout(function() { form.clk = form.clk_x = form.clk_y = 
null; }, 100);
        });
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
        return this.unbind('submit.form-plugin click.form-plugin');
};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example 
of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' 
} ]
 *
 * It is this array that is passed to pre-submit callback functions provided to 
the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
        var a = [];
        if (this.length == 0) return a;

        var form = this[0];
        var els = semantic ? form.getElementsByTagName('*') : form.elements;
        if (!els) return a;
        for(var i=0, max=els.length; i < max; i++) {
                var el = els[i];
                var n = el.name;
                if (!n) continue;

                if (semantic && form.clk && el.type == "image") {
                        // handle image inputs on the fly when semantic == true
                        if(!el.disabled && form.clk == el) {
                                a.push({name: n, value: $(el).val()});
                                a.push({name: n+'.x', value: form.clk_x}, 
{name: n+'.y', value: form.clk_y});
                        }
                        continue;
                }

                var v = $.fieldValue(el, true);
                if (v && v.constructor == Array) {
                        for(var j=0, jmax=v.length; j < jmax; j++)
                                a.push({name: n, value: v[j]});
                }
                else if (v !== null && typeof v != 'undefined')
                        a.push({name: n, value: v});
        }

        if (!semantic && form.clk) {
                // input type=='image' are not found in elements array! handle 
it here
                var $input = $(form.clk), input = $input[0], n = input.name;
                if (n && !input.disabled && input.type == 'image') {
                        a.push({name: n, value: $input.val()});
                        a.push({name: n+'.x', value: form.clk_x}, {name: 
n+'.y', value: form.clk_y});
                }
        }
        return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a 
string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
        //hand off to jQuery.param for proper encoding
        return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
        var a = [];
        this.each(function() {
                var n = this.name;
                if (!n) return;
                var v = $.fieldValue(this, successful);
                if (v && v.constructor == Array) {
                        for (var i=0,max=v.length; i < max; i++)
                                a.push({name: n, value: v[i]});
                }
                else if (v !== null && typeof v != 'undefined')
                        a.push({name: this.name, value: v});
        });
        //hand off to jQuery.param for proper encoding
        return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.  For example, 
consider the following form:
 *
 *  <form><fieldset>
 *        <input name="A" type="text" />
 *        <input name="A" type="text" />
 *        <input name="B" type="checkbox" value="B1" />
 *        <input name="B" type="checkbox" value="B2"/>
 *        <input name="C" type="radio" value="C1" />
 *        <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 
'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is 
false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be 
determined the
 *         array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
        for (var val=[], i=0, max=this.length; i < max; i++) {
                var el = this[i];
                var v = $.fieldValue(el, successful);
                if (v === null || typeof v == 'undefined' || (v.constructor == 
Array && !v.length))
                        continue;
                v.constructor == Array ? $.merge(val, v) : val.push(v);
        }
        return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
        var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
        if (typeof successful == 'undefined') successful = true;

        if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
                (t == 'checkbox' || t == 'radio') && !el.checked ||
                (t == 'submit' || t == 'image') && el.form && el.form.clk != el 
||
                tag == 'select' && el.selectedIndex == -1))
                        return null;

        if (tag == 'select') {
                var index = el.selectedIndex;
                if (index < 0) return null;
                var a = [], ops = el.options;
                var one = (t == 'select-one');
                var max = (one ? index+1 : ops.length);
                for(var i=(one ? index : 0); i < max; i++) {
                        var op = ops[i];
                        if (op.selected) {
                                var v = op.value;
                                if (!v) // extra pain for IE...
                                        v = (op.attributes && 
op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : 
op.value;
                                if (one) return v;
                                a.push(v);
                        }
                }
                return a;
        }
        return el.value;
};

/**
 * Clears the form data.  Takes the following actions on the form's input 
fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 */
$.fn.clearForm = function() {
        return this.each(function() {
                $('input,select,textarea', this).clearFields();
        });
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
        return this.each(function() {
                var t = this.type, tag = this.tagName.toLowerCase();
                if (t == 'text' || t == 'password' || tag == 'textarea')
                        this.value = '';
                else if (t == 'checkbox' || t == 'radio')
                        this.checked = false;
                else if (tag == 'select')
                        this.selectedIndex = -1;
        });
};

/**
 * Resets the form data.  Causes all form elements to be reset to their 
original value.
 */
$.fn.resetForm = function() {
        return this.each(function() {
                // guard against an input with the name of 'reset'
                // note that IE reports the reset function as an 'object'
                if (typeof this.reset == 'function' || (typeof this.reset == 
'object' && !this.reset.nodeType))
                        this.reset();
        });
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) {
        if (b == undefined) b = true;
        return this.each(function() {
                this.disabled = !b;
        });
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.selected = function(select) {
        if (select == undefined) select = true;
        return this.each(function() {
                var t = this.type;
                if (t == 'checkbox' || t == 'radio')
                        this.checked = select;
                else if (this.tagName.toLowerCase() == 'option') {
                        var $sel = $(this).parent('select');
                        if (select && $sel[0] && $sel[0].type == 'select-one') {
                                // deselect all other options
                                $sel.find('option').selected(false);
                        }
                        this.selected = select;
                }
        });
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
        if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
                window.console.log('[jquery.form] ' + 
Array.prototype.join.call(arguments,''));
};

})(jQuery);
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to