diff --git a/Gruntfile.js b/Gruntfile.js index a8916fb8..bf00840e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -29,7 +29,8 @@ module.exports = function(grunt) { src: ['test/*.html'], }, options: { - run: true + run: true, + growlOnSuccess: false } }, diff --git a/README.md b/README.md index bdd5fb93..fc27bf37 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,13 @@ The HTTP method to use for the request (e.g. 'POST', 'GET', 'PUT'). ### replaceTarget Optionally used along with the the target option. Set to true if the target should be replaced or false if only the target contents should be replaced. +### requestFormat +The encoding format to use for the request body. The following values are supported: + +* `form` : HTTP form (x-www-form-urlencoded) format, this is default option. +* `json` : JSON encoded string + * You may need polyfill JSON functionality with old browsers, recommending: https://github.com/douglascrockford/JSON-js/blob/master/json2.js + ### resetForm Boolean flag indicating whether the form should be reset if the submit is successful diff --git a/docs/options.md b/docs/options.md index 7c6b6874..6833b1b7 100644 --- a/docs/options.md +++ b/docs/options.md @@ -91,6 +91,18 @@ The HTTP method to use for the request (e.g. 'POST', 'GET', 'PUT'). **(version a Default: `false` Optionally used along with the the [`target`](#target) option. Set to `true` if the target should be replaced or `false` if only the target _contents_ should be replaced. **(version added: 2.43)** + +### requestFormat +Default: `form` +The encoding format to use for the request body. **(version added: 4.3.0)** +The following values are supported: + +**'form'**: HTTP form (x-www-form-urlencoded) format + +**'json'**: JSON encoded string + * You may need polyfill JSON functionality with old browsers, recommending: https://github.com/douglascrockford/JSON-js/blob/master/json2.js + + ### resetForm Default: `null` Boolean flag indicating whether the form should be reset if the submit is successful diff --git a/src/jquery.form.js b/src/jquery.form.js index a1d0a428..30af3f4f 100644 --- a/src/jquery.form.js +++ b/src/jquery.form.js @@ -170,6 +170,7 @@ url : url, success : $.ajaxSettings.success, type : method || $.ajaxSettings.type, + requestFormat: 'form', iframeSrc : /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' // eslint-disable-line no-script-url }, options); @@ -200,9 +201,10 @@ var elements = []; var qx, a = this.formToArray(options.semantic, elements, options.filtering); + var optionsData; if (options.data) { - var optionsData = $.isFunction(options.data) ? options.data(a) : options.data; + optionsData = $.isFunction(options.data) ? options.data(a) : options.data; options.extraData = optionsData; qx = $.param(optionsData, traditional); @@ -232,7 +234,13 @@ if (options.type.toUpperCase() === 'GET') { options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; options.data = null; // data is null for 'get' + } else if (options.requestFormat.toLowerCase() === 'json') { + var formData = this.formArrayToJsonData(a); + var jsonData = $.extend({}, formData, traditional); + options.data = JSON.stringify(jsonData); + options.contentType = 'application/json'; } else { + // form-data post options.data = q; // data is the query string for 'post' } @@ -1194,6 +1202,19 @@ return $.param(this.formToArray(semantic)); }; + /** + * Transform form array data into json object. + */ + $.fn.formArrayToJsonData = function (arrayOfData) { + var result = {}; + + $.each(arrayOfData, function (index, node) { + result[node.name] = node.value; + }); + + return result; + }; + /** * Serializes all field elements in the jQuery object into a query string. * This method will return a string in the format: name1=value1&name2=value2 diff --git a/test/test.js b/test/test.js index 5f8c9951..ba6a9b19 100644 --- a/test/test.js +++ b/test/test.js @@ -65,6 +65,26 @@ describe('form', function() { } }); + it('formToArray: json object', function() { + var a = $('#form1').formToArray(); + var o = $.fn.formArrayToJsonData(a); + + assert.strictEqual(o.constructor, Object, 'type check'); + assert.deepEqual(o, { + 'Hidden': 'hiddenValue', + 'Name': 'MyName1', + 'Password': '', + 'Multiple': 'six', + 'Single': 'one', + 'Single2': 'A', + 'Check': '2', + 'Radio': '2', + 'action': '1', + 'method': '2', + 'Text': 'This is Form1' + }); + }); + it('formToArray: text promotion for missing value attributes', function() { var expected = [ { name: 'A', value: ''},