hgbook
diff web/support/javascript/form.js @ 1089:0e202b76f958
2.5.0 2 para
author | Zhaoping Sun <zhaopingsun@gmail.com> |
---|---|
date | Sun Nov 22 21:35:38 2009 -0500 (2009-11-22) |
parents | ad304b606163 |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/web/support/javascript/form.js Sun Nov 22 21:35:38 2009 -0500 1.3 @@ -0,0 +1,819 @@ 1.4 +/* 1.5 + * jQuery Form Plugin 1.6 + * @requires jQuery v1.1 or later 1.7 + * 1.8 + * Examples at: http://malsup.com/jquery/form/ 1.9 + * Dual licensed under the MIT and GPL licenses: 1.10 + * http://www.opensource.org/licenses/mit-license.php 1.11 + * http://www.gnu.org/licenses/gpl.html 1.12 + * 1.13 + * Revision: $Id$ 1.14 + */ 1.15 + (function($) { 1.16 +/** 1.17 + * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX. 1.18 + * 1.19 + * ajaxSubmit accepts a single argument which can be either a success callback function 1.20 + * or an options Object. If a function is provided it will be invoked upon successful 1.21 + * completion of the submit and will be passed the response from the server. 1.22 + * If an options Object is provided, the following attributes are supported: 1.23 + * 1.24 + * target: Identifies the element(s) in the page to be updated with the server response. 1.25 + * This value may be specified as a jQuery selection string, a jQuery object, 1.26 + * or a DOM element. 1.27 + * default value: null 1.28 + * 1.29 + * url: URL to which the form data will be submitted. 1.30 + * default value: value of form's 'action' attribute 1.31 + * 1.32 + * type: The method in which the form data should be submitted, 'GET' or 'POST'. 1.33 + * default value: value of form's 'method' attribute (or 'GET' if none found) 1.34 + * 1.35 + * data: Additional data to add to the request, specified as key/value pairs (see $.ajax). 1.36 + * 1.37 + * beforeSubmit: Callback method to be invoked before the form is submitted. 1.38 + * default value: null 1.39 + * 1.40 + * success: Callback method to be invoked after the form has been successfully submitted 1.41 + * and the response has been returned from the server 1.42 + * default value: null 1.43 + * 1.44 + * dataType: Expected dataType of the response. One of: null, 'xml', 'script', or 'json' 1.45 + * default value: null 1.46 + * 1.47 + * semantic: Boolean flag indicating whether data must be submitted in semantic order (slower). 1.48 + * default value: false 1.49 + * 1.50 + * resetForm: Boolean flag indicating whether the form should be reset if the submit is successful 1.51 + * 1.52 + * clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful 1.53 + * 1.54 + * 1.55 + * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for 1.56 + * validating the form data. If the 'beforeSubmit' callback returns false then the form will 1.57 + * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data 1.58 + * in array format, the jQuery object, and the options object passed into ajaxSubmit. 1.59 + * The form data array takes the following form: 1.60 + * 1.61 + * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] 1.62 + * 1.63 + * If a 'success' callback method is provided it is invoked after the response has been returned 1.64 + * from the server. It is passed the responseText or responseXML value (depending on dataType). 1.65 + * See jQuery.ajax for further details. 1.66 + * 1.67 + * 1.68 + * The dataType option provides a means for specifying how the server response should be handled. 1.69 + * This maps directly to the jQuery.httpData method. The following values are supported: 1.70 + * 1.71 + * 'xml': if dataType == 'xml' the server response is treated as XML and the 'success' 1.72 + * callback method, if specified, will be passed the responseXML value 1.73 + * 'json': if dataType == 'json' the server response will be evaluted and passed to 1.74 + * the 'success' callback, if specified 1.75 + * 'script': if dataType == 'script' the server response is evaluated in the global context 1.76 + * 1.77 + * 1.78 + * Note that it does not make sense to use both the 'target' and 'dataType' options. If both 1.79 + * are provided the target will be ignored. 1.80 + * 1.81 + * The semantic argument can be used to force form serialization in semantic order. 1.82 + * This is normally true anyway, unless the form contains input elements of type='image'. 1.83 + * If your form must be submitted with name/value pairs in semantic order and your form 1.84 + * contains an input of type='image" then pass true for this arg, otherwise pass false 1.85 + * (or nothing) to avoid the overhead for this logic. 1.86 + * 1.87 + * 1.88 + * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this: 1.89 + * 1.90 + * $("#form-id").submit(function() { 1.91 + * $(this).ajaxSubmit(options); 1.92 + * return false; // cancel conventional submit 1.93 + * }); 1.94 + * 1.95 + * When using ajaxForm(), however, this is done for you. 1.96 + * 1.97 + * @example 1.98 + * $('#myForm').ajaxSubmit(function(data) { 1.99 + * alert('Form submit succeeded! Server returned: ' + data); 1.100 + * }); 1.101 + * @desc Submit form and alert server response 1.102 + * 1.103 + * 1.104 + * @example 1.105 + * var options = { 1.106 + * target: '#myTargetDiv' 1.107 + * }; 1.108 + * $('#myForm').ajaxSubmit(options); 1.109 + * @desc Submit form and update page element with server response 1.110 + * 1.111 + * 1.112 + * @example 1.113 + * var options = { 1.114 + * success: function(responseText) { 1.115 + * alert(responseText); 1.116 + * } 1.117 + * }; 1.118 + * $('#myForm').ajaxSubmit(options); 1.119 + * @desc Submit form and alert the server response 1.120 + * 1.121 + * 1.122 + * @example 1.123 + * var options = { 1.124 + * beforeSubmit: function(formArray, jqForm) { 1.125 + * if (formArray.length == 0) { 1.126 + * alert('Please enter data.'); 1.127 + * return false; 1.128 + * } 1.129 + * } 1.130 + * }; 1.131 + * $('#myForm').ajaxSubmit(options); 1.132 + * @desc Pre-submit validation which aborts the submit operation if form data is empty 1.133 + * 1.134 + * 1.135 + * @example 1.136 + * var options = { 1.137 + * url: myJsonUrl.php, 1.138 + * dataType: 'json', 1.139 + * success: function(data) { 1.140 + * // 'data' is an object representing the the evaluated json data 1.141 + * } 1.142 + * }; 1.143 + * $('#myForm').ajaxSubmit(options); 1.144 + * @desc json data returned and evaluated 1.145 + * 1.146 + * 1.147 + * @example 1.148 + * var options = { 1.149 + * url: myXmlUrl.php, 1.150 + * dataType: 'xml', 1.151 + * success: function(responseXML) { 1.152 + * // responseXML is XML document object 1.153 + * var data = $('myElement', responseXML).text(); 1.154 + * } 1.155 + * }; 1.156 + * $('#myForm').ajaxSubmit(options); 1.157 + * @desc XML data returned from server 1.158 + * 1.159 + * 1.160 + * @example 1.161 + * var options = { 1.162 + * resetForm: true 1.163 + * }; 1.164 + * $('#myForm').ajaxSubmit(options); 1.165 + * @desc submit form and reset it if successful 1.166 + * 1.167 + * @example 1.168 + * $('#myForm).submit(function() { 1.169 + * $(this).ajaxSubmit(); 1.170 + * return false; 1.171 + * }); 1.172 + * @desc Bind form's submit event to use ajaxSubmit 1.173 + * 1.174 + * 1.175 + * @name ajaxSubmit 1.176 + * @type jQuery 1.177 + * @param options object literal containing options which control the form submission process 1.178 + * @cat Plugins/Form 1.179 + * @return jQuery 1.180 + */ 1.181 +$.fn.ajaxSubmit = function(options) { 1.182 + if (typeof options == 'function') 1.183 + options = { success: options }; 1.184 + 1.185 + options = $.extend({ 1.186 + url: this.attr('action') || window.location, 1.187 + type: this.attr('method') || 'GET' 1.188 + }, options || {}); 1.189 + 1.190 + // hook for manipulating the form data before it is extracted; 1.191 + // convenient for use with rich editors like tinyMCE or FCKEditor 1.192 + var veto = {}; 1.193 + $.event.trigger('form.pre.serialize', [this, options, veto]); 1.194 + if (veto.veto) return this; 1.195 + 1.196 + var a = this.formToArray(options.semantic); 1.197 + if (options.data) { 1.198 + for (var n in options.data) 1.199 + a.push( { name: n, value: options.data[n] } ); 1.200 + } 1.201 + 1.202 + // give pre-submit callback an opportunity to abort the submit 1.203 + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this; 1.204 + 1.205 + // fire vetoable 'validate' event 1.206 + $.event.trigger('form.submit.validate', [a, this, options, veto]); 1.207 + if (veto.veto) return this; 1.208 + 1.209 + var q = $.param(a);//.replace(/%20/g,'+'); 1.210 + 1.211 + if (options.type.toUpperCase() == 'GET') { 1.212 + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; 1.213 + options.data = null; // data is null for 'get' 1.214 + } 1.215 + else 1.216 + options.data = q; // data is the query string for 'post' 1.217 + 1.218 + var $form = this, callbacks = []; 1.219 + if (options.resetForm) callbacks.push(function() { $form.resetForm(); }); 1.220 + if (options.clearForm) callbacks.push(function() { $form.clearForm(); }); 1.221 + 1.222 + // perform a load on the target only if dataType is not provided 1.223 + if (!options.dataType && options.target) { 1.224 + var oldSuccess = options.success || function(){}; 1.225 + callbacks.push(function(data) { 1.226 + if (this.evalScripts) 1.227 + $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments); 1.228 + else // jQuery v1.1.4 1.229 + $(options.target).html(data).each(oldSuccess, arguments); 1.230 + }); 1.231 + } 1.232 + else if (options.success) 1.233 + callbacks.push(options.success); 1.234 + 1.235 + options.success = function(data, status) { 1.236 + for (var i=0, max=callbacks.length; i < max; i++) 1.237 + callbacks[i](data, status, $form); 1.238 + }; 1.239 + 1.240 + // are there files to upload? 1.241 + var files = $('input:file', this).fieldValue(); 1.242 + var found = false; 1.243 + for (var j=0; j < files.length; j++) 1.244 + if (files[j]) 1.245 + found = true; 1.246 + 1.247 + if (options.iframe || found) // options.iframe allows user to force iframe mode 1.248 + fileUpload(); 1.249 + else 1.250 + $.ajax(options); 1.251 + 1.252 + // fire 'notify' event 1.253 + $.event.trigger('form.submit.notify', [this, options]); 1.254 + return this; 1.255 + 1.256 + 1.257 + // private function for handling file uploads (hat tip to YAHOO!) 1.258 + function fileUpload() { 1.259 + var form = $form[0]; 1.260 + var opts = $.extend({}, $.ajaxSettings, options); 1.261 + 1.262 + var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++; 1.263 + var $io = $('<iframe id="' + id + '" name="' + id + '" />'); 1.264 + var io = $io[0]; 1.265 + var op8 = $.browser.opera && window.opera.version() < 9; 1.266 + if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");'; 1.267 + $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); 1.268 + 1.269 + var xhr = { // mock object 1.270 + responseText: null, 1.271 + responseXML: null, 1.272 + status: 0, 1.273 + statusText: 'n/a', 1.274 + getAllResponseHeaders: function() {}, 1.275 + getResponseHeader: function() {}, 1.276 + setRequestHeader: function() {} 1.277 + }; 1.278 + 1.279 + var g = opts.global; 1.280 + // trigger ajax global events so that activity/block indicators work like normal 1.281 + if (g && ! $.active++) $.event.trigger("ajaxStart"); 1.282 + if (g) $.event.trigger("ajaxSend", [xhr, opts]); 1.283 + 1.284 + var cbInvoked = 0; 1.285 + var timedOut = 0; 1.286 + 1.287 + // take a breath so that pending repaints get some cpu time before the upload starts 1.288 + setTimeout(function() { 1.289 + $io.appendTo('body'); 1.290 + // jQuery's event binding doesn't work for iframe events in IE 1.291 + io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); 1.292 + 1.293 + // make sure form attrs are set 1.294 + var encAttr = form.encoding ? 'encoding' : 'enctype'; 1.295 + var t = $form.attr('target'); 1.296 + $form.attr({ 1.297 + target: id, 1.298 + method: 'POST', 1.299 + action: opts.url 1.300 + }); 1.301 + form[encAttr] = 'multipart/form-data'; 1.302 + 1.303 + // support timout 1.304 + if (opts.timeout) 1.305 + setTimeout(function() { timedOut = true; cb(); }, opts.timeout); 1.306 + 1.307 + form.submit(); 1.308 + $form.attr('target', t); // reset target 1.309 + }, 10); 1.310 + 1.311 + function cb() { 1.312 + if (cbInvoked++) return; 1.313 + 1.314 + io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); 1.315 + 1.316 + var ok = true; 1.317 + try { 1.318 + if (timedOut) throw 'timeout'; 1.319 + // extract the server response from the iframe 1.320 + var data, doc; 1.321 + doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document; 1.322 + xhr.responseText = doc.body ? doc.body.innerHTML : null; 1.323 + xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; 1.324 + 1.325 + if (opts.dataType == 'json' || opts.dataType == 'script') { 1.326 + var ta = doc.getElementsByTagName('textarea')[0]; 1.327 + data = ta ? ta.value : xhr.responseText; 1.328 + if (opts.dataType == 'json') 1.329 + eval("data = " + data); 1.330 + else 1.331 + $.globalEval(data); 1.332 + } 1.333 + else if (opts.dataType == 'xml') { 1.334 + data = xhr.responseXML; 1.335 + if (!data && xhr.responseText != null) 1.336 + data = toXml(xhr.responseText); 1.337 + } 1.338 + else { 1.339 + data = xhr.responseText; 1.340 + } 1.341 + } 1.342 + catch(e){ 1.343 + ok = false; 1.344 + $.handleError(opts, xhr, 'error', e); 1.345 + } 1.346 + 1.347 + // ordering of these callbacks/triggers is odd, but that's how $.ajax does it 1.348 + if (ok) { 1.349 + opts.success(data, 'success'); 1.350 + if (g) $.event.trigger("ajaxSuccess", [xhr, opts]); 1.351 + } 1.352 + if (g) $.event.trigger("ajaxComplete", [xhr, opts]); 1.353 + if (g && ! --$.active) $.event.trigger("ajaxStop"); 1.354 + if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error'); 1.355 + 1.356 + // clean up 1.357 + setTimeout(function() { 1.358 + $io.remove(); 1.359 + xhr.responseXML = null; 1.360 + }, 100); 1.361 + }; 1.362 + 1.363 + function toXml(s, doc) { 1.364 + if (window.ActiveXObject) { 1.365 + doc = new ActiveXObject('Microsoft.XMLDOM'); 1.366 + doc.async = 'false'; 1.367 + doc.loadXML(s); 1.368 + } 1.369 + else 1.370 + doc = (new DOMParser()).parseFromString(s, 'text/xml'); 1.371 + return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null; 1.372 + }; 1.373 + }; 1.374 +}; 1.375 +$.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids 1.376 + 1.377 +/** 1.378 + * ajaxForm() provides a mechanism for fully automating form submission. 1.379 + * 1.380 + * The advantages of using this method instead of ajaxSubmit() are: 1.381 + * 1.382 + * 1: This method will include coordinates for <input type="image" /> elements (if the element 1.383 + * is used to submit the form). 1.384 + * 2. This method will include the submit element's name/value data (for the element that was 1.385 + * used to submit the form). 1.386 + * 3. This method binds the submit() method to the form for you. 1.387 + * 1.388 + * Note that for accurate x/y coordinates of image submit elements in all browsers 1.389 + * you need to also use the "dimensions" plugin (this method will auto-detect its presence). 1.390 + * 1.391 + * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely 1.392 + * passes the options argument along after properly binding events for submit elements and 1.393 + * the form itself. See ajaxSubmit for a full description of the options argument. 1.394 + * 1.395 + * 1.396 + * @example 1.397 + * var options = { 1.398 + * target: '#myTargetDiv' 1.399 + * }; 1.400 + * $('#myForm').ajaxSForm(options); 1.401 + * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response 1.402 + * when the form is submitted. 1.403 + * 1.404 + * 1.405 + * @example 1.406 + * var options = { 1.407 + * success: function(responseText) { 1.408 + * alert(responseText); 1.409 + * } 1.410 + * }; 1.411 + * $('#myForm').ajaxSubmit(options); 1.412 + * @desc Bind form's submit event so that server response is alerted after the form is submitted. 1.413 + * 1.414 + * 1.415 + * @example 1.416 + * var options = { 1.417 + * beforeSubmit: function(formArray, jqForm) { 1.418 + * if (formArray.length == 0) { 1.419 + * alert('Please enter data.'); 1.420 + * return false; 1.421 + * } 1.422 + * } 1.423 + * }; 1.424 + * $('#myForm').ajaxSubmit(options); 1.425 + * @desc Bind form's submit event so that pre-submit callback is invoked before the form 1.426 + * is submitted. 1.427 + * 1.428 + * 1.429 + * @name ajaxForm 1.430 + * @param options object literal containing options which control the form submission process 1.431 + * @return jQuery 1.432 + * @cat Plugins/Form 1.433 + * @type jQuery 1.434 + */ 1.435 +$.fn.ajaxForm = function(options) { 1.436 + return this.ajaxFormUnbind().submit(submitHandler).each(function() { 1.437 + // store options in hash 1.438 + this.formPluginId = $.fn.ajaxForm.counter++; 1.439 + $.fn.ajaxForm.optionHash[this.formPluginId] = options; 1.440 + $(":submit,input:image", this).click(clickHandler); 1.441 + }); 1.442 +}; 1.443 + 1.444 +$.fn.ajaxForm.counter = 1; 1.445 +$.fn.ajaxForm.optionHash = {}; 1.446 + 1.447 +function clickHandler(e) { 1.448 + var $form = this.form; 1.449 + $form.clk = this; 1.450 + if (this.type == 'image') { 1.451 + if (e.offsetX != undefined) { 1.452 + $form.clk_x = e.offsetX; 1.453 + $form.clk_y = e.offsetY; 1.454 + } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin 1.455 + var offset = $(this).offset(); 1.456 + $form.clk_x = e.pageX - offset.left; 1.457 + $form.clk_y = e.pageY - offset.top; 1.458 + } else { 1.459 + $form.clk_x = e.pageX - this.offsetLeft; 1.460 + $form.clk_y = e.pageY - this.offsetTop; 1.461 + } 1.462 + } 1.463 + // clear form vars 1.464 + setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10); 1.465 +}; 1.466 + 1.467 +function submitHandler() { 1.468 + // retrieve options from hash 1.469 + var id = this.formPluginId; 1.470 + var options = $.fn.ajaxForm.optionHash[id]; 1.471 + $(this).ajaxSubmit(options); 1.472 + return false; 1.473 +}; 1.474 + 1.475 +/** 1.476 + * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm 1.477 + * 1.478 + * @name ajaxFormUnbind 1.479 + * @return jQuery 1.480 + * @cat Plugins/Form 1.481 + * @type jQuery 1.482 + */ 1.483 +$.fn.ajaxFormUnbind = function() { 1.484 + this.unbind('submit', submitHandler); 1.485 + return this.each(function() { 1.486 + $(":submit,input:image", this).unbind('click', clickHandler); 1.487 + }); 1.488 + 1.489 +}; 1.490 + 1.491 +/** 1.492 + * formToArray() gathers form element data into an array of objects that can 1.493 + * be passed to any of the following ajax functions: $.get, $.post, or load. 1.494 + * Each object in the array has both a 'name' and 'value' property. An example of 1.495 + * an array for a simple login form might be: 1.496 + * 1.497 + * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] 1.498 + * 1.499 + * It is this array that is passed to pre-submit callback functions provided to the 1.500 + * ajaxSubmit() and ajaxForm() methods. 1.501 + * 1.502 + * The semantic argument can be used to force form serialization in semantic order. 1.503 + * This is normally true anyway, unless the form contains input elements of type='image'. 1.504 + * If your form must be submitted with name/value pairs in semantic order and your form 1.505 + * contains an input of type='image" then pass true for this arg, otherwise pass false 1.506 + * (or nothing) to avoid the overhead for this logic. 1.507 + * 1.508 + * @example var data = $("#myForm").formToArray(); 1.509 + * $.post( "myscript.cgi", data ); 1.510 + * @desc Collect all the data from a form and submit it to the server. 1.511 + * 1.512 + * @name formToArray 1.513 + * @param semantic true if serialization must maintain strict semantic ordering of elements (slower) 1.514 + * @type Array<Object> 1.515 + * @cat Plugins/Form 1.516 + */ 1.517 +$.fn.formToArray = function(semantic) { 1.518 + var a = []; 1.519 + if (this.length == 0) return a; 1.520 + 1.521 + var form = this[0]; 1.522 + var els = semantic ? form.getElementsByTagName('*') : form.elements; 1.523 + if (!els) return a; 1.524 + for(var i=0, max=els.length; i < max; i++) { 1.525 + var el = els[i]; 1.526 + var n = el.name; 1.527 + if (!n) continue; 1.528 + 1.529 + if (semantic && form.clk && el.type == "image") { 1.530 + // handle image inputs on the fly when semantic == true 1.531 + if(!el.disabled && form.clk == el) 1.532 + a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 1.533 + continue; 1.534 + } 1.535 + 1.536 + var v = $.fieldValue(el, true); 1.537 + if (v && v.constructor == Array) { 1.538 + for(var j=0, jmax=v.length; j < jmax; j++) 1.539 + a.push({name: n, value: v[j]}); 1.540 + } 1.541 + else if (v !== null && typeof v != 'undefined') 1.542 + a.push({name: n, value: v}); 1.543 + } 1.544 + 1.545 + if (!semantic && form.clk) { 1.546 + // input type=='image' are not found in elements array! handle them here 1.547 + var inputs = form.getElementsByTagName("input"); 1.548 + for(var i=0, max=inputs.length; i < max; i++) { 1.549 + var input = inputs[i]; 1.550 + var n = input.name; 1.551 + if(n && !input.disabled && input.type == "image" && form.clk == input) 1.552 + a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); 1.553 + } 1.554 + } 1.555 + return a; 1.556 +}; 1.557 + 1.558 + 1.559 +/** 1.560 + * Serializes form data into a 'submittable' string. This method will return a string 1.561 + * in the format: name1=value1&name2=value2 1.562 + * 1.563 + * The semantic argument can be used to force form serialization in semantic order. 1.564 + * If your form must be submitted with name/value pairs in semantic order then pass 1.565 + * true for this arg, otherwise pass false (or nothing) to avoid the overhead for 1.566 + * this logic (which can be significant for very large forms). 1.567 + * 1.568 + * @example var data = $("#myForm").formSerialize(); 1.569 + * $.ajax('POST', "myscript.cgi", data); 1.570 + * @desc Collect all the data from a form into a single string 1.571 + * 1.572 + * @name formSerialize 1.573 + * @param semantic true if serialization must maintain strict semantic ordering of elements (slower) 1.574 + * @type String 1.575 + * @cat Plugins/Form 1.576 + */ 1.577 +$.fn.formSerialize = function(semantic) { 1.578 + //hand off to jQuery.param for proper encoding 1.579 + return $.param(this.formToArray(semantic)); 1.580 +}; 1.581 + 1.582 + 1.583 +/** 1.584 + * Serializes all field elements in the jQuery object into a query string. 1.585 + * This method will return a string in the format: name1=value1&name2=value2 1.586 + * 1.587 + * The successful argument controls whether or not serialization is limited to 1.588 + * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 1.589 + * The default value of the successful argument is true. 1.590 + * 1.591 + * @example var data = $("input").formSerialize(); 1.592 + * @desc Collect the data from all successful input elements into a query string 1.593 + * 1.594 + * @example var data = $(":radio").formSerialize(); 1.595 + * @desc Collect the data from all successful radio input elements into a query string 1.596 + * 1.597 + * @example var data = $("#myForm :checkbox").formSerialize(); 1.598 + * @desc Collect the data from all successful checkbox input elements in myForm into a query string 1.599 + * 1.600 + * @example var data = $("#myForm :checkbox").formSerialize(false); 1.601 + * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string 1.602 + * 1.603 + * @example var data = $(":input").formSerialize(); 1.604 + * @desc Collect the data from all successful input, select, textarea and button elements into a query string 1.605 + * 1.606 + * @name fieldSerialize 1.607 + * @param successful true if only successful controls should be serialized (default is true) 1.608 + * @type String 1.609 + * @cat Plugins/Form 1.610 + */ 1.611 +$.fn.fieldSerialize = function(successful) { 1.612 + var a = []; 1.613 + this.each(function() { 1.614 + var n = this.name; 1.615 + if (!n) return; 1.616 + var v = $.fieldValue(this, successful); 1.617 + if (v && v.constructor == Array) { 1.618 + for (var i=0,max=v.length; i < max; i++) 1.619 + a.push({name: n, value: v[i]}); 1.620 + } 1.621 + else if (v !== null && typeof v != 'undefined') 1.622 + a.push({name: this.name, value: v}); 1.623 + }); 1.624 + //hand off to jQuery.param for proper encoding 1.625 + return $.param(a); 1.626 +}; 1.627 + 1.628 + 1.629 +/** 1.630 + * Returns the value(s) of the element in the matched set. For example, consider the following form: 1.631 + * 1.632 + * <form><fieldset> 1.633 + * <input name="A" type="text" /> 1.634 + * <input name="A" type="text" /> 1.635 + * <input name="B" type="checkbox" value="B1" /> 1.636 + * <input name="B" type="checkbox" value="B2"/> 1.637 + * <input name="C" type="radio" value="C1" /> 1.638 + * <input name="C" type="radio" value="C2" /> 1.639 + * </fieldset></form> 1.640 + * 1.641 + * var v = $(':text').fieldValue(); 1.642 + * // if no values are entered into the text inputs 1.643 + * v == ['',''] 1.644 + * // if values entered into the text inputs are 'foo' and 'bar' 1.645 + * v == ['foo','bar'] 1.646 + * 1.647 + * var v = $(':checkbox').fieldValue(); 1.648 + * // if neither checkbox is checked 1.649 + * v === undefined 1.650 + * // if both checkboxes are checked 1.651 + * v == ['B1', 'B2'] 1.652 + * 1.653 + * var v = $(':radio').fieldValue(); 1.654 + * // if neither radio is checked 1.655 + * v === undefined 1.656 + * // if first radio is checked 1.657 + * v == ['C1'] 1.658 + * 1.659 + * The successful argument controls whether or not the field element must be 'successful' 1.660 + * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 1.661 + * The default value of the successful argument is true. If this value is false the value(s) 1.662 + * for each element is returned. 1.663 + * 1.664 + * Note: This method *always* returns an array. If no valid value can be determined the 1.665 + * array will be empty, otherwise it will contain one or more values. 1.666 + * 1.667 + * @example var data = $("#myPasswordElement").fieldValue(); 1.668 + * alert(data[0]); 1.669 + * @desc Alerts the current value of the myPasswordElement element 1.670 + * 1.671 + * @example var data = $("#myForm :input").fieldValue(); 1.672 + * @desc Get the value(s) of the form elements in myForm 1.673 + * 1.674 + * @example var data = $("#myForm :checkbox").fieldValue(); 1.675 + * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object. 1.676 + * 1.677 + * @example var data = $("#mySingleSelect").fieldValue(); 1.678 + * @desc Get the value(s) of the select control 1.679 + * 1.680 + * @example var data = $(':text').fieldValue(); 1.681 + * @desc Get the value(s) of the text input or textarea elements 1.682 + * 1.683 + * @example var data = $("#myMultiSelect").fieldValue(); 1.684 + * @desc Get the values for the select-multiple control 1.685 + * 1.686 + * @name fieldValue 1.687 + * @param Boolean successful true if only the values for successful controls should be returned (default is true) 1.688 + * @type Array<String> 1.689 + * @cat Plugins/Form 1.690 + */ 1.691 +$.fn.fieldValue = function(successful) { 1.692 + for (var val=[], i=0, max=this.length; i < max; i++) { 1.693 + var el = this[i]; 1.694 + var v = $.fieldValue(el, successful); 1.695 + if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) 1.696 + continue; 1.697 + v.constructor == Array ? $.merge(val, v) : val.push(v); 1.698 + } 1.699 + return val; 1.700 +}; 1.701 + 1.702 +/** 1.703 + * Returns the value of the field element. 1.704 + * 1.705 + * The successful argument controls whether or not the field element must be 'successful' 1.706 + * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). 1.707 + * The default value of the successful argument is true. If the given element is not 1.708 + * successful and the successful arg is not false then the returned value will be null. 1.709 + * 1.710 + * Note: If the successful flag is true (default) but the element is not successful, the return will be null 1.711 + * Note: The value returned for a successful select-multiple element will always be an array. 1.712 + * Note: If the element has no value the return value will be undefined. 1.713 + * 1.714 + * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]); 1.715 + * @desc Gets the current value of the myPasswordElement element 1.716 + * 1.717 + * @name fieldValue 1.718 + * @param Element el The DOM element for which the value will be returned 1.719 + * @param Boolean successful true if value returned must be for a successful controls (default is true) 1.720 + * @type String or Array<String> or null or undefined 1.721 + * @cat Plugins/Form 1.722 + */ 1.723 +$.fieldValue = function(el, successful) { 1.724 + var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); 1.725 + if (typeof successful == 'undefined') successful = true; 1.726 + 1.727 + if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || 1.728 + (t == 'checkbox' || t == 'radio') && !el.checked || 1.729 + (t == 'submit' || t == 'image') && el.form && el.form.clk != el || 1.730 + tag == 'select' && el.selectedIndex == -1)) 1.731 + return null; 1.732 + 1.733 + if (tag == 'select') { 1.734 + var index = el.selectedIndex; 1.735 + if (index < 0) return null; 1.736 + var a = [], ops = el.options; 1.737 + var one = (t == 'select-one'); 1.738 + var max = (one ? index+1 : ops.length); 1.739 + for(var i=(one ? index : 0); i < max; i++) { 1.740 + var op = ops[i]; 1.741 + if (op.selected) { 1.742 + // extra pain for IE... 1.743 + var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value; 1.744 + if (one) return v; 1.745 + a.push(v); 1.746 + } 1.747 + } 1.748 + return a; 1.749 + } 1.750 + return el.value; 1.751 +}; 1.752 + 1.753 + 1.754 +/** 1.755 + * Clears the form data. Takes the following actions on the form's input fields: 1.756 + * - input text fields will have their 'value' property set to the empty string 1.757 + * - select elements will have their 'selectedIndex' property set to -1 1.758 + * - checkbox and radio inputs will have their 'checked' property set to false 1.759 + * - inputs of type submit, button, reset, and hidden will *not* be effected 1.760 + * - button elements will *not* be effected 1.761 + * 1.762 + * @example $('form').clearForm(); 1.763 + * @desc Clears all forms on the page. 1.764 + * 1.765 + * @name clearForm 1.766 + * @type jQuery 1.767 + * @cat Plugins/Form 1.768 + */ 1.769 +$.fn.clearForm = function() { 1.770 + return this.each(function() { 1.771 + $('input,select,textarea', this).clearFields(); 1.772 + }); 1.773 +}; 1.774 + 1.775 +/** 1.776 + * Clears the selected form elements. Takes the following actions on the matched elements: 1.777 + * - input text fields will have their 'value' property set to the empty string 1.778 + * - select elements will have their 'selectedIndex' property set to -1 1.779 + * - checkbox and radio inputs will have their 'checked' property set to false 1.780 + * - inputs of type submit, button, reset, and hidden will *not* be effected 1.781 + * - button elements will *not* be effected 1.782 + * 1.783 + * @example $('.myInputs').clearFields(); 1.784 + * @desc Clears all inputs with class myInputs 1.785 + * 1.786 + * @name clearFields 1.787 + * @type jQuery 1.788 + * @cat Plugins/Form 1.789 + */ 1.790 +$.fn.clearFields = $.fn.clearInputs = function() { 1.791 + return this.each(function() { 1.792 + var t = this.type, tag = this.tagName.toLowerCase(); 1.793 + if (t == 'text' || t == 'password' || tag == 'textarea') 1.794 + this.value = ''; 1.795 + else if (t == 'checkbox' || t == 'radio') 1.796 + this.checked = false; 1.797 + else if (tag == 'select') 1.798 + this.selectedIndex = -1; 1.799 + }); 1.800 +}; 1.801 + 1.802 + 1.803 +/** 1.804 + * Resets the form data. Causes all form elements to be reset to their original value. 1.805 + * 1.806 + * @example $('form').resetForm(); 1.807 + * @desc Resets all forms on the page. 1.808 + * 1.809 + * @name resetForm 1.810 + * @type jQuery 1.811 + * @cat Plugins/Form 1.812 + */ 1.813 +$.fn.resetForm = function() { 1.814 + return this.each(function() { 1.815 + // guard against an input with the name of 'reset' 1.816 + // note that IE reports the reset function as an 'object' 1.817 + if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) 1.818 + this.reset(); 1.819 + }); 1.820 +}; 1.821 + 1.822 +})(jQuery);