From fac634433f0d3748e16f463b369df2ac06c041ba Mon Sep 17 00:00:00 2001 From: BrainFooLong Date: Thu, 1 Apr 2021 19:28:49 +0200 Subject: [PATCH] added a new feature `inputFilter` to `FormDataOptions` --- CHANGELOG.md | 3 ++ README.md | 69 +++++++++++++++++--------- dist/form-data-json.min.js | 4 +- docs/example/playground.html | 25 ++++++++-- docs/lib/form-data-json.min.js | 4 +- docs/tests/test.html | 23 +++++++-- package.json | 2 +- src/form-data-json.js | 91 ++++++++++++++++++++++++---------- 8 files changed, 161 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d370b06..db1ce3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 1.3.0 - 1. April 2021 +* added a new feature `inputFilter` to `FormDataOptions` - Thanks to [@alcalyn](https://github.com/alcalyn) for the idea and initial coding in [#8](https://github.com/brainfoolong/form-data-json/issues/8) + ### 1.2.2 - 9. December 2020 * fixed node module usage [#7](https://github.com/brainfoolong/form-data-json/issues/7) diff --git a/README.md b/README.md index 63bc460..7671478 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,10 @@ let values = FormDataJson.formToJson(document.querySelector("form"), new FormDat ```javascript FormDataJson.formToJson(document.querySelector("form"), null, function(values){}) ``` +###### Read form input values but filter out, for example, all password fields +```javascript +let values = FormDataJson.formToJson(document.querySelector("form"), new FormDataJsonOptions({ inputFilter: function(inputElement) { return (inputElement.type || 'text') !== 'password' } })) +``` ###### Read a single input field ```javascript @@ -71,41 +75,58 @@ let values = FormDataJson.getInputValue(document.querySelector("input")) ```javascript FormDataJson.fillFormFromJsonValues(document.querySelector("form"), {'name': 'BrainFooLong'}) ``` + ###### Set form input values and unset all other existing input values ```javascript FormDataJson.fillFormFromJsonValues(document.querySelector("form"), {'name': 'BrainFooLong'}, new FormDataJsonOptions({ unsetAllInputsOnFill: true })) ``` +###### Set form input values but ignore, for example, password fields +```javascript +FormDataJson.fillFormFromJsonValues(document.querySelector("form"), {'name': 'BrainFooLong'}, new FormDataJsonOptions({ inputFilter: function(inputElement) { return (inputElement.type || 'text') !== 'password' } }) +``` + ###### Set a single input field ```javascript let values = FormDataJson.setInputValue(document.querySelector("input"), 'foo') ``` ###### All options and their defaults -You can edit this defaults to your needs. +You can edit this defaults to your needs. You can pass this options directly to the `new FormDataOptions({...})` instantiation. ```javascript FormDataJsonOptions.defaults = { - /** - * Include all disabled inputs in result data - * @type {boolean} - */ - includeDisabled: false, - /** - * Include checkboxes that are unchecked with a null, otherwise the key will not exist in result data - * @type {boolean} - */ - includeUncheckedAsNull: false, - /** - * Include all input buttons/submits values, otherwise the key they will not exist in result data - * @type {boolean} - */ - includeButtonValues: false, - /** - * Will unset all existing input fields in form when using fillFormFromJsonValues - * This will be helpful if you have checkboxes and want to fill from json object, but checkboxes still stay checked - * because the key not exist in the json data - * @type {boolean} - */ - unsetAllInputsOnFill: false - } + /** + * Include all disabled inputs in result data + * @type {boolean} + */ + includeDisabled, + + /** + * Include checkboxes that are unchecked with a null, otherwise the key will not exist in result data + * @type {boolean} + */ + includeUncheckedAsNull, + + /** + * Include all input buttons/submits values, otherwise the key they will not exist in result data + * @type {boolean} + */ + includeButtonValues, + + /** + * Will unset all existing input fields in form when using fillFormFromJsonValues + * This will be helpful if you have checkboxes and want to fill from json object, but checkboxes still stay checked + * because the key not exist in the json data + * @type {boolean} + */ + unsetAllInputsOnFill, + + /** + * If set to a function, this will receive the current input element in progress of formToJson|fillFormFromJsonValues|unsetFormInputs + * It must return bool true to allow the script to progress the input element + * If other than true is returned, than the input will be skipped + * @type {FormDataJsonOptions~inputFilterCallback|null} + */ + inputFilter +} ``` \ No newline at end of file diff --git a/dist/form-data-json.min.js b/dist/form-data-json.min.js index 3e8276c..e1de365 100644 --- a/dist/form-data-json.min.js +++ b/dist/form-data-json.min.js @@ -1,2 +1,2 @@ -// form-data-json-convert | version: 1.2.2 | url: https://brainfoolong.github.io/form-data-json/example/playground.html -'use strict';function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _classCallCheck(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function _defineProperties(a,b){for(var c,d=0;d -Form Data Json
+Form Data Json
+
@@ -179,11 +184,25 @@

Results

function getOptions () { let options = FormDataJson.formToJson(document.querySelector('.options')) + let optionsStringify = {} for (let i in options) { + optionsStringify[i] = options[i] === '1' options[i] = options[i] === '1' + if (i === 'inputFilter' && options[i]) { + optionsStringify[i] = '__inputFilter__' + options[i] = function (inputElement) { + return (inputElement.type || 'text') !== 'password' + } + } + } + let optionsStringified = JSON.stringify(optionsStringify) + optionsStringified = optionsStringified.replace(/"__inputFilter__"/ig, 'function(inputElement) { return (inputElement.type || \'text\') !== \'password\'}') + let optionsCall = Object.keys(options).length ? ', new FormDataJsonOptions(' + optionsStringified + ')' : '' + return { + 'options': Object.keys(options).length ? new FormDataJsonOptions(options) : null, + 'call': optionsCall, + 'callfiles': optionsCall !== '' ? optionsCall : ', null' } - let optionsCall = Object.keys(options).length ? ', new FormDataJsonOptions(' + JSON.stringify(options) + ')' : '' - return { 'options': Object.keys(options).length ? new FormDataJsonOptions(options) : null, 'call': optionsCall, 'callfiles' : optionsCall !== '' ? optionsCall : ', null'} } function toJson () { diff --git a/docs/lib/form-data-json.min.js b/docs/lib/form-data-json.min.js index 3e8276c..e1de365 100644 --- a/docs/lib/form-data-json.min.js +++ b/docs/lib/form-data-json.min.js @@ -1,2 +1,2 @@ -// form-data-json-convert | version: 1.2.2 | url: https://brainfoolong.github.io/form-data-json/example/playground.html -'use strict';function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _classCallCheck(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function _defineProperties(a,b){for(var c,d=0;d

-

Testing read formToJson() with files callback. To test this with manual user input, you have to choose the test-file.gif from this directory for both single and multiple file inputs. After choosing both the test must turn green again.

+

Testing read formToJson() with files callback. To test this with manual user input, you have to choose the + test-file.gif from this directory for both single and multiple file inputs. After choosing both the test must + turn green again.

Single:
- Multiple: + data-test-value='"data:image/gif;base64,R0lGODdhAQABAPAAAPUAAMlFJiH5BAEAAAEALAAAAAABAAEAAAICRAEAOw=="'>
+ Multiple:
+ +
+

+

Testing option "inputFilter" for read and write.

+ + +
+
+ \ No newline at end of file diff --git a/package.json b/package.json index a5c2d7d..f14da3f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "git", "url": "git+https://github.com/brainfoolong/form-data-json.git" }, - "version": "1.2.2", + "version": "1.3.0", "scripts": { "dist": "node build/dist.js" }, diff --git a/src/form-data-json.js b/src/form-data-json.js index 6621adf..894d842 100644 --- a/src/form-data-json.js +++ b/src/form-data-json.js @@ -110,6 +110,7 @@ class FormDataJson { let files = [] for (let i = 0; i < inputs.length; i++) { let input = inputs[i] + if (!FormDataJson.isElementAllowed(input, options)) continue let inputType = (input.type || 'text').toLowerCase() if (!input.name || input.name.length === 0) continue if (!options.includeDisabled && input.disabled) continue @@ -217,6 +218,7 @@ class FormDataJson { let inputs = formElement.querySelectorAll('select, textarea, input, button') for (let i = 0; i < inputs.length; i++) { let input = inputs[i] + if (!FormDataJson.isElementAllowed(input, options)) continue let inputName = input.name let isMultiple = input instanceof HTMLSelectElement && input.multiple if (!inputName || inputName.length === 0) continue @@ -258,17 +260,20 @@ class FormDataJson { } /** - * Unset for inputs + * Unset for inputs in given form/container * @param {HTMLFormElement|Element} formElement + * @param {FormDataJsonOptions=} options */ - static unsetFormInputs (formElement) { + static unsetFormInputs (formElement, options) { let inputs = formElement.querySelectorAll('select, textarea, input') for (let i = 0; i < inputs.length; i++) { - let inputType = (inputs[i].type || 'text').toLowerCase() + let input = inputs[i] + if (!FormDataJson.isElementAllowed(input, options)) continue + let inputType = (input.type || 'text').toLowerCase() if (FormDataJson.buttonInputTypes.indexOf(inputType) > -1) { continue } - FormDataJson.setInputValue(inputs[i], null) + FormDataJson.setInputValue(input, null) } } @@ -280,6 +285,17 @@ class FormDataJson { static isArray (arg) { return typeof arg === 'object' && Object.prototype.toString.call(arg) === '[object Array]' } + + /** + * Check if given input element is allowed depending on the given options + * @param {HTMLInputElement|HTMLSelectElement|HTMLTextAreaElement} element + * @param {FormDataJsonOptions=} options + * @return {boolean} + */ + static isElementAllowed (element, options) { + if (!element || !options || !options.inputFilter || typeof options.inputFilter !== 'function') return true + return options.inputFilter(element) === true + } } /** @@ -289,33 +305,51 @@ class FormDataJsonOptions { /** * Default option values + * For detailed explanation check properties bellow * @type {Object} */ static defaults = { - /** - * Include all disabled inputs in result data - * @type {boolean} - */ includeDisabled: false, - /** - * Include checkboxes that are unchecked with a null, otherwise the key will not exist in result data - * @type {boolean} - */ includeUncheckedAsNull: false, - /** - * Include all input buttons/submits values, otherwise the key they will not exist in result data - * @type {boolean} - */ includeButtonValues: false, - /** - * Will unset all existing input fields in form when using fillFormFromJsonValues - * This will be helpful if you have checkboxes and want to fill from json object, but checkboxes still stay checked - * because the key not exist in the json data - * @type {boolean} - */ - unsetAllInputsOnFill: false + unsetAllInputsOnFill: false, + inputFilter: null } + /** + * Include all disabled inputs in result data + * @type {boolean} + */ + includeDisabled + + /** + * Include checkboxes that are unchecked with a null, otherwise the key will not exist in result data + * @type {boolean} + */ + includeUncheckedAsNull + + /** + * Include all input buttons/submits values, otherwise the key they will not exist in result data + * @type {boolean} + */ + includeButtonValues + + /** + * Will unset all existing input fields in form when using fillFormFromJsonValues + * This will be helpful if you have checkboxes and want to fill from json object, but checkboxes still stay checked + * because the key not exist in the json data + * @type {boolean} + */ + unsetAllInputsOnFill + + /** + * If set to a function, this will receive the current input element in progress of formToJson|fillFormFromJsonValues|unsetFormInputs + * It must return bool true to allow the script to progress the input element + * If other than true is returned, than the input will be skipped + * @type {FormDataJsonOptions~inputFilterCallback|null} + */ + inputFilter + /** * Constructor * @param {Object=} options @@ -338,8 +372,15 @@ class FormDataJsonOptions { } } -// node module export -if (typeof module !== 'undefined') { +/** + * The input filter callback documentation + * @callback FormDataJsonOptions~inputFilterCallback + * @param {HTMLInputElement|HTMLSelectElement|HTMLTextAreaElement} element + * @return {boolean} + */ + +// module exports +if (typeof module !== 'undefined' && module.exports) { module.exports = { 'FormDataJson': FormDataJson, 'FormDataJsonOptions': FormDataJsonOptions