PageSourceSearch

https://www.marianomosquera.com/granbahia/js/jquery.form.js

js marianomosquera.com collected 2026-09-27 02:46:32 UTC 41,095 bytes, 1,174 lines download raw bytes

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