]> git.mxchange.org Git - friendica-addons.git/blob - jappixmini/jappix/js/jquery.form.js
Merge pull request #520 from rabuzarus/20180206_-_membersince_frio_support
[friendica-addons.git] / jappixmini / jappix / js / jquery.form.js
1 /*!
2  * jQuery Form Plugin
3  * version: 2.49 (18-OCT-2010)
4  * @requires jQuery v1.3.2 or later
5  *
6  * Examples and documentation at: http://malsup.com/jquery/form/
7  * Dual licensed under the MIT and GPL licenses:
8  *   http://www.opensource.org/licenses/mit-license.php
9  *   http://www.gnu.org/licenses/gpl.html
10  */
11 ;(function($) {
12
13 /*
14         Usage Note:
15         -----------
16         Do not use both ajaxSubmit and ajaxForm on the same form.  These
17         functions are intended to be exclusive.  Use ajaxSubmit if you want
18         to bind your own submit handler to the form.  For example,
19
20         $(document).ready(function() {
21                 $('#myForm').bind('submit', function(e) {
22                         e.preventDefault(); // <-- important
23                         $(this).ajaxSubmit({
24                                 target: '#output'
25                         });
26                 });
27         });
28
29         Use ajaxForm when you want the plugin to manage all the event binding
30         for you.  For example,
31
32         $(document).ready(function() {
33                 $('#myForm').ajaxForm({
34                         target: '#output'
35                 });
36         });
37
38         When using ajaxForm, the ajaxSubmit function will be invoked for you
39         at the appropriate time.
40 */
41
42 /**
43  * ajaxSubmit() provides a mechanism for immediately submitting
44  * an HTML form using AJAX.
45  */
46 $.fn.ajaxSubmit = function(options) {
47         // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
48         if (!this.length) {
49                 log('ajaxSubmit: skipping submit process - no element selected');
50                 return this;
51         }
52
53         if (typeof options == 'function') {
54                 options = { success: options };
55         }
56
57         var url = $.trim(this.attr('action'));
58         if (url) {
59                 // clean url (don't include hash vaue)
60                 url = (url.match(/^([^#]+)/)||[])[1];
61         }
62         url = url || window.location.href || '';
63
64         options = $.extend(true, {
65                 url:  url,
66                 type: this.attr('method') || 'GET',
67                 iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
68         }, options);
69
70         // hook for manipulating the form data before it is extracted;
71         // convenient for use with rich editors like tinyMCE or FCKEditor
72         var veto = {};
73         this.trigger('form-pre-serialize', [this, options, veto]);
74         if (veto.veto) {
75                 log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
76                 return this;
77         }
78
79         // provide opportunity to alter form data before it is serialized
80         if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
81                 log('ajaxSubmit: submit aborted via beforeSerialize callback');
82                 return this;
83         }
84
85         var n,v,a = this.formToArray(options.semantic);
86         if (options.data) {
87                 options.extraData = options.data;
88                 for (n in options.data) {
89                         if(options.data[n] instanceof Array) {
90                                 for (var k in options.data[n]) {
91                                         a.push( { name: n, value: options.data[n][k] } );
92                                 }
93                         }
94                         else {
95                                 v = options.data[n];
96                                 v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
97                                 a.push( { name: n, value: v } );
98                         }
99                 }
100         }
101
102         // give pre-submit callback an opportunity to abort the submit
103         if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
104                 log('ajaxSubmit: submit aborted via beforeSubmit callback');
105                 return this;
106         }
107
108         // fire vetoable 'validate' event
109         this.trigger('form-submit-validate', [a, this, options, veto]);
110         if (veto.veto) {
111                 log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
112                 return this;
113         }
114
115         var q = $.param(a);
116
117         if (options.type.toUpperCase() == 'GET') {
118                 options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
119                 options.data = null;  // data is null for 'get'
120         }
121         else {
122                 options.data = q; // data is the query string for 'post'
123         }
124
125         var $form = this, callbacks = [];
126         if (options.resetForm) {
127                 callbacks.push(function() { $form.resetForm(); });
128         }
129         if (options.clearForm) {
130                 callbacks.push(function() { $form.clearForm(); });
131         }
132
133         // perform a load on the target only if dataType is not provided
134         if (!options.dataType && options.target) {
135                 var oldSuccess = options.success || function(){};
136                 callbacks.push(function(data) {
137                         var fn = options.replaceTarget ? 'replaceWith' : 'html';
138                         $(options.target)[fn](data).each(oldSuccess, arguments);
139                 });
140         }
141         else if (options.success) {
142                 callbacks.push(options.success);
143         }
144
145         options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
146                 var context = options.context || options;   // jQuery 1.4+ supports scope context 
147                 for (var i=0, max=callbacks.length; i < max; i++) {
148                         callbacks[i].apply(context, [data, status, xhr || $form, $form]);
149                 }
150         };
151
152         // are there files to upload?
153         var fileInputs = $('input:file', this).length > 0;
154         var mp = 'multipart/form-data';
155         var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
156
157         // options.iframe allows user to force iframe mode
158         // 06-NOV-09: now defaulting to iframe mode if file input is detected
159    if (options.iframe !== false && (fileInputs || options.iframe || multipart)) {
160            // hack to fix Safari hang (thanks to Tim Molendijk for this)
161            // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
162            if (options.closeKeepAlive) {
163                    $.get(options.closeKeepAlive, fileUpload);
164                 }
165            else {
166                    fileUpload();
167                 }
168    }
169    else {
170            $.ajax(options);
171    }
172
173         // fire 'notify' event
174         this.trigger('form-submit-notify', [this, options]);
175         return this;
176
177
178         // private function for handling file uploads (hat tip to YAHOO!)
179         function fileUpload() {
180                 var form = $form[0];
181
182                 if ($(':input[name=submit],:input[id=submit]', form).length) {
183                         // if there is an input with a name or id of 'submit' then we won't be
184                         // able to invoke the submit fn on the form (at least not x-browser)
185                         alert('Error: Form elements must not have name or id of "submit".');
186                         return;
187                 }
188                 
189                 var s = $.extend(true, {}, $.ajaxSettings, options);
190                 s.context = s.context || s;
191                 var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
192                 window[fn] = function() {
193                         var f = $io.data('form-plugin-onload');
194                         if (f) {
195                                 f();
196                                 window[fn] = undefined;
197                                 try { delete window[fn]; } catch(e){}
198                         }
199                 }
200                 var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" onload="window[\'_\'+this.id]()" />');
201                 var io = $io[0];
202
203                 $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
204
205                 var xhr = { // mock object
206                         aborted: 0,
207                         responseText: null,
208                         responseXML: null,
209                         status: 0,
210                         statusText: 'n/a',
211                         getAllResponseHeaders: function() {},
212                         getResponseHeader: function() {},
213                         setRequestHeader: function() {},
214                         abort: function() {
215                                 this.aborted = 1;
216                                 $io.attr('src', s.iframeSrc); // abort op in progress
217                         }
218                 };
219
220                 var g = s.global;
221                 // trigger ajax global events so that activity/block indicators work like normal
222                 if (g && ! $.active++) {
223                         $.event.trigger("ajaxStart");
224                 }
225                 if (g) {
226                         $.event.trigger("ajaxSend", [xhr, s]);
227                 }
228
229                 if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
230                         if (s.global) { 
231                                 $.active--;
232                         }
233                         return;
234                 }
235                 if (xhr.aborted) {
236                         return;
237                 }
238
239                 var cbInvoked = false;
240                 var timedOut = 0;
241
242                 // add submitting element to data if we know it
243                 var sub = form.clk;
244                 if (sub) {
245                         var n = sub.name;
246                         if (n && !sub.disabled) {
247                                 s.extraData = s.extraData || {};
248                                 s.extraData[n] = sub.value;
249                                 if (sub.type == "image") {
250                                         s.extraData[n+'.x'] = form.clk_x;
251                                         s.extraData[n+'.y'] = form.clk_y;
252                                 }
253                         }
254                 }
255
256                 // take a breath so that pending repaints get some cpu time before the upload starts
257                 function doSubmit() {
258                         // make sure form attrs are set
259                         var t = $form.attr('target'), a = $form.attr('action');
260
261                         // update form attrs in IE friendly way
262                         form.setAttribute('target',id);
263                         if (form.getAttribute('method') != 'POST') {
264                                 form.setAttribute('method', 'POST');
265                         }
266                         if (form.getAttribute('action') != s.url) {
267                                 form.setAttribute('action', s.url);
268                         }
269
270                         // ie borks in some cases when setting encoding
271                         if (! s.skipEncodingOverride) {
272                                 $form.attr({
273                                         encoding: 'multipart/form-data',
274                                         enctype:  'multipart/form-data'
275                                 });
276                         }
277
278                         // support timout
279                         if (s.timeout) {
280                                 setTimeout(function() { timedOut = true; cb(); }, s.timeout);
281                         }
282
283                         // add "extra" data to form if provided in options
284                         var extraInputs = [];
285                         try {
286                                 if (s.extraData) {
287                                         for (var n in s.extraData) {
288                                                 extraInputs.push(
289                                                         $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
290                                                                 .appendTo(form)[0]);
291                                         }
292                                 }
293
294                                 // add iframe to doc and submit the form
295                                 $io.appendTo('body');
296                                 $io.data('form-plugin-onload', cb);
297                                 form.submit();
298                         }
299                         finally {
300                                 // reset attrs and remove "extra" input elements
301                                 form.setAttribute('action',a);
302                                 if(t) {
303                                         form.setAttribute('target', t);
304                                 } else {
305                                         $form.removeAttr('target');
306                                 }
307                                 $(extraInputs).remove();
308                         }
309                 }
310
311                 if (s.forceSync) {
312                         doSubmit();
313                 }
314                 else {
315                         setTimeout(doSubmit, 10); // this lets dom updates render
316                 }
317         
318                 var data, doc, domCheckCount = 50;
319
320                 function cb() {
321                         if (cbInvoked) {
322                                 return;
323                         }
324
325                         $io.removeData('form-plugin-onload');
326                         
327                         var ok = true;
328                         try {
329                                 if (timedOut) {
330                                         throw 'timeout';
331                                 }
332                                 // extract the server response from the iframe
333                                 doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
334                                 
335                                 var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
336                                 log('isXml='+isXml);
337                                 if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
338                                         if (--domCheckCount) {
339                                                 // in some browsers (Opera) the iframe DOM is not always traversable when
340                                                 // the onload callback fires, so we loop a bit to accommodate
341                                                 log('requeing onLoad callback, DOM not available');
342                                                 setTimeout(cb, 250);
343                                                 return;
344                                         }
345                                         // let this fall through because server response could be an empty document
346                                         //log('Could not access iframe DOM after mutiple tries.');
347                                         //throw 'DOMException: not available';
348                                 }
349
350                                 //log('response detected');
351                                 cbInvoked = true;
352                                 xhr.responseText = doc.documentElement ? doc.documentElement.innerHTML : null; 
353                                 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
354                                 xhr.getResponseHeader = function(header){
355                                         var headers = {'content-type': s.dataType};
356                                         return headers[header];
357                                 };
358
359                                 var scr = /(json|script)/.test(s.dataType);
360                                 if (scr || s.textarea) {
361                                         // see if user embedded response in textarea
362                                         var ta = doc.getElementsByTagName('textarea')[0];
363                                         if (ta) {
364                                                 xhr.responseText = ta.value;
365                                         }
366                                         else if (scr) {
367                                                 // account for browsers injecting pre around json response
368                                                 var pre = doc.getElementsByTagName('pre')[0];
369                                                 var b = doc.getElementsByTagName('body')[0];
370                                                 if (pre) {
371                                                         xhr.responseText = pre.innerHTML;
372                                                 }
373                                                 else if (b) {
374                                                         xhr.responseText = b.innerHTML;
375                                                 }
376                                         }                         
377                                 }
378                                 else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
379                                         xhr.responseXML = toXml(xhr.responseText);
380                                 }
381                                 data = $.httpData(xhr, s.dataType);
382                         }
383                         catch(e){
384                                 log('error caught:',e);
385                                 ok = false;
386                                 xhr.error = e;
387                                 $.handleError(s, xhr, 'error', e);
388                         }
389
390                         // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
391                         if (ok) {
392                                 s.success.call(s.context, data, 'success', xhr);
393                                 if (g) {
394                                         $.event.trigger("ajaxSuccess", [xhr, s]);
395                                 }
396                         }
397                         if (g) {
398                                 $.event.trigger("ajaxComplete", [xhr, s]);
399                         }
400                         if (g && ! --$.active) {
401                                 $.event.trigger("ajaxStop");
402                         }
403                         if (s.complete) {
404                                 s.complete.call(s.context, xhr, ok ? 'success' : 'error');
405                         }
406
407                         // clean up
408                         setTimeout(function() {
409                                 $io.removeData('form-plugin-onload');
410                                 $io.remove();
411                                 xhr.responseXML = null;
412                         }, 100);
413                 }
414
415                 function toXml(s, doc) {
416                         if (window.ActiveXObject) {
417                                 doc = new ActiveXObject('Microsoft.XMLDOM');
418                                 doc.async = 'false';
419                                 doc.loadXML(s);
420                         }
421                         else {
422                                 doc = (new DOMParser()).parseFromString(s, 'text/xml');
423                         }
424                         return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
425                 }
426         }
427 };
428
429 /**
430  * ajaxForm() provides a mechanism for fully automating form submission.
431  *
432  * The advantages of using this method instead of ajaxSubmit() are:
433  *
434  * 1: This method will include coordinates for <input type="image" /> elements (if the element
435  *      is used to submit the form).
436  * 2. This method will include the submit element's name/value data (for the element that was
437  *      used to submit the form).
438  * 3. This method binds the submit() method to the form for you.
439  *
440  * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
441  * passes the options argument along after properly binding events for submit elements and
442  * the form itself.
443  */
444 $.fn.ajaxForm = function(options) {
445         // in jQuery 1.3+ we can fix mistakes with the ready state
446         if (this.length === 0) {
447                 var o = { s: this.selector, c: this.context };
448                 if (!$.isReady && o.s) {
449                         log('DOM not ready, queuing ajaxForm');
450                         $(function() {
451                                 $(o.s,o.c).ajaxForm(options);
452                         });
453                         return this;
454                 }
455                 // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
456                 log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
457                 return this;
458         }
459         
460         return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
461                 if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
462                         e.preventDefault();
463                         $(this).ajaxSubmit(options);
464                 }
465         }).bind('click.form-plugin', function(e) {
466                 var target = e.target;
467                 var $el = $(target);
468                 if (!($el.is(":submit,input:image"))) {
469                         // is this a child element of the submit el?  (ex: a span within a button)
470                         var t = $el.closest(':submit');
471                         if (t.length == 0) {
472                                 return;
473                         }
474                         target = t[0];
475                 }
476                 var form = this;
477                 form.clk = target;
478                 if (target.type == 'image') {
479                         if (e.offsetX != undefined) {
480                                 form.clk_x = e.offsetX;
481                                 form.clk_y = e.offsetY;
482                         } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
483                                 var offset = $el.offset();
484                                 form.clk_x = e.pageX - offset.left;
485                                 form.clk_y = e.pageY - offset.top;
486                         } else {
487                                 form.clk_x = e.pageX - target.offsetLeft;
488                                 form.clk_y = e.pageY - target.offsetTop;
489                         }
490                 }
491                 // clear form vars
492                 setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
493         });
494 };
495
496 // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
497 $.fn.ajaxFormUnbind = function() {
498         return this.unbind('submit.form-plugin click.form-plugin');
499 };
500
501 /**
502  * formToArray() gathers form element data into an array of objects that can
503  * be passed to any of the following ajax functions: $.get, $.post, or load.
504  * Each object in the array has both a 'name' and 'value' property.  An example of
505  * an array for a simple login form might be:
506  *
507  * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
508  *
509  * It is this array that is passed to pre-submit callback functions provided to the
510  * ajaxSubmit() and ajaxForm() methods.
511  */
512 $.fn.formToArray = function(semantic) {
513         var a = [];
514         if (this.length === 0) {
515                 return a;
516         }
517
518         var form = this[0];
519         var els = semantic ? form.getElementsByTagName('*') : form.elements;
520         if (!els) {
521                 return a;
522         }
523         
524         var i,j,n,v,el,max,jmax;
525         for(i=0, max=els.length; i < max; i++) {
526                 el = els[i];
527                 n = el.name;
528                 if (!n) {
529                         continue;
530                 }
531
532                 if (semantic && form.clk && el.type == "image") {
533                         // handle image inputs on the fly when semantic == true
534                         if(!el.disabled && form.clk == el) {
535                                 a.push({name: n, value: $(el).val()});
536                                 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
537                         }
538                         continue;
539                 }
540
541                 v = $.fieldValue(el, true);
542                 if (v && v.constructor == Array) {
543                         for(j=0, jmax=v.length; j < jmax; j++) {
544                                 a.push({name: n, value: v[j]});
545                         }
546                 }
547                 else if (v !== null && typeof v != 'undefined') {
548                         a.push({name: n, value: v});
549                 }
550         }
551
552         if (!semantic && form.clk) {
553                 // input type=='image' are not found in elements array! handle it here
554                 var $input = $(form.clk), input = $input[0];
555                 n = input.name;
556                 if (n && !input.disabled && input.type == 'image') {
557                         a.push({name: n, value: $input.val()});
558                         a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
559                 }
560         }
561         return a;
562 };
563
564 /**
565  * Serializes form data into a 'submittable' string. This method will return a string
566  * in the format: name1=value1&amp;name2=value2
567  */
568 $.fn.formSerialize = function(semantic) {
569         //hand off to jQuery.param for proper encoding
570         return $.param(this.formToArray(semantic));
571 };
572
573 /**
574  * Serializes all field elements in the jQuery object into a query string.
575  * This method will return a string in the format: name1=value1&amp;name2=value2
576  */
577 $.fn.fieldSerialize = function(successful) {
578         var a = [];
579         this.each(function() {
580                 var n = this.name;
581                 if (!n) {
582                         return;
583                 }
584                 var v = $.fieldValue(this, successful);
585                 if (v && v.constructor == Array) {
586                         for (var i=0,max=v.length; i < max; i++) {
587                                 a.push({name: n, value: v[i]});
588                         }
589                 }
590                 else if (v !== null && typeof v != 'undefined') {
591                         a.push({name: this.name, value: v});
592                 }
593         });
594         //hand off to jQuery.param for proper encoding
595         return $.param(a);
596 };
597
598 /**
599  * Returns the value(s) of the element in the matched set.  For example, consider the following form:
600  *
601  *  <form><fieldset>
602  *        <input name="A" type="text" />
603  *        <input name="A" type="text" />
604  *        <input name="B" type="checkbox" value="B1" />
605  *        <input name="B" type="checkbox" value="B2"/>
606  *        <input name="C" type="radio" value="C1" />
607  *        <input name="C" type="radio" value="C2" />
608  *  </fieldset></form>
609  *
610  *  var v = $(':text').fieldValue();
611  *  // if no values are entered into the text inputs
612  *  v == ['','']
613  *  // if values entered into the text inputs are 'foo' and 'bar'
614  *  v == ['foo','bar']
615  *
616  *  var v = $(':checkbox').fieldValue();
617  *  // if neither checkbox is checked
618  *  v === undefined
619  *  // if both checkboxes are checked
620  *  v == ['B1', 'B2']
621  *
622  *  var v = $(':radio').fieldValue();
623  *  // if neither radio is checked
624  *  v === undefined
625  *  // if first radio is checked
626  *  v == ['C1']
627  *
628  * The successful argument controls whether or not the field element must be 'successful'
629  * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
630  * The default value of the successful argument is true.  If this value is false the value(s)
631  * for each element is returned.
632  *
633  * Note: This method *always* returns an array.  If no valid value can be determined the
634  *         array will be empty, otherwise it will contain one or more values.
635  */
636 $.fn.fieldValue = function(successful) {
637         for (var val=[], i=0, max=this.length; i < max; i++) {
638                 var el = this[i];
639                 var v = $.fieldValue(el, successful);
640                 if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
641                         continue;
642                 }
643                 v.constructor == Array ? $.merge(val, v) : val.push(v);
644         }
645         return val;
646 };
647
648 /**
649  * Returns the value of the field element.
650  */
651 $.fieldValue = function(el, successful) {
652         var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
653         if (successful === undefined) {
654                 successful = true;
655         }
656
657         if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
658                 (t == 'checkbox' || t == 'radio') && !el.checked ||
659                 (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
660                 tag == 'select' && el.selectedIndex == -1)) {
661                         return null;
662         }
663
664         if (tag == 'select') {
665                 var index = el.selectedIndex;
666                 if (index < 0) {
667                         return null;
668                 }
669                 var a = [], ops = el.options;
670                 var one = (t == 'select-one');
671                 var max = (one ? index+1 : ops.length);
672                 for(var i=(one ? index : 0); i < max; i++) {
673                         var op = ops[i];
674                         if (op.selected) {
675                                 var v = op.value;
676                                 if (!v) { // extra pain for IE...
677                                         v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
678                                 }
679                                 if (one) {
680                                         return v;
681                                 }
682                                 a.push(v);
683                         }
684                 }
685                 return a;
686         }
687         return $(el).val();
688 };
689
690 /**
691  * Clears the form data.  Takes the following actions on the form's input fields:
692  *  - input text fields will have their 'value' property set to the empty string
693  *  - select elements will have their 'selectedIndex' property set to -1
694  *  - checkbox and radio inputs will have their 'checked' property set to false
695  *  - inputs of type submit, button, reset, and hidden will *not* be effected
696  *  - button elements will *not* be effected
697  */
698 $.fn.clearForm = function() {
699         return this.each(function() {
700                 $('input,select,textarea', this).clearFields();
701         });
702 };
703
704 /**
705  * Clears the selected form elements.
706  */
707 $.fn.clearFields = $.fn.clearInputs = function() {
708         return this.each(function() {
709                 var t = this.type, tag = this.tagName.toLowerCase();
710                 if (t == 'text' || t == 'password' || tag == 'textarea') {
711                         this.value = '';
712                 }
713                 else if (t == 'checkbox' || t == 'radio') {
714                         this.checked = false;
715                 }
716                 else if (tag == 'select') {
717                         this.selectedIndex = -1;
718                 }
719         });
720 };
721
722 /**
723  * Resets the form data.  Causes all form elements to be reset to their original value.
724  */
725 $.fn.resetForm = function() {
726         return this.each(function() {
727                 // guard against an input with the name of 'reset'
728                 // note that IE reports the reset function as an 'object'
729                 if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
730                         this.reset();
731                 }
732         });
733 };
734
735 /**
736  * Enables or disables any matching elements.
737  */
738 $.fn.enable = function(b) {
739         if (b === undefined) {
740                 b = true;
741         }
742         return this.each(function() {
743                 this.disabled = !b;
744         });
745 };
746
747 /**
748  * Checks/unchecks any matching checkboxes or radio buttons and
749  * selects/deselects and matching option elements.
750  */
751 $.fn.selected = function(select) {
752         if (select === undefined) {
753                 select = true;
754         }
755         return this.each(function() {
756                 var t = this.type;
757                 if (t == 'checkbox' || t == 'radio') {
758                         this.checked = select;
759                 }
760                 else if (this.tagName.toLowerCase() == 'option') {
761                         var $sel = $(this).parent('select');
762                         if (select && $sel[0] && $sel[0].type == 'select-one') {
763                                 // deselect all other options
764                                 $sel.find('option').selected(false);
765                         }
766                         this.selected = select;
767                 }
768         });
769 };
770
771 // helper fn for console logging
772 // set $.fn.ajaxSubmit.debug to true to enable debug logging
773 function log() {
774         if ($.fn.ajaxSubmit.debug) {
775                 var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
776                 if (window.console && window.console.log) {
777                         window.console.log(msg);
778                 }
779                 else if (window.opera && window.opera.postError) {
780                         window.opera.postError(msg);
781                 }
782         }
783 };
784
785 })(jQuery);