PageSourceSearch

https://www.bintang4dpwin001.com/assets/js/jquery.form.js

js bintang4dpwin001.com collected 2026-10-09 22:40:44 UTC 38,140 bytes, 1,089 lines download raw bytes

1/*!
2 * jQuery Form Plugin
3 * version: 3.14 (30-JUL-2012)
4 * @requires jQuery v1.3.2 or later
5 *
6 * Examples and documentation at: http://malsup.com/jquery/form/
7 * Project repository: https://github.com/malsup/form
8 * Dual licensed under the MIT and GPL licenses:
9 *    http://malsup.github.com/mit-license.txt
10 *    http://malsup.github.com/gpl-license-v2.txt
11 */
12/*global ActiveXObject alert */
13;(function($) {
14"use strict";
15
16/*
17    Usage Note:
18    -----------
19    Do not use both ajaxSubmit and ajaxForm on the same form.  These
20    functions are mutually exclusive.  Use ajaxSubmit if you want
21    to bind your own submit handler to the form.  For example,
22
23    $(document).ready(function() {
24        $('#myForm').on('submit', function(e) {
25            e.preventDefault(); // <-- important
26            $(this).ajaxSubmit({
27                target: '#output'
28            });
29        });
30    });
31
32    Use ajaxForm when you want the plugin to manage all the event binding
33    for you.  For example,
34
35    $(document).ready(function() {
36        $('#myForm').ajaxForm({
37            target: '#output'
38        });
39    });
40    
41    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
42    form does not have to exist when you invoke ajaxForm:
43
44    $('#myForm').ajaxForm({
45        delegation: true,
46        target: '#output'
47    });
48    
49    When using ajaxForm, the ajaxSubmit function will be invoked for you
50    at the appropriate time.
51*/
52
53/**
54 * Feature detection
55 */
56var feature = {};
57feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
58feature.formdata = window.FormData !== undefined;
59
60/**
61 * ajaxSubmit() provides a mechanism for immediately submitting
62 * an HTML form using AJAX.
63 */
64$.fn.ajaxSubmit = function(options) {
65    /*jshint scripturl:true */
66
67    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
68    if (!this.length) {
69        log('ajaxSubmit: skipping submit process - no element selected');
70        return this;
71    }
72    
73    var method, action, url, $form = this;
74
75    if (typeof options == 'function') {
76        options = { success: options };
77    }
78
79    method = this.attr('method');
80    action = this.attr('action');
81    url = (typeof action === 'string') ? $.trim(action) : '';
82    url = url || window.location.href || '';
83    if (url) {
84        // clean url (don't include hash vaue)
85        url = (url.match(/^([^#]+)/)||[])[1];
86    }
87
88    options = $.extend(true, {
89        url:  url,
90        success: $.ajaxSettings.success,
91        type: method || 'GET',
92        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
93    }, options);
94
95    // hook for manipulating the form data before it is extracted;
96    // convenient for use with rich editors like tinyMCE or FCKEditor
97    var veto = {};
98    this.trigger('form-pre-serialize', [this, options, veto]);
99    if (veto.veto) {
100        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
101        return this;
102    }
103
104    // provide opportunity to alter form data before it is serialized
105    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
106        log('ajaxSubmit: submit aborted via beforeSerialize callback');
107        return this;
108    }
109
110    var traditional = options.traditional;
111    if ( traditional === undefined ) {
112        traditional = $.ajaxSettings.traditional;
113    }
114    
115    var elements = [];
116    var qx, a = this.formToArray(options.semantic, elements);
117    if (options.data) {
118        options.extraData = options.data;
119        qx = $.param(options.data, traditional);
120    }
121
122    // give pre-submit callback an opportunity to abort the submit
123    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
124        log('ajaxSubmit: submit aborted via beforeSubmit callback');
125        return this;
126    }
127
128    // fire vetoable 'validate' event
129    this.trigger('form-submit-validate', [a, this, options, veto]);
130    if (veto.veto) {
131        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
132        return this;
133    }
134
135    var q = $.param(a, traditional);
136    if (qx) {
137        q = ( q ? (q + '&' + qx) : qx );
138    }    
139    if (options.type.toUpperCase() == 'GET') {
140        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
141        options.data = null;  // data is null for 'get'
142    }
143    else {
144        options.data = q; // data is the query string for 'post'
145    }
146
147    var callbacks = [];
148    if (options.resetForm) {
149        callbacks.push(function() { $form.resetForm(); });
150    }
151    if (options.clearForm) {
152        callbacks.push(function() { $form.clearForm(options.includeHidden); });
153    }
154
155    // perform a load on the target only if dataType is not provided
156    if (!options.dataType && options.target) {
157        var oldSuccess = options.success || function(){};
158        callbacks.push(function(data) {
159            var fn = options.replaceTarget ? 'replaceWith' : 'html';
160            $(options.target)[fn](data).each(oldSuccess, arguments);
161        });
162    }
163    else if (options.success) {
164        callbacks.push(options.success);
165    }
166
167    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
168        var context = options.context || this ;    // jQuery 1.4+ supports scope context 
169        for (var i=0, max=callbacks.length; i < max; i++) {
170            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
171        }
172    };
173
174    // are there files to upload?
175    var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
176    var hasFileInputs = fileInputs.length > 0;
177    var mp = 'multipart/form-data';
178    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
179
180    var fileAPI = feature.fileapi && feature.formdata;
181    log("fileAPI :" + fileAPI);
182    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
183
184    // options.iframe allows user to force iframe mode
185    // 06-NOV-09: now defaulting to iframe mode if file input is detected
186    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
187        // hack to fix Safari hang (thanks to Tim Molendijk for this)
188        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
189        if (options.closeKeepAlive) {
190            $.get(options.closeKeepAlive, function() {
191                fileUploadIframe(a);
192            });
193        }
194          else {
195            fileUploadIframe(a);
196          }
197    }
198    else if ((hasFileInputs || multipart) && fileAPI) {
199        fileUploadXhr(a);
200    }
201    else {
202        $.ajax(options);
203    }
204
205    // clear element array
206    for (var k=0; k < elements.length; k++)
207        elements[k] = null;
208
209    // fire 'notify' event
210    this.trigger('form-submit-notify', [this, options]);
211    return this;
212
213     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
214    function fileUploadXhr(a) {
215        var formdata = new FormData();
216
217        for (var i=0; i < a.length; i++) {
218            formdata.append(a[i].name, a[i].value);
219        }
220
221        if (options.extraData) {
222            for (var p in options.extraData)
223                if (options.extraData.hasOwnProperty(p))
224                    formdata.append(p, options.extraData[p]);
225        }
226
227        options.data = null;
228
229        var s = $.extend(true, {}, $.ajaxSettings, options, {
230            contentType: false,
231            processData: false,
232            cache: false,
233            type: 'POST'
234        });
235        
236        if (options.uploadProgress) {
237            // workaround because jqXHR does not expose upload property
238            s.xhr = function() {
239                var xhr = jQuery.ajaxSettings.xhr();
240                if (xhr.upload) {
241                    xhr.upload.onprogress = function(event) {
242                        var percent = 0;
243                        var position = event.loaded || event.position; /*event.position is deprecated*/
244                        var total = event.total;
245                        if (event.lengthComputable) {
246                            percent = Math.ceil(position / total * 100);
247                        }
248                        options.uploadProgress(event, position, total, percent);
249                    };
250                }
251                return xhr;
252            };
253        }
254
255        s.data = null;
256            var beforeSend = s.beforeSend;
257            s.beforeSend = function(xhr, o) {
258                o.data = formdata;
259                if(beforeSend)
260                    beforeSend.call(this, xhr, o);
261        };
262        $.ajax(s);
263    }
264
265    // private function for handling file uploads (hat tip to YAHOO!)
266    function fileUploadIframe(a) {
267        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
268        var useProp = !!$.fn.prop;
269
270        if ($(':input[name=submit],:input[id=submit]', form).length) {
271            // if there is an input with a name or id of 'submit' then we won't be
272            // able to invoke the submit fn on the form (at least not x-browser)
273            alert('Error: Form elements must not have name or id of "submit".');
274            return;
275        }
276        
277        if (a) {
278            // ensure that every serialized input is still enabled
279            for (i=0; i < elements.length; i++) {
280                el = $(elements[i]);
281                if ( useProp )
282                    el.prop('disabled', false);
283                else
284                    el.removeAttr('disabled');
285            }
286        }
287
288        s = $.extend(true, {}, $.ajaxSettings, options);
289        s.context = s.context || s;
290        id = 'jqFormIO' + (new Date().getTime());
291        if (s.iframeTarget) {
292            $io = $(s.iframeTarget);
293            n = $io.attr('name');
294            if (!n)
295                 $io.attr('name', id);
296            else
297                id = n;
298        }
299        else {
300            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
301            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
302        }
303        io = $io[0];
304
305
306        xhr = { // mock object
307            aborted: 0,
308            responseText: null,
309            responseXML: null,
310            status: 0,
311            statusText: 'n/a',
312            getAllResponseHeaders: function() {},
313            getResponseHeader: function() {},
314            setRequestHeader: function() {},
315            abort: function(status) {
316                var e = (status === 'timeout' ? 'timeout' : 'aborted');
317                log('aborting upload... ' + e);
318                this.aborted = 1;
319                // #214
320                if (io.contentWindow.document.execCommand) {
321                    try { // #214
322                        io.contentWindow.document.execCommand('Stop');
323                    } catch(ignore) {}
324                }
325                $io.attr('src', s.iframeSrc); // abort op in progress
326                xhr.error = e;
327                if (s.error)
328                    s.error.call(s.context, xhr, e, status);
329                if (g)
330                    $.event.trigger("ajaxError", [xhr, s, e]);
331                if (s.complete)
332                    s.complete.call(s.context, xhr, e);
333            }
334        };
335
336        g = s.global;
337        // trigger ajax global events so that activity/block indicators work like normal
338        if (g && 0 === $.active++) {
339            $.event.trigger("ajaxStart");
340        }
341        if (g) {
342            $.event.trigger("ajaxSend", [xhr, s]);
343        }
344
345        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
346            if (s.global) {
347                $.active--;
348            }
349            return;
350        }
351        if (xhr.aborted) {
352            return;
353        }
354
355        // add submitting element to data if we know it
356        sub = form.clk;
357        if (sub) {
358            n = sub.name;
359            if (n && !sub.disabled) {
360                s.extraData = s.extraData || {};
361                s.extraData[n] = sub.value;
362                if (sub.type == "image") {
363                    s.extraData[n+'.x'] = form.clk_x;
364                    s.extraData[n+'.y'] = form.clk_y;
365                }
366            }
367        }
368        
369        var CLIENT_TIMEOUT_ABORT = 1;
370        var SERVER_ABORT = 2;
371
372        function getDoc(frame) {
373            var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
374            return doc;
375        }
376        
377        // Rails CSRF hack (thanks to Yvan Barthelemy)
378        var csrf_token = $('meta[name=csrf-token]').attr('content');
379        var csrf_param = $('meta[name=csrf-param]').attr('content');
380        if (csrf_param && csrf_token) {
381            s.extraData = s.extraData || {};
382            s.extraData[csrf_param] = csrf_token;
383        }
384
385        // take a breath so that pending repaints get some cpu time before the upload starts
386        function doSubmit() {
387            // make sure form attrs are set
388            var t = $form.attr('target'), a = $form.attr('action');
389
390            // update form attrs in IE friendly way
391            form.setAttribute('target',id);
392            if (!method) {
393                form.setAttribute('method', 'POST');
394            }
395            if (a != s.url) {
396                form.setAttribute('action', s.url);
397            }
398
399            // ie borks in some cases when setting encoding
400            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
401                $form.attr({
402                    encoding: 'multipart/form-data',
403                    enctype:  'multipart/form-data'
404                });
405            }
406
407            // support timout
408            if (s.timeout) {
409                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
410            }
411            
412            // look for server aborts
413            function checkState() {
414                try {
415                    var state = getDoc(io).readyState;
416                    log('state = ' + state);
417                    if (state && state.toLowerCase() == 'uninitialized')
418                        setTimeout(checkState,50);
419                }
420                catch(e) {
421                    log('Server abort: ' , e, ' (', e.name, ')');
422                    cb(SERVER_ABORT);
423                    if (timeoutHandle)
424                        clearTimeout(timeoutHandle);
425                    timeoutHandle = undefined;
426                }
427            }
428
429            // add "extra" data to form if provided in options
430            var extraInputs = [];
431            try {
432                if (s.extraData) {
433                    for (var n in s.extraData) {
434                        if (s.extraData.hasOwnProperty(n)) {
435                           // if using the $.param format that allows for multiple values with the same name
436                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
437                               extraInputs.push(
438                               $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value)
439                                   .appendTo(form)[0]);
440                           } else {
441                               extraInputs.push(
442                               $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
443                                   .appendTo(form)[0]);
444                           }
445                        }
446                    }
447                }
448
449                if (!s.iframeTarget) {
450                    // add iframe to doc and submit the form
451                    $io.appendTo('body');
452                    if (io.attachEvent)
453                        io.attachEvent('onload', cb);
454                    else
455                        io.addEventListener('load', cb, false);
456                }
457                setTimeout(checkState,15);
458                form.submit();
459            }
460            finally {
461                // reset attrs and remove "extra" input elements
462                form.setAttribute('action',a);
463                if(t) {
464                    form.setAttribute('target', t);
465                } else {
466                    $form.removeAttr('target');
467                }
468                $(extraInputs).remove();
469            }
470        }
471
472        if (s.forceSync) {
473            doSubmit();
474        }
475        else {
476            setTimeout(doSubmit, 10); // this lets dom updates render
477        }
478
479        var data, doc, domCheckCount = 50, callbackProcessed;
480
481        function cb(e) {
482            if (xhr.aborted || callbackProcessed) {
483                return;
484            }
485            try {
486                doc = getDoc(io);
487            }
488            catch(ex) {
489                log('cannot access response document: ', ex);
490                e = SERVER_ABORT;
491            }
492            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
493                xhr.abort('timeout');
494                return;
495            }
496            else if (e == SERVER_ABORT && xhr) {
497                xhr.abort('server abort');
498                return;
499            }
500
501            if (!doc || doc.location.href == s.iframeSrc) {
502                // response not received yet
503                if (!timedOut)
504                    return;
505            }
506            if (io.detachEvent)
507                io.detachEvent('onload', cb);
508            else    
509                io.removeEventListener('load', cb, false);
510
511            var status = 'success', errMsg;
512            try {
513                if (timedOut) {
514                    throw 'timeout';
515                }
516
517                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
518                log('isXml='+isXml);
519                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
520                    if (--domCheckCount) {
521                        // in some browsers (Opera) the iframe DOM is not always traversable when
522                        // the onload callback fires, so we loop a bit to accommodate
523                        log('requeing onLoad callback, DOM not available');
524                        setTimeout(cb, 250);
525                        return;
526                    }
527                    // let this fall through because server response could be an empty document
528                    //log('Could not access iframe DOM after mutiple tries.');
529                    //throw 'DOMException: not available';
530                }
531
532                //log('response detected');
533                var docRoot = doc.body ? doc.body : doc.documentElement;
534                xhr.responseText = docRoot ? docRoot.innerHTML : null;
535                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
536                if (isXml)
537                    s.dataType = 'xml';
538                xhr.getResponseHeader = function(header){
539                    var headers = {'content-type': s.dataType};
540                    return headers[header];
541                };
542                // support for XHR 'status' & 'statusText' emulation :
543                if (docRoot) {
544                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
545                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
546                }
547
548                var dt = (s.dataType || '').toLowerCase();
549                var scr = /(json|script|text)/.test(dt);
550                if (scr || s.textarea) {
551                    // see if user embedded response in textarea
552                    var ta = doc.getElementsByTagName('textarea')[0];
553                    if (ta) {
554                        xhr.responseText = ta.value;
555                        // support for XHR 'status' & 'statusText' emulation :
556                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
557                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
558                    }
559                    else if (scr) {
560                        // account for browsers injecting pre around json response
561                        var pre = doc.getElementsByTagName('pre')[0];
562                        var b = doc.getElementsByTagName('body')[0];
563                        if (pre) {
564                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
565                        }
566                        else if (b) {
567                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
568                        }
569                    }
570                }
571                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
572                    xhr.responseXML = toXml(xhr.responseText);
573                }
574
575                try {
576                    data = httpData(xhr, dt, s);
577                }
578                catch (e) {
579                    status = 'parsererror';
580                    xhr.error = errMsg = (e || status);
581                }
582            }
583            catch (e) {
584                log('error caught: ',e);
585                status = 'error';
586                xhr.error = errMsg = (e || status);
587            }
588
589            if (xhr.aborted) {
590                log('upload aborted');
591                status = null;
592            }
593
594            if (xhr.status) { // we've set xhr.status
595                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
596            }
597
598            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
599            if (status === 'success') {
600                if (s.success)
601                    s.success.call(s.context, data, 'success', xhr);
602                if (g)
603                    $.event.trigger("ajaxSuccess", [xhr, s]);
604            }
605            else if (status) {
606                if (errMsg === undefined)
607                    errMsg = xhr.statusText;
608                if (s.error)
609                    s.error.call(s.context, xhr, status, errMsg);
610                if (g)
611                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
612            }
613
614            if (g)
615                $.event.trigger("ajaxComplete", [xhr, s]);
616
617            if (g && ! --$.active) {
618                $.event.trigger("ajaxStop");
619            }
620
621            if (s.complete)
622                s.complete.call(s.context, xhr, status);
623
624            callbackProcessed = true;
625            if (s.timeout)
626                clearTimeout(timeoutHandle);
627
628            // clean up
629            setTimeout(function() {
630                if (!s.iframeTarget)
631                    $io.remove();
632                xhr.responseXML = null;
633            }, 100);
634        }
635
636        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
637            if (window.ActiveXObject) {
638                doc = new ActiveXObject('Microsoft.XMLDOM');
639                doc.async = 'false';
640                doc.loadXML(s);
641            }
642            else {
643                doc = (new DOMParser()).parseFromString(s, 'text/xml');
644            }
645            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
646        };
647        var parseJSON = $.parseJSON || function(s) {
648            /*jslint evil:true */
649            return window['eval']('(' + s + ')');
650        };
651
652        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
653
654            var ct = xhr.getResponseHeader('content-type') || '',
655                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
656                data = xml ? xhr.responseXML : xhr.responseText;
657
658            if (xml && data.documentElement.nodeName === 'parsererror') {
659                if ($.error)
660                    $.error('parsererror');
661            }
662            if (s && s.dataFilter) {
663                data = s.dataFilter(data, type);
664            }
665            if (typeof data === 'string') {
666                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
667                    data = parseJSON(data);
668                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
669                    $.globalEval(data);
670                }
671            }
672            return data;
673        };
674    }
675};
676
677/**
678 * ajaxForm() provides a mechanism for fully automating form submission.
679 *
680 * The advantages of using this method instead of ajaxSubmit() are:
681 *
682 * 1: This method will include coordinates for <input type="image" /> elements (if the element
683 *    is used to submit the form).
684 * 2. This method will include the submit element's name/value data (for the element that was
685 *    used to submit the form).
686 * 3. This method binds the submit() method to the form for you.
687 *
688 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
689 * passes the options argument along after properly binding events for submit elements and
690 * the form itself.
691 */
692$.fn.ajaxForm = function(options) {
693    options = options || {};
694    options.delegation = options.delegation && $.isFunction($.fn.on);
695    
696    // in jQuery 1.3+ we can fix mistakes with the ready state
697    if (!options.delegation && this.length === 0) {
698        var o = { s: this.selector, c: this.context };
699        if (!$.isReady && o.s) {
700            log('DOM not ready, queuing ajaxForm');
701            $(function() {
702                $(o.s,o.c).ajaxForm(options);
703            });
704            return this;
705        }
706        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
707        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
708        return this;
709    }
710
711    if ( options.delegation ) {
712        $(document)
713            .off('submit.form-plugin', this.selector, doAjaxSubmit)
714            .off('click.form-plugin', this.selector, captureSubmittingElement)
715            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
716            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
717        return this;
718    }
719
720    return this.ajaxFormUnbind()
721        .bind('submit.form-plugin', options, doAjaxSubmit)
722        .bind('click.form-plugin', options, captureSubmittingElement);
723};
724
725// private event handlers    
726function doAjaxSubmit(e) {
727    /*jshint validthis:true */
728    var options = e.data;
729    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
730        e.preventDefault();
731        $(this).ajaxSubmit(options);
732    }
733}
734    
735function captureSubmittingElement(e) {
736    /*jshint validthis:true */
737    var target = e.target;
738    var $el = $(target);
739    if (!($el.is(":submit,input:image"))) {
740        // is this a child element of the submit el?  (ex: a span within a button)
741        var t = $el.closest(':submit');
742        if (t.length === 0) {
743            return;
744        }
745        target = t[0];
746    }
747    var form = this;
748    form.clk = target;
749    if (target.type == 'image') {
750        if (e.offsetX !== undefined) {
751            form.clk_x = e.offsetX;
752            form.clk_y = e.offsetY;
753        } else if (typeof $.fn.offset == 'function') {
754            var offset = $el.offset();
755            form.clk_x = e.pageX - offset.left;
756            form.clk_y = e.pageY - offset.top;
757        } else {
758            form.clk_x = e.pageX - target.offsetLeft;
759            form.clk_y = e.pageY - target.offsetTop;
760        }
761    }
762    // clear form vars
763    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
764}
765
766
767// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
768$.fn.ajaxFormUnbind = function() {
769    return this.unbind('submit.form-plugin click.form-plugin');
770};
771
772/**
773 * formToArray() gathers form element data into an array of objects that can
774 * be passed to any of the following ajax functions: $.get, $.post, or load.
775 * Each object in the array has both a 'name' and 'value' property.  An example of
776 * an array for a simple login form might be:
777 *
778 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
779 *
780 * It is this array that is passed to pre-submit callback functions provided to the
781 * ajaxSubmit() and ajaxForm() methods.
782 */
783$.fn.formToArray = function(semantic, elements) {
784    var a = [];
785    if (this.length === 0) {
786        return a;
787    }
788
789    var form = this[0];
790    var els = semantic ? form.getElementsByTagName('*') : form.elements;
791    if (!els) {
792        return a;
793    }
794
795    var i,j,n,v,el,max,jmax;
796    for(i=0, max=els.length; i < max; i++) {
797        el = els[i];
798        n = el.name;
799        if (!n) {
800            continue;
801        }
802
803        if (semantic && form.clk && el.type == "image") {
804            // handle image inputs on the fly when semantic == true
805            if(!el.disabled && form.clk == el) {
806                a.push({name: n, value: $(el).val(), type: el.type });
807                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
808            }
809            continue;
810        }
811
812        v = $.fieldValue(el, true);
813        if (v && v.constructor == Array) {
814            if (elements) 
815                elements.push(el);
816            for(j=0, jmax=v.length; j < jmax; j++) {
817                a.push({name: n, value: v[j]});
818            }
819        }
820        else if (feature.fileapi && el.type == 'file' && !el.disabled) {
821            if (elements) 
822                elements.push(el);
823            var files = el.files;
824            if (files.length) {
825                for (j=0; j < files.length; j++) {
826                    a.push({name: n, value: files[j], type: el.type});
827                }
828            }
829            else {
830                // #180
831                a.push({ name: n, value: '', type: el.type });
832            }
833        }
834        else if (v !== null && typeof v != 'undefined') {
835            if (elements) 
836                elements.push(el);
837            a.push({name: n, value: v, type: el.type, required: el.required});
838        }
839    }
840
841    if (!semantic && form.clk) {
842        // input type=='image' are not found in elements array! handle it here
843        var $input = $(form.clk), input = $input[0];
844        n = input.name;
845        if (n && !input.disabled && input.type == 'image') {
846            a.push({name: n, value: $input.val()});
847            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
848        }
849    }
850    return a;
851};
852
853/**
854 * Serializes form data into a 'submittable' string. This method will return a string
855 * in the format: name1=value1&amp;name2=value2
856 */
857$.fn.formSerialize = function(semantic) {
858    //hand off to jQuery.param for proper encoding
859    return $.param(this.formToArray(semantic));
860};
861
862/**
863 * Serializes all field elements in the jQuery object into a query string.
864 * This method will return a string in the format: name1=value1&amp;name2=value2
865 */
866$.fn.fieldSerialize = function(successful) {
867    var a = [];
868    this.each(function() {
869        var n = this.name;
870        if (!n) {
871            return;
872        }
873        var v = $.fieldValue(this, successful);
874        if (v && v.constructor == Array) {
875            for (var i=0,max=v.length; i < max; i++) {
876                a.push({name: n, value: v[i]});
877            }
878        }
879        else if (v !== null && typeof v != 'undefined') {
880            a.push({name: this.name, value: v});
881        }
882    });
883    //hand off to jQuery.param for proper encoding
884    return $.param(a);
885};
886
887/**
888 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
889 *
890 *  <form><fieldset>
891 *      <input name="A" type="text" />
892 *      <input name="A" type="text" />
893 *      <input name="B" type="checkbox" value="B1" />
894 *      <input name="B" type="checkbox" value="B2"/>
895 *      <input name="C" type="radio" value="C1" />
896 *      <input name="C" type="radio" value="C2" />
897 *  </fieldset></form>
898 *
899 *  var v = $(':text').fieldValue();
900 *  // if no values are entered into the text inputs
901 *  v == ['','']
902 *  // if values entered into the text inputs are 'foo' and 'bar'
903 *  v == ['foo','bar']
904 *
905 *  var v = $(':checkbox').fieldValue();
906 *  // if neither checkbox is checked
907 *  v === undefined
908 *  // if both checkboxes are checked
909 *  v == ['B1', 'B2']
910 *
911 *  var v = $(':radio').fieldValue();
912 *  // if neither radio is checked
913 *  v === undefined
914 *  // if first radio is checked
915 *  v == ['C1']
916 *
917 * The successful argument controls whether or not the field element must be 'successful'
918 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
919 * The default value of the successful argument is true.  If this value is false the value(s)
920 * for each element is returned.
921 *
922 * Note: This method *always* returns an array.  If no valid value can be determined the
923 *    array will be empty, otherwise it will contain one or more values.
924 */
925$.fn.fieldValue = function(successful) {
926    for (var val=[], i=0, max=this.length; i < max; i++) {
927        var el = this[i];
928        var v = $.fieldValue(el, successful);
929        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
930            continue;
931        }
932        if (v.constructor == Array)
933            $.merge(val, v);
934        else
935            val.push(v);
936    }
937    return val;
938};
939
940/**
941 * Returns the value of the field element.
942 */
943$.fieldValue = function(el, successful) {
944    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
945    if (successful === undefined) {
946        successful = true;
947    }
948
949    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
950        (t == 'checkbox' || t == 'radio') && !el.checked ||
951        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
952        tag == 'select' && el.selectedIndex == -1)) {
953            return null;
954    }
955
956    if (tag == 'select') {
957        var index = el.selectedIndex;
958        if (index < 0) {
959            return null;
960        }
961        var a = [], ops = el.options;
962        var one = (t == 'select-one');
963        var max = (one ? index+1 : ops.length);
964        for(var i=(one ? index : 0); i < max; i++) {
965            var op = ops[i];
966            if (op.selected) {
967                var v = op.value;
968                if (!v) { // extra pain for IE...
969                    v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
970                }
971                if (one) {
972                    return v;
973                }
974                a.push(v);
975            }
976        }
977        return a;
978    }
979    return $(el).val();
980};
981
982/**
983 * Clears the form data.  Takes the following actions on the form's input fields:
984 *  - input text fields will have their 'value' property set to the empty string
985 *  - select elements will have their 'selectedIndex' property set to -1
986 *  - checkbox and radio inputs will have their 'checked' property set to false
987 *  - inputs of type submit, button, reset, and hidden will *not* be effected
988 *  - button elements will *not* be effected
989 */
990$.fn.clearForm = function(includeHidden) {
991    return this.each(function() {
992        $('input,select,textarea', this).clearFields(includeHidden);
993    });
994};
995
996/**
997 * Clears the selected form elements.
998 */
999$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
1000    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
1001    return this.each(function() {
1002        var t = this.type, tag = this.tagName.toLowerCase();
1003        if (re.test(t) || tag == 'textarea') {
1004            this.value = '';
1005        }
1006        else if (t == 'checkbox' || t == 'radio') {
1007            this.checked = false;
1008        }
1009        else if (tag == 'select') {
1010            this.selectedIndex = -1;
1011        }
1012        else if (includeHidden) {
1013            // includeHidden can be the value true, or it can be a selector string
1014            // indicating a special test; for example:
1015            //  $('#myForm').clearForm('.special:hidden')
1016            // the above would clean hidden inputs that have the class of 'special'
1017            if ( (includeHidden === true && /hidden/.test(t)) ||
1018                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
1019                this.value = '';
1020        }
1021    });
1022};
1023
1024/**
1025 * Resets the form data.  Causes all form elements to be reset to their original value.
1026 */
1027$.fn.resetForm = function() {
1028    return this.each(function() {
1029        // guard against an input with the name of 'reset'
1030        // note that IE reports the reset function as an 'object'
1031        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
1032            this.reset();
1033        }
1034    });
1035};
1036
1037/**
1038 * Enables or disables any matching elements.
1039 */
1040$.fn.enable = function(b) {
1041    if (b === undefined) {
1042        b = true;
1043    }
1044    return this.each(function() {
1045        this.disabled = !b;
1046    });
1047};
1048
1049/**
1050 * Checks/unchecks any matching checkboxes or radio buttons and
1051 * selects/deselects and matching option elements.
1052 */
1053$.fn.selected = function(select) {
1054    if (select === undefined) {
1055        select = true;
1056    }
1057    return this.each(function() {
1058        var t = this.type;
1059        if (t == 'checkbox' || t == 'radio') {
1060            this.checked = select;
1061        }
1062        else if (this.tagName.toLowerCase() == 'option') {
1063            var $sel = $(this).parent('select');
1064            if (select && $sel[0] && $sel[0].type == 'select-one') {
1065                // deselect all other options
1066                $sel.find('option').selected(false);
1067            }
1068            this.selected = select;
1069        }
1070    });
1071};
1072
1073// expose debug var
1074$.fn.ajaxSubmit.debug = false;
1075
1076// helper fn for console logging
1077function log() {
1078    if (!$.fn.ajaxSubmit.debug) 
1079        return;
1080    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
1081    if (window.console && window.console.log) {
1082        window.console.log(msg);
1083    }
1084    else if (window.opera && window.opera.postError) {
1085        window.opera.postError(msg);
1086    }
1087}
1088
1089})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.