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