diff --git a/package.json b/package.json index dd333b3f62..1b6fccee5b 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "dependencies": { "@formio/bootstrap": "3.0.0-dev.98.17ba6ea", "@formio/choices.js": "^10.2.1", - "@formio/core": "v2.1.0-dev.174.9a3c6ec", + "@formio/core": "2.1.0-dev.183.b3387fc", "@formio/text-mask-addons": "^3.8.0-formio.3", "@formio/vanilla-text-mask": "^5.1.1-formio.1", "abortcontroller-polyfill": "^1.7.5", diff --git a/src/components/_classes/component/Component.js b/src/components/_classes/component/Component.js index 62d9305828..a95020c519 100644 --- a/src/components/_classes/component/Component.js +++ b/src/components/_classes/component/Component.js @@ -3,7 +3,7 @@ import { conformToMask } from '@formio/vanilla-text-mask'; import tippy from 'tippy.js'; import _ from 'lodash'; import isMobile from 'ismobilejs'; -import { processOne, processOneSync, validateProcessInfo } from '@formio/core/process'; +import { processOne, processOneSync, validateProcessInfo, conditionProcessInfo } from '@formio/core/process'; import { Formio } from '../../../Formio'; import * as FormioUtils from '../../../utils/utils'; @@ -227,7 +227,7 @@ export default class Component extends Element { * @param options */ /* eslint-disable no-unused-vars */ - static tableView(value, options) {} + static tableView(value, options) { } /* eslint-enable no-unused-vars */ /** @@ -867,9 +867,9 @@ export default class Component extends Element { labelIsHidden() { return !this.component.label || ((!this.isInDataGrid && this.component.hideLabel) || - (this.isInDataGrid && !this.component.dataGridLabel) || - this.options.floatingLabels || - this.options.inputsOnly) && !this.builderMode; + (this.isInDataGrid && !this.component.dataGridLabel) || + this.options.floatingLabels || + this.options.inputsOnly) && !this.builderMode; } transform(type, value) { @@ -1056,7 +1056,7 @@ export default class Component extends Element { settings.shadowRoot = this.root.shadowRoot; } - const widget = settings && Widgets[settings.type] ? new Widgets[settings.type](settings, this.component, this): null; + const widget = settings && Widgets[settings.type] ? new Widgets[settings.type](settings, this.component, this) : null; return widget; } @@ -1278,7 +1278,7 @@ export default class Component extends Element { const tooltipAttribute = tooltipEl.getAttribute('data-tooltip'); const tooltipDataTitle = tooltipEl.getAttribute('data-title'); const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute) - .replace(/(?:\r\n|\r|\n)/g, '
'); + .replace(/(?:\r\n|\r|\n)/g, '
'); return tippy(tooltipEl, { allowHTML: true, @@ -1733,7 +1733,7 @@ export default class Component extends Element { const handleCloseClick = (e) => { if (confirm) { confirm().then(() => close(e)) - .catch(() => {}); + .catch(() => { }); } else { close(e); @@ -1763,7 +1763,7 @@ export default class Component extends Element { * @returns {string} - The class name of this component. */ get className() { - let className = this.hasInput ? `${this.transform('class', 'form-group')} has-feedback `: ''; + let className = this.hasInput ? `${this.transform('class', 'form-group')} has-feedback ` : ''; className += `formio-component formio-component-${this.component.type} `; // TODO: find proper way to avoid overriding of default type-based component styles if (this.key && this.key !== 'form') { @@ -1957,7 +1957,7 @@ export default class Component extends Element { * @returns {string} - The error message configured for this component. */ errorMessage(type) { - return (this.component.errors && this.component.errors[type]) ? this.component.errors[type] : type; + return (this.component.errors && this.component.errors[type]) ? this.component.errors[type] : type; } /** @@ -2137,6 +2137,7 @@ export default class Component extends Element { * @param {any} row - The row data to check against. * @returns {boolean} - TRUE if the component is visible. */ + checkComponentConditions(data, flags, row) { data = data || this.rootValue; flags = flags || {}; @@ -2146,9 +2147,37 @@ export default class Component extends Element { this.redraw(); } + let pathCorrect = this.path; + + if (this.parent?.type !== 'datagrid') { + pathCorrect = this.path.replace(/\[[0-9]+\]/g, ''); + } + // Check advanced conditions - const visible = this.conditionallyVisible(data, row); + const processContext = { + component: this.component, + data, + row, + value: this.validationValue, + path: pathCorrect || this.component.key, + instance: this, + scope: { errors: [] }, + form: this.root, + processors: [ + conditionProcessInfo + ] + }; + let visible = true; + if (this.builderMode || this.previewMode || !this.hasCondition()) { + visible = !this.component.hidden; + } + else { + processOneSync(processContext); + const componentPath = pathCorrect || this.component.key; + const componentCondition = processContext.scope?.conditionals?.find(x => x.path === componentPath); + visible = !componentCondition?.conditionallyHidden; + } if (this.visible !== visible) { this.visible = visible; } @@ -2346,11 +2375,11 @@ export default class Component extends Element { value: _.clone(oldValue), data, row, - input: oldValue, + input: oldValue, component: newComponent, result, }, - 'value'); + 'value'); if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && !this.visible)) { this.setValue(newValue); @@ -2621,8 +2650,8 @@ export default class Component extends Element { 'ckeditor', isIEBrowser ? 'CKEDITOR' : 'ClassicEditor', _.get(this.options, 'editors.ckeditor.src', - `${Formio.cdn.ckeditor}/ckeditor.js` - ), true) + `${Formio.cdn.ckeditor}/ckeditor.js` + ), true) .then(() => { if (!element.parentNode) { return Promise.reject(); @@ -2846,7 +2875,7 @@ export default class Component extends Element { getCustomDefaultValue(defaultValue) { if (this.component.customDefaultValue && !this.options.preview) { - defaultValue = this.evaluate( + defaultValue = this.evaluate( this.component.customDefaultValue, { value: '' }, 'value' @@ -3136,21 +3165,21 @@ export default class Component extends Element { } convertNumberOrBoolToString(value) { - if (typeof value === 'number' || typeof value === 'boolean' ) { + if (typeof value === 'number' || typeof value === 'boolean') { return value.toString(); } return value; } doValueCalculation(dataValue, data, row) { - return this.evaluate(this.component.calculateValue, { - value: dataValue, - data, - row: row || this.data, - submission: this.root?._submission || { - data: this.rootValue - } - }, 'value'); + return this.evaluate(this.component.calculateValue, { + value: dataValue, + data, + row: row || this.data, + submission: this.root?._submission || { + data: this.rootValue + } + }, 'value'); } /* eslint-disable max-statements */ @@ -3833,7 +3862,7 @@ export default class Component extends Element { getRelativePath(path) { const keyPart = `.${this.key}`; const thisPath = this.isInputComponent ? this.path - : this.path.slice(0).replace(keyPart, ''); + : this.path.slice(0).replace(keyPart, ''); return path.replace(thisPath, ''); } @@ -4003,7 +4032,7 @@ export default class Component extends Element { return formio; } - resetCaches() {} + resetCaches() { } get previewMode() { return false; @@ -4011,7 +4040,7 @@ export default class Component extends Element { } Component.externalLibraries = {}; -Component.requireLibrary = function(name, property, src, polling) { +Component.requireLibrary = function (name, property, src, polling) { if (!Component.externalLibraries.hasOwnProperty(name)) { Component.externalLibraries[name] = {}; Component.externalLibraries[name].ready = new Promise((resolve, reject) => { @@ -4022,7 +4051,7 @@ Component.requireLibrary = function(name, property, src, polling) { const callbackName = `${name}Callback`; if (!polling && !window[callbackName]) { - window[callbackName] = function() { + window[callbackName] = function () { this.resolve(); }.bind(Component.externalLibraries[name]); } @@ -4087,7 +4116,7 @@ Component.requireLibrary = function(name, property, src, polling) { return Component.externalLibraries[name].ready; }; -Component.libraryReady = function(name) { +Component.libraryReady = function (name) { if ( Component.externalLibraries.hasOwnProperty(name) && Component.externalLibraries[name].ready diff --git a/src/components/select/Select.js b/src/components/select/Select.js index 068b2dd29e..43e4dae836 100644 --- a/src/components/select/Select.js +++ b/src/components/select/Select.js @@ -1487,7 +1487,6 @@ export default class SelectComponent extends ListComponent { } templateData[value] = this.templateData[value]; } - _.set(submission.metadata.selectData, this.path, templateData); } if (flags.resetValue && this.root?.submission && !this.options.readOnly) { diff --git a/test/unit/Webform.unit.js b/test/unit/Webform.unit.js index c67beebed3..53d7e1fde0 100644 --- a/test/unit/Webform.unit.js +++ b/test/unit/Webform.unit.js @@ -3310,8 +3310,8 @@ describe('Webform tests', function() { setTimeout(() => { assert.equal(conditionalComponent.visible, false, '(3) Component should be conditionally visible'); done(); - }, 300); - }, 300); + }, 500); + }, 500); }).catch((err) => done(err)); }); }); diff --git a/yarn.lock b/yarn.lock index 2ab2a0c002..506ca70e97 100644 --- a/yarn.lock +++ b/yarn.lock @@ -381,15 +381,15 @@ fuse.js "^6.6.2" redux "^4.2.0" -"@formio/core@v2.1.0-dev.174.9a3c6ec": - version "2.1.0-dev.174.9a3c6ec" - resolved "https://registry.yarnpkg.com/@formio/core/-/core-2.1.0-dev.174.9a3c6ec.tgz#f223b5ce4f374a9f4e922dada0af7c029320e035" - integrity sha512-QQK04dP0xBFa3vuhiOi+TUP8Zwqlg38qxzHgDmBwSlRO5XqQIObPJpSSnv2VA8H7fBWWiV2g7AErHBxugJW7Rw== +"@formio/core@2.1.0-dev.183.b3387fc": + version "2.1.0-dev.183.b3387fc" + resolved "https://registry.yarnpkg.com/@formio/core/-/core-2.1.0-dev.183.b3387fc.tgz#c10a87daff08018484e7d7e2b85dd88190f77253" + integrity sha512-aev1pLaLsmlNLYMo0zVyHD+jXWy7rjuA5jtphCcTVGqVza7p3rNDy22iwv0FvJR5e3ruWiUzo3nzqh6C2okURw== dependencies: browser-cookies "^1.2.0" core-js "^3.38.0" dayjs "^1.11.12" - dompurify "^3.1.6" + dompurify "^3.1.7" eventemitter3 "^5.0.0" fast-json-patch "^3.1.1" fetch-ponyfill "^7.1.0" @@ -2498,6 +2498,11 @@ dompurify@^3.1.6: resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.6.tgz#43c714a94c6a7b8801850f82e756685300a027e2" integrity sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ== +dompurify@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.7.tgz#711a8c96479fb6ced93453732c160c3c72418a6a" + integrity sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ== + downloadjs@^1.4.7: version "1.4.7" resolved "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz#f69f96f940e0d0553dac291139865a3cd0101e3c" @@ -7319,7 +7324,7 @@ string-replace-loader@^3.1.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -"string-width-cjs@npm:string-width@^4.2.0": +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7337,15 +7342,6 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -7406,7 +7402,7 @@ stringifier@^1.3.0: traverse "^0.6.6" type-name "^2.0.1" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -7427,13 +7423,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -8496,7 +8485,7 @@ workerpool@6.2.1: resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -8522,15 +8511,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"