Ticket #15909: jquery.form.diff
| File jquery.form.diff, 50.3 KB (added by niallkennedy, 2 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.63 (29-JAN-2011) 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[0].getAttribute('method') || 'GET', // IE7 massage (see issue 57) 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 // fire 'notify' event258 $.event.trigger('form.submit.notify', [this, options]);259 return this;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 var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" />'); 194 var io = $io[0]; 273 195 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 }; 196 $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); 283 197 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]); 198 var xhr = { // mock object 199 aborted: 0, 200 responseText: null, 201 responseXML: null, 202 status: 0, 203 statusText: 'n/a', 204 getAllResponseHeaders: function() {}, 205 getResponseHeader: function() {}, 206 setRequestHeader: function() {}, 207 abort: function() { 208 this.aborted = 1; 209 $io.attr('src', s.iframeSrc); // abort op in progress 210 } 211 }; 288 212 289 var cbInvoked = 0; 290 var timedOut = 0; 213 var g = s.global; 214 // trigger ajax global events so that activity/block indicators work like normal 215 if (g && ! $.active++) { 216 $.event.trigger("ajaxStart"); 217 } 218 if (g) { 219 $.event.trigger("ajaxSend", [xhr, s]); 220 } 291 221 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'; 222 if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) { 223 if (s.global) { 224 $.active--; 225 } 226 return; 227 } 228 if (xhr.aborted) { 229 return; 230 } 303 231 304 // support timout 305 if (opts.timeout) 306 setTimeout(function() { timedOut = true; cb(); }, opts.timeout); 232 var timedOut = 0; 307 233 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); 234 // add submitting element to data if we know it 235 var sub = form.clk; 236 if (sub) { 237 var n = sub.name; 238 if (n && !sub.disabled) { 239 s.extraData = s.extraData || {}; 240 s.extraData[n] = sub.value; 241 if (sub.type == "image") { 242 s.extraData[n+'.x'] = form.clk_x; 243 s.extraData[n+'.y'] = form.clk_y; 244 } 245 } 246 } 314 247 315 function cb() { 316 if (cbInvoked++) return; 248 // take a breath so that pending repaints get some cpu time before the upload starts 249 function doSubmit() { 250 // make sure form attrs are set 251 var t = $form.attr('target'), a = $form.attr('action'); 317 252 253 // update form attrs in IE friendly way 254 form.setAttribute('target',id); 255 if (form.getAttribute('method') != 'POST') { 256 form.setAttribute('method', 'POST'); 257 } 258 if (form.getAttribute('action') != s.url) { 259 form.setAttribute('action', s.url); 260 } 261 262 // ie borks in some cases when setting encoding 263 if (! s.skipEncodingOverride) { 264 $form.attr({ 265 encoding: 'multipart/form-data', 266 enctype: 'multipart/form-data' 267 }); 268 } 269 270 // support timout 271 if (s.timeout) { 272 setTimeout(function() { timedOut = true; cb(); }, s.timeout); 273 } 274 275 // add "extra" data to form if provided in options 276 var extraInputs = []; 277 try { 278 if (s.extraData) { 279 for (var n in s.extraData) { 280 extraInputs.push( 281 $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />') 282 .appendTo(form)[0]); 283 } 284 } 285 286 // add iframe to doc and submit the form 287 $io.appendTo('body'); 288 io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); 289 form.submit(); 290 } 291 finally { 292 // reset attrs and remove "extra" input elements 293 form.setAttribute('action',a); 294 if(t) { 295 form.setAttribute('target', t); 296 } else { 297 $form.removeAttr('target'); 298 } 299 $(extraInputs).remove(); 300 } 301 } 302 303 if (s.forceSync) { 304 doSubmit(); 305 } 306 else { 307 setTimeout(doSubmit, 10); // this lets dom updates render 308 } 309 310 var data, doc, domCheckCount = 50; 311 312 function cb() { 313 doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; 314 if (!doc || doc.location.href == s.iframeSrc) { 315 // response not received yet 316 return; 317 } 318 318 io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); 319 319 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; 320 var ok = true; 321 try { 322 if (timedOut) { 323 throw 'timeout'; 324 } 328 325 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 } 326 var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); 327 log('isXml='+isXml); 328 if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) { 329 if (--domCheckCount) { 330 // in some browsers (Opera) the iframe DOM is not always traversable when 331 // the onload callback fires, so we loop a bit to accommodate 332 log('requeing onLoad callback, DOM not available'); 333 setTimeout(cb, 250); 334 return; 335 } 336 // let this fall through because server response could be an empty document 337 //log('Could not access iframe DOM after mutiple tries.'); 338 //throw 'DOMException: not available'; 339 } 350 340 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'); 341 //log('response detected'); 342 xhr.responseText = doc.body ? doc.body.innerHTML : doc.documentElement ? doc.documentElement.innerHTML : null; 343 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; 344 xhr.getResponseHeader = function(header){ 345 var headers = {'content-type': s.dataType}; 346 return headers[header]; 347 }; 359 348 360 // clean up 361 setTimeout(function() { 362 $io.remove(); 363 xhr.responseXML = null; 364 }, 100); 365 }; 349 var scr = /(json|script)/.test(s.dataType); 350 if (scr || s.textarea) { 351 // see if user embedded response in textarea 352 var ta = doc.getElementsByTagName('textarea')[0]; 353 if (ta) { 354 xhr.responseText = ta.value; 355 } 356 else if (scr) { 357 // account for browsers injecting pre around json response 358 var pre = doc.getElementsByTagName('pre')[0]; 359 var b = doc.getElementsByTagName('body')[0]; 360 if (pre) { 361 xhr.responseText = pre.textContent; 362 } 363 else if (b) { 364 xhr.responseText = b.innerHTML; 365 } 366 } 367 } 368 else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { 369 xhr.responseXML = toXml(xhr.responseText); 370 } 371 372 data = httpData(xhr, s.dataType, s); 373 } 374 catch(e){ 375 log('error caught:',e); 376 ok = false; 377 xhr.error = e; 378 s.error.call(s.context, xhr, 'error', e); 379 g && $.event.trigger("ajaxError", [xhr, s, e]); 380 } 381 382 if (xhr.aborted) { 383 log('upload aborted'); 384 ok = false; 385 } 366 386 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 }; 387 // ordering of these callbacks/triggers is odd, but that's how $.ajax does it 388 if (ok) { 389 s.success.call(s.context, data, 'success', xhr); 390 g && $.event.trigger("ajaxSuccess", [xhr, s]); 391 } 392 393 g && $.event.trigger("ajaxComplete", [xhr, s]); 394 395 if (g && ! --$.active) { 396 $.event.trigger("ajaxStop"); 397 } 398 399 s.complete && s.complete.call(s.context, xhr, ok ? 'success' : 'error'); 400 401 // clean up 402 setTimeout(function() { 403 $io.removeData('form-plugin-onload'); 404 $io.remove(); 405 xhr.responseXML = null; 406 }, 100); 407 } 408 409 var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+) 410 if (window.ActiveXObject) { 411 doc = new ActiveXObject('Microsoft.XMLDOM'); 412 doc.async = 'false'; 413 doc.loadXML(s); 414 } 415 else { 416 doc = (new DOMParser()).parseFromString(s, 'text/xml'); 417 } 418 return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null; 419 }; 420 var parseJSON = $.parseJSON || function(s) { 421 return window['eval']('(' + s + ')'); 422 }; 423 424 var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4 425 var ct = xhr.getResponseHeader('content-type') || '', 426 xml = type === 'xml' || !type && ct.indexOf('xml') >= 0, 427 data = xml ? xhr.responseXML : xhr.responseText; 428 429 if (xml && data.documentElement.nodeName === 'parsererror') { 430 $.error && $.error('parsererror'); 431 } 432 if (s && s.dataFilter) { 433 data = s.dataFilter(data, type); 434 } 435 if (typeof data === 'string') { 436 if (type === 'json' || !type && ct.indexOf('json') >= 0) { 437 data = parseJSON(data); 438 } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) { 439 $.globalEval(data); 440 } 441 } 442 return data; 443 }; 444 } 378 445 }; 379 $.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids380 446 381 447 /** 382 448 * ajaxForm() provides a mechanism for fully automating form submission. … … 384 450 * The advantages of using this method instead of ajaxSubmit() are: 385 451 * 386 452 * 1: This method will include coordinates for <input type="image" /> elements (if the element 387 * is used to submit the form).453 * is used to submit the form). 388 454 * 2. This method will include the submit element's name/value data (for the element that was 389 * used to submit the form).455 * used to submit the form). 390 456 * 3. This method binds the submit() method to the form for you. 391 457 * 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 458 * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely 396 459 * 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 460 * the form itself. 438 461 */ 439 462 $.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 }); 463 // in jQuery 1.3+ we can fix mistakes with the ready state 464 if (this.length === 0) { 465 var o = { s: this.selector, c: this.context }; 466 if (!$.isReady && o.s) { 467 log('DOM not ready, queuing ajaxForm'); 468 $(function() { 469 $(o.s,o.c).ajaxForm(options); 470 }); 471 return this; 472 } 473 // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready() 474 log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); 475 return this; 476 } 477 478 return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) { 479 if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed 480 e.preventDefault(); 481 $(this).ajaxSubmit(options); 482 } 483 }).bind('click.form-plugin', function(e) { 484 var target = e.target; 485 var $el = $(target); 486 if (!($el.is(":submit,input:image"))) { 487 // is this a child element of the submit el? (ex: a span within a button) 488 var t = $el.closest(':submit'); 489 if (t.length == 0) { 490 return; 491 } 492 target = t[0]; 493 } 494 var form = this; 495 form.clk = target; 496 if (target.type == 'image') { 497 if (e.offsetX != undefined) { 498 form.clk_x = e.offsetX; 499 form.clk_y = e.offsetY; 500 } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin 501 var offset = $el.offset(); 502 form.clk_x = e.pageX - offset.left; 503 form.clk_y = e.pageY - offset.top; 504 } else { 505 form.clk_x = e.pageX - target.offsetLeft; 506 form.clk_y = e.pageY - target.offsetTop; 507 } 508 } 509 // clear form vars 510 setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); 511 }); 446 512 }; 447 513 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 */ 514 // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm 487 515 $.fn.ajaxFormUnbind = function() { 488 this.unbind('submit', submitHandler); 489 return this.each(function() { 490 $(":submit,input:image", this).unbind('click', clickHandler); 491 }); 492 516 return this.unbind('submit.form-plugin click.form-plugin'); 493 517 }; 494 518 495 519 /** … … 502 526 * 503 527 * It is this array that is passed to pre-submit callback functions provided to the 504 528 * 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 529 */ 521 530 $.fn.formToArray = function(semantic) { 522 var a = []; 523 if (this.length == 0) return a; 531 var a = []; 532 if (this.length === 0) { 533 return a; 534 } 524 535 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; 536 var form = this[0]; 537 var els = semantic ? form.getElementsByTagName('*') : form.elements; 538 if (!els) { 539 return a; 540 } 541 542 var i,j,n,v,el,max,jmax; 543 for(i=0, max=els.length; i < max; i++) { 544 el = els[i]; 545 n = el.name; 546 if (!n) { 547 continue; 548 } 532 549 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 } 550 if (semantic && form.clk && el.type == "image") { 551 // handle image inputs on the fly when semantic == true 552 if(!el.disabled && form.clk == el) { 553 a.push({name: n, value: $(el).val()}); 554 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 555 } 556 continue; 557 } 539 558 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 } 559 v = $.fieldValue(el, true); 560 if (v && v.constructor == Array) { 561 for(j=0, jmax=v.length; j < jmax; j++) { 562 a.push({name: n, value: v[j]}); 563 } 564 } 565 else if (v !== null && typeof v != 'undefined') { 566 a.push({name: n, value: v}); 567 } 568 } 548 569 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; 570 if (!semantic && form.clk) { 571 // input type=='image' are not found in elements array! handle it here 572 var $input = $(form.clk), input = $input[0]; 573 n = input.name; 574 if (n && !input.disabled && input.type == 'image') { 575 a.push({name: n, value: $input.val()}); 576 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 577 } 578 } 579 return a; 560 580 }; 561 581 562 563 582 /** 564 583 * Serializes form data into a 'submittable' string. This method will return a string 565 584 * 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 585 */ 581 586 $.fn.formSerialize = function(semantic) { 582 //hand off to jQuery.param for proper encoding583 return $.param(this.formToArray(semantic));587 //hand off to jQuery.param for proper encoding 588 return $.param(this.formToArray(semantic)); 584 589 }; 585 590 586 587 591 /** 588 592 * Serializes all field elements in the jQuery object into a query string. 589 593 * 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 594 */ 615 595 $.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); 596 var a = []; 597 this.each(function() { 598 var n = this.name; 599 if (!n) { 600 return; 601 } 602 var v = $.fieldValue(this, successful); 603 if (v && v.constructor == Array) { 604 for (var i=0,max=v.length; i < max; i++) { 605 a.push({name: n, value: v[i]}); 606 } 607 } 608 else if (v !== null && typeof v != 'undefined') { 609 a.push({name: this.name, value: v}); 610 } 611 }); 612 //hand off to jQuery.param for proper encoding 613 return $.param(a); 630 614 }; 631 615 632 633 616 /** 634 617 * Returns the value(s) of the element in the matched set. For example, consider the following form: 635 618 * 636 619 * <form><fieldset> 637 * <input name="A" type="text" />638 * <input name="A" type="text" />639 * <input name="B" type="checkbox" value="B1" />640 * <input name="B" type="checkbox" value="B2"/>641 * <input name="C" type="radio" value="C1" />642 * <input name="C" type="radio" value="C2" />620 * <input name="A" type="text" /> 621 * <input name="A" type="text" /> 622 * <input name="B" type="checkbox" value="B1" /> 623 * <input name="B" type="checkbox" value="B2"/> 624 * <input name="C" type="radio" value="C1" /> 625 * <input name="C" type="radio" value="C2" /> 643 626 * </fieldset></form> 644 627 * 645 628 * var v = $(':text').fieldValue(); … … 666 649 * for each element is returned. 667 650 * 668 651 * 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 652 * array will be empty, otherwise it will contain one or more values. 694 653 */ 695 654 $.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; 655 for (var val=[], i=0, max=this.length; i < max; i++) { 656 var el = this[i]; 657 var v = $.fieldValue(el, successful); 658 if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) { 659 continue; 660 } 661 v.constructor == Array ? $.merge(val, v) : val.push(v); 662 } 663 return val; 704 664 }; 705 665 706 666 /** 707 667 * 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 668 */ 727 669 $.fieldValue = function(el, successful) { 728 var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); 729 if (typeof successful == 'undefined') successful = true; 670 var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); 671 if (successful === undefined) { 672 successful = true; 673 } 730 674 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; 675 if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || 676 (t == 'checkbox' || t == 'radio') && !el.checked || 677 (t == 'submit' || t == 'image') && el.form && el.form.clk != el || 678 tag == 'select' && el.selectedIndex == -1)) { 679 return null; 680 } 736 681 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; 682 if (tag == 'select') { 683 var index = el.selectedIndex; 684 if (index < 0) { 685 return null; 686 } 687 var a = [], ops = el.options; 688 var one = (t == 'select-one'); 689 var max = (one ? index+1 : ops.length); 690 for(var i=(one ? index : 0); i < max; i++) { 691 var op = ops[i]; 692 if (op.selected) { 693 var v = op.value; 694 if (!v) { // extra pain for IE... 695 v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; 696 } 697 if (one) { 698 return v; 699 } 700 a.push(v); 701 } 702 } 703 return a; 704 } 705 return $(el).val(); 755 706 }; 756 707 757 758 708 /** 759 709 * Clears the form data. Takes the following actions on the form's input fields: 760 710 * - input text fields will have their 'value' property set to the empty string … … 762 712 * - checkbox and radio inputs will have their 'checked' property set to false 763 713 * - inputs of type submit, button, reset, and hidden will *not* be effected 764 714 * - 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 715 */ 773 716 $.fn.clearForm = function() { 774 return this.each(function() {775 $('input,select,textarea', this).clearFields();776 });717 return this.each(function() { 718 $('input,select,textarea', this).clearFields(); 719 }); 777 720 }; 778 721 779 722 /** 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 723 * Clears the selected form elements. 793 724 */ 794 725 $.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 }); 726 return this.each(function() { 727 var t = this.type, tag = this.tagName.toLowerCase(); 728 if (t == 'text' || t == 'password' || tag == 'textarea') { 729 this.value = ''; 730 } 731 else if (t == 'checkbox' || t == 'radio') { 732 this.checked = false; 733 } 734 else if (tag == 'select') { 735 this.selectedIndex = -1; 736 } 737 }); 804 738 }; 805 739 806 807 740 /** 808 741 * 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 742 */ 817 743 $.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 }); 744 return this.each(function() { 745 // guard against an input with the name of 'reset' 746 // note that IE reports the reset function as an 'object' 747 if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) { 748 this.reset(); 749 } 750 }); 824 751 }; 825 752 826 827 753 /** 828 754 * 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 755 */ 837 $.fn.enable = function(b) { 838 if (b == undefined) b = true; 839 return this.each(function() { 840 this.disabled = !b 841 }); 756 $.fn.enable = function(b) { 757 if (b === undefined) { 758 b = true; 759 } 760 return this.each(function() { 761 this.disabled = !b; 762 }); 842 763 }; 843 764 844 765 /** 845 766 * Checks/unchecks any matching checkboxes or radio buttons and 846 767 * selects/deselects and matching option elements. 847 *848 * @example $(':checkbox').selected();849 * @desc Checks all checkboxes850 *851 * @name select852 * @type jQuery853 * @cat Plugins/Form854 768 */ 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 }); 769 $.fn.selected = function(select) { 770 if (select === undefined) { 771 select = true; 772 } 773 return this.each(function() { 774 var t = this.type; 775 if (t == 'checkbox' || t == 'radio') { 776 this.checked = select; 777 } 778 else if (this.tagName.toLowerCase() == 'option') { 779 var $sel = $(this).parent('select'); 780 if (select && $sel[0] && $sel[0].type == 'select-one') { 781 // deselect all other options 782 $sel.find('option').selected(false); 783 } 784 this.selected = select; 785 } 786 }); 870 787 }; 871 788 872 })(jQuery); 789 // helper fn for console logging 790 // set $.fn.ajaxSubmit.debug to true to enable debug logging 791 function log() { 792 if ($.fn.ajaxSubmit.debug) { 793 var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); 794 if (window.console && window.console.log) { 795 window.console.log(msg); 796 } 797 else if (window.opera && window.opera.postError) { 798 window.opera.postError(msg); 799 } 800 } 801 }; 802 803 })(jQuery); 804 No newline at end of file
