PageSourceSearch

https://data.gov.om/Js/jQuery/extensions/jquery.form.js

js data.gov.om collected 2026-09-24 23:01:39 UTC 39,396 bytes, 1,127 lines download raw bytes

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