From 84950ac69ade1f92e7f5fad5871857515d1d0e32 Mon Sep 17 00:00:00 2001 From: Meir Rotstein Date: Sun, 8 Dec 2019 11:35:22 +0200 Subject: [PATCH] onValidationError to report any kind of error (#861) * onValidationError to report any kind of error * lint fixes --- docs/api.md | 21 ++++++++++++++++++--- examples/22_on_validation_event.html | 2 +- src/js/textmode.js | 8 +++++++- src/js/treemode.js | 6 ++++-- src/js/util.js | 7 ++++++- src/js/validationUtils.js | 3 ++- 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/docs/api.md b/docs/api.md index 1110360..469216e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -165,10 +165,11 @@ Constructs a new JSONEditor. - `{function} onValidationError(errors)` - Set a callback function for validation errors. Available in all modes. + Set a callback function for validation and parse errors. Available in all modes. - On validation of the json, if errors were found this callback is invoked with the validation errors data. - Between validations, the callback will be invoked only if the validation errors were changed. + On validation of the json, if errors of any kind were found this callback is invoked with the errors data. + + On change, the callback will be invoked only if errors were changed. Example: @@ -178,6 +179,20 @@ Constructs a new JSONEditor. * @param {Array} errors validation errors */ onValidationError: function (errors) { + errors.forEach((error) => { + switch (error.type) { + case 'validation': // schema validation error + ... + break; + case 'customValidation': // custom validation error + ... + break; + case 'error': // json parse error + ... + break; + ... + } + }); ... } } diff --git a/examples/22_on_validation_event.html b/examples/22_on_validation_event.html index f8eac4e..2b289ca 100644 --- a/examples/22_on_validation_event.html +++ b/examples/22_on_validation_event.html @@ -131,7 +131,7 @@ onValidationError: function(errors) { console.error('onValidationError', errors); const outputEL = document.getElementById('onValidationOutput') - outputEL.innerHTML = 'onValidationError was called with ' + errors.length + ' errors
' + + outputEL.innerHTML = 'onValidationError was called with ' + errors.length + ' error' + (errors.length > 1 ? 's' : '') + '
' + 'open the browser console to see the error objects'; }, onValidate: function (json) { diff --git a/src/js/textmode.js b/src/js/textmode.js index 98f7c67..b507c4b 100644 --- a/src/js/textmode.js +++ b/src/js/textmode.js @@ -804,7 +804,6 @@ textmode.validate = function () { console.error('Custom validation function did throw an error', err) }) } catch (err) { - this.lastSchemaErrors = undefined if (this.getText()) { // try to extract the line number from the jsonlint error message const match = /\w*line\s*(\d+)\w*/g.exec(err.message) @@ -820,6 +819,13 @@ textmode.validate = function () { } this._renderErrors(parseErrors) + + if (typeof this.options.onValidationError === 'function') { + if (isValidationErrorChanged(parseErrors, this.lastSchemaErrors)) { + this.options.onValidationError.call(this, parseErrors) + } + this.lastSchemaErrors = parseErrors + } } } diff --git a/src/js/treemode.js b/src/js/treemode.js index 25bcf46..7f541d1 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -563,7 +563,8 @@ treemode.validate = function () { .map(function findNode (error) { return { node: root.findNode(error.dataPath), - error: error + error: error, + type: 'validation' } }) .filter(function hasNode (entry) { @@ -675,7 +676,8 @@ treemode._validateCustom = function (json) { return { node: node, - error: error + error: error, + type: 'customValidation' } }) .filter(entry => entry && entry.node && entry.error && entry.error.message) diff --git a/src/js/util.js b/src/js/util.js index 0058474..a4bf66d 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -1464,7 +1464,12 @@ export function isValidationErrorChanged (currErr, prevErr) { if (prevErr.length !== currErr.length) { return true } for (let i = 0; i < currErr.length; ++i) { - const pErr = prevErr.find(p => p.dataPath === currErr[i].dataPath && p.schemaPath === currErr[i].schemaPath) + let pErr + if (currErr[i].type === 'error') { + pErr = prevErr.find(p => p.line === currErr[i].line) + } else { + pErr = prevErr.find(p => p.dataPath === currErr[i].dataPath && p.schemaPath === currErr[i].schemaPath) + } if (!pErr) { return true } diff --git a/src/js/validationUtils.js b/src/js/validationUtils.js index 2418b4c..0ec44ca 100644 --- a/src/js/validationUtils.js +++ b/src/js/validationUtils.js @@ -34,7 +34,8 @@ export function validateCustom (json, onValidate) { .map(error => // change data structure into the structure matching the JSON schema errors ({ dataPath: stringifyPath(error.path), - message: error.message + message: error.message, + type: 'customValidation' })) } else { return []