Merge lp:~unifield-team/unifield-web/us-1088 into lp:unifield-web
- us-1088
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 4830 |
Proposed branch: | lp:~unifield-team/unifield-web/us-1088 |
Merge into: | lp:unifield-web |
Diff against target: |
1763 lines (+1071/-661) 1 file modified
openobject/static/javascript/jQuery/jquery.form.js (+1071/-661) |
To merge this branch: | bzr merge lp:~unifield-team/unifield-web/us-1088 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Dev Team | Pending | ||
Review via email: mp+314823@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'openobject/static/javascript/jQuery/jquery.form.js' |
2 | --- openobject/static/javascript/jQuery/jquery.form.js 2016-04-20 14:18:32 +0000 |
3 | +++ openobject/static/javascript/jQuery/jquery.form.js 2017-01-16 10:17:30 +0000 |
4 | @@ -1,688 +1,1098 @@ |
5 | /*! |
6 | * jQuery Form Plugin |
7 | - * version: 2.43 (12-MAR-2010) |
8 | + * version: 3.14 (30-JUL-2012) |
9 | * @requires jQuery v1.3.2 or later |
10 | * |
11 | * Examples and documentation at: http://malsup.com/jquery/form/ |
12 | + * Project repository: https://github.com/malsup/form |
13 | * Dual licensed under the MIT and GPL licenses: |
14 | - * http://www.opensource.org/licenses/mit-license.php |
15 | - * http://www.gnu.org/licenses/gpl.html |
16 | - */ |
17 | -(function($) { |
18 | - |
19 | - /* |
20 | - Usage Note: |
21 | - ----------- |
22 | - Do not use both ajaxSubmit and ajaxForm on the same form. These |
23 | - functions are intended to be exclusive. Use ajaxSubmit if you want |
24 | - to bind your own submit handler to the form. For example, |
25 | - |
26 | - $(document).ready(function() { |
27 | - $('#myForm').bind('submit', function() { |
28 | - $(this).ajaxSubmit({ |
29 | - target: '#output' |
30 | - }); |
31 | - return false; // <-- important! |
32 | - }); |
33 | - }); |
34 | - |
35 | - Use ajaxForm when you want the plugin to manage all the event binding |
36 | - for you. For example, |
37 | - |
38 | - $(document).ready(function() { |
39 | - $('#myForm').ajaxForm({ |
40 | - target: '#output' |
41 | - }); |
42 | - }); |
43 | - |
44 | - When using ajaxForm, the ajaxSubmit function will be invoked for you |
45 | - at the appropriate time. |
46 | - */ |
47 | - |
48 | - /** |
49 | - * ajaxSubmit() provides a mechanism for immediately submitting |
50 | - * an HTML form using AJAX. |
51 | - */ |
52 | - $.fn.ajaxSubmit = function(options) { |
53 | - // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) |
54 | - if (!this.length) { |
55 | - log('ajaxSubmit: skipping submit process - no element selected'); |
56 | - return this; |
57 | - } |
58 | - |
59 | - if (typeof options == 'function') |
60 | - options = { success: options }; |
61 | - |
62 | - var url = $.trim(this.attr('action')); |
63 | - if (url) { |
64 | - // clean url (don't include hash vaue) |
65 | - url = (url.match(/^([^#]+)/) || [])[1]; |
66 | - } |
67 | - url = url || window.location.href || ''; |
68 | - |
69 | - options = $.extend({ |
70 | - url: url, |
71 | - type: this.attr('method') || 'GET', |
72 | - iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' |
73 | - }, options || {}); |
74 | - |
75 | - // hook for manipulating the form data before it is extracted; |
76 | - // convenient for use with rich editors like tinyMCE or FCKEditor |
77 | - var veto = {}; |
78 | - this.trigger('form-pre-serialize', [this, options, veto]); |
79 | - if (veto.veto) { |
80 | - log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); |
81 | - return this; |
82 | - } |
83 | - |
84 | - // provide opportunity to alter form data before it is serialized |
85 | - if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { |
86 | - log('ajaxSubmit: submit aborted via beforeSerialize callback'); |
87 | - return this; |
88 | - } |
89 | - |
90 | - var a = this.formToArray(options.semantic); |
91 | - if (options.data) { |
92 | - options.extraData = options.data; |
93 | - for (var n in options.data) { |
94 | - if (options.data[n] instanceof Array) { |
95 | - for (var k in options.data[n]) |
96 | - a.push({ name: n, value: options.data[n][k] }); |
97 | + * http://malsup.github.com/mit-license.txt |
98 | + * http://malsup.github.com/gpl-license-v2.txt |
99 | + */ |
100 | +/*global ActiveXObject alert */ |
101 | +;(function($) { |
102 | +"use strict"; |
103 | + |
104 | +/* |
105 | + Usage Note: |
106 | + ----------- |
107 | + Do not use both ajaxSubmit and ajaxForm on the same form. These |
108 | + functions are mutually exclusive. Use ajaxSubmit if you want |
109 | + to bind your own submit handler to the form. For example, |
110 | + |
111 | + $(document).ready(function() { |
112 | + $('#myForm').on('submit', function(e) { |
113 | + e.preventDefault(); // <-- important |
114 | + $(this).ajaxSubmit({ |
115 | + target: '#output' |
116 | + }); |
117 | + }); |
118 | + }); |
119 | + |
120 | + Use ajaxForm when you want the plugin to manage all the event binding |
121 | + for you. For example, |
122 | + |
123 | + $(document).ready(function() { |
124 | + $('#myForm').ajaxForm({ |
125 | + target: '#output' |
126 | + }); |
127 | + }); |
128 | + |
129 | + You can also use ajaxForm with delegation (requires jQuery v1.7+), so the |
130 | + form does not have to exist when you invoke ajaxForm: |
131 | + |
132 | + $('#myForm').ajaxForm({ |
133 | + delegation: true, |
134 | + target: '#output' |
135 | + }); |
136 | + |
137 | + When using ajaxForm, the ajaxSubmit function will be invoked for you |
138 | + at the appropriate time. |
139 | +*/ |
140 | + |
141 | +/** |
142 | + * Feature detection |
143 | + */ |
144 | +var feature = {}; |
145 | +feature.fileapi = $("<input type='file'/>").get(0).files !== undefined; |
146 | +feature.formdata = window.FormData !== undefined; |
147 | + |
148 | +/** |
149 | + * ajaxSubmit() provides a mechanism for immediately submitting |
150 | + * an HTML form using AJAX. |
151 | + */ |
152 | +$.fn.ajaxSubmit = function(options) { |
153 | + /*jshint scripturl:true */ |
154 | + |
155 | + // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) |
156 | + if (!this.length) { |
157 | + log('ajaxSubmit: skipping submit process - no element selected'); |
158 | + return this; |
159 | + } |
160 | + |
161 | + var method, action, url, $form = this; |
162 | + |
163 | + if (typeof options == 'function') { |
164 | + options = { success: options }; |
165 | + } |
166 | + |
167 | + method = this.attr('method'); |
168 | + action = this.attr('action'); |
169 | + url = (typeof action === 'string') ? $.trim(action) : ''; |
170 | + url = url || window.location.href || ''; |
171 | + if (url) { |
172 | + // clean url (don't include hash vaue) |
173 | + url = (url.match(/^([^#]+)/)||[])[1]; |
174 | + } |
175 | + |
176 | + options = $.extend(true, { |
177 | + url: url, |
178 | + success: $.ajaxSettings.success, |
179 | + type: method || 'GET', |
180 | + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' |
181 | + }, options); |
182 | + |
183 | + // hook for manipulating the form data before it is extracted; |
184 | + // convenient for use with rich editors like tinyMCE or FCKEditor |
185 | + var veto = {}; |
186 | + this.trigger('form-pre-serialize', [this, options, veto]); |
187 | + if (veto.veto) { |
188 | + log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); |
189 | + return this; |
190 | + } |
191 | + |
192 | + // provide opportunity to alter form data before it is serialized |
193 | + if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { |
194 | + log('ajaxSubmit: submit aborted via beforeSerialize callback'); |
195 | + return this; |
196 | + } |
197 | + |
198 | + var traditional = options.traditional; |
199 | + if ( traditional === undefined ) { |
200 | + traditional = $.ajaxSettings.traditional; |
201 | + } |
202 | + |
203 | + var elements = []; |
204 | + var qx, a = this.formToArray(options.semantic, elements); |
205 | + if (options.data) { |
206 | + options.extraData = options.data; |
207 | + qx = $.param(options.data, traditional); |
208 | + } |
209 | + |
210 | + // give pre-submit callback an opportunity to abort the submit |
211 | + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { |
212 | + log('ajaxSubmit: submit aborted via beforeSubmit callback'); |
213 | + return this; |
214 | + } |
215 | + |
216 | + // fire vetoable 'validate' event |
217 | + this.trigger('form-submit-validate', [a, this, options, veto]); |
218 | + if (veto.veto) { |
219 | + log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); |
220 | + return this; |
221 | + } |
222 | + |
223 | + var q = $.param(a, traditional); |
224 | + if (qx) { |
225 | + q = ( q ? (q + '&' + qx) : qx ); |
226 | + } |
227 | + if (options.type.toUpperCase() == 'GET') { |
228 | + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; |
229 | + options.data = null; // data is null for 'get' |
230 | + } |
231 | + else { |
232 | + options.data = q; // data is the query string for 'post' |
233 | + } |
234 | + |
235 | + var callbacks = []; |
236 | + if (options.resetForm) { |
237 | + callbacks.push(function() { $form.resetForm(); }); |
238 | + } |
239 | + if (options.clearForm) { |
240 | + callbacks.push(function() { $form.clearForm(options.includeHidden); }); |
241 | + } |
242 | + |
243 | + // perform a load on the target only if dataType is not provided |
244 | + if (!options.dataType && options.target) { |
245 | + var oldSuccess = options.success || function(){}; |
246 | + callbacks.push(function(data) { |
247 | + var fn = options.replaceTarget ? 'replaceWith' : 'html'; |
248 | + $(options.target)[fn](data).each(oldSuccess, arguments); |
249 | + }); |
250 | + } |
251 | + else if (options.success) { |
252 | + callbacks.push(options.success); |
253 | + } |
254 | + |
255 | + options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg |
256 | + var context = options.context || this ; // jQuery 1.4+ supports scope context |
257 | + for (var i=0, max=callbacks.length; i < max; i++) { |
258 | + callbacks[i].apply(context, [data, status, xhr || $form, $form]); |
259 | + } |
260 | + }; |
261 | + |
262 | + // are there files to upload? |
263 | + var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113) |
264 | + var hasFileInputs = fileInputs.length > 0; |
265 | + var mp = 'multipart/form-data'; |
266 | + var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); |
267 | + |
268 | + // extra check to disable usage of iframe hack under some conditions |
269 | + // for OpenERP web client to behave correctly |
270 | + var skipIframeHackForOpenERP = true; |
271 | + if (hasFileInputs) { |
272 | + // only allow usage of iframe hack only for form containing real <input type="file"/> |
273 | + // (i.e this means containing fields.binary() in OpenERP terms.) |
274 | + skipIframeHackForOpenERP = false; |
275 | + } |
276 | + |
277 | + var fileAPI = feature.fileapi && feature.formdata; |
278 | + log("fileAPI :" + fileAPI); |
279 | + var shouldUseFrame = (hasFileInputs || multipart) && !skipIframeHackForOpenERP && !fileAPI; |
280 | + |
281 | + // options.iframe allows user to force iframe mode |
282 | + // 06-NOV-09: now defaulting to iframe mode if file input is detected |
283 | + if (options.iframe !== false && (options.iframe || shouldUseFrame)) { |
284 | + // hack to fix Safari hang (thanks to Tim Molendijk for this) |
285 | + // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d |
286 | + if (options.closeKeepAlive) { |
287 | + $.get(options.closeKeepAlive, function() { |
288 | + fileUploadIframe(a); |
289 | + }); |
290 | + } |
291 | + else { |
292 | + fileUploadIframe(a); |
293 | + } |
294 | + } |
295 | + else if ((hasFileInputs || multipart) && fileAPI) { |
296 | + fileUploadXhr(a); |
297 | + } |
298 | + else { |
299 | + $.ajax(options); |
300 | + } |
301 | + |
302 | + // clear element array |
303 | + for (var k=0; k < elements.length; k++) |
304 | + elements[k] = null; |
305 | + |
306 | + // fire 'notify' event |
307 | + this.trigger('form-submit-notify', [this, options]); |
308 | + return this; |
309 | + |
310 | + // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz) |
311 | + function fileUploadXhr(a) { |
312 | + var formdata = new FormData(); |
313 | + |
314 | + for (var i=0; i < a.length; i++) { |
315 | + formdata.append(a[i].name, a[i].value); |
316 | + } |
317 | + |
318 | + if (options.extraData) { |
319 | + for (var p in options.extraData) |
320 | + if (options.extraData.hasOwnProperty(p)) |
321 | + formdata.append(p, options.extraData[p]); |
322 | + } |
323 | + |
324 | + options.data = null; |
325 | + |
326 | + var s = $.extend(true, {}, $.ajaxSettings, options, { |
327 | + contentType: false, |
328 | + processData: false, |
329 | + cache: false, |
330 | + type: 'POST' |
331 | + }); |
332 | + |
333 | + if (options.uploadProgress) { |
334 | + // workaround because jqXHR does not expose upload property |
335 | + s.xhr = function() { |
336 | + var xhr = jQuery.ajaxSettings.xhr(); |
337 | + if (xhr.upload) { |
338 | + xhr.upload.onprogress = function(event) { |
339 | + var percent = 0; |
340 | + var position = event.loaded || event.position; /*event.position is deprecated*/ |
341 | + var total = event.total; |
342 | + if (event.lengthComputable) { |
343 | + percent = Math.ceil(position / total * 100); |
344 | + } |
345 | + options.uploadProgress(event, position, total, percent); |
346 | + }; |
347 | } |
348 | - else |
349 | - a.push({ name: n, value: options.data[n] }); |
350 | - } |
351 | - } |
352 | - |
353 | - // give pre-submit callback an opportunity to abort the submit |
354 | - if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { |
355 | - log('ajaxSubmit: submit aborted via beforeSubmit callback'); |
356 | - return this; |
357 | - } |
358 | - |
359 | - // fire vetoable 'validate' event |
360 | - this.trigger('form-submit-validate', [a, this, options, veto]); |
361 | - if (veto.veto) { |
362 | - log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); |
363 | - return this; |
364 | - } |
365 | - |
366 | - var q = $.param(a); |
367 | - |
368 | - if (options.type.toUpperCase() == 'GET') { |
369 | - options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; |
370 | - options.data = null; // data is null for 'get' |
371 | - } |
372 | - else |
373 | - options.data = q; // data is the query string for 'post' |
374 | - |
375 | - var $form = this, callbacks = []; |
376 | - if (options.resetForm) callbacks.push(function() { |
377 | - $form.resetForm(); |
378 | - }); |
379 | - if (options.clearForm) callbacks.push(function() { |
380 | - $form.clearForm(); |
381 | - }); |
382 | - |
383 | - // perform a load on the target only if dataType is not provided |
384 | - if (!options.dataType && options.target) { |
385 | - var oldSuccess = options.success || function() { |
386 | + return xhr; |
387 | }; |
388 | - callbacks.push(function(data) { |
389 | - var fn = options.replaceTarget ? 'replaceWith' : 'html'; |
390 | - $(options.target)[fn](data).each(oldSuccess, arguments); |
391 | - }); |
392 | } |
393 | - else if (options.success) |
394 | - callbacks.push(options.success); |
395 | |
396 | - options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg |
397 | - for (var i = 0, max = callbacks.length; i < max; i++) |
398 | - callbacks[i].apply(options, [data, status, xhr || $form, $form]); |
399 | + s.data = null; |
400 | + var beforeSend = s.beforeSend; |
401 | + s.beforeSend = function(xhr, o) { |
402 | + o.data = formdata; |
403 | + if(beforeSend) |
404 | + beforeSend.call(this, xhr, o); |
405 | }; |
406 | - |
407 | - // are there files to upload? |
408 | - var files = $('input:file', this).fieldValue(); |
409 | - var found = false; |
410 | - for (var j = 0; j < files.length; j++) |
411 | - if (files[j]) |
412 | - found = true; |
413 | - |
414 | - var multipart = false; |
415 | - // var mp = 'multipart/form-data'; |
416 | - // multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); |
417 | - |
418 | - // options.iframe allows user to force iframe mode |
419 | - // 06-NOV-09: now defaulting to iframe mode if file input is detected |
420 | - if ((files.length && options.iframe !== false) || options.iframe || found || multipart) { |
421 | - // hack to fix Safari hang (thanks to Tim Molendijk for this) |
422 | - // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d |
423 | - if (options.closeKeepAlive) |
424 | - $.get(options.closeKeepAlive, fileUpload); |
425 | + $.ajax(s); |
426 | + } |
427 | + |
428 | + // private function for handling file uploads (hat tip to YAHOO!) |
429 | + function fileUploadIframe(a) { |
430 | + var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; |
431 | + var useProp = !!$.fn.prop; |
432 | + |
433 | + if ($(':input[name=submit],:input[id=submit]', form).length) { |
434 | + // if there is an input with a name or id of 'submit' then we won't be |
435 | + // able to invoke the submit fn on the form (at least not x-browser) |
436 | + alert('Error: Form elements must not have name or id of "submit".'); |
437 | + return; |
438 | + } |
439 | + |
440 | + if (a) { |
441 | + // ensure that every serialized input is still enabled |
442 | + for (i=0; i < elements.length; i++) { |
443 | + el = $(elements[i]); |
444 | + if ( useProp ) |
445 | + el.prop('disabled', false); |
446 | + else |
447 | + el.removeAttr('disabled'); |
448 | + } |
449 | + } |
450 | + |
451 | + s = $.extend(true, {}, $.ajaxSettings, options); |
452 | + s.context = s.context || s; |
453 | + id = 'jqFormIO' + (new Date().getTime()); |
454 | + if (s.iframeTarget) { |
455 | + $io = $(s.iframeTarget); |
456 | + n = $io.attr('name'); |
457 | + if (!n) |
458 | + $io.attr('name', id); |
459 | else |
460 | - fileUpload(); |
461 | + id = n; |
462 | } |
463 | - else |
464 | - $.ajax(options); |
465 | - |
466 | - // fire 'notify' event |
467 | - this.trigger('form-submit-notify', [this, options]); |
468 | - return this; |
469 | - |
470 | - |
471 | - // private function for handling file uploads (hat tip to YAHOO!) |
472 | - function fileUpload() { |
473 | - var form = $form[0]; |
474 | - |
475 | - if ($(':input[name=submit]', form).length) { |
476 | - error_display('Error: Form elements must not be named "submit".'); |
477 | - return; |
478 | - } |
479 | - |
480 | - var opts = $.extend({}, $.ajaxSettings, options); |
481 | - var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts); |
482 | - |
483 | - var id = 'jqFormIO' + (new Date().getTime()); |
484 | - var $io = $('<iframe id="' + id + '" name="' + id + '" src="' + opts.iframeSrc + '" onload="(jQuery(this).data(\'form-plugin-onload\'))()" />'); |
485 | - var io = $io[0]; |
486 | - |
487 | + else { |
488 | + $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />'); |
489 | $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); |
490 | - |
491 | - var xhr = { // mock object |
492 | - aborted: 0, |
493 | - responseText: null, |
494 | - responseXML: null, |
495 | - status: 0, |
496 | - statusText: 'n/a', |
497 | - getAllResponseHeaders: function() { |
498 | - }, |
499 | - getResponseHeader: function() { |
500 | - }, |
501 | - setRequestHeader: function() { |
502 | - }, |
503 | - abort: function() { |
504 | - this.aborted = 1; |
505 | - $io.attr('src', opts.iframeSrc); // abort op in progress |
506 | - } |
507 | - }; |
508 | - |
509 | - var g = opts.global; |
510 | - // trigger ajax global events so that activity/block indicators work like normal |
511 | - if (g && ! $.active++) $.event.trigger("ajaxStart"); |
512 | - if (g) $.event.trigger("ajaxSend", [xhr, opts]); |
513 | - |
514 | - if (s.beforeSend && s.beforeSend(xhr, s) === false) { |
515 | - s.global && $.active--; |
516 | - return; |
517 | - } |
518 | - if (xhr.aborted) |
519 | - return; |
520 | - |
521 | - var cbInvoked = false; |
522 | - var timedOut = 0; |
523 | - |
524 | - // add submitting element to data if we know it |
525 | - var sub = form.clk; |
526 | - if (sub) { |
527 | - var n = sub.name; |
528 | - if (n && !sub.disabled) { |
529 | - opts.extraData = opts.extraData || {}; |
530 | - opts.extraData[n] = sub.value; |
531 | - if (sub.type == "image") { |
532 | - opts.extraData[n + '.x'] = form.clk_x; |
533 | - opts.extraData[n + '.y'] = form.clk_y; |
534 | + } |
535 | + io = $io[0]; |
536 | + |
537 | + |
538 | + xhr = { // mock object |
539 | + aborted: 0, |
540 | + responseText: null, |
541 | + responseXML: null, |
542 | + status: 0, |
543 | + statusText: 'n/a', |
544 | + getAllResponseHeaders: function() {}, |
545 | + getResponseHeader: function() {}, |
546 | + setRequestHeader: function() {}, |
547 | + abort: function(status) { |
548 | + var e = (status === 'timeout' ? 'timeout' : 'aborted'); |
549 | + log('aborting upload... ' + e); |
550 | + this.aborted = 1; |
551 | + // #214 |
552 | + if (io.contentWindow.document.execCommand) { |
553 | + try { // #214 |
554 | + io.contentWindow.document.execCommand('Stop'); |
555 | + } catch(ignore) {} |
556 | + } |
557 | + $io.attr('src', s.iframeSrc); // abort op in progress |
558 | + xhr.error = e; |
559 | + if (s.error) |
560 | + s.error.call(s.context, xhr, e, status); |
561 | + if (g) |
562 | + $.event.trigger("ajaxError", [xhr, s, e]); |
563 | + if (s.complete) |
564 | + s.complete.call(s.context, xhr, e); |
565 | + } |
566 | + }; |
567 | + |
568 | + g = s.global; |
569 | + // trigger ajax global events so that activity/block indicators work like normal |
570 | + if (g && 0 === $.active++) { |
571 | + $.event.trigger("ajaxStart"); |
572 | + } |
573 | + if (g) { |
574 | + $.event.trigger("ajaxSend", [xhr, s]); |
575 | + } |
576 | + |
577 | + if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) { |
578 | + if (s.global) { |
579 | + $.active--; |
580 | + } |
581 | + return; |
582 | + } |
583 | + if (xhr.aborted) { |
584 | + return; |
585 | + } |
586 | + |
587 | + // add submitting element to data if we know it |
588 | + sub = form.clk; |
589 | + if (sub) { |
590 | + n = sub.name; |
591 | + if (n && !sub.disabled) { |
592 | + s.extraData = s.extraData || {}; |
593 | + s.extraData[n] = sub.value; |
594 | + if (sub.type == "image") { |
595 | + s.extraData[n+'.x'] = form.clk_x; |
596 | + s.extraData[n+'.y'] = form.clk_y; |
597 | + } |
598 | + } |
599 | + } |
600 | + |
601 | + var CLIENT_TIMEOUT_ABORT = 1; |
602 | + var SERVER_ABORT = 2; |
603 | + |
604 | + function getDoc(frame) { |
605 | + var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document; |
606 | + return doc; |
607 | + } |
608 | + |
609 | + // Rails CSRF hack (thanks to Yvan Barthelemy) |
610 | + var csrf_token = $('meta[name=csrf-token]').attr('content'); |
611 | + var csrf_param = $('meta[name=csrf-param]').attr('content'); |
612 | + if (csrf_param && csrf_token) { |
613 | + s.extraData = s.extraData || {}; |
614 | + s.extraData[csrf_param] = csrf_token; |
615 | + } |
616 | + |
617 | + // take a breath so that pending repaints get some cpu time before the upload starts |
618 | + function doSubmit() { |
619 | + // make sure form attrs are set |
620 | + var t = $form.attr('target'), a = $form.attr('action'); |
621 | + |
622 | + // update form attrs in IE friendly way |
623 | + form.setAttribute('target',id); |
624 | + if (!method) { |
625 | + form.setAttribute('method', 'POST'); |
626 | + } |
627 | + if (a != s.url) { |
628 | + form.setAttribute('action', s.url); |
629 | + } |
630 | + |
631 | + // ie borks in some cases when setting encoding |
632 | + if (! s.skipEncodingOverride && (!method || /post/i.test(method))) { |
633 | + $form.attr({ |
634 | + encoding: 'multipart/form-data', |
635 | + enctype: 'multipart/form-data' |
636 | + }); |
637 | + } |
638 | + |
639 | + // support timout |
640 | + if (s.timeout) { |
641 | + timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout); |
642 | + } |
643 | + |
644 | + // look for server aborts |
645 | + function checkState() { |
646 | + try { |
647 | + var state = getDoc(io).readyState; |
648 | + log('state = ' + state); |
649 | + if (state && state.toLowerCase() == 'uninitialized') |
650 | + setTimeout(checkState,50); |
651 | + } |
652 | + catch(e) { |
653 | + log('Server abort: ' , e, ' (', e.name, ')'); |
654 | + cb(SERVER_ABORT); |
655 | + if (timeoutHandle) |
656 | + clearTimeout(timeoutHandle); |
657 | + timeoutHandle = undefined; |
658 | + } |
659 | + } |
660 | + |
661 | + // add "extra" data to form if provided in options |
662 | + var extraInputs = []; |
663 | + try { |
664 | + if (s.extraData) { |
665 | + for (var n in s.extraData) { |
666 | + if (s.extraData.hasOwnProperty(n)) { |
667 | + // if using the $.param format that allows for multiple values with the same name |
668 | + if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) { |
669 | + extraInputs.push( |
670 | + $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value) |
671 | + .appendTo(form)[0]); |
672 | + } else { |
673 | + extraInputs.push( |
674 | + $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n]) |
675 | + .appendTo(form)[0]); |
676 | + } |
677 | + } |
678 | } |
679 | } |
680 | - } |
681 | - |
682 | - // take a breath so that pending repaints get some cpu time before the upload starts |
683 | - function doSubmit() { |
684 | - // make sure form attrs are set |
685 | - var t = $form.attr('target'), a = $form.attr('action'); |
686 | - |
687 | - // update form attrs in IE friendly way |
688 | - form.setAttribute('target', id); |
689 | - if (form.getAttribute('method') != 'POST') |
690 | - form.setAttribute('method', 'POST'); |
691 | - if (form.getAttribute('action') != opts.url) |
692 | - form.setAttribute('action', opts.url); |
693 | - |
694 | - // ie borks in some cases when setting encoding |
695 | - if (! opts.skipEncodingOverride) { |
696 | - $form.attr({ |
697 | - encoding: 'multipart/form-data', |
698 | - enctype: 'multipart/form-data' |
699 | - }); |
700 | - } |
701 | - |
702 | - // support timout |
703 | - if (opts.timeout) |
704 | - setTimeout(function() { |
705 | - timedOut = true; |
706 | - cb(); |
707 | - }, opts.timeout); |
708 | - |
709 | - // add "extra" data to form if provided in options |
710 | - var extraInputs = []; |
711 | - try { |
712 | - if (opts.extraData) |
713 | - for (var n in opts.extraData) |
714 | - extraInputs.push( |
715 | - $('<input type="hidden" name="' + n + '" value="' + opts.extraData[n] + '" />') |
716 | - .appendTo(form)[0]); |
717 | - |
718 | + |
719 | + if (!s.iframeTarget) { |
720 | // add iframe to doc and submit the form |
721 | - $io.data('form-plugin-onload', cb); |
722 | $io.appendTo('body'); |
723 | - form.submit(); |
724 | - } |
725 | - finally { |
726 | - // reset attrs and remove "extra" input elements |
727 | - form.setAttribute('action', a); |
728 | - t ? form.setAttribute('target', t) : $form.removeAttr('target'); |
729 | - $(extraInputs).remove(); |
730 | - } |
731 | - } |
732 | - |
733 | - if (opts.forceSync) |
734 | - doSubmit(); |
735 | - else |
736 | - setTimeout(doSubmit, 10); // this lets dom updates render |
737 | - |
738 | - var domCheckCount = 10; |
739 | - |
740 | - function cb() { |
741 | - if (cbInvoked) |
742 | + if (io.attachEvent) |
743 | + io.attachEvent('onload', cb); |
744 | + else |
745 | + io.addEventListener('load', cb, false); |
746 | + } |
747 | + setTimeout(checkState,15); |
748 | + form.submit(); |
749 | + } |
750 | + finally { |
751 | + // reset attrs and remove "extra" input elements |
752 | + form.setAttribute('action',a); |
753 | + if(t) { |
754 | + form.setAttribute('target', t); |
755 | + } else { |
756 | + $form.removeAttr('target'); |
757 | + } |
758 | + $(extraInputs).remove(); |
759 | + } |
760 | + } |
761 | + |
762 | + if (s.forceSync) { |
763 | + doSubmit(); |
764 | + } |
765 | + else { |
766 | + setTimeout(doSubmit, 10); // this lets dom updates render |
767 | + } |
768 | + |
769 | + var data, doc, domCheckCount = 50, callbackProcessed; |
770 | + |
771 | + function cb(e) { |
772 | + if (xhr.aborted || callbackProcessed) { |
773 | + return; |
774 | + } |
775 | + try { |
776 | + doc = getDoc(io); |
777 | + } |
778 | + catch(ex) { |
779 | + log('cannot access response document: ', ex); |
780 | + e = SERVER_ABORT; |
781 | + } |
782 | + if (e === CLIENT_TIMEOUT_ABORT && xhr) { |
783 | + xhr.abort('timeout'); |
784 | + return; |
785 | + } |
786 | + else if (e == SERVER_ABORT && xhr) { |
787 | + xhr.abort('server abort'); |
788 | + return; |
789 | + } |
790 | + |
791 | + if (!doc || doc.location.href == s.iframeSrc) { |
792 | + // response not received yet |
793 | + if (!timedOut) |
794 | return; |
795 | - |
796 | - var ok = true; |
797 | - try { |
798 | - if (timedOut) throw 'timeout'; |
799 | - // extract the server response from the iframe |
800 | - var data, doc; |
801 | - |
802 | - doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; |
803 | - |
804 | - var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); |
805 | - log('isXml=' + isXml); |
806 | - if (!isXml && (doc.body == null || doc.body.innerHTML == '')) { |
807 | - if (--domCheckCount) { |
808 | - // in some browsers (Opera) the iframe DOM is not always traversable when |
809 | - // the onload callback fires, so we loop a bit to accommodate |
810 | - log('requeing onLoad callback, DOM not available'); |
811 | - setTimeout(cb, 250); |
812 | - return; |
813 | - } |
814 | - log('Could not access iframe DOM after 10 tries.'); |
815 | - if (g && ! --$.active) $.event.trigger("ajaxStop"); |
816 | + } |
817 | + if (io.detachEvent) |
818 | + io.detachEvent('onload', cb); |
819 | + else |
820 | + io.removeEventListener('load', cb, false); |
821 | + |
822 | + var status = 'success', errMsg; |
823 | + try { |
824 | + if (timedOut) { |
825 | + throw 'timeout'; |
826 | + } |
827 | + |
828 | + var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); |
829 | + log('isXml='+isXml); |
830 | + if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) { |
831 | + if (--domCheckCount) { |
832 | + // in some browsers (Opera) the iframe DOM is not always traversable when |
833 | + // the onload callback fires, so we loop a bit to accommodate |
834 | + log('requeing onLoad callback, DOM not available'); |
835 | + setTimeout(cb, 250); |
836 | return; |
837 | } |
838 | - |
839 | - log('response detected'); |
840 | - cbInvoked = true; |
841 | - xhr.responseText = doc.body ? doc.body.innerHTML : null; |
842 | - xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; |
843 | - xhr.getResponseHeader = function(header) { |
844 | - var headers = {'content-type': opts.dataType}; |
845 | - return headers[header]; |
846 | - }; |
847 | - |
848 | - if (opts.dataType == 'json' || opts.dataType == 'script') { |
849 | - // see if user embedded response in textarea |
850 | - var ta = doc.getElementsByTagName('textarea')[0]; |
851 | - if (ta) |
852 | - xhr.responseText = ta.value; |
853 | - else { |
854 | - // account for browsers injecting pre around json response |
855 | - var pre = doc.getElementsByTagName('pre')[0]; |
856 | - if (pre) |
857 | - xhr.responseText = pre.innerHTML; |
858 | - } |
859 | - } |
860 | - else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { |
861 | - xhr.responseXML = toXml(xhr.responseText); |
862 | - } |
863 | - data = $.httpData(xhr, opts.dataType); |
864 | - } |
865 | - catch(e) { |
866 | - log('error caught:', e); |
867 | - ok = false; |
868 | - xhr.error = e; |
869 | - $.handleError(opts, xhr, 'error', e); |
870 | - } |
871 | - |
872 | - // ordering of these callbacks/triggers is odd, but that's how $.ajax does it |
873 | - if (ok) { |
874 | - opts.success(data, 'success'); |
875 | - if (g) $.event.trigger("ajaxSuccess", [xhr, opts]); |
876 | - } |
877 | - if (g) $.event.trigger("ajaxComplete", [xhr, opts]); |
878 | - if (g && ! --$.active) $.event.trigger("ajaxStop"); |
879 | - if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error'); |
880 | - |
881 | - // clean up |
882 | - setTimeout(function() { |
883 | - $io.removeData('form-plugin-onload'); |
884 | + // let this fall through because server response could be an empty document |
885 | + //log('Could not access iframe DOM after mutiple tries.'); |
886 | + //throw 'DOMException: not available'; |
887 | + } |
888 | + |
889 | + //log('response detected'); |
890 | + var docRoot = doc.body ? doc.body : doc.documentElement; |
891 | + xhr.responseText = docRoot ? docRoot.innerHTML : null; |
892 | + xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; |
893 | + if (isXml) |
894 | + s.dataType = 'xml'; |
895 | + xhr.getResponseHeader = function(header){ |
896 | + var headers = {'content-type': s.dataType}; |
897 | + return headers[header]; |
898 | + }; |
899 | + // support for XHR 'status' & 'statusText' emulation : |
900 | + if (docRoot) { |
901 | + xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status; |
902 | + xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText; |
903 | + } |
904 | + |
905 | + var dt = (s.dataType || '').toLowerCase(); |
906 | + var scr = /(json|script|text)/.test(dt); |
907 | + if (scr || s.textarea) { |
908 | + // see if user embedded response in textarea |
909 | + var ta = doc.getElementsByTagName('textarea')[0]; |
910 | + if (ta) { |
911 | + xhr.responseText = ta.value; |
912 | + // support for XHR 'status' & 'statusText' emulation : |
913 | + xhr.status = Number( ta.getAttribute('status') ) || xhr.status; |
914 | + xhr.statusText = ta.getAttribute('statusText') || xhr.statusText; |
915 | + } |
916 | + else if (scr) { |
917 | + // account for browsers injecting pre around json response |
918 | + var pre = doc.getElementsByTagName('pre')[0]; |
919 | + var b = doc.getElementsByTagName('body')[0]; |
920 | + if (pre) { |
921 | + xhr.responseText = pre.textContent ? pre.textContent : pre.innerText; |
922 | + } |
923 | + else if (b) { |
924 | + xhr.responseText = b.textContent ? b.textContent : b.innerText; |
925 | + } |
926 | + } |
927 | + } |
928 | + else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) { |
929 | + xhr.responseXML = toXml(xhr.responseText); |
930 | + } |
931 | + |
932 | + try { |
933 | + data = httpData(xhr, dt, s); |
934 | + } |
935 | + catch (e) { |
936 | + status = 'parsererror'; |
937 | + xhr.error = errMsg = (e || status); |
938 | + } |
939 | + } |
940 | + catch (e) { |
941 | + log('error caught: ',e); |
942 | + status = 'error'; |
943 | + xhr.error = errMsg = (e || status); |
944 | + } |
945 | + |
946 | + if (xhr.aborted) { |
947 | + log('upload aborted'); |
948 | + status = null; |
949 | + } |
950 | + |
951 | + if (xhr.status) { // we've set xhr.status |
952 | + status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error'; |
953 | + } |
954 | + |
955 | + // ordering of these callbacks/triggers is odd, but that's how $.ajax does it |
956 | + if (status === 'success') { |
957 | + if (s.success) |
958 | + s.success.call(s.context, data, 'success', xhr); |
959 | + if (g) |
960 | + $.event.trigger("ajaxSuccess", [xhr, s]); |
961 | + } |
962 | + else if (status) { |
963 | + if (errMsg === undefined) |
964 | + errMsg = xhr.statusText; |
965 | + if (s.error) |
966 | + s.error.call(s.context, xhr, status, errMsg); |
967 | + if (g) |
968 | + $.event.trigger("ajaxError", [xhr, s, errMsg]); |
969 | + } |
970 | + |
971 | + if (g) |
972 | + $.event.trigger("ajaxComplete", [xhr, s]); |
973 | + |
974 | + if (g && ! --$.active) { |
975 | + $.event.trigger("ajaxStop"); |
976 | + } |
977 | + |
978 | + if (s.complete) |
979 | + s.complete.call(s.context, xhr, status); |
980 | + |
981 | + callbackProcessed = true; |
982 | + if (s.timeout) |
983 | + clearTimeout(timeoutHandle); |
984 | + |
985 | + // clean up |
986 | + setTimeout(function() { |
987 | + if (!s.iframeTarget) |
988 | $io.remove(); |
989 | - xhr.responseXML = null; |
990 | - }, 100); |
991 | - } |
992 | - |
993 | - function toXml(s, doc) { |
994 | - if (window.ActiveXObject) { |
995 | - doc = new ActiveXObject('Microsoft.XMLDOM'); |
996 | - doc.async = 'false'; |
997 | - doc.loadXML(s); |
998 | - } |
999 | - else |
1000 | - doc = (new DOMParser()).parseFromString(s, 'text/xml'); |
1001 | - return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null; |
1002 | - } |
1003 | - } |
1004 | - }; |
1005 | - |
1006 | - /** |
1007 | - * ajaxForm() provides a mechanism for fully automating form submission. |
1008 | - * |
1009 | - * The advantages of using this method instead of ajaxSubmit() are: |
1010 | - * |
1011 | - * 1: This method will include coordinates for <input type="image" /> elements (if the element |
1012 | - * is used to submit the form). |
1013 | - * 2. This method will include the submit element's name/value data (for the element that was |
1014 | - * used to submit the form). |
1015 | - * 3. This method binds the submit() method to the form for you. |
1016 | - * |
1017 | - * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely |
1018 | - * passes the options argument along after properly binding events for submit elements and |
1019 | - * the form itself. |
1020 | - */ |
1021 | - $.fn.ajaxForm = function(options) { |
1022 | - return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) { |
1023 | - e.preventDefault(); |
1024 | - $(this).ajaxSubmit(options); |
1025 | - }).bind('click.form-plugin', function(e) { |
1026 | - var target = e.target; |
1027 | - var $el = $(target); |
1028 | - if (!($el.is(":submit,input:image"))) { |
1029 | - // is this a child element of the submit el? (ex: a span within a button) |
1030 | - var t = $el.closest(':submit'); |
1031 | - if (t.length == 0) |
1032 | - return; |
1033 | - target = t[0]; |
1034 | - } |
1035 | - var form = this; |
1036 | - form.clk = target; |
1037 | - if (target.type == 'image') { |
1038 | - if (e.offsetX != undefined) { |
1039 | - form.clk_x = e.offsetX; |
1040 | - form.clk_y = e.offsetY; |
1041 | - } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin |
1042 | - var offset = $el.offset(); |
1043 | - form.clk_x = e.pageX - offset.left; |
1044 | - form.clk_y = e.pageY - offset.top; |
1045 | - } else { |
1046 | - form.clk_x = e.pageX - target.offsetLeft; |
1047 | - form.clk_y = e.pageY - target.offsetTop; |
1048 | - } |
1049 | - } |
1050 | - // clear form vars |
1051 | - setTimeout(function() { |
1052 | - form.clk = form.clk_x = form.clk_y = null; |
1053 | + xhr.responseXML = null; |
1054 | }, 100); |
1055 | - }); |
1056 | - }; |
1057 | - |
1058 | - // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm |
1059 | - $.fn.ajaxFormUnbind = function() { |
1060 | - return this.unbind('submit.form-plugin click.form-plugin'); |
1061 | - }; |
1062 | - |
1063 | - /** |
1064 | - * formToArray() gathers form element data into an array of objects that can |
1065 | - * be passed to any of the following ajax functions: $.get, $.post, or load. |
1066 | - * Each object in the array has both a 'name' and 'value' property. An example of |
1067 | - * an array for a simple login form might be: |
1068 | - * |
1069 | - * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] |
1070 | - * |
1071 | - * It is this array that is passed to pre-submit callback functions provided to the |
1072 | - * ajaxSubmit() and ajaxForm() methods. |
1073 | - */ |
1074 | - $.fn.formToArray = function(semantic) { |
1075 | - var a = []; |
1076 | - if (this.length == 0) return a; |
1077 | - |
1078 | - var form = this[0]; |
1079 | - var els = semantic ? form.getElementsByTagName('*') : form.elements; |
1080 | - if (!els) return a; |
1081 | - for (var i = 0, max = els.length; i < max; i++) { |
1082 | - var el = els[i]; |
1083 | - var n = el.name; |
1084 | - if (!n) continue; |
1085 | - |
1086 | - if (semantic && form.clk && el.type == "image") { |
1087 | - // handle image inputs on the fly when semantic == true |
1088 | - if (!el.disabled && form.clk == el) { |
1089 | - a.push({name: n, value: $(el).val()}); |
1090 | - a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y}); |
1091 | - } |
1092 | - continue; |
1093 | - } |
1094 | - |
1095 | - var v = $.fieldValue(el, true); |
1096 | - if (v && v.constructor == Array) { |
1097 | - for (var j = 0, jmax = v.length; j < jmax; j++) |
1098 | - a.push({name: n, value: v[j]}); |
1099 | - } |
1100 | - else if (v !== null && typeof v != 'undefined') |
1101 | - a.push({name: n, value: v}); |
1102 | - } |
1103 | - |
1104 | - if (!semantic && form.clk) { |
1105 | - // input type=='image' are not found in elements array! handle it here |
1106 | - var $input = $(form.clk), input = $input[0], n = input.name; |
1107 | - if (n && !input.disabled && input.type == 'image') { |
1108 | - a.push({name: n, value: $input.val()}); |
1109 | - a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y}); |
1110 | - } |
1111 | - } |
1112 | - return a; |
1113 | - }; |
1114 | - |
1115 | - /** |
1116 | - * Serializes form data into a 'submittable' string. This method will return a string |
1117 | - * in the format: name1=value1&name2=value2 |
1118 | - */ |
1119 | - $.fn.formSerialize = function(semantic) { |
1120 | - //hand off to jQuery.param for proper encoding |
1121 | - return $.param(this.formToArray(semantic)); |
1122 | - }; |
1123 | - |
1124 | - /** |
1125 | - * Serializes all field elements in the jQuery object into a query string. |
1126 | - * This method will return a string in the format: name1=value1&name2=value2 |
1127 | - */ |
1128 | - $.fn.fieldSerialize = function(successful) { |
1129 | - var a = []; |
1130 | - this.each(function() { |
1131 | - var n = this.name; |
1132 | - if (!n) return; |
1133 | - var v = $.fieldValue(this, successful); |
1134 | - if (v && v.constructor == Array) { |
1135 | - for (var i = 0,max = v.length; i < max; i++) |
1136 | - a.push({name: n, value: v[i]}); |
1137 | - } |
1138 | - else if (v !== null && typeof v != 'undefined') |
1139 | - a.push({name: this.name, value: v}); |
1140 | - }); |
1141 | - //hand off to jQuery.param for proper encoding |
1142 | - return $.param(a); |
1143 | - }; |
1144 | - |
1145 | - /** |
1146 | - * Returns the value(s) of the element in the matched set. For example, consider the following form: |
1147 | - * |
1148 | - * <form><fieldset> |
1149 | - * <input name="A" type="text" /> |
1150 | - * <input name="A" type="text" /> |
1151 | - * <input name="B" type="checkbox" value="B1" /> |
1152 | - * <input name="B" type="checkbox" value="B2"/> |
1153 | - * <input name="C" type="radio" value="C1" /> |
1154 | - * <input name="C" type="radio" value="C2" /> |
1155 | - * </fieldset></form> |
1156 | - * |
1157 | - * var v = $(':text').fieldValue(); |
1158 | - * // if no values are entered into the text inputs |
1159 | - * v == ['',''] |
1160 | - * // if values entered into the text inputs are 'foo' and 'bar' |
1161 | - * v == ['foo','bar'] |
1162 | - * |
1163 | - * var v = $(':checkbox').fieldValue(); |
1164 | - * // if neither checkbox is checked |
1165 | - * v === undefined |
1166 | - * // if both checkboxes are checked |
1167 | - * v == ['B1', 'B2'] |
1168 | - * |
1169 | - * var v = $(':radio').fieldValue(); |
1170 | - * // if neither radio is checked |
1171 | - * v === undefined |
1172 | - * // if first radio is checked |
1173 | - * v == ['C1'] |
1174 | - * |
1175 | - * The successful argument controls whether or not the field element must be 'successful' |
1176 | - * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). |
1177 | - * The default value of the successful argument is true. If this value is false the value(s) |
1178 | - * for each element is returned. |
1179 | - * |
1180 | - * Note: This method *always* returns an array. If no valid value can be determined the |
1181 | - * array will be empty, otherwise it will contain one or more values. |
1182 | - */ |
1183 | - $.fn.fieldValue = function(successful) { |
1184 | - for (var val = [], i = 0, max = this.length; i < max; i++) { |
1185 | - var el = this[i]; |
1186 | - var v = $.fieldValue(el, successful); |
1187 | - if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) |
1188 | - continue; |
1189 | - v.constructor == Array ? $.merge(val, v) : val.push(v); |
1190 | - } |
1191 | - return val; |
1192 | - }; |
1193 | - |
1194 | - /** |
1195 | - * Returns the value of the field element. |
1196 | - */ |
1197 | - $.fieldValue = function(el, successful) { |
1198 | - var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); |
1199 | - if (typeof successful == 'undefined') successful = true; |
1200 | - |
1201 | - if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || |
1202 | - (t == 'checkbox' || t == 'radio') && !el.checked || |
1203 | - (t == 'submit' || t == 'image') && el.form && el.form.clk != el || |
1204 | - tag == 'select' && el.selectedIndex == -1)) |
1205 | - return null; |
1206 | - |
1207 | - if (tag == 'select') { |
1208 | - var index = el.selectedIndex; |
1209 | - if (index < 0) return null; |
1210 | - var a = [], ops = el.options; |
1211 | - var one = (t == 'select-one'); |
1212 | - var max = (one ? index + 1 : ops.length); |
1213 | - for (var i = (one ? index : 0); i < max; i++) { |
1214 | - var op = ops[i]; |
1215 | - if (op.selected) { |
1216 | - var v = op.value; |
1217 | - if (!v) // extra pain for IE... |
1218 | - v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; |
1219 | - if (one) return v; |
1220 | - a.push(v); |
1221 | - } |
1222 | - } |
1223 | - return a; |
1224 | - } |
1225 | - return el.value; |
1226 | - }; |
1227 | - |
1228 | - /** |
1229 | - * Clears the form data. Takes the following actions on the form's input fields: |
1230 | - * - input text fields will have their 'value' property set to the empty string |
1231 | - * - select elements will have their 'selectedIndex' property set to -1 |
1232 | - * - checkbox and radio inputs will have their 'checked' property set to false |
1233 | - * - inputs of type submit, button, reset, and hidden will *not* be effected |
1234 | - * - button elements will *not* be effected |
1235 | - */ |
1236 | - $.fn.clearForm = function() { |
1237 | - return this.each(function() { |
1238 | - $('input,select,textarea', this).clearFields(); |
1239 | - }); |
1240 | - }; |
1241 | - |
1242 | - /** |
1243 | - * Clears the selected form elements. |
1244 | - */ |
1245 | - $.fn.clearFields = $.fn.clearInputs = function() { |
1246 | - return this.each(function() { |
1247 | - var t = this.type, tag = this.tagName.toLowerCase(); |
1248 | - if (t == 'text' || t == 'password' || tag == 'textarea') |
1249 | + } |
1250 | + |
1251 | + var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+) |
1252 | + if (window.ActiveXObject) { |
1253 | + doc = new ActiveXObject('Microsoft.XMLDOM'); |
1254 | + doc.async = 'false'; |
1255 | + doc.loadXML(s); |
1256 | + } |
1257 | + else { |
1258 | + doc = (new DOMParser()).parseFromString(s, 'text/xml'); |
1259 | + } |
1260 | + return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null; |
1261 | + }; |
1262 | + var parseJSON = $.parseJSON || function(s) { |
1263 | + /*jslint evil:true */ |
1264 | + return window['eval']('(' + s + ')'); |
1265 | + }; |
1266 | + |
1267 | + var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4 |
1268 | + |
1269 | + var ct = xhr.getResponseHeader('content-type') || '', |
1270 | + xml = type === 'xml' || !type && ct.indexOf('xml') >= 0, |
1271 | + data = xml ? xhr.responseXML : xhr.responseText; |
1272 | + |
1273 | + if (xml && data.documentElement.nodeName === 'parsererror') { |
1274 | + if ($.error) |
1275 | + $.error('parsererror'); |
1276 | + } |
1277 | + if (s && s.dataFilter) { |
1278 | + data = s.dataFilter(data, type); |
1279 | + } |
1280 | + if (typeof data === 'string') { |
1281 | + if (type === 'json' || !type && ct.indexOf('json') >= 0) { |
1282 | + data = parseJSON(data); |
1283 | + } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) { |
1284 | + $.globalEval(data); |
1285 | + } |
1286 | + } |
1287 | + return data; |
1288 | + }; |
1289 | + } |
1290 | +}; |
1291 | + |
1292 | +/** |
1293 | + * ajaxForm() provides a mechanism for fully automating form submission. |
1294 | + * |
1295 | + * The advantages of using this method instead of ajaxSubmit() are: |
1296 | + * |
1297 | + * 1: This method will include coordinates for <input type="image" /> elements (if the element |
1298 | + * is used to submit the form). |
1299 | + * 2. This method will include the submit element's name/value data (for the element that was |
1300 | + * used to submit the form). |
1301 | + * 3. This method binds the submit() method to the form for you. |
1302 | + * |
1303 | + * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely |
1304 | + * passes the options argument along after properly binding events for submit elements and |
1305 | + * the form itself. |
1306 | + */ |
1307 | +$.fn.ajaxForm = function(options) { |
1308 | + options = options || {}; |
1309 | + options.delegation = options.delegation && $.isFunction($.fn.on); |
1310 | + |
1311 | + // in jQuery 1.3+ we can fix mistakes with the ready state |
1312 | + if (!options.delegation && this.length === 0) { |
1313 | + var o = { s: this.selector, c: this.context }; |
1314 | + if (!$.isReady && o.s) { |
1315 | + log('DOM not ready, queuing ajaxForm'); |
1316 | + $(function() { |
1317 | + $(o.s,o.c).ajaxForm(options); |
1318 | + }); |
1319 | + return this; |
1320 | + } |
1321 | + // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready() |
1322 | + log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); |
1323 | + return this; |
1324 | + } |
1325 | + |
1326 | + if ( options.delegation ) { |
1327 | + $(document) |
1328 | + .off('submit.form-plugin', this.selector, doAjaxSubmit) |
1329 | + .off('click.form-plugin', this.selector, captureSubmittingElement) |
1330 | + .on('submit.form-plugin', this.selector, options, doAjaxSubmit) |
1331 | + .on('click.form-plugin', this.selector, options, captureSubmittingElement); |
1332 | + return this; |
1333 | + } |
1334 | + |
1335 | + return this.ajaxFormUnbind() |
1336 | + .bind('submit.form-plugin', options, doAjaxSubmit) |
1337 | + .bind('click.form-plugin', options, captureSubmittingElement); |
1338 | +}; |
1339 | + |
1340 | +// private event handlers |
1341 | +function doAjaxSubmit(e) { |
1342 | + /*jshint validthis:true */ |
1343 | + var options = e.data; |
1344 | + if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed |
1345 | + e.preventDefault(); |
1346 | + $(this).ajaxSubmit(options); |
1347 | + } |
1348 | +} |
1349 | + |
1350 | +function captureSubmittingElement(e) { |
1351 | + /*jshint validthis:true */ |
1352 | + var target = e.target; |
1353 | + var $el = $(target); |
1354 | + if (!($el.is(":submit,input:image"))) { |
1355 | + // is this a child element of the submit el? (ex: a span within a button) |
1356 | + var t = $el.closest(':submit'); |
1357 | + if (t.length === 0) { |
1358 | + return; |
1359 | + } |
1360 | + target = t[0]; |
1361 | + } |
1362 | + var form = this; |
1363 | + form.clk = target; |
1364 | + if (target.type == 'image') { |
1365 | + if (e.offsetX !== undefined) { |
1366 | + form.clk_x = e.offsetX; |
1367 | + form.clk_y = e.offsetY; |
1368 | + } else if (typeof $.fn.offset == 'function') { |
1369 | + var offset = $el.offset(); |
1370 | + form.clk_x = e.pageX - offset.left; |
1371 | + form.clk_y = e.pageY - offset.top; |
1372 | + } else { |
1373 | + form.clk_x = e.pageX - target.offsetLeft; |
1374 | + form.clk_y = e.pageY - target.offsetTop; |
1375 | + } |
1376 | + } |
1377 | + // clear form vars |
1378 | + setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); |
1379 | +} |
1380 | + |
1381 | + |
1382 | +// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm |
1383 | +$.fn.ajaxFormUnbind = function() { |
1384 | + return this.unbind('submit.form-plugin click.form-plugin'); |
1385 | +}; |
1386 | + |
1387 | +/** |
1388 | + * formToArray() gathers form element data into an array of objects that can |
1389 | + * be passed to any of the following ajax functions: $.get, $.post, or load. |
1390 | + * Each object in the array has both a 'name' and 'value' property. An example of |
1391 | + * an array for a simple login form might be: |
1392 | + * |
1393 | + * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] |
1394 | + * |
1395 | + * It is this array that is passed to pre-submit callback functions provided to the |
1396 | + * ajaxSubmit() and ajaxForm() methods. |
1397 | + */ |
1398 | +$.fn.formToArray = function(semantic, elements) { |
1399 | + var a = []; |
1400 | + if (this.length === 0) { |
1401 | + return a; |
1402 | + } |
1403 | + |
1404 | + var form = this[0]; |
1405 | + var els = semantic ? form.getElementsByTagName('*') : form.elements; |
1406 | + if (!els) { |
1407 | + return a; |
1408 | + } |
1409 | + |
1410 | + var i,j,n,v,el,max,jmax; |
1411 | + for(i=0, max=els.length; i < max; i++) { |
1412 | + el = els[i]; |
1413 | + n = el.name; |
1414 | + if (!n) { |
1415 | + continue; |
1416 | + } |
1417 | + |
1418 | + if (semantic && form.clk && el.type == "image") { |
1419 | + // handle image inputs on the fly when semantic == true |
1420 | + if(!el.disabled && form.clk == el) { |
1421 | + a.push({name: n, value: $(el).val(), type: el.type }); |
1422 | + a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); |
1423 | + } |
1424 | + continue; |
1425 | + } |
1426 | + |
1427 | + v = $.fieldValue(el, true); |
1428 | + if (v && v.constructor == Array) { |
1429 | + if (elements) |
1430 | + elements.push(el); |
1431 | + for(j=0, jmax=v.length; j < jmax; j++) { |
1432 | + a.push({name: n, value: v[j]}); |
1433 | + } |
1434 | + } |
1435 | + else if (feature.fileapi && el.type == 'file' && !el.disabled) { |
1436 | + if (elements) |
1437 | + elements.push(el); |
1438 | + var files = el.files; |
1439 | + if (files.length) { |
1440 | + for (j=0; j < files.length; j++) { |
1441 | + a.push({name: n, value: files[j], type: el.type}); |
1442 | + } |
1443 | + } |
1444 | + else { |
1445 | + // #180 |
1446 | + a.push({ name: n, value: '', type: el.type }); |
1447 | + } |
1448 | + } |
1449 | + else if (v !== null && typeof v != 'undefined') { |
1450 | + if (elements) |
1451 | + elements.push(el); |
1452 | + a.push({name: n, value: v, type: el.type, required: el.required}); |
1453 | + } |
1454 | + } |
1455 | + |
1456 | + if (!semantic && form.clk) { |
1457 | + // input type=='image' are not found in elements array! handle it here |
1458 | + var $input = $(form.clk), input = $input[0]; |
1459 | + n = input.name; |
1460 | + if (n && !input.disabled && input.type == 'image') { |
1461 | + a.push({name: n, value: $input.val()}); |
1462 | + a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); |
1463 | + } |
1464 | + } |
1465 | + return a; |
1466 | +}; |
1467 | + |
1468 | +/** |
1469 | + * Serializes form data into a 'submittable' string. This method will return a string |
1470 | + * in the format: name1=value1&name2=value2 |
1471 | + */ |
1472 | +$.fn.formSerialize = function(semantic) { |
1473 | + //hand off to jQuery.param for proper encoding |
1474 | + return $.param(this.formToArray(semantic)); |
1475 | +}; |
1476 | + |
1477 | +/** |
1478 | + * Serializes all field elements in the jQuery object into a query string. |
1479 | + * This method will return a string in the format: name1=value1&name2=value2 |
1480 | + */ |
1481 | +$.fn.fieldSerialize = function(successful) { |
1482 | + var a = []; |
1483 | + this.each(function() { |
1484 | + var n = this.name; |
1485 | + if (!n) { |
1486 | + return; |
1487 | + } |
1488 | + var v = $.fieldValue(this, successful); |
1489 | + if (v && v.constructor == Array) { |
1490 | + for (var i=0,max=v.length; i < max; i++) { |
1491 | + a.push({name: n, value: v[i]}); |
1492 | + } |
1493 | + } |
1494 | + else if (v !== null && typeof v != 'undefined') { |
1495 | + a.push({name: this.name, value: v}); |
1496 | + } |
1497 | + }); |
1498 | + //hand off to jQuery.param for proper encoding |
1499 | + return $.param(a); |
1500 | +}; |
1501 | + |
1502 | +/** |
1503 | + * Returns the value(s) of the element in the matched set. For example, consider the following form: |
1504 | + * |
1505 | + * <form><fieldset> |
1506 | + * <input name="A" type="text" /> |
1507 | + * <input name="A" type="text" /> |
1508 | + * <input name="B" type="checkbox" value="B1" /> |
1509 | + * <input name="B" type="checkbox" value="B2"/> |
1510 | + * <input name="C" type="radio" value="C1" /> |
1511 | + * <input name="C" type="radio" value="C2" /> |
1512 | + * </fieldset></form> |
1513 | + * |
1514 | + * var v = $(':text').fieldValue(); |
1515 | + * // if no values are entered into the text inputs |
1516 | + * v == ['',''] |
1517 | + * // if values entered into the text inputs are 'foo' and 'bar' |
1518 | + * v == ['foo','bar'] |
1519 | + * |
1520 | + * var v = $(':checkbox').fieldValue(); |
1521 | + * // if neither checkbox is checked |
1522 | + * v === undefined |
1523 | + * // if both checkboxes are checked |
1524 | + * v == ['B1', 'B2'] |
1525 | + * |
1526 | + * var v = $(':radio').fieldValue(); |
1527 | + * // if neither radio is checked |
1528 | + * v === undefined |
1529 | + * // if first radio is checked |
1530 | + * v == ['C1'] |
1531 | + * |
1532 | + * The successful argument controls whether or not the field element must be 'successful' |
1533 | + * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). |
1534 | + * The default value of the successful argument is true. If this value is false the value(s) |
1535 | + * for each element is returned. |
1536 | + * |
1537 | + * Note: This method *always* returns an array. If no valid value can be determined the |
1538 | + * array will be empty, otherwise it will contain one or more values. |
1539 | + */ |
1540 | +$.fn.fieldValue = function(successful) { |
1541 | + for (var val=[], i=0, max=this.length; i < max; i++) { |
1542 | + var el = this[i]; |
1543 | + var v = $.fieldValue(el, successful); |
1544 | + if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) { |
1545 | + continue; |
1546 | + } |
1547 | + if (v.constructor == Array) |
1548 | + $.merge(val, v); |
1549 | + else |
1550 | + val.push(v); |
1551 | + } |
1552 | + return val; |
1553 | +}; |
1554 | + |
1555 | +/** |
1556 | + * Returns the value of the field element. |
1557 | + */ |
1558 | +$.fieldValue = function(el, successful) { |
1559 | + var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); |
1560 | + if (successful === undefined) { |
1561 | + successful = true; |
1562 | + } |
1563 | + |
1564 | + if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || |
1565 | + (t == 'checkbox' || t == 'radio') && !el.checked || |
1566 | + (t == 'submit' || t == 'image') && el.form && el.form.clk != el || |
1567 | + tag == 'select' && el.selectedIndex == -1)) { |
1568 | + return null; |
1569 | + } |
1570 | + |
1571 | + if (tag == 'select') { |
1572 | + var index = el.selectedIndex; |
1573 | + if (index < 0) { |
1574 | + return null; |
1575 | + } |
1576 | + var a = [], ops = el.options; |
1577 | + var one = (t == 'select-one'); |
1578 | + var max = (one ? index+1 : ops.length); |
1579 | + for(var i=(one ? index : 0); i < max; i++) { |
1580 | + var op = ops[i]; |
1581 | + if (op.selected) { |
1582 | + var v = op.value; |
1583 | + if (!v) { // extra pain for IE... |
1584 | + v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; |
1585 | + } |
1586 | + if (one) { |
1587 | + return v; |
1588 | + } |
1589 | + a.push(v); |
1590 | + } |
1591 | + } |
1592 | + return a; |
1593 | + } |
1594 | + return $(el).val(); |
1595 | +}; |
1596 | + |
1597 | +/** |
1598 | + * Clears the form data. Takes the following actions on the form's input fields: |
1599 | + * - input text fields will have their 'value' property set to the empty string |
1600 | + * - select elements will have their 'selectedIndex' property set to -1 |
1601 | + * - checkbox and radio inputs will have their 'checked' property set to false |
1602 | + * - inputs of type submit, button, reset, and hidden will *not* be effected |
1603 | + * - button elements will *not* be effected |
1604 | + */ |
1605 | +$.fn.clearForm = function(includeHidden) { |
1606 | + return this.each(function() { |
1607 | + $('input,select,textarea', this).clearFields(includeHidden); |
1608 | + }); |
1609 | +}; |
1610 | + |
1611 | +/** |
1612 | + * Clears the selected form elements. |
1613 | + */ |
1614 | +$.fn.clearFields = $.fn.clearInputs = function(includeHidden) { |
1615 | + var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list |
1616 | + return this.each(function() { |
1617 | + var t = this.type, tag = this.tagName.toLowerCase(); |
1618 | + if (re.test(t) || tag == 'textarea') { |
1619 | + this.value = ''; |
1620 | + } |
1621 | + else if (t == 'checkbox' || t == 'radio') { |
1622 | + this.checked = false; |
1623 | + } |
1624 | + else if (tag == 'select') { |
1625 | + this.selectedIndex = -1; |
1626 | + } |
1627 | + else if (includeHidden) { |
1628 | + // includeHidden can be the value true, or it can be a selector string |
1629 | + // indicating a special test; for example: |
1630 | + // $('#myForm').clearForm('.special:hidden') |
1631 | + // the above would clean hidden inputs that have the class of 'special' |
1632 | + if ( (includeHidden === true && /hidden/.test(t)) || |
1633 | + (typeof includeHidden == 'string' && $(this).is(includeHidden)) ) |
1634 | this.value = ''; |
1635 | - else if (t == 'checkbox' || t == 'radio') |
1636 | - this.checked = false; |
1637 | - else if (tag == 'select') |
1638 | - this.selectedIndex = -1; |
1639 | - }); |
1640 | - }; |
1641 | - |
1642 | - /** |
1643 | - * Resets the form data. Causes all form elements to be reset to their original value. |
1644 | - */ |
1645 | - $.fn.resetForm = function() { |
1646 | - return this.each(function() { |
1647 | - // guard against an input with the name of 'reset' |
1648 | - // note that IE reports the reset function as an 'object' |
1649 | - if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) |
1650 | - this.reset(); |
1651 | - }); |
1652 | - }; |
1653 | - |
1654 | - /** |
1655 | - * Enables or disables any matching elements. |
1656 | - */ |
1657 | - $.fn.enable = function(b) { |
1658 | - if (b == undefined) b = true; |
1659 | - return this.each(function() { |
1660 | - this.disabled = !b; |
1661 | - }); |
1662 | - }; |
1663 | - |
1664 | - /** |
1665 | - * Checks/unchecks any matching checkboxes or radio buttons and |
1666 | - * selects/deselects and matching option elements. |
1667 | - */ |
1668 | - $.fn.selected = function(select) { |
1669 | - if (select == undefined) select = true; |
1670 | - return this.each(function() { |
1671 | - var t = this.type; |
1672 | - if (t == 'checkbox' || t == 'radio') |
1673 | - this.checked = select; |
1674 | - else if (this.tagName.toLowerCase() == 'option') { |
1675 | - var $sel = $(this).parent('select'); |
1676 | - if (select && $sel[0] && $sel[0].type == 'select-one') { |
1677 | - // deselect all other options |
1678 | - $sel.find('option').selected(false); |
1679 | - } |
1680 | - this.selected = select; |
1681 | + } |
1682 | + }); |
1683 | +}; |
1684 | + |
1685 | +/** |
1686 | + * Resets the form data. Causes all form elements to be reset to their original value. |
1687 | + */ |
1688 | +$.fn.resetForm = function() { |
1689 | + return this.each(function() { |
1690 | + // guard against an input with the name of 'reset' |
1691 | + // note that IE reports the reset function as an 'object' |
1692 | + if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) { |
1693 | + this.reset(); |
1694 | + } |
1695 | + }); |
1696 | +}; |
1697 | + |
1698 | +/** |
1699 | + * Enables or disables any matching elements. |
1700 | + */ |
1701 | +$.fn.enable = function(b) { |
1702 | + if (b === undefined) { |
1703 | + b = true; |
1704 | + } |
1705 | + return this.each(function() { |
1706 | + this.disabled = !b; |
1707 | + }); |
1708 | +}; |
1709 | + |
1710 | +/** |
1711 | + * Checks/unchecks any matching checkboxes or radio buttons and |
1712 | + * selects/deselects and matching option elements. |
1713 | + */ |
1714 | +$.fn.selected = function(select) { |
1715 | + if (select === undefined) { |
1716 | + select = true; |
1717 | + } |
1718 | + return this.each(function() { |
1719 | + var t = this.type; |
1720 | + if (t == 'checkbox' || t == 'radio') { |
1721 | + this.checked = select; |
1722 | + } |
1723 | + else if (this.tagName.toLowerCase() == 'option') { |
1724 | + var $sel = $(this).parent('select'); |
1725 | + if (select && $sel[0] && $sel[0].type == 'select-one') { |
1726 | + // deselect all other options |
1727 | + $sel.find('option').selected(false); |
1728 | } |
1729 | - }); |
1730 | - }; |
1731 | - |
1732 | - // helper fn for console logging |
1733 | - // set $.fn.ajaxSubmit.debug to true to enable debug logging |
1734 | - function log() { |
1735 | - if ($.fn.ajaxSubmit.debug) { |
1736 | - var msg = '[jquery.form] ' + Array.prototype.join.call(arguments, ''); |
1737 | - if (window.console && window.console.log) |
1738 | - window.console.log(msg); |
1739 | - else if (window.opera && window.opera.postError) |
1740 | - window.opera.postError(msg); |
1741 | + this.selected = select; |
1742 | } |
1743 | - } |
1744 | + }); |
1745 | +}; |
1746 | + |
1747 | +// expose debug var |
1748 | +$.fn.ajaxSubmit.debug = false; |
1749 | + |
1750 | +// helper fn for console logging |
1751 | +function log() { |
1752 | + if (!$.fn.ajaxSubmit.debug) |
1753 | + return; |
1754 | + var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); |
1755 | + if (window.console && window.console.log) { |
1756 | + window.console.log(msg); |
1757 | + } |
1758 | + else if (window.opera && window.opera.postError) { |
1759 | + window.opera.postError(msg); |
1760 | + } |
1761 | +} |
1762 | + |
1763 | })(jQuery); |