Skip to main content

Bug Tracker

Side navigation

#13879 closed feature (notabug)

Opened May 10, 2013 09:23AM UTC

Closed May 10, 2013 11:38AM UTC

seemore

Reported by: cimo Owned by:
Priority: undecided Milestone: None
Component: unfiled Version: 1.7.2
Keywords: Cc:
Blocked by: Blocking:
Description
Attachments (0)
Change History (1)

Changed May 10, 2013 11:38AM UTC by scottgonzalez comment:1

description: /*! \ * jQuery Form Plugin \ * version: 2.83 (11-JUL-2011) \ * @requires jQuery v1.3.2 or later \ * \ * Examples and documentation at: http://malsup.com/jquery/form/ \ * Dual licensed under the MIT and GPL licenses: \ * http://www.opensource.org/licenses/mit-license.php \ * http://www.gnu.org/licenses/gpl.html \ */ \ ;(function($) { \ \ /* \ Usage Note: \ ----------- \ Do not use both ajaxSubmit and ajaxForm on the same form. These \ functions are intended to be exclusive. Use ajaxSubmit if you want \ to bind your own submit handler to the form. For example, \ \ $(document).ready(function() { \ $('#myForm').bind('submit', function(e) { \ e.preventDefault(); // <-- important \ $(this).ajaxSubmit({ \ target: '#output' \ }); \ }); \ }); \ \ Use ajaxForm when you want the plugin to manage all the event binding \ for you. For example, \ \ $(document).ready(function() { \ $('#myForm').ajaxForm({ \ target: '#output' \ }); \ }); \ \ When using ajaxForm, the ajaxSubmit function will be invoked for you \ at the appropriate time. \ */ \ \ /** \ * ajaxSubmit() provides a mechanism for immediately submitting \ * an HTML form using AJAX. \ */ \ $.fn.ajaxSubmit = function(options) { \ // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) \ if (!this.length) { \ log('ajaxSubmit: skipping submit process - no element selected'); \ return this; \ } \ \ var method, action, url, $form = this; \ \ if (typeof options == 'function') { \ options = { success: options }; \ } \ \ method = this.attr('method'); \ action = this.attr('action'); \ url = (typeof action === 'string') ? $.trim(action) : ''; \ url = url || window.location.href || ''; \ if (url) { \ // clean url (don't include hash vaue) \ url = (url.match(/^([^#]+)/)||[])[1]; \ } \ \ options = $.extend(true, { \ url: url, \ success: $.ajaxSettings.success, \ type: method || 'GET', \ iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' \ }, options); \ \ // hook for manipulating the form data before it is extracted; \ // convenient for use with rich editors like tinyMCE or FCKEditor \ var veto = {}; \ this.trigger('form-pre-serialize', [this, options, veto]); \ if (veto.veto) { \ log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); \ return this; \ } \ \ // provide opportunity to alter form data before it is serialized \ if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { \ log('ajaxSubmit: submit aborted via beforeSerialize callback'); \ return this; \ } \ \ var n,v,a = this.formToArray(options.semantic); \ if (options.data) { \ options.extraData = options.data; \ for (n in options.data) { \ if(options.data[n] instanceof Array) { \ for (var k in options.data[n]) { \ a.push( { name: n, value: options.data[n][k] } ); \ } \ } \ else { \ v = options.data[n]; \ v = $.isFunction(v) ? v() : v; // if value is fn, invoke it \ a.push( { name: n, value: v } ); \ } \ } \ } \ \ // give pre-submit callback an opportunity to abort the submit \ if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { \ log('ajaxSubmit: submit aborted via beforeSubmit callback'); \ return this; \ } \ \ // fire vetoable 'validate' event \ this.trigger('form-submit-validate', [a, this, options, veto]); \ if (veto.veto) { \ log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); \ return this; \ } \ \ var q = $.param(a); \ \ if (options.type.toUpperCase() == 'GET') { \ options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; \ options.data = null; // data is null for 'get' \ } \ else { \ options.data = q; // data is the query string for 'post' \ } \ \ var callbacks = []; \ if (options.resetForm) { \ callbacks.push(function() { $form.resetForm(); }); \ } \ if (options.clearForm) { \ callbacks.push(function() { $form.clearForm(); }); \ } \ \ // perform a load on the target only if dataType is not provided \ if (!options.dataType && options.target) { \ var oldSuccess = options.success || function(){}; \ callbacks.push(function(data) { \ var fn = options.replaceTarget ? 'replaceWith' : 'html'; \ $(options.target)[fn](data).each(oldSuccess, arguments); \ }); \ } \ else if (options.success) { \ callbacks.push(options.success); \ } \ \ options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg \ var context = options.context || options; // jQuery 1.4+ supports scope context \ for (var i=0, max=callbacks.length; i < max; i++) { \ callbacks[i].apply(context, [data, status, xhr || $form, $form]); \ } \ }; \ \ // are there files to upload? \ var fileInputs = $('input:file', this).length > 0; \ var mp = 'multipart/form-data'; \ var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); \ \ // options.iframe allows user to force iframe mode \ // 06-NOV-09: now defaulting to iframe mode if file input is detected \ if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { \ // hack to fix Safari hang (thanks to Tim Molendijk for this) \ // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d \ if (options.closeKeepAlive) { \ $.get(options.closeKeepAlive, function() { fileUpload(a); }); \ } \ else { \ fileUpload(a); \ } \ } \ else { \ // IE7 massage (see issue 57) \ if ($.browser.msie && method == 'get') { \ var ieMeth = $form[0].getAttribute('method'); \ if (typeof ieMeth === 'string') \ options.type = ieMeth; \ } \ $.ajax(options); \ } \ \ // fire 'notify' event \ this.trigger('form-submit-notify', [this, options]); \ return this; \ \ \ // private function for handling file uploads (hat tip to YAHOO!) \ function fileUpload(a) { \ var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; \ var useProp = !!$.fn.prop; \ \ if (a) { \ // ensure that every serialized input is still enabled \ for (i=0; i < a.length; i++) { \ el = $(form[a[i].name]); \ el[ useProp ? 'prop' : 'attr' ]('disabled', false); \ } \ } \ \ if ($(':input[name=submit],:input[id=submit]', form).length) { \ // if there is an input with a name or id of 'submit' then we won't be \ // able to invoke the submit fn on the form (at least not x-browser) \ alert('Error: Form elements must not have name or id of "submit".'); \ return; \ } \ \ s = $.extend(true, {}, $.ajaxSettings, options); \ s.context = s.context || s; \ id = 'jqFormIO' + (new Date().getTime()); \ if (s.iframeTarget) { \ $io = $(s.iframeTarget); \ n = $io.attr('name'); \ if (n == null) \ $io.attr('name', id); \ else \ id = n; \ } \ else { \ $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />'); \ $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' }); \ } \ io = $io[0]; \ \ \ xhr = { // mock object \ aborted: 0, \ responseText: null, \ responseXML: null, \ status: 0, \ statusText: 'n/a', \ getAllResponseHeaders: function() {}, \ getResponseHeader: function() {}, \ setRequestHeader: function() {}, \ abort: function(status) { \ var e = (status === 'timeout' ? 'timeout' : 'aborted'); \ log('aborting upload... ' + e); \ this.aborted = 1; \ $io.attr('src', s.iframeSrc); // abort op in progress \ xhr.error = e; \ s.error && s.error.call(s.context, xhr, e, status); \ g && $.event.trigger("ajaxError", [xhr, s, e]); \ s.complete && s.complete.call(s.context, xhr, e); \ } \ }; \ \ g = s.global; \ // trigger ajax global events so that activity/block indicators work like normal \ if (g && ! $.active++) { \ $.event.trigger("ajaxStart"); \ } \ if (g) { \ $.event.trigger("ajaxSend", [xhr, s]); \ } \ \ if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) { \ if (s.global) { \ $.active--; \ } \ return; \ } \ if (xhr.aborted) { \ return; \ } \ \ // add submitting element to data if we know it \ sub = form.clk; \ if (sub) { \ n = sub.name; \ if (n && !sub.disabled) { \ s.extraData = s.extraData || {}; \ s.extraData[n] = sub.value; \ if (sub.type == "image") { \ s.extraData[n+'.x'] = form.clk_x; \ s.extraData[n+'.y'] = form.clk_y; \ } \ } \ } \ \ var CLIENT_TIMEOUT_ABORT = 1; \ var SERVER_ABORT = 2; \ \ function getDoc(frame) { \ var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document; \ return doc; \ } \ \ // take a breath so that pending repaints get some cpu time before the upload starts \ function doSubmit() { \ // make sure form attrs are set \ var t = $form.attr('target'), a = $form.attr('action'); \ \ // update form attrs in IE friendly way \ form.setAttribute('target',id); \ if (!method) { \ form.setAttribute('method', 'POST'); \ } \ if (a != s.url) { \ form.setAttribute('action', s.url); \ } \ \ // ie borks in some cases when setting encoding \ if (! s.skipEncodingOverride && (!method || /post/i.test(method))) { \ $form.attr({ \ encoding: 'multipart/form-data', \ enctype: 'multipart/form-data' \ }); \ } \ \ // support timout \ if (s.timeout) { \ timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout); \ } \ \ // look for server aborts \ function checkState() { \ try { \ var state = getDoc(io).readyState; \ log('state = ' + state); \ if (state.toLowerCase() == 'uninitialized') \ setTimeout(checkState,50); \ } \ catch(e) { \ log('Server abort: ' , e, ' (', e.name, ')'); \ cb(SERVER_ABORT); \ timeoutHandle && clearTimeout(timeoutHandle); \ timeoutHandle = undefined; \ } \ } \ \ // add "extra" data to form if provided in options \ var extraInputs = []; \ try { \ if (s.extraData) { \ for (var n in s.extraData) { \ extraInputs.push( \ $('<input type="hidden" name="'+n+'" />').attr('value',s.extraData[n]) \ .appendTo(form)[0]); \ } \ } \ \ if (!s.iframeTarget) { \ // add iframe to doc and submit the form \ $io.appendTo('body'); \ io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false); \ } \ setTimeout(checkState,15); \ form.submit(); \ } \ finally { \ // reset attrs and remove "extra" input elements \ form.setAttribute('action',a); \ if(t) { \ form.setAttribute('target', t); \ } else { \ $form.removeAttr('target'); \ } \ $(extraInputs).remove(); \ } \ } \ \ if (s.forceSync) { \ doSubmit(); \ } \ else { \ setTimeout(doSubmit, 10); // this lets dom updates render \ } \ \ var data, doc, domCheckCount = 50, callbackProcessed; \ \ function cb(e) { \ if (xhr.aborted || callbackProcessed) { \ return; \ } \ try { \ doc = getDoc(io); \ } \ catch(ex) { \ log('cannot access response document: ', ex); \ e = SERVER_ABORT; \ } \ if (e === CLIENT_TIMEOUT_ABORT && xhr) { \ xhr.abort('timeout'); \ return; \ } \ else if (e == SERVER_ABORT && xhr) { \ xhr.abort('server abort'); \ return; \ } \ \ if (!doc || doc.location.href == s.iframeSrc) { \ // response not received yet \ if (!timedOut) \ return; \ } \ io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false); \ \ var status = 'success', errMsg; \ try { \ if (timedOut) { \ throw 'timeout'; \ } \ \ var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc); \ log('isXml='+isXml); \ if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) { \ if (--domCheckCount) { \ // in some browsers (Opera) the iframe DOM is not always traversable when \ // the onload callback fires, so we loop a bit to accommodate \ log('requeing onLoad callback, DOM not available'); \ setTimeout(cb, 250); \ return; \ } \ // let this fall through because server response could be an empty document \ //log('Could not access iframe DOM after mutiple tries.'); \ //throw 'DOMException: not available'; \ } \ \ //log('response detected'); \ var docRoot = doc.body ? doc.body : doc.documentElement; \ xhr.responseText = docRoot ? docRoot.innerHTML : null; \ xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc; \ if (isXml) \ s.dataType = 'xml'; \ xhr.getResponseHeader = function(header){ \ var headers = {'content-type': s.dataType}; \ return headers[header]; \ }; \ // support for XHR 'status' & 'statusText' emulation : \ if (docRoot) { \ xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status; \ xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText; \ } \ \ var dt = s.dataType || ''; \ var scr = /(json|script|text)/.test(dt.toLowerCase()); \ if (scr || s.textarea) { \ // see if user embedded response in textarea \ var ta = doc.getElementsByTagName('textarea')[0]; \ if (ta) { \ xhr.responseText = ta.value; \ // support for XHR 'status' & 'statusText' emulation : \ xhr.status = Number( ta.getAttribute('status') ) || xhr.status; \ xhr.statusText = ta.getAttribute('statusText') || xhr.statusText; \ } \ else if (scr) { \ // account for browsers injecting pre around json response \ var pre = doc.getElementsByTagName('pre')[0]; \ var b = doc.getElementsByTagName('body')[0]; \ if (pre) { \ xhr.responseText = pre.textContent ? pre.textContent : pre.innerHTML; \ } \ else if (b) { \ xhr.responseText = b.innerHTML; \ } \ } \ } \ else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) { \ xhr.responseXML = toXml(xhr.responseText); \ } \ \ try { \ data = httpData(xhr, s.dataType, s); \ } \ catch (e) { \ status = 'parsererror'; \ xhr.error = errMsg = (e || status); \ } \ } \ catch (e) { \ log('error caught: ',e); \ status = 'error'; \ xhr.error = errMsg = (e || status); \ } \ \ if (xhr.aborted) { \ log('upload aborted'); \ status = null; \ } \ \ if (xhr.status) { // we've set xhr.status \ status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error'; \ } \ \ // ordering of these callbacks/triggers is odd, but that's how $.ajax does it \ if (status === 'success') { \ s.success && s.success.call(s.context, data, 'success', xhr); \ g && $.event.trigger("ajaxSuccess", [xhr, s]); \ } \ else if (status) { \ if (errMsg == undefined) \ errMsg = xhr.statusText; \ s.error && s.error.call(s.context, xhr, status, errMsg); \ g && $.event.trigger("ajaxError", [xhr, s, errMsg]); \ } \ \ g && $.event.trigger("ajaxComplete", [xhr, s]); \ \ if (g && ! --$.active) { \ $.event.trigger("ajaxStop"); \ } \ \ s.complete && s.complete.call(s.context, xhr, status); \ \ callbackProcessed = true; \ if (s.timeout) \ clearTimeout(timeoutHandle); \ \ // clean up \ setTimeout(function() { \ if (!s.iframeTarget) \ $io.remove(); \ xhr.responseXML = null; \ }, 100); \ } \ \ var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+) \ if (window.ActiveXObject) { \ doc = new ActiveXObject('Microsoft.XMLDOM'); \ doc.async = 'false'; \ doc.loadXML(s); \ } \ else { \ doc = (new DOMParser()).parseFromString(s, 'text/xml'); \ } \ return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null; \ }; \ var parseJSON = $.parseJSON || function(s) { \ return window['eval']('(' + s + ')'); \ }; \ \ var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4 \ \ var ct = xhr.getResponseHeader('content-type') || '', \ xml = type === 'xml' || !type && ct.indexOf('xml') >= 0, \ data = xml ? xhr.responseXML : xhr.responseText; \ \ if (xml && data.documentElement.nodeName === 'parsererror') { \ $.error && $.error('parsererror'); \ } \ if (s && s.dataFilter) { \ data = s.dataFilter(data, type); \ } \ if (typeof data === 'string') { \ if (type === 'json' || !type && ct.indexOf('json') >= 0) { \ data = parseJSON(data); \ } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) { \ $.globalEval(data); \ } \ } \ return data; \ }; \ } \ }; \ \ /** \ * ajaxForm() provides a mechanism for fully automating form submission. \ * \ * The advantages of using this method instead of ajaxSubmit() are: \ * \ * 1: This method will include coordinates for <input type="image" /> elements (if the element \ * is used to submit the form). \ * 2. This method will include the submit element's name/value data (for the element that was \ * used to submit the form). \ * 3. This method binds the submit() method to the form for you. \ * \ * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely \ * passes the options argument along after properly binding events for submit elements and \ * the form itself. \ */ \ $.fn.ajaxForm = function(options) { \ // in jQuery 1.3+ we can fix mistakes with the ready state \ if (this.length === 0) { \ var o = { s: this.selector, c: this.context }; \ if (!$.isReady && o.s) { \ log('DOM not ready, queuing ajaxForm'); \ $(function() { \ $(o.s,o.c).ajaxForm(options); \ }); \ return this; \ } \ // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready() \ log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); \ return this; \ } \ \ return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) { \ if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed \ e.preventDefault(); \ $(this).ajaxSubmit(options); \ } \ }).bind('click.form-plugin', function(e) { \ var target = e.target; \ var $el = $(target); \ if (!($el.is(":submit,input:image"))) { \ // is this a child element of the submit el? (ex: a span within a button) \ var t = $el.closest(':submit'); \ if (t.length == 0) { \ return; \ } \ target = t[0]; \ } \ var form = this; \ form.clk = target; \ if (target.type == 'image') { \ if (e.offsetX != undefined) { \ form.clk_x = e.offsetX; \ form.clk_y = e.offsetY; \ } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin \ var offset = $el.offset(); \ form.clk_x = e.pageX - offset.left; \ form.clk_y = e.pageY - offset.top; \ } else { \ form.clk_x = e.pageX - target.offsetLeft; \ form.clk_y = e.pageY - target.offsetTop; \ } \ } \ // clear form vars \ setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100); \ }); \ }; \ \ // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm \ $.fn.ajaxFormUnbind = function() { \ return this.unbind('submit.form-plugin click.form-plugin'); \ }; \ \ /** \ * formToArray() gathers form element data into an array of objects that can \ * be passed to any of the following ajax functions: $.get, $.post, or load. \ * Each object in the array has both a 'name' and 'value' property. An example of \ * an array for a simple login form might be: \ * \ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] \ * \ * It is this array that is passed to pre-submit callback functions provided to the \ * ajaxSubmit() and ajaxForm() methods. \ */ \ $.fn.formToArray = function(semantic) { \ var a = []; \ if (this.length === 0) { \ return a; \ } \ \ var form = this[0]; \ var els = semantic ? form.getElementsByTagName('*') : form.elements; \ if (!els) { \ return a; \ } \ \ var i,j,n,v,el,max,jmax; \ for(i=0, max=els.length; i < max; i++) { \ el = els[i]; \ n = el.name; \ if (!n) { \ continue; \ } \ \ if (semantic && form.clk && el.type == "image") { \ // handle image inputs on the fly when semantic == true \ if(!el.disabled && form.clk == el) { \ a.push({name: n, value: $(el).val()}); \ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); \ } \ continue; \ } \ \ v = $.fieldValue(el, true); \ if (v && v.constructor == Array) { \ for(j=0, jmax=v.length; j < jmax; j++) { \ a.push({name: n, value: v[j]}); \ } \ } \ else if (v !== null && typeof v != 'undefined') { \ a.push({name: n, value: v}); \ } \ } \ \ if (!semantic && form.clk) { \ // input type=='image' are not found in elements array! handle it here \ var $input = $(form.clk), input = $input[0]; \ n = input.name; \ if (n && !input.disabled && input.type == 'image') { \ a.push({name: n, value: $input.val()}); \ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y}); \ } \ } \ return a; \ }; \ \ /** \ * Serializes form data into a 'submittable' string. This method will return a string \ * in the format: name1=value1&amp;name2=value2 \ */ \ $.fn.formSerialize = function(semantic) { \ //hand off to jQuery.param for proper encoding \ return $.param(this.formToArray(semantic)); \ }; \ \ /** \ * Serializes all field elements in the jQuery object into a query string. \ * This method will return a string in the format: name1=value1&amp;name2=value2 \ */ \ $.fn.fieldSerialize = function(successful) { \ var a = []; \ this.each(function() { \ var n = this.name; \ if (!n) { \ return; \ } \ var v = $.fieldValue(this, successful); \ if (v && v.constructor == Array) { \ for (var i=0,max=v.length; i < max; i++) { \ a.push({name: n, value: v[i]}); \ } \ } \ else if (v !== null && typeof v != 'undefined') { \ a.push({name: this.name, value: v}); \ } \ }); \ //hand off to jQuery.param for proper encoding \ return $.param(a); \ }; \ \ /** \ * Returns the value(s) of the element in the matched set. For example, consider the following form: \ * \ * <form><fieldset> \ * <input name="A" type="text" /> \ * <input name="A" type="text" /> \ * <input name="B" type="checkbox" value="B1" /> \ * <input name="B" type="checkbox" value="B2"/> \ * <input name="C" type="radio" value="C1" /> \ * <input name="C" type="radio" value="C2" /> \ * </fieldset></form> \ * \ * var v = $(':text').fieldValue(); \ * // if no values are entered into the text inputs \ * v == ['',''] \ * // if values entered into the text inputs are 'foo' and 'bar' \ * v == ['foo','bar'] \ * \ * var v = $(':checkbox').fieldValue(); \ * // if neither checkbox is checked \ * v === undefined \ * // if both checkboxes are checked \ * v == ['B1', 'B2'] \ * \ * var v = $(':radio').fieldValue(); \ * // if neither radio is checked \ * v === undefined \ * // if first radio is checked \ * v == ['C1'] \ * \ * The successful argument controls whether or not the field element must be 'successful' \ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). \ * The default value of the successful argument is true. If this value is false the value(s) \ * for each element is returned. \ * \ * Note: This method *always* returns an array. If no valid value can be determined the \ * array will be empty, otherwise it will contain one or more values. \ */ \ $.fn.fieldValue = function(successful) { \ for (var val=[], i=0, max=this.length; i < max; i++) { \ var el = this[i]; \ var v = $.fieldValue(el, successful); \ if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) { \ continue; \ } \ v.constructor == Array ? $.merge(val, v) : val.push(v); \ } \ return val; \ }; \ \ /** \ * Returns the value of the field element. \ */ \ $.fieldValue = function(el, successful) { \ var n = el.name, t = el.type, tag = el.tagName.toLowerCase(); \ if (successful === undefined) { \ successful = true; \ } \ \ if (successful && (!n || el.disabled || t == 'reset' || t == 'button' || \ (t == 'checkbox' || t == 'radio') && !el.checked || \ (t == 'submit' || t == 'image') && el.form && el.form.clk != el || \ tag == 'select' && el.selectedIndex == -1)) { \ return null; \ } \ \ if (tag == 'select') { \ var index = el.selectedIndex; \ if (index < 0) { \ return null; \ } \ var a = [], ops = el.options; \ var one = (t == 'select-one'); \ var max = (one ? index+1 : ops.length); \ for(var i=(one ? index : 0); i < max; i++) { \ var op = ops[i]; \ if (op.selected) { \ var v = op.value; \ if (!v) { // extra pain for IE... \ v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value; \ } \ if (one) { \ return v; \ } \ a.push(v); \ } \ } \ return a; \ } \ return $(el).val(); \ }; \ \ /** \ * Clears the form data. Takes the following actions on the form's input fields: \ * - input text fields will have their 'value' property set to the empty string \ * - select elements will have their 'selectedIndex' property set to -1 \ * - checkbox and radio inputs will have their 'checked' property set to false \ * - inputs of type submit, button, reset, and hidden will *not* be effected \ * - button elements will *not* be effected \ */ \ $.fn.clearForm = function() { \ return this.each(function() { \ $('input,select,textarea', this).clearFields(); \ }); \ }; \ \ /** \ * Clears the selected form elements. \ */ \ $.fn.clearFields = $.fn.clearInputs = function() { \ var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list \ return this.each(function() { \ var t = this.type, tag = this.tagName.toLowerCase(); \ if (re.test(t) || tag == 'textarea') { \ this.value = ''; \ } \ else if (t == 'checkbox' || t == 'radio') { \ this.checked = false; \ } \ else if (tag == 'select') { \ this.selectedIndex = -1; \ } \ }); \ }; \ \ /** \ * Resets the form data. Causes all form elements to be reset to their original value. \ */ \ $.fn.resetForm = function() { \ return this.each(function() { \ // guard against an input with the name of 'reset' \ // note that IE reports the reset function as an 'object' \ if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) { \ this.reset(); \ } \ }); \ }; \ \ /** \ * Enables or disables any matching elements. \ */ \ $.fn.enable = function(b) { \ if (b === undefined) { \ b = true; \ } \ return this.each(function() { \ this.disabled = !b; \ }); \ }; \ \ /** \ * Checks/unchecks any matching checkboxes or radio buttons and \ * selects/deselects and matching option elements. \ */ \ $.fn.selected = function(select) { \ if (select === undefined) { \ select = true; \ } \ return this.each(function() { \ var t = this.type; \ if (t == 'checkbox' || t == 'radio') { \ this.checked = select; \ } \ else if (this.tagName.toLowerCase() == 'option') { \ var $sel = $(this).parent('select'); \ if (select && $sel[0] && $sel[0].type == 'select-one') { \ // deselect all other options \ $sel.find('option').selected(false); \ } \ this.selected = select; \ } \ }); \ }; \ \ // helper fn for console logging \ function log() { \ var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,''); \ if (window.console && window.console.log) { \ window.console.log(msg); \ } \ else if (window.opera && window.opera.postError) { \ window.opera.postError(msg); \ } \ }; \ \ })(jQuery); \ \
resolution: → notabug
status: newclosed