diff --git a/web-client/core/themes/italia/static/formio/css/src/CDN.js b/web-client/core/themes/italia/static/formio/css/src/CDN.js
deleted file mode 100644
index 4f4190d9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/CDN.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// All external libs URLs should be injected through this class.
-// CDN libs URLs are accessible throuh CDN object properties
-// like Formio.cdn.ace === 'http://cdn.form.io/ace/1.4.12'.
-// For latest version use empty string
-class CDN {
- constructor(baseUrl) {
- this.baseUrl = baseUrl || 'https://cdn.form.io';
- this.overrides = {};
- this.libs = {
- 'ace': '1.4.12',
- 'bootstrap': '4.6.2',
- 'ckeditor': '19.0.0',
- 'flatpickr': '4.6.8',
- 'flatpickr-formio': '4.6.13-formio.3',
- 'font-awesome': '4.7.0',
- 'grid': 'latest',
- 'moment-timezone': 'latest',
- 'quill': '2.0.0-dev.3',
- 'shortcut-buttons-flatpickr': '0.4.0',
- 'uswds': '2.4.8',
- 'core': ''
- };
- this.updateUrls();
- }
-
- getVersion(lib) {
- return this.libs[lib];
- }
-
- // Sets a specific library version
- setVersion(lib, version) {
- this.libs[lib] = version;
- this.updateUrls();
- }
-
- // Sets base CDN url for all libraries
- setBaseUrl(url) {
- this.baseUrl = url;
- this.updateUrls();
- }
-
- // Allows to override CDN url for a specific library
- setOverrideUrl(lib, url) {
- this.overrides[lib] = url;
- this.updateUrls();
- }
-
- // Removes override for a specific library
- removeOverride(lib) {
- delete this.overrides[lib];
- this.updateUrls();
- }
-
- // Removes all overrides
- removeOverrides() {
- this.overrides = {};
- this.updateUrls();
- }
-
- buildUrl(cdnUrl, lib, version) {
- let url;
- if (version === 'latest' || version === '') {
- url = `${cdnUrl}/${lib}`;
- }
- else {
- url = `${cdnUrl}/${lib}/${version}`;
- }
- return url;
- }
-
- updateUrls() {
- for (const lib in this.libs) {
- if (lib in this.overrides) {
- this[lib] = this.buildUrl(this.overrides[lib], lib, this.libs[lib]);
- }
- else {
- this[lib] = this.buildUrl(this.baseUrl, lib, this.libs[lib]);
- }
- }
- }
-}
-
-export default CDN;
diff --git a/web-client/core/themes/italia/static/formio/css/src/CDN.unit.js b/web-client/core/themes/italia/static/formio/css/src/CDN.unit.js
deleted file mode 100644
index 0e92d810..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/CDN.unit.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import CDN from './CDN';
-import assert from 'power-assert';
-
-describe('Formio.js CDN class Tests', () => {
- let cdn;
- before(() => {
- cdn = new CDN('https://cdn.form.io');
- });
-
- it('Should give correct CDN URLs', () => {
- for (const lib in cdn.libs) {
- let expectedUrl = `${cdn.baseUrl}/${lib}/${cdn.libs[lib]}`;
- if (cdn.libs[lib] === '' || cdn.libs[lib] === 'latest') {
- expectedUrl = `${cdn.baseUrl}/${lib}`;
- }
- assert.equal(cdn[lib], expectedUrl);
- }
- });
-
- it('Should update lib versions', () => {
- cdn.setVersion('grid', '1.1.1');
- assert.equal(cdn.grid, 'https://cdn.form.io/grid/1.1.1');
- });
-
- it('Shoudl override CDN urls', () => {
- cdn.setOverrideUrl('grid', 'http://cdn.test-form.io');
- cdn.setVersion('grid', 'latest');
- assert.equal(cdn.grid, 'http://cdn.test-form.io/grid');
-
- cdn.setOverrideUrl('ace', 'http://cdn.test-form.io');
- });
-
- it('Should remove overrides', () => {
- cdn.removeOverrides();
- for (const lib in cdn.libs) {
- let expectedUrl = `${cdn.baseUrl}/${lib}/${cdn.libs[lib]}`;
- if (cdn.libs[lib] === '' || cdn.libs[lib] === 'latest') {
- expectedUrl = `${cdn.baseUrl}/${lib}`;
- }
- assert.equal(cdn[lib], expectedUrl);
- }
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/Element.js b/web-client/core/themes/italia/static/formio/css/src/Element.js
deleted file mode 100644
index adb84edb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Element.js
+++ /dev/null
@@ -1,617 +0,0 @@
-import EventEmitter from './EventEmitter';
-import { GlobalFormio as Formio } from './Formio';
-import * as FormioUtils from './utils/utils';
-import i18next from 'i18next';
-import _ from 'lodash';
-import moment from 'moment';
-import maskInput from '@formio/vanilla-text-mask';
-
-/**
- * The root component for all elements within the Form.io renderer.
- */
-export default class Element {
- constructor(options) {
- /**
- * The options for this component.
- * @type {{}}
- */
- this.options = Object.assign({
- language: 'en',
- highlightErrors: true,
- componentErrorClass: 'formio-error-wrapper',
- componentWarningClass: 'formio-warning-wrapper',
- row: '',
- namespace: 'formio'
- }, options || {});
-
- /**
- * The ID of this component. This value is auto-generated when the component is created, but
- * can also be provided from the component.id value passed into the constructor.
- * @type {string}
- */
- this.id = FormioUtils.getRandomComponentId();
- /**
- * An array of event handlers so that the destry command can deregister them.
- * @type {Array}
- */
- this.eventHandlers = [];
-
- // Use the i18next that is passed in, otherwise use the global version.
- this.i18next = this.options.i18next || i18next;
-
- /**
- * An instance of the EventEmitter class to handle the emitting and registration of events.
- *
- * @type {EventEmitter}
- */
- this.events = (options && options.events) ? options.events : new EventEmitter();
-
- this.defaultMask = null;
- /**
- * Conditional to show or hide helplinks in editForm
- *
- * @type {*|boolean}
- */
- this.helplinks = (this.options.helplinks === 'false') ? false : (this.options.helplinks || 'https://help.form.io');
- }
-
- /**
- * Register for a new event within this component.
- *
- * @example
- * let component = new BaseComponent({
- * type: 'textfield',
- * label: 'First Name',
- * key: 'firstName'
- * });
- * component.on('componentChange', (changed) => {
- * console.log('this element is changed.');
- * });
- *
- *
- * @param {string} event - The event you wish to register the handler for.
- * @param {function} cb - The callback handler to handle this event.
- */
- on(event, cb, internal, once = false) {
- if (!this.events) {
- return;
- }
- const type = `${this.options.namespace}.${event}`;
-
- // Store the component id in the handler so that we can determine which events are for this component.
- cb.id = this.id;
- cb.key = this.key;
- cb.internal = internal;
-
- // Register for this event.
- return this.events[once ? 'once' : 'on'](type, cb);
- }
-
- /**
- * Register for a new single-fire event within this component.
- *
- * @param {string} event - The event you wish to register the handler for.
- * @param {function} cb - The callback handler to handle this event.
- */
- once(event, cb, internal) {
- return this.on(event, cb, internal, true);
- }
-
- /**
- * Allow catching any event.
- *
- * @param cb
- * @returns {this}
- */
- onAny(cb) {
- if (!this.events) {
- return;
- }
-
- return this.events.onAny(cb);
- }
-
- /**
- * Removes the listener that will be fired when any event is emitted.
- *
- * @param cb
- * @returns {this}
- */
- offAny(cb) {
- if (!this.events) {
- return;
- }
-
- return this.events.offAny(cb);
- }
-
- /**
- * Removes a listener for a certain event. Not passing the 2nd arg will remove all listeners for that event.
- *
- * @param {string} event - The event you wish to register the handler for.
- * @param {function|undefined} cb - The callback handler to handle this event.
- */
- off(event, cb) {
- if (!this.events) {
- return;
- }
-
- const type = `${this.options.namespace}.${event}`;
-
- this.events.listeners(type).forEach((listener) => {
- // Ensure the listener is for this element
- if (!listener || listener.id !== this.id) {
- return;
- }
-
- // If there is a given callback, only deal with the match
- if (cb && cb !== listener) {
- return;
- }
-
- this.events.off(type, listener);
- });
- }
-
- /**
- * Emit a new event.
- *
- * @param {string} event - The event to emit.
- * @param {Object} data - The data to emit with the handler.
- */
- emit(event, ...data) {
- if (this.events) {
- this.events.emit(`${this.options.namespace}.${event}`, ...data);
- }
- }
-
- /**
- * Check if the component has an event handler set up for the event.
- *
- * @param {string} event - The event name.
- * @returns {boolean}
- */
- hasEventHandler(event) {
- if (!this.events) {
- return false;
- }
-
- const type = `${this.options.namespace}.${event}`;
-
- return this.events.listeners(type).some((listener) => {
- if (!listener) {
- return false;
- }
-
- return listener.id === this.id || listener.key === this.key;
- });
- }
-
- /**
- * Wrapper method to add an event listener to an HTML element.
- *
- * @param obj
- * The DOM element to add the event to.
- * @param type
- * The event name to add.
- * @param func
- * The callback function to be executed when the listener is triggered.
- * @param persistent
- * If this listener should persist beyond "destroy" commands.
- */
- addEventListener(obj, type, func, persistent, capture) {
- if (!obj) {
- return;
- }
- if (!persistent) {
- this.eventHandlers.push({ id: this.id, obj, type, func });
- }
- if ('addEventListener' in obj) {
- obj.addEventListener(type, func, !!capture);
- }
- else if ('attachEvent' in obj) {
- obj.attachEvent(`on${type}`, func);
- }
-
- return this;
- }
-
- /**
- * Remove an event listener from the object.
- *
- * @param obj
- * @param type
- */
- removeEventListener(obj, type, func = null) {
- const indexes = [];
- if (!obj) {
- return;
- }
-
- this.eventHandlers.forEach((handler, index) => {
- if (
- (handler.id === this.id)
- && obj.removeEventListener
- && (handler.type === type)
- && (!func || handler.func === func)
- ) {
- obj.removeEventListener(type, handler.func);
- indexes.push(index);
- }
- });
- if (indexes.length) {
- _.pullAt(this.eventHandlers, indexes);
- }
-
- return this;
- }
-
- removeEventListeners() {
- this.eventHandlers.forEach(handler => {
- if ((this.id === handler.id) && handler.type && handler.obj && handler.obj.removeEventListener) {
- handler.obj.removeEventListener(handler.type, handler.func);
- }
- });
- this.eventHandlers = [];
- }
-
- removeAllEvents(includeExternal) {
- _.each(this.events._events, (events, type) => {
- _.each(events, (listener) => {
- if (listener && (this.id === listener.id) && (includeExternal || listener.internal)) {
- this.events.off(type, listener);
- }
- });
- });
- }
-
- /**
- * Removes all event listeners attached to this component.
- */
- destroy() {
- this.removeEventListeners();
- this.removeAllEvents();
- }
-
- /**
- * Append an HTML DOM element to a container.
- *
- * @param element
- * @param container
- */
- appendTo(element, container) {
- container?.appendChild(element);
- return this;
- }
-
- /**
- * Prepend an HTML DOM element to a container.
- *
- * @param {HTMLElement} element - The DOM element to prepend.
- * @param {HTMLElement} container - The DOM element that is the container of the element getting prepended.
- */
- prependTo(element, container) {
- if (container) {
- if (container.firstChild) {
- try {
- container.insertBefore(element, container.firstChild);
- }
- catch (err) {
- console.warn(err);
- container.appendChild(element);
- }
- }
- else {
- container.appendChild(element);
- }
- }
-
- return this;
- }
-
- /**
- * Removes an HTML DOM element from its bounding container.
- *
- * @param {HTMLElement} element - The element to remove.
- * @param {HTMLElement} container - The DOM element that is the container of the element to remove.
- */
- removeChildFrom(element, container) {
- if (container && container.contains(element)) {
- try {
- container.removeChild(element);
- }
- catch (err) {
- console.warn(err);
- }
- }
-
- return this;
- }
-
- /**
- * Alias for document.createElement.
- *
- * @param {string} type - The type of element to create
- * @param {Object} attr - The element attributes to add to the created element.
- * @param {Various} children - Child elements. Can be a DOM Element, string or array of both.
- *
- * @return {HTMLElement} - The created element.
- */
- ce(type, attr, children = null) {
- // console.warn('Call to deprecated this.ce(). Dom elements should be created with templates, not manually with ce.');
- // Create the element.
- const element = document.createElement(type);
-
- // Add attributes.
- if (attr) {
- this.attr(element, attr);
- }
-
- // Append the children.
- this.appendChild(element, children);
- return element;
- }
-
- /**
- * Append different types of children.
- *
- * @param child
- */
- appendChild(element, child) {
- if (Array.isArray(child)) {
- child.forEach((oneChild) => this.appendChild(element, oneChild));
- }
- else if (child instanceof HTMLElement || child instanceof Text) {
- element.appendChild(child);
- }
- else if (child) {
- element.appendChild(this.text(child.toString()));
- }
-
- return this;
- }
-
- /**
- * Creates a new input mask placeholder.
- * @param {HTMLElement} mask - The input mask.
- * @returns {string} - The placeholder that will exist within the input as they type.
- */
- maskPlaceholder(mask) {
- return mask.map((char) => (char instanceof RegExp) ? this.placeholderChar : char).join('');
- }
-
- get placeholderChar() {
- return this.component?.inputMaskPlaceholderChar || '_';
- }
-
- /**
- * Sets the input mask for an input.
- *
- * @param {HTMLElement} input - The html input to apply the mask to.
- * @param {String} inputMask - The input mask to add to this input.
- * @param {Boolean} usePlaceholder - Set the mask placeholder on the input.
- */
- setInputMask(input, inputMask, usePlaceholder) {
- if (input && inputMask) {
- const mask = FormioUtils.getInputMask(inputMask, this.placeholderChar);
- this.defaultMask = mask;
-
- try {
- //destroy previous mask
- if (input.mask) {
- input.mask.destroy();
- }
-
- input.mask = maskInput({
- inputElement: input,
- mask,
- placeholderChar: this.placeholderChar,
- shadowRoot: this.root ? this.root.shadowRoot : null
- });
- }
- catch (e) {
- // Don't pass error up, to prevent form rejection.
- // Internal bug of vanilla-text-mask on iOS (`selectionEnd`);
- console.warn(e);
- }
- if (mask.numeric) {
- input.setAttribute('pattern', '\\d*');
- }
- if (usePlaceholder) {
- input.setAttribute('placeholder', this.maskPlaceholder(mask));
- }
- }
- }
-
- /**
- * Translate a text using the i18n system.
- *
- * @param {string|Array} text - The i18n identifier.
- * @param {Object} params - The i18n parameters to use for translation.
- */
- t(text, ...args) {
- return this.i18next.t(text, ...args);
- }
-
- /**
- * Alias to create a text node.
- * @param text
- * @returns {Text}
- */
- text(text) {
- return document.createTextNode(this.t(text));
- }
-
- /**
- * Adds an object of attributes onto an element.
- * @param {HtmlElement} element - The element to add the attributes to.
- * @param {Object} attr - The attributes to add to the input element.
- */
- attr(element, attr) {
- if (!element) {
- return;
- }
- _.each(attr, (value, key) => {
- if (typeof value !== 'undefined') {
- if (key.indexOf('on') === 0) {
- // If this is an event, add a listener.
- this.addEventListener(element, key.substr(2).toLowerCase(), value);
- }
- else {
- // Otherwise it is just an attribute.
- element.setAttribute(key, value);
- }
- }
- });
- }
-
- /**
- * Determines if an element has a class.
- *
- * Taken from jQuery https://j11y.io/jquery/#v=1.5.0&fn=jQuery.fn.hasClass
- */
- hasClass(element, className) {
- if (!element) {
- return false;
- }
- // Allow templates to intercept.
- className = ` ${className} `;
- return ((` ${element.className} `).replace(/[\n\t\r]/g, ' ').indexOf(className) > -1);
- }
-
- /**
- * Adds a class to a DOM element.
- *
- * @param element
- * The element to add a class to.
- * @param className
- * The name of the class to add.
- */
- addClass(element, className) {
- if (!element || !(element instanceof HTMLElement)) {
- return this;
- }
- // Allow templates to intercept.
- const classes = element.getAttribute('class');
- if (!classes?.includes(className)) {
- element.setAttribute('class', `${classes} ${className}`);
- }
-
- return this;
- }
-
- /**
- * Remove a class from a DOM element.
- *
- * @param element
- * The DOM element to remove the class from.
- * @param className
- * The name of the class that is to be removed.
- */
- removeClass(element, className) {
- if (!element || !className || !(element instanceof HTMLElement)) {
- return this;
- }
- // Allow templates to intercept.
- let cls = element.getAttribute('class');
- if (cls) {
- cls = cls.replace(new RegExp(` ${className}`, 'g'), '');
- element.setAttribute('class', cls);
- }
-
- return this;
- }
-
- /**
- * Empty's an HTML DOM element.
- *
- * @param {HTMLElement} element - The element you wish to empty.
- */
- empty(element) {
- if (element) {
- while (element.firstChild) {
- element.removeChild(element.firstChild);
- }
- }
- }
-
- /**
- * Create an evaluation context for all script executions and interpolations.
- *
- * @param additional
- * @return {*}
- */
- evalContext(additional) {
- return Object.assign({
- _,
- utils: FormioUtils,
- util: FormioUtils,
- user: Formio.getUser(),
- moment,
- instance: this,
- self: this,
- token: Formio.getToken({
- decode: true
- }),
- config: this.root && this.root.form && this.root.form.config
- ? this.root.form.config
- : this.options?.formConfig
- ? this.options.formConfig
- : {},
- }, additional, _.get(this.root, 'options.evalContext', {}));
- }
-
- /**
- * Performs an interpolation using the evaluation context of this component.
- *
- * @param string
- * @param data
- * @return {XML|string|*|void}
- */
- interpolate(string, data, options = {}) {
- if (typeof string !== 'function' && (this.component.content || this.component.html)
- && !FormioUtils.Evaluator.templateSettings.interpolate.test(string)) {
- string = FormioUtils.translateHTMLTemplate(String(string), (value) => this.t(value));
- }
-
- return FormioUtils.interpolate(string, this.evalContext(data), options);
- }
-
- /**
- * Performs an evaluation using the evaluation context of this component.
- *
- * @param func
- * @param args
- * @param ret
- * @param tokenize
- * @return {*}
- */
- evaluate(func, args, ret, tokenize) {
- return FormioUtils.evaluate(func, this.evalContext(args), ret, tokenize);
- }
-
- /**
- * Allow for options to hook into the functionality of this renderer.
- * @return {*}
- */
- hook() {
- const name = arguments[0];
- if (
- this.options &&
- this.options.hooks &&
- this.options.hooks[name]
- ) {
- return this.options.hooks[name].apply(this, Array.prototype.slice.call(arguments, 1));
- }
- else {
- // If this is an async hook instead of a sync.
- const fn = (typeof arguments[arguments.length - 1] === 'function') ? arguments[arguments.length - 1] : null;
- if (fn) {
- return fn(null, arguments[1]);
- }
- else {
- return arguments[1];
- }
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/Embed.js b/web-client/core/themes/italia/static/formio/css/src/Embed.js
deleted file mode 100644
index c8680b48..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Embed.js
+++ /dev/null
@@ -1,388 +0,0 @@
-import CDN from './CDN';
-// eslint-disable-next-line max-statements
-export function embed(config = {}) {
- const scripts = document.getElementsByTagName('script');
- config = Object.assign(config, window.FormioConfig);
- let thisScript = null;
- let i = scripts.length;
- const scriptName = config.scriptName || 'formio.embed.';
- while (i--) {
- if (
- scripts[i].src && (scripts[i].src.indexOf(scriptName) !== -1)
- ) {
- thisScript = scripts[i];
- break;
- }
- }
-
- if (thisScript) {
- const query = {};
- const queryString = thisScript.src.replace(/^[^?]+\??/, '');
- queryString.replace(/\?/g, '&').split('&').forEach((item) => {
- query[item.split('=')[0]] = item.split('=')[1] && decodeURIComponent(item.split('=')[1]);
- });
-
- let scriptSrc = thisScript.src.replace(/^([^?]+).*/, '$1').split('/');
- scriptSrc.pop();
- if (config.formioPath) {
- config.formioPath(scriptSrc);
- }
- scriptSrc = scriptSrc.join('/');
- query.script = query.script || (`${config.updatePath ? config.updatePath() :scriptSrc}/formio.form.min.js`);
- query.styles = query.styles || (`${config.updatePath ? config.updatePath() :scriptSrc}/formio.form.min.css`);
- const cdn = query.cdn || 'https://cdn.jsdelivr.net/npm';
-
- const resolveLibs = (cdn) => {
- const libs = {
- uswds: {
- fa: true,
- js: `${cdn}/uswds@2.10.0/dist/js/uswds.min.js`,
- css: `${cdn}/uswds@2.10.0/dist/css/uswds.min.css`
- },
- fontawesome: {
- css: `${cdn}/font-awesome@4.7.0/css/font-awesome.min.css`
- },
- bootstrap: {
- css: `${cdn}/bootstrap@4.6.0/dist/css/bootstrap.min.css`
- }
- };
- // Check if using cdn.form.io standart folders format
- if (cdn instanceof CDN) {
- const url = cdn.baseUrl;
- libs.uswds.js = `${url}/uswds/${cdn.getVersion('uswds')}/uswds.min.js`;
- libs.uswds.css = `${url}/uswds/${cdn.getVersion('uswds')}/uswds.min.css`;
- libs.fontawesome.css = `${url}/font-awesome/${cdn.getVersion('font-awesome')}/css/font-awesome.min.css`;
- libs.bootstrap.css = `${url}/bootstrap/${cdn.getVersion('bootstrap')}/css/bootstrap.min.css`;
- }
- return libs;
- };
-
- config = Object.assign({
- script: query.script,
- style: query.styles,
- class: (query.class || 'formio-form-wrapper'),
- src: query.src,
- form: null,
- submission: null,
- project: query.project,
- base: query.base,
- submit: query.submit,
- includeLibs: (query.libs === 'true' || query.libs === '1'),
- template: query.template,
- debug: (query.debug === 'true' || query.debug === '1'),
- config: {},
- redirect: (query.return || query.redirect),
- before: () => {},
- after: () => {}
- }, config);
-
- /**
- * Print debug statements.
- *
- * @param {...any} args Arguments to pass to the console.log method.
- */
- const debug = (...args) => {
- if (config.debug) {
- console.log(...args);
- }
- };
-
- /**
- * Creates a new DOM element.
- *
- * @param {string} tag The HTMLElement to add to the wrapper or shadow dom.
- * @param {Object} attrs The attributes to add to this element.
- * @param {Array} children The children attached to this element.
- */
- const createElement = (tag, attrs, children) => {
- const element = document.createElement(tag);
- for (const attr in attrs) {
- if (attrs.hasOwnProperty(attr)) {
- element.setAttribute(attr, attrs[attr]);
- }
- }
- (children || []).forEach(child => {
- element.appendChild(createElement(child.tag, child.attrs, child.children));
- });
- return element;
- };
-
- debug('Embedding Configuration', config);
-
- if (config.addPremiumLib) {
- config.addPremiumLib(config, scriptSrc);
- }
-
- // The id for this embedded form.
- const id = `formio-${Math.random().toString(36).substring(7)}`;
- config.id = id;
-
- debug('Creating form wrapper');
- let wrapper = createElement('div', {
- 'id': `"${id}-wrapper"`
- });
-
- // insertAfter doesn't exist, but effect is identical.
- thisScript.parentNode.insertBefore(wrapper, thisScript.parentNode.firstElementChild.nextSibling);
-
- // If we include the libraries, then we will attempt to run this in shadow dom.
- if (config.includeLibs && (typeof wrapper.attachShadow === 'function') && !config.premium) {
- wrapper = wrapper.attachShadow({
- mode: 'open'
- });
- config.config.shadowRoot = wrapper;
- }
-
- const global = (name) => {
- const globalValue = window[name];
- debug(`Getting global ${name}`, globalValue);
- return globalValue;
- };
-
- const addStyles = (href, global) => {
- if (!href) {
- return;
- }
- if (typeof href !== 'string' && href.length) {
- href.forEach(ref => addStyles(ref));
- return;
- }
- debug('Adding Styles', href);
- const link = createElement('link', {
- rel: 'stylesheet',
- href
- });
- if (global) {
- // Add globally as well.
- document.head.appendChild(link);
- }
- wrapper.appendChild(createElement('link', {
- rel: 'stylesheet',
- href
- }));
- };
-
- const addScript = (src, globalProp, onReady) => {
- if (!src) {
- return;
- }
- if (typeof src !== 'string' && src.length) {
- src.forEach(ref => addScript(ref));
- return;
- }
- if (globalProp && global(globalProp)) {
- debug(`${globalProp} already loaded.`);
- return global(globalProp);
- }
- debug('Adding Script', src);
- wrapper.appendChild(createElement('script', {
- src
- }));
- if (globalProp && onReady) {
- debug(`Waiting to load ${globalProp}`);
- const wait = setInterval(() => {
- if (global(globalProp)) {
- clearInterval(wait);
- debug(`${globalProp} loaded.`);
- onReady(global(globalProp));
- }
- }, 100);
- }
- };
-
- // Create a loader
- addStyles(`${config.updatePath ? config.updatePath() : scriptSrc}/formio.embed.min.css`);
- debug('Creating loader');
- const loader = createElement('div', {
- 'class': 'formio-loader'
- }, [{
- tag: 'div',
- attrs: {
- class: 'loader-wrapper'
- },
- children: [{
- tag: 'div',
- attrs: {
- class: 'loader text-center'
- }
- }]
- }]);
- wrapper.appendChild(loader);
-
- // Add the wrapper for the rendered form.
- debug('Creating form element');
- const formElement = createElement('div', {
- class: config.class
- });
- wrapper.appendChild(formElement);
-
- // Add the main formio script.
- addScript(config.script, 'Formio', (Formio) => {
- const renderForm = () => {
- addStyles(config.style);
- const isReady = config.before(Formio, formElement, config) || Formio.Promise.resolve();
- const form = (config.form || config.src);
- debug('Creating form', form, config.config);
- isReady.then(() => {
- Formio.license = true;
- Formio.createForm(formElement, form, config.config).then((instance) => {
- const submitDone = (submission) => {
- debug('Submision Complete', submission);
- let returnUrl = config.redirect;
-
- // Allow form based configuration for return url.
- if (
- !returnUrl &&
- (
- instance._form &&
- instance._form.settings &&
- (
- instance._form.settings.returnUrl ||
- instance._form.settings.redirect
- )
- )
- ) {
- debug('Return url found in form configuration');
- returnUrl = instance._form.settings.returnUrl || instance._form.settings.redirect;
- }
-
- if (returnUrl) {
- const formSrc = instance.formio ? instance.formio.formUrl : '';
- const hasQuery = !!returnUrl.match(/\?/);
- const isOrigin = returnUrl.indexOf(location.origin) === 0;
- returnUrl += hasQuery ? '&' : '?';
- returnUrl += `sub=${submission._id}`;
- if (!isOrigin && formSrc) {
- returnUrl += `&form=${encodeURIComponent(formSrc)}`;
- }
- debug('Return URL', returnUrl);
- window.location.href = returnUrl;
- if (isOrigin) {
- window.location.reload();
- }
- }
- };
-
- if (config.submit) {
- instance.nosubmit = true;
- }
-
- debug('Form created', instance);
-
- // Remove the loader.
- debug('Removing loader');
- wrapper.removeChild(loader);
-
- // Set the default submission data.
- if (config.submission) {
- debug('Setting submission', config.submission);
- instance.submission = config.submission;
- }
-
- // Allow them to provide additional configs.
- debug('Triggering embed event');
- Formio.events.emit('formEmbedded', instance);
-
- debug('Calling ready callback');
- config.after(instance, config);
-
- // Configure a redirect.
- instance.on('submit', (submission) => {
- debug("on('submit')", submission);
- if (config.submit) {
- debug(`Sending submission to ${config.submit}`);
- const headers = {
- 'content-type': 'application/json'
- };
- const token = Formio.getToken();
- if (token) {
- headers['x-jwt-token'] = token;
- }
- Formio.fetch(config.submit, {
- body: JSON.stringify(submission),
- headers: headers,
- method: 'POST',
- mode: 'cors',
- })
- .then(resp => resp.json())
- .then(submission => submitDone(submission));
- }
- else {
- submitDone(submission);
- }
- });
- });
- });
- };
-
- if (config.base) {
- Formio.setBaseUrl(config.base);
- }
- if (config.project) {
- Formio.setProjectUrl(config.project);
- }
-
- // Add premium modules
- if (global('premium')) {
- debug('Using premium module.');
- Formio.use(global('premium'));
- }
-
- if (global('vpat')) {
- debug('Using vpat module.');
- Formio.use(global('vpat'));
- }
-
- if (config.template) {
- if (config.includeLibs) {
- addStyles(config.libs[config.template].css);
- addScript(config.libs[config.template].js);
- if (config.libs[config.template].fa) {
- addStyles(config.libs.fontawesome.css, true);
- }
- }
- let templateSrc;
- if (cdn instanceof CDN) {
- templateSrc = `${cdn[config.template]}/${config.template}.min`;
- }
- else {
- templateSrc = `${cdn}/@formio/${config.template}@latest/dist/${config.template}.min`;
- }
- addStyles(`${templateSrc}.css`);
- addScript(`${templateSrc}.js`, config.template, (template) => {
- debug(`Using ${config.template}`);
- Formio.use(template);
- renderForm();
- });
- }
- else if (global('uswds')) {
- debug('Using uswds module.');
- Formio.use(global('uswds'));
- }
- // Default bootstrap + fontawesome.
- else if (config.includeLibs) {
- Formio.cdn = new CDN();
- config.libs = resolveLibs(query.cdn || Formio.cdn);
- addStyles(config.libs.fontawesome.css, true);
- addStyles(config.libs.bootstrap.css);
- }
- if (config.premium) {
- addStyles(config.premium.css);
- addScript(config.premium.js, 'premium', (premium) => {
- debug('Using premium');
- Formio.use(premium);
- renderForm();
- });
- }
-
- // Render the form if no template is provided.
- if (!config.template && !config.premium) {
- renderForm();
- }
- });
- }
- else {
- // Show an error if the script cannot be found.
- document.write('Could not locate the Embedded form. ');
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/EventEmitter.js b/web-client/core/themes/italia/static/formio/css/src/EventEmitter.js
deleted file mode 100644
index 06455250..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/EventEmitter.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import { EventEmitter as EventEmitter3 } from 'eventemitter3';
-import * as utils from './utils/utils';
-export default class EventEmitter extends EventEmitter3 {
- constructor(conf = {}) {
- const { loadLimit = 1000, eventsSafeInterval = 300 } = conf;
- super();
-
- const overloadHandler = () => {
- console.warn(`There were more than ${loadLimit} events emitted in ${eventsSafeInterval} ms. It might be caused by events' infinite loop`, this.id);
- };
-
- const dispatch = utils.observeOverload(overloadHandler, {
- limit: loadLimit,
- delay: eventsSafeInterval
- });
-
- this.emit = (...args) => {
- super.emit(...args);
- super.emit('any', ...args);
-
- dispatch();
- };
- }
-
- onAny = (fn) => {
- this.on('any', fn);
- }
-
- offAny = (fn) => {
- this.off('any', fn);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/Form.js b/web-client/core/themes/italia/static/formio/css/src/Form.js
deleted file mode 100644
index 094e11ac..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Form.js
+++ /dev/null
@@ -1,321 +0,0 @@
-import Element from './Element';
-import { GlobalFormio as Formio } from './Formio';
-import Displays from './displays';
-import templates from './templates';
-import * as FormioUtils from './utils/utils';
-import NativePromise from 'native-promise-only';
-
-export default class Form extends Element {
- /**
- * Creates an easy to use interface for embedding webforms, pdfs, and wizards into your application.
- *
- * @param {Object} element - The DOM element you wish to render this form within.
- * @param {Object | string} form - Either a Form JSON schema or the URL of a hosted form via. form.io.
- * @param {Object} options - The options to create a new form instance.
- * @param {boolean} options.readOnly - Set this form to readOnly
- * @param {boolean} options.noAlerts - Set to true to disable the alerts dialog.
- * @param {boolean} options.i18n - The translation file for this rendering. @see https://github.com/formio/formio.js/blob/master/i18n.js
- * @param {boolean} options.template - Provides a way to inject custom logic into the creation of every element rendered within the form.
- *
- * @example
- * import Form from 'formiojs/Form';
- * const form = new Form(document.getElementById('formio'), 'https://examples.form.io/example');
- * form.build();
- */
- constructor(...args) {
- let options = args[0] instanceof HTMLElement ? args[2] : args[1];
- if (Formio.options && Formio.options.form) {
- options = Object.assign(options, Formio.options.form);
- }
-
- super(options);
-
- if (this.options.useSessionToken) {
- Formio.useSessionToken(this.options);
- }
-
- this.ready = new NativePromise((resolve, reject) => {
- this.readyResolve = resolve;
- this.readyReject = reject;
- });
-
- this.instance = null;
- if (args[0] instanceof HTMLElement) {
- this.element = args[0];
- this.options = args[2] || {};
- this.options.events = this.events;
- this.setForm(args[1])
- .then(() => this.readyResolve(this.instance))
- .catch(this.readyReject);
- }
- else if (args[0]) {
- this.element = null;
- this.options = args[1] || {};
- this.options.events = this.events;
- this.setForm(args[0])
- .then(() => this.readyResolve(this.instance))
- .catch(this.readyReject);
- }
- else {
- this.element = null;
- this.options = {};
- this.options.events = this.events;
- }
- this.display = '';
- }
-
- /**
- * Create a new form instance provided the display of the form.
- *
- * @param {string} display - The display of the form, either "wizard", "form", or "pdf"
- * @return {*}
- */
- create(display) {
- if (this.options && (this.options.flatten || this.options.renderMode === 'flat')) {
- display = 'form';
- }
- this.display = display;
- if (Displays.displays[display]) {
- return new Displays.displays[display](this.element, this.options);
- }
- else {
- // eslint-disable-next-line new-cap
- return new Displays.displays['webform'](this.element, this.options);
- }
- }
-
- /**
- * Sets the form. Either as JSON or a URL to a form JSON schema.
- *
- * @param {string|object} formParam - Either the form JSON or the URL of the form json.
- * @return {*}
- */
- set form(formParam) {
- return this.setForm(formParam);
- }
-
- errorForm(err) {
- return {
- components: [
- {
- 'label': 'HTML',
- 'tag': 'div',
- 'className': 'error error-message alert alert-danger ui red message',
- 'attrs': [
- {
- 'attr': 'role',
- 'value': 'alert'
- }
- ],
- 'key': 'errorMessage',
- 'type': 'htmlelement',
- 'input': false,
- 'content': typeof err === 'string' ? err : err.message,
- }
- ]
- };
- }
-
- setForm(formParam) {
- let result;
- formParam = formParam || this.form;
- if (typeof formParam === 'string') {
- const formio = new Formio(formParam);
- let error;
- result = this.getSubmission(formio, this.options)
- .catch((err) => {
- error = err;
- })
- .then((submission) => {
- return formio.loadForm()
- // If the form returned an error, show it instead of the form.
- .catch(err => {
- error = err;
- })
- .then((form) => {
- // If the submission returned an error, show it instead of the form.
- if (error) {
- form = this.errorForm(error);
- }
- this.instance = this.instance || this.create(form.display);
- this.instance.url = formParam;
- this.instance.nosubmit = false;
- this._form = this.instance.form = form;
- if (submission) {
- this.instance.submission = submission;
- }
- if (error) {
- throw error;
- }
- return this.instance;
- });
- });
- }
- else {
- this.instance = this.instance || this.create(formParam.display);
- this._form = this.instance.form = formParam;
- result = this.instance.ready;
- }
-
- // A redraw has occurred so save off the new element in case of a setDisplay causing a rebuild.
- return result.then(() => {
- this.element = this.instance.element;
- return this.instance;
- });
- }
-
- getSubmission(formio, opts) {
- if (formio.submissionId) {
- return formio.loadSubmission(null, opts);
- }
- return NativePromise.resolve();
- }
-
- /**
- * Returns the loaded forms JSON.
- *
- * @return {object} - The loaded form's JSON
- */
- get form() {
- return this._form;
- }
-
- /**
- * Changes the display of the form.
- *
- * @param {string} display - The display to set this form. Either "wizard", "form", or "pdf"
- * @return {Promise}
- */
- setDisplay(display) {
- if ((this.display === display) && this.instance) {
- return NativePromise.resolve(this.instance);
- }
-
- this.form.display = display;
- this.instance.destroy();
- this.instance = this.create(display);
- return this.setForm(this.form);
- }
-
- empty() {
- if (this.element) {
- while (this.element.firstChild) {
- this.element.removeChild(this.element.firstChild);
- }
- }
- }
-
- static embed(embed) {
- return new NativePromise((resolve) => {
- if (!embed || !embed.src) {
- resolve();
- }
- const id = this.id || `formio-${Math.random().toString(36).substring(7)}`;
- const className = embed.class || 'formio-form-wrapper';
- let code = embed.styles ? ` ` : '';
- code += `
`;
- document.write(code);
- let attempts = 0;
- const wait = setInterval(() => {
- attempts++;
- const formElement = document.getElementById(id);
- if (formElement || attempts > 10) {
- resolve(new Form(formElement, embed.src).ready);
- clearInterval(wait);
- }
- }, 10);
- });
- }
-
- /**
- * Sanitize an html string.
- *
- * @param string
- * @returns {*}
- */
- sanitize(dirty, forceSanitize) {
- // If Sanitize is turned off
- if (this.options.sanitize === false && !forceSanitize) {
- return dirty;
- }
- return FormioUtils.sanitize(dirty, this.options);
- }
-
- setContent(element, content, forceSanitize) {
- if (element instanceof HTMLElement) {
- element.innerHTML = this.sanitize(content, forceSanitize);
- return true;
- }
- return false;
- }
-
- /**
- * Build a new form.
- *
- * @return {Promise}
- */
- build() {
- if (!this.instance) {
- return NativePromise.reject('Form not ready. Use form.ready promise');
- }
-
- if (!this.element) {
- return NativePromise.reject('No DOM element for form.');
- }
-
- // Add temporary loader.
- const template = (this.options && this.options.template) ? this.options.template : 'bootstrap';
- const loader = templates[template].loader || templates.bootstrap.loader;
- this.setContent(this.element, loader.form);
-
- return this.render().then(html => {
- this.setContent(this.element, html);
- return this.attach(this.element).then(() => this.instance);
- })
- .then((param) => {
- this.emit('build', param);
- return param;
- });
- }
-
- render() {
- if (!this.instance) {
- return NativePromise.reject('Form not ready. Use form.ready promise');
- }
- return NativePromise.resolve(this.instance.render())
- .then((param) => {
- this.emit('render', param);
- return param;
- });
- }
-
- attach(element) {
- if (!this.instance) {
- return NativePromise.reject('Form not ready. Use form.ready promise');
- }
- this.element = element;
- return this.instance.attach(this.element)
- .then((param) => {
- this.emit('attach', param);
- return param;
- });
- }
-}
-
-// Allow simple embedding.
-Formio.embedForm = (embed) => Form.embed(embed);
-
-/**
- * Factory that creates a new form based on the form parameters.
- *
- * @param element {HMTLElement} - The HTML Element to add this form to.
- * @param form {string|Object} - The src of the form, or a form object.
- * @param options {Object} - The options to create this form.
- *
- * @return {Promise} - When the form is instance is ready.
- */
-Formio.createForm = (...args) => {
- return (new Form(...args)).ready;
-};
-
-Formio.Form = Form;
diff --git a/web-client/core/themes/italia/static/formio/css/src/FormBuilder.js b/web-client/core/themes/italia/static/formio/css/src/FormBuilder.js
deleted file mode 100644
index 788aa6ac..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/FormBuilder.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import { GlobalFormio as Formio } from './Formio';
-import Builders from './builders';
-import Form from './Form';
-
-export default class FormBuilder extends Form {
- static options = {};
- constructor(element, form, options) {
- form = form || {};
- options = options || {};
- super(element, form, Object.assign(
- options,
- FormBuilder.options,
- ((Formio.options && Formio.options.builder) ? Formio.options.builder : {})
- ));
- }
-
- create(display) {
- if (Builders.builders[display]) {
- return new Builders.builders[display](this.element, this.options);
- }
- else {
- // eslint-disable-next-line new-cap
- return new Builders.builders['webform'](this.element, this.options);
- }
- }
-}
-
-/**
- * Factory that creates a new form builder based on the form parameter.
- *
- * @param element {HMTLElement} - The HTML Element to add this form to.
- * @param form {string|Object} - The src of the form, or a form object.
- * @param options {Object} - The options to create this form.
- *
- * @return {Promise} - When the form is instance is ready.
- */
-Formio.builder = (...args) => {
- return (new FormBuilder(...args)).ready;
-};
-
-Formio.FormBuilder = FormBuilder;
diff --git a/web-client/core/themes/italia/static/formio/css/src/Formio.js b/web-client/core/themes/italia/static/formio/css/src/Formio.js
deleted file mode 100644
index 34ff6c4f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Formio.js
+++ /dev/null
@@ -1,1684 +0,0 @@
-/* globals OktaAuth */
-// Intentionally use native-promise-only here... Other promise libraries (es6-promise)
-// duck-punch the global Promise definition which messes up Angular 2 since it
-// also duck-punches the global Promise definition. For now, keep native-promise-only.
-import NativePromise from 'native-promise-only';
-import fetchPonyfill from 'fetch-ponyfill';
-import EventEmitter from './EventEmitter';
-import cookies from 'browser-cookies';
-import Providers from './providers';
-import _intersection from 'lodash/intersection';
-import _get from 'lodash/get';
-import _cloneDeep from 'lodash/cloneDeep';
-import _defaults from 'lodash/defaults';
-import { eachComponent } from './utils/utils';
-import jwtDecode from 'jwt-decode';
-import './polyfills';
-import CDN from './CDN';
-
-const { fetch, Headers } = fetchPonyfill({
- Promise: NativePromise
-});
-
-const isBoolean = (val) => typeof val === typeof true;
-const isNil = (val) => val === null || val === undefined;
-const isObject = (val) => val && typeof val === 'object';
-
-function cloneResponse(response) {
- const copy = _cloneDeep(response);
-
- if (Array.isArray(response)) {
- copy.skip = response.skip;
- copy.limit = response.limit;
- copy.serverCount = response.serverCount;
- }
-
- return copy;
-}
-
-/**
- * The Formio interface class.
- *
- * let formio = new Formio('https://examples.form.io/example');
- */
-class Formio {
- static currentUserResolved = true;
- /* eslint-disable max-statements */
- constructor(path, options = {}) {
- // Ensure we have an instance of Formio.
- if (!(this instanceof Formio)) {
- return new Formio(path);
- }
-
- // Initialize our variables.
- this.base = '';
- this.projectsUrl = '';
- this.projectUrl = '';
- this.projectId = '';
- this.roleUrl = '';
- this.rolesUrl = '';
- this.roleId = '';
- this.formUrl = '';
- this.formsUrl = '';
- this.formId = '';
- this.submissionsUrl = '';
- this.submissionUrl = '';
- this.submissionId = '';
- this.actionsUrl = '';
- this.actionId = '';
- this.actionUrl = '';
- this.vsUrl = '';
- this.vId = '';
- this.vUrl = '';
- this.query = '';
-
- // Store the original path and options.
- this.path = path;
- this.options = options;
-
- if (options.useSessionToken) {
- Formio.useSessionToken(options);
- }
-
- if (options.hasOwnProperty('base')) {
- this.base = options.base;
- }
- else if (Formio.baseUrl) {
- this.base = Formio.baseUrl;
- }
- else if (typeof window !== 'undefined') {
- this.base = window.location.href.match(/http[s]?:\/\/api./)[0];
- }
-
- if (!path) {
- // Allow user to create new projects if this was instantiated without
- // a url
- this.projectUrl = Formio.projectUrl || `${this.base}/project`;
- this.projectsUrl = `${this.base}/project`;
- this.projectId = false;
- this.query = '';
- return;
- }
-
- if (options.hasOwnProperty('project')) {
- this.projectUrl = options.project;
- }
-
- const project = this.projectUrl || Formio.projectUrl;
- const projectRegEx = /(^|\/)(project)($|\/[^/]+)/;
- const isProjectUrl = (path.search(projectRegEx) !== -1);
-
- // The baseURL is the same as the projectUrl, and does not contain "/project/MONGO_ID" in
- // its domain. This is almost certainly against the Open Source server.
- if (project && this.base === project && !isProjectUrl) {
- this.noProject = true;
- this.projectUrl = this.base;
- }
-
- // Normalize to an absolute path.
- if ((path.indexOf('http') !== 0) && (path.indexOf('//') !== 0)) {
- path = this.base + path;
- }
-
- const hostparts = this.getUrlParts(path);
- let parts = [];
- const hostName = hostparts[1] + hostparts[2];
- path = hostparts.length > 3 ? hostparts[3] : '';
- const queryparts = path.split('?');
- if (queryparts.length > 1) {
- path = queryparts[0];
- this.query = `?${queryparts[1]}`;
- }
-
- // Register a specific path.
- const registerPath = (name, base) => {
- this[`${name}sUrl`] = `${base}/${name}`;
- const regex = new RegExp(`/${name}/([^/]+)`);
- if (path.search(regex) !== -1) {
- parts = path.match(regex);
- this[`${name}Url`] = parts ? (base + parts[0]) : '';
- this[`${name}Id`] = (parts.length > 1) ? parts[1] : '';
- base += parts[0];
- }
- return base;
- };
-
- // Register an array of items.
- const registerItems = (items, base, staticBase) => {
- for (const i in items) {
- if (items.hasOwnProperty(i)) {
- const item = items[i];
- if (Array.isArray(item)) {
- registerItems(item, base, true);
- }
- else {
- const newBase = registerPath(item, base);
- base = staticBase ? base : newBase;
- }
- }
- }
- };
-
- if (!this.projectUrl || (this.projectUrl === this.base)) {
- // If a project uses Subdirectories path type, we need to specify a projectUrl
- if (!this.projectUrl && !isProjectUrl && Formio.pathType === 'Subdirectories') {
- const regex = `^${hostName.replace(/\//g, '\\/')}.[^/]+`;
- const match = project.match(new RegExp(regex));
- this.projectUrl = match ? match[0] : hostName;
- }
- else {
- this.projectUrl = hostName;
- }
- }
- // Check if we have a specified path type.
- let isNotSubdomainType = false;
-
- if (Formio.pathType) {
- isNotSubdomainType = Formio.pathType !== 'Subdomains';
- }
-
- if (!this.noProject) {
- // Determine the projectUrl and projectId
- if (isProjectUrl) {
- // Get project id as project/:projectId.
- registerItems(['project'], hostName);
- path = path.replace(projectRegEx, '');
- }
- else if (hostName === this.base) {
- // Get project id as first part of path (subdirectory).
- if (hostparts.length > 3 && path.split('/').length > 1) {
- const isFile = path.match(/.json/);
- const pathParts = path.split('/');
-
- if (isFile) {
- this.projectUrl = hostName;
- }
- else {
- pathParts.shift(); // Throw away the first /.
- this.projectId = pathParts.shift();
- path = `/${pathParts.join('/')}`;
- this.projectUrl = `${hostName}/${this.projectId}`;
- }
- }
- }
- else {
- // Get project id from subdomain.
- if (hostparts.length > 2 && (hostparts[2].split('.').length > 2 || hostName.includes('localhost')) && !isNotSubdomainType) {
- this.projectUrl = hostName;
- this.projectId = hostparts[2].split('.')[0];
- }
- }
- this.projectsUrl = this.projectsUrl || `${this.base}/project`;
- }
-
- // Configure Role urls and role ids.
- registerItems(['role'], this.projectUrl);
-
- // Configure Form urls and form ids.
- if (/(^|\/)(form)($|\/)/.test(path)) {
- registerItems(['form', ['submission', 'action', 'v']], this.projectUrl);
- }
- else {
- const subRegEx = new RegExp('/(submission|action|v)($|/.*)');
- const subs = path.match(subRegEx);
- this.pathType = (subs && (subs.length > 1)) ? subs[1] : '';
- path = path.replace(subRegEx, '');
- path = path.replace(/\/$/, '');
- this.formsUrl = `${this.projectUrl}/form`;
- this.formUrl = path ? this.projectUrl + path : '';
- this.formId = path.replace(/^\/+|\/+$/g, '');
- const items = ['submission', 'action', 'v'];
- for (const i in items) {
- if (items.hasOwnProperty(i)) {
- const item = items[i];
- this[`${item}sUrl`] = `${this.projectUrl + path}/${item}`;
- if ((this.pathType === item) && (subs.length > 2) && subs[2]) {
- this[`${item}Id`] = subs[2].replace(/^\/+|\/+$/g, '');
- this[`${item}Url`] = this.projectUrl + path + subs[0];
- }
- }
- }
- }
-
- // Set the app url if it is not set.
- if (!Formio.projectUrlSet) {
- Formio.projectUrl = this.projectUrl;
- }
- }
- /* eslint-enable max-statements */
-
- delete(type, opts) {
- const _id = `${type}Id`;
- const _url = `${type}Url`;
- if (!this[_id]) {
- return NativePromise.reject('Nothing to delete');
- }
- Formio.cache = {};
- return this.makeRequest(type, this[_url], 'delete', null, opts);
- }
-
- static useSessionToken(options) {
- const tokenName = `${options.namespace || Formio.namespace || 'formio'}Token`;
- const token = localStorage.getItem(tokenName);
-
- if (token) {
- localStorage.removeItem(tokenName);
- sessionStorage.setItem(tokenName, token);
- }
-
- const userName = `${options.namespace || Formio.namespace || 'formio'}User`;
- const user = localStorage.getItem(userName);
-
- if (user) {
- localStorage.removeItem(userName);
- sessionStorage.setItem(userName, user);
- }
-
- localStorage.setItem('useSessionToken', true);
- }
-
- index(type, query, opts) {
- const _url = `${type}Url`;
- query = query || '';
- if (query && isObject(query)) {
- query = `?${Formio.serialize(query.params)}`;
- }
- return this.makeRequest(type, this[_url] + query, 'get', null, opts);
- }
-
- save(type, data, opts) {
- const _id = `${type}Id`;
- const _url = `${type}Url`;
- const method = (this[_id] || data._id) ? 'put' : 'post';
- let reqUrl = this[_id] ? this[_url] : this[`${type}sUrl`];
- if (!this[_id] && data._id && (method === 'put') && !reqUrl.includes(data._id)) {
- reqUrl += `/${data._id}`;
- }
- Formio.cache = {};
- return this.makeRequest(type, reqUrl + this.query, method, data, opts);
- }
-
- load(type, query, opts) {
- const _id = `${type}Id`;
- const _url = `${type}Url`;
- if (query && isObject(query)) {
- query = Formio.serialize(query.params);
- }
- if (query) {
- query = this.query ? (`${this.query}&${query}`) : (`?${query}`);
- }
- else {
- query = this.query;
- }
- if (!this[_id]) {
- return NativePromise.reject(`Missing ${_id}`);
- }
-
- let url = this[_url] + query;
-
- if (type==='form' && !isNaN(parseInt(this.vId)) && parseInt(this.vId) !== 0) {
- url += url.match(/\?/) ? '&' : '?';
- url += `formRevision=${this.vId}`;
- }
- return this.makeRequest(type, url, 'get', null, opts);
- }
-
- makeRequest(...args) {
- return Formio.makeRequest(this, ...args);
- }
-
- loadProject(query, opts) {
- return this.load('project', query, opts);
- }
-
- saveProject(data, opts) {
- return this.save('project', data, opts);
- }
-
- deleteProject(opts) {
- return this.delete('project', opts);
- }
-
- static loadProjects(query, opts) {
- query = query || '';
- if (isObject(query)) {
- query = `?${Formio.serialize(query.params)}`;
- }
- return Formio.makeStaticRequest(`${Formio.baseUrl}/project${query}`, 'GET', null, opts);
- }
-
- loadRole(opts) {
- return this.load('role', null, opts);
- }
-
- saveRole(data, opts) {
- return this.save('role', data, opts);
- }
-
- deleteRole(opts) {
- return this.delete('role', opts);
- }
-
- loadRoles(opts) {
- return this.index('roles', null, opts);
- }
-
- loadForm(query, opts) {
- return this.load('form', query, opts)
- .then((currentForm) => {
- // Check to see if there isn't a number in vId.
- if (!currentForm.revisions || isNaN(parseInt(this.vId))) {
- return currentForm;
- }
- // If a submission already exists but form is marked to load current version of form.
- if (currentForm.revisions === 'current' && this.submissionId) {
- return currentForm;
- }
- // eslint-disable-next-line eqeqeq
- if (currentForm._vid == this.vId || currentForm.revisionId === this.vId) {
- return currentForm;
- }
- // If they specified a revision form, load the revised form components.
- if (query && isObject(query)) {
- query = Formio.serialize(query.params);
- }
- if (query) {
- query = this.query ? (`${this.query}&${query}`) : (`?${query}`);
- }
- else {
- query = this.query;
- }
- return this.makeRequest('form', this.vUrl + query, 'get', null, opts)
- .then((revisionForm) => {
- currentForm._vid = revisionForm._vid;
- currentForm.components = revisionForm.components;
- currentForm.settings = revisionForm.settings;
- currentForm.revisionId = revisionForm.revisionId;
- // Using object.assign so we don't cross polinate multiple form loads.
- return Object.assign({}, currentForm);
- })
- // If we couldn't load the revision, just return the original form.
- .catch(() => Object.assign({}, currentForm));
- });
- }
-
- saveForm(data, opts) {
- return this.save('form', data, opts);
- }
-
- deleteForm(opts) {
- return this.delete('form', opts);
- }
-
- loadForms(query, opts) {
- return this.index('forms', query, opts);
- }
-
- loadSubmission(query, opts) {
- return this.load('submission', query, opts)
- .then((submission) => {
- this.vId = submission._frid || submission._fvid;
- this.vUrl = `${this.formUrl}/v/${this.vId}`;
- return submission;
- });
- }
-
- saveSubmission(data, opts) {
- if (!isNaN(parseInt(this.vId))) {
- data._fvid = this.vId;
- }
- return this.save('submission', data, opts);
- }
-
- deleteSubmission(opts) {
- return this.delete('submission', opts);
- }
-
- loadSubmissions(query, opts) {
- return this.index('submissions', query, opts);
- }
-
- loadAction(query, opts) {
- return this.load('action', query, opts);
- }
-
- saveAction(data, opts) {
- return this.save('action', data, opts);
- }
-
- deleteAction(opts) {
- return this.delete('action', opts);
- }
-
- loadActions(query, opts) {
- return this.index('actions', query, opts);
- }
-
- availableActions() {
- return this.makeRequest('availableActions', `${this.formUrl}/actions`);
- }
-
- actionInfo(name) {
- return this.makeRequest('actionInfo', `${this.formUrl}/actions/${name}`);
- }
-
- isObjectId(id) {
- const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
- return checkForHexRegExp.test(id);
- }
-
- getProjectId() {
- if (!this.projectId) {
- return NativePromise.resolve('');
- }
- if (this.isObjectId(this.projectId)) {
- return NativePromise.resolve(this.projectId);
- }
- else {
- return this.loadProject().then((project) => {
- return project._id;
- });
- }
- }
-
- getFormId() {
- if (!this.formId) {
- return NativePromise.resolve('');
- }
- if (this.isObjectId(this.formId)) {
- return NativePromise.resolve(this.formId);
- }
- else {
- return this.loadForm().then((form) => {
- return form._id;
- });
- }
- }
-
- currentUser(options) {
- return Formio.currentUser(this, options);
- }
-
- accessInfo() {
- return Formio.accessInfo(this);
- }
-
- /**
- * Sets OAuth Logout URL.
- *
- * @return {*}
- */
- oauthLogoutURI(uri, options) {
- return Formio.oauthLogoutURI(uri, Object.assign({ formio: this }, this.options, options));
- }
-
- /**
- * Returns the JWT token for this instance.
- *
- * @return {*}
- */
- getToken(options) {
- return Formio.getToken(Object.assign({ formio: this }, this.options, options));
- }
-
- /**
- * Sets the JWT token for this instance.
- *
- * @return {*}
- */
- setToken(token, options) {
- return Formio.setToken(token, Object.assign({ formio: this }, this.options, options));
- }
-
- /**
- * Returns a temporary authentication token for single purpose token generation.
- */
- getTempToken(expire, allowed, options) {
- const token = Formio.getToken(options);
- if (!token) {
- return NativePromise.reject('You must be authenticated to generate a temporary auth token.');
- }
- const authUrl = Formio.authUrl || this.projectUrl;
- return this.makeRequest('tempToken', `${authUrl}/token`, 'GET', null, {
- ignoreCache: true,
- header: new Headers({
- 'x-expire': expire,
- 'x-allow': allowed
- })
- });
- }
-
- /**
- * Get a download url for a submission PDF of this submission.
- *
- * @return {*}
- */
- getDownloadUrl(form) {
- if (!this.submissionId) {
- return NativePromise.resolve('');
- }
-
- if (!form) {
- // Make sure to load the form first.
- return this.loadForm().then((_form) => {
- if (!_form) {
- return '';
- }
- return this.getDownloadUrl(_form);
- });
- }
-
- let apiUrl = `/project/${form.project}`;
- apiUrl += `/form/${form._id}`;
- apiUrl += `/submission/${this.submissionId}`;
- const postfix = form.submissionRevisions && form.settings.changeLog? '/download/changelog' : '/download';
- apiUrl += postfix;
-
- let download = this.base + apiUrl;
- return new NativePromise((resolve, reject) => {
- this.getTempToken(3600, `GET:${apiUrl}`).then((tempToken) => {
- download += `?token=${tempToken.key}`;
- resolve(download);
- }, () => {
- resolve(download);
- }).catch(reject);
- });
- }
-
- uploadFile(storage, file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, uploadStartCallback, abortCallback, multipartOptions) {
- const requestArgs = {
- provider: storage,
- method: 'upload',
- file: file,
- fileName: fileName,
- dir: dir
- };
- fileKey = fileKey || 'file';
- const request = Formio.pluginWait('preRequest', requestArgs)
- .then(() => {
- return Formio.pluginGet('fileRequest', requestArgs)
- .then((result) => {
- if (storage && isNil(result)) {
- const Provider = Providers.getProvider('storage', storage);
- if (Provider) {
- const provider = new Provider(this);
- if (uploadStartCallback) {
- uploadStartCallback();
- }
- return provider.uploadFile(file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback, multipartOptions);
- }
- else {
- throw ('Storage provider not found');
- }
- }
- return result || { url: '' };
- });
- });
-
- return Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);
- }
-
- downloadFile(file, options) {
- const requestArgs = {
- method: 'download',
- file: file
- };
-
- const request = Formio.pluginWait('preRequest', requestArgs)
- .then(() => {
- return Formio.pluginGet('fileRequest', requestArgs)
- .then((result) => {
- if (file.storage && isNil(result)) {
- const Provider = Providers.getProvider('storage', file.storage);
- if (Provider) {
- const provider = new Provider(this);
- return provider.downloadFile(file, options);
- }
- else {
- throw ('Storage provider not found');
- }
- }
- return result || { url: '' };
- });
- });
-
- return Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);
- }
-
- deleteFile(file, options) {
- const requestArgs = {
- method: 'delete',
- file: file
- };
-
- const request = Formio.pluginWait('preRequest', requestArgs)
- .then(() => {
- return Formio.pluginGet('fileRequest', requestArgs)
- .then((result) => {
- if (file.storage && isNil(result)) {
- const Provider = Providers.getProvider('storage', file.storage);
- if (Provider) {
- const provider = new Provider(this);
- return provider.deleteFile(file, options);
- }
- else {
- throw ('Storage provider not found');
- }
- }
- return result || { url: '' };
- });
- });
-
- return Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);
- }
-
- /**
- * Returns the user permissions to a form and submission.
- *
- * @param user - The user or current user if undefined. For anonymous, use "null"
- * @param form - The form or current form if undefined. For no form check, use "null"
- * @param submission - The submisison or "index" if undefined.
- *
- * @return {create: boolean, read: boolean, edit: boolean, delete: boolean}
- */
- userPermissions(user, form, submission) {
- return NativePromise.all([
- (form !== undefined) ? NativePromise.resolve(form) : this.loadForm(),
- (user !== undefined) ? NativePromise.resolve(user) : this.currentUser(),
- (submission !== undefined || !this.submissionId) ? NativePromise.resolve(submission) : this.loadSubmission(),
- this.accessInfo()
- ]).then((results) => {
- const form = results.shift();
- const user = results.shift() || { _id: false, roles: [] };
- const submission = results.shift();
- const access = results.shift();
- const permMap = {
- create: 'create',
- read: 'read',
- update: 'edit',
- delete: 'delete'
- };
- const perms = {
- user: user,
- form: form,
- access: access,
- create: false,
- read: false,
- edit: false,
- delete: false
- };
- for (const roleName in access.roles) {
- if (access.roles.hasOwnProperty(roleName)) {
- const role = access.roles[roleName];
- if (role.default && (user._id === false)) {
- // User is anonymous. Add the anonymous role.
- user.roles.push(role._id);
- }
- else if (role.admin && user.roles.indexOf(role._id) !== -1) {
- perms.create = true;
- perms.read = true;
- perms.delete = true;
- perms.edit = true;
- return perms;
- }
- }
- }
- if (form && form.submissionAccess) {
- for (let i = 0; i < form.submissionAccess.length; i++) {
- const permission = form.submissionAccess[i];
- const [perm, scope] = permission.type.split('_');
- if (['create', 'read', 'update', 'delete'].includes(perm)) {
- if (_intersection(permission.roles, user.roles).length) {
- perms[permMap[perm]] = (scope === 'all') || (!submission || (user._id === submission.owner));
- }
- }
- }
- }
- // check for Group Permissions
- if (submission) {
- // we would anyway need to loop through components for create permission, so we'll do that for all of them
- eachComponent(form.components, (component, path) => {
- if (component && component.defaultPermission) {
- const value = _get(submission.data, path);
- // make it work for single-select Group and multi-select Group
- const groups = Array.isArray(value) ? value : [value];
- groups.forEach(group => {
- if (
- group && group._id && // group id is present
- user.roles.indexOf(group._id) > -1 // user has group id in his roles
- ) {
- if (component.defaultPermission === 'read') {
- perms[permMap.read] = true;
- }
- if (component.defaultPermission === 'create') {
- perms[permMap.create] = true;
- perms[permMap.read] = true;
- }
- if (component.defaultPermission === 'write') {
- perms[permMap.create] = true;
- perms[permMap.read] = true;
- perms[permMap.update] = true;
- }
- if (component.defaultPermission === 'admin') {
- perms[permMap.create] = true;
- perms[permMap.read] = true;
- perms[permMap.update] = true;
- perms[permMap.delete] = true;
- }
- }
- });
- }
- });
- }
- return perms;
- });
- }
-
- /**
- * Determine if the current user can submit a form.
- * @return {*}
- */
- canSubmit() {
- return this.userPermissions().then((perms) => {
- // If there is user and they cannot create, then check anonymous user permissions.
- if (!perms.create && Formio.getUser()) {
- return this.userPermissions(null).then((anonPerms) => {
- if (anonPerms.create) {
- Formio.setUser(null);
- return true;
- }
-
- return false;
- });
- }
-
- return perms.create;
- });
- }
-
- getUrlParts(url) {
- return Formio.getUrlParts(url, this);
- }
-
- static getUrlParts(url, formio) {
- const base = (formio && formio.base) ? formio.base : Formio.baseUrl;
- let regex = '^(http[s]?:\\/\\/)';
- if (base && url.indexOf(base) === 0) {
- regex += `(${base.replace(/^http[s]?:\/\//, '')})`;
- }
- else {
- regex += '([^/]+)';
- }
- regex += '($|\\/.*)';
- return url.match(new RegExp(regex));
- }
-
- static serialize(obj, _interpolate) {
- const str = [];
- const interpolate = (item) => {
- return _interpolate ? _interpolate(item) : item;
- };
- for (const p in obj) {
- if (obj.hasOwnProperty(p)) {
- str.push(`${encodeURIComponent(p)}=${encodeURIComponent(interpolate(obj[p]))}`);
- }
- }
- return str.join('&');
- }
-
- static getRequestArgs(formio, type, url, method, data, opts) {
- method = (method || 'GET').toUpperCase();
- if (!opts || !isObject(opts)) {
- opts = {};
- }
-
- const requestArgs = {
- url,
- method,
- data: data || null,
- opts
- };
-
- if (type) {
- requestArgs.type = type;
- }
-
- if (formio) {
- requestArgs.formio = formio;
- }
- return requestArgs;
- }
-
- static makeStaticRequest(url, method, data, opts) {
- const requestArgs = Formio.getRequestArgs(null, '', url, method, data, opts);
- const request = Formio.pluginWait('preRequest', requestArgs)
- .then(() => Formio.pluginGet('staticRequest', requestArgs)
- .then((result) => {
- if (isNil(result)) {
- return Formio.request(requestArgs.url, requestArgs.method, requestArgs.data, requestArgs.opts.header, requestArgs.opts);
- }
- return result;
- }));
-
- return Formio.pluginAlter('wrapStaticRequestPromise', request, requestArgs);
- }
-
- static makeRequest(formio, type, url, method, data, opts) {
- if (!formio) {
- return Formio.makeStaticRequest(url, method, data, opts);
- }
-
- const requestArgs = Formio.getRequestArgs(formio, type, url, method, data, opts);
- requestArgs.opts = requestArgs.opts || {};
- requestArgs.opts.formio = formio;
-
- //for Formio requests default Accept and Content-type headers
- if (!requestArgs.opts.headers) {
- requestArgs.opts.headers = {};
- }
- requestArgs.opts.headers = _defaults(requestArgs.opts.headers, {
- 'Accept': 'application/json',
- 'Content-type': 'application/json'
- });
- const request = Formio.pluginWait('preRequest', requestArgs)
- .then(() => Formio.pluginGet('request', requestArgs)
- .then((result) => {
- if (isNil(result)) {
- return Formio.request(requestArgs.url, requestArgs.method, requestArgs.data, requestArgs.opts.header, requestArgs.opts);
- }
- return result;
- }));
-
- return Formio.pluginAlter('wrapRequestPromise', request, requestArgs);
- }
-
- static request(url, method, data, header, opts) {
- if (!url) {
- return NativePromise.reject('No url provided');
- }
- const _Formio = Formio;
- method = (method || 'GET').toUpperCase();
-
- // For reverse compatibility, if they provided the ignoreCache parameter,
- // then change it back to the options format where that is a parameter.
- if (isBoolean(opts)) {
- opts = { ignoreCache: opts };
- }
- if (!opts || !isObject(opts)) {
- opts = {};
- }
-
- // Generate a cachekey.
- const cacheKey = btoa(encodeURI(url));
-
- // Get the cached promise to save multiple loads.
- if (!opts.ignoreCache && method === 'GET' && _Formio.cache.hasOwnProperty(cacheKey)) {
- return NativePromise.resolve(cloneResponse(_Formio.cache[cacheKey]));
- }
-
- // Set up and fetch request
- const headers = header || new Headers(opts.headers || {
- 'Accept': 'application/json',
- 'Content-type': 'application/json'
- });
- const token = _Formio.getToken(opts);
- if (token && !opts.noToken) {
- headers.append('x-jwt-token', token);
- }
-
- // The fetch-ponyfill can't handle a proper Headers class anymore. Change it back to an object.
- const headerObj = {};
- headers.forEach(function(value, name) {
- headerObj[name] = value;
- });
-
- let options = {
- method: method,
- headers: headerObj,
- mode: 'cors'
- };
- if (data) {
- options.body = JSON.stringify(data);
- }
-
- // Allow plugins to alter the options.
- options = _Formio.pluginAlter('requestOptions', options, url);
- if (options.namespace || _Formio.namespace) {
- opts.namespace = options.namespace || _Formio.namespace;
- }
-
- const requestToken = options.headers['x-jwt-token'];
- const result = _Formio.pluginAlter('wrapFetchRequestPromise', _Formio.fetch(url, options),
- { url, method, data, opts }).then((response) => {
- // Allow plugins to respond.
- response = _Formio.pluginAlter('requestResponse', response, _Formio, data);
-
- if (!response.ok) {
- if (response.status === 440) {
- _Formio.setToken(null, opts);
- _Formio.events.emit('formio.sessionExpired', response.body);
- }
- else if (response.status === 401) {
- _Formio.events.emit('formio.unauthorized', response.body);
- }
- else if (response.status === 416) {
- _Formio.events.emit('formio.rangeIsNotSatisfiable', response.body);
- }
- else if (response.status === 504) {
- return NativePromise.reject(new Error('Network request failed'));
- }
-
- // Parse and return the error as a rejected promise to reject this promise
- return (response.headers.get('content-type').includes('application/json')
- ? response.json()
- : response.text())
- .then((error) => {
- return NativePromise.reject(error);
- });
- }
-
- // Handle fetch results
- const token = response.headers.get('x-jwt-token');
-
- // In some strange cases, the fetch library will return an x-jwt-token without sending
- // one to the server. This has even been debugged on the server to verify that no token
- // was introduced with the request, but the response contains a token. This is an Invalid
- // case where we do not send an x-jwt-token and get one in return for any GET request.
- let tokenIntroduced = false;
- if (
- (method === 'GET') &&
- !requestToken &&
- token &&
- !opts.external &&
- !url.includes('token=') &&
- !url.includes('x-jwt-token=')
- ) {
- console.warn('Token was introduced in request.');
- tokenIntroduced = true;
- }
-
- if (
- response.status >= 200 &&
- response.status < 300 &&
- token &&
- token !== '' &&
- !tokenIntroduced
- ) {
- _Formio.setToken(token, opts);
- }
- // 204 is no content. Don't try to .json() it.
- if (response.status === 204) {
- return {};
- }
-
- const getResult = response.headers.get('content-type').includes('application/json')
- ? response.json()
- : response.text();
- return getResult.then((result) => {
- // Add some content-range metadata to the result here
- let range = response.headers.get('content-range');
- if (range && isObject(result)) {
- range = range.split('/');
- if (range[0] !== '*') {
- const skipLimit = range[0].split('-');
- result.skip = Number(skipLimit[0]);
- result.limit = skipLimit[1] - skipLimit[0] + 1;
- }
- result.serverCount = range[1] === '*' ? range[1] : Number(range[1]);
- }
-
- if (!opts.getHeaders) {
- return result;
- }
-
- const headers = {};
- response.headers.forEach((item, key) => {
- headers[key] = item;
- });
-
- // Return the result with the headers.
- return {
- result,
- headers,
- };
- });
- })
- .then((result) => {
- if (opts.getHeaders) {
- return result;
- }
-
- // Cache the response.
- if (method === 'GET') {
- _Formio.cache[cacheKey] = result;
- }
-
- return cloneResponse(result);
- })
- .catch((err) => {
- if (err === 'Bad Token') {
- _Formio.setToken(null, opts);
- _Formio.events.emit('formio.badToken', err);
- }
- if (err.message) {
- err = new Error(`Could not connect to API server (${err.message}): ${url}`);
- err.networkError = true;
- }
-
- if (method === 'GET') {
- delete _Formio.cache[cacheKey];
- }
-
- return NativePromise.reject(err);
- });
-
- return result;
- }
-
- // Needed to maintain reverse compatability...
- static get token() {
- if (!Formio.tokens) {
- Formio.tokens = {};
- }
-
- return Formio.tokens.formioToken || '';
- }
-
- // Needed to maintain reverse compatability...
- static set token(token) {
- if (!Formio.tokens) {
- Formio.tokens = {};
- }
-
- Formio.tokens.formioToken = token || '';
- }
-
- static setToken(token = '', opts) {
- token = token || '';
- opts = (typeof opts === 'string') ? { namespace: opts } : opts || {};
- const tokenName = `${opts.namespace || Formio.namespace || 'formio'}Token`;
-
- if (!Formio.tokens) {
- Formio.tokens = {};
- }
-
- const storage = localStorage.getItem('useSessionToken') ? sessionStorage : localStorage;
-
- if (!token) {
- if (!opts.fromUser) {
- opts.fromToken = true;
- Formio.setUser(null, opts);
- }
- // iOS in private browse mode will throw an error but we can't detect ahead of time that we are in private mode.
- try {
- storage.removeItem(tokenName);
- }
- catch (err) {
- cookies.erase(tokenName, { path: '/' });
- }
- Formio.tokens[tokenName] = token;
- return NativePromise.resolve(null);
- }
-
- if (Formio.tokens[tokenName] !== token) {
- Formio.tokens[tokenName] = token;
- // iOS in private browse mode will throw an error but we can't detect ahead of time that we are in private mode.
- try {
- storage.setItem(tokenName, token);
- }
- catch (err) {
- cookies.set(tokenName, token, { path: '/' });
- }
- }
- // Return or updates the current user
- return this.currentUserResolved
- ? Formio.currentUser(opts.formio, opts)
- : NativePromise.resolve(null);
- }
-
- static getToken(options) {
- options = (typeof options === 'string') ? { namespace: options } : options || {};
- const tokenName = `${options.namespace || Formio.namespace || 'formio'}Token`;
- const decodedTokenName = options.decode ? `${tokenName}Decoded` : tokenName;
- if (!Formio.tokens) {
- Formio.tokens = {};
- }
-
- if (Formio.tokens[decodedTokenName]) {
- return Formio.tokens[decodedTokenName];
- }
- try {
- const token = localStorage.getItem('useSessionToken')
- ? sessionStorage.getItem(tokenName)
- : localStorage.getItem(tokenName);
- Formio.tokens[tokenName] = token || '';
- if (options.decode) {
- Formio.tokens[decodedTokenName] = Formio.tokens[tokenName] ? jwtDecode(Formio.tokens[tokenName]) : {};
- return Formio.tokens[decodedTokenName];
- }
- return Formio.tokens[tokenName];
- }
- catch (e) {
- Formio.tokens[tokenName] = cookies.get(tokenName);
- return Formio.tokens[tokenName];
- }
- }
-
- static oauthLogoutURI(uri, options) {
- options = (typeof options === 'string') ? { namespace: options } : options || {};
- const logoutURIName = `${options.namespace || Formio.namespace || 'formio'}LogoutAuthUrl`;
- Formio.tokens[logoutURIName];
- localStorage.setItem(logoutURIName, uri);
- return Formio.tokens[logoutURIName];
- }
-
- static setUser(user, opts = {}) {
- const userName = `${opts.namespace || Formio.namespace || 'formio'}User`;
- const storage = localStorage.getItem('useSessionToken') ? sessionStorage : localStorage;
-
- if (!user) {
- if (!opts.fromToken) {
- opts.fromUser = true;
- Formio.setToken(null, opts);
- }
-
- // Emit an event on the cleared user.
- Formio.events.emit('formio.user', null);
-
- // iOS in private browse mode will throw an error but we can't detect ahead of time that we are in private mode.
- try {
- return storage.removeItem(userName);
- }
- catch (err) {
- return cookies.erase(userName, { path: '/' });
- }
- }
- // iOS in private browse mode will throw an error but we can't detect ahead of time that we are in private mode.
- try {
- storage.setItem(userName, JSON.stringify(user));
- }
- catch (err) {
- cookies.set(userName, JSON.stringify(user), { path: '/' });
- }
-
- // Emit an event on the authenticated user.
- Formio.events.emit('formio.user', user);
- }
-
- static getUser(options) {
- options = options || {};
- var userName = `${options.namespace || Formio.namespace || 'formio'}User`;
- try {
- return JSON.parse(
- (localStorage.getItem('useSessionToken')
- ? sessionStorage
- : localStorage
- ).getItem(userName) || null
- );
- }
- catch (e) {
- return JSON.parse(cookies.get(userName));
- }
- }
-
- static setBaseUrl(url) {
- Formio.baseUrl = url;
- if (!Formio.projectUrlSet) {
- Formio.projectUrl = url;
- }
- }
-
- static getBaseUrl() {
- return Formio.baseUrl;
- }
-
- static setApiUrl(url) {
- return Formio.setBaseUrl(url);
- }
-
- static getApiUrl() {
- return Formio.getBaseUrl();
- }
-
- static setAppUrl(url) {
- console.warn('Formio.setAppUrl() is deprecated. Use Formio.setProjectUrl instead.');
- Formio.projectUrl = url;
- Formio.projectUrlSet = true;
- }
-
- static setProjectUrl(url) {
- Formio.projectUrl = url;
- Formio.projectUrlSet = true;
- }
-
- static setAuthUrl(url) {
- Formio.authUrl = url;
- }
-
- static getAppUrl() {
- console.warn('Formio.getAppUrl() is deprecated. Use Formio.getProjectUrl instead.');
- return Formio.projectUrl;
- }
-
- static getProjectUrl() {
- return Formio.projectUrl;
- }
-
- static clearCache() {
- Formio.cache = {};
- }
-
- static noop() {}
- static identity(value) {
- return value;
- }
-
- static deregisterPlugin(plugin) {
- const beforeLength = Formio.plugins.length;
- Formio.plugins = Formio.plugins.filter((p) => {
- if (p !== plugin && p.__name !== plugin) {
- return true;
- }
-
- (p.deregister || Formio.noop).call(plugin, Formio);
- return false;
- });
- return beforeLength !== Formio.plugins.length;
- }
-
- static registerPlugin(plugin, name) {
- const __Formio = Formio;
- __Formio.plugins.push(plugin);
- __Formio.plugins.sort((a, b) => (b.priority || 0) - (a.priority || 0));
- plugin.__name = name;
- (plugin.init || __Formio.noop).call(plugin, __Formio);
- }
-
- static getPlugin(name) {
- for (const plugin of Formio.plugins) {
- if (plugin.__name === name) {
- return plugin;
- }
- }
-
- return null;
- }
-
- static pluginWait(pluginFn, ...args) {
- return NativePromise.all(Formio.plugins.map((plugin) =>
- (plugin[pluginFn] || Formio.noop).call(plugin, ...args)));
- }
-
- static pluginGet(pluginFn, ...args) {
- const callPlugin = (index) => {
- const plugin = Formio.plugins[index];
-
- if (!plugin) {
- return NativePromise.resolve(null);
- }
-
- return NativePromise.resolve((plugin[pluginFn] || Formio.noop).call(plugin, ...args))
- .then((result) => {
- if (!isNil(result)) {
- return result;
- }
-
- return callPlugin(index + 1);
- });
- };
- return callPlugin(0);
- }
-
- static pluginAlter(pluginFn, value, ...args) {
- return Formio.plugins.reduce((value, plugin) =>
- (plugin[pluginFn] || Formio.identity)(value, ...args), value);
- }
-
- static accessInfo(formio) {
- const projectUrl = formio ? formio.projectUrl : Formio.projectUrl;
- return Formio.makeRequest(formio, 'accessInfo', `${projectUrl}/access`);
- }
-
- static projectRoles(formio) {
- const projectUrl = formio ? formio.projectUrl : Formio.projectUrl;
- return Formio.makeRequest(formio, 'projectRoles', `${projectUrl}/role`);
- }
-
- static currentUser(formio, options) {
- let authUrl = Formio.authUrl;
- if (!authUrl) {
- authUrl = formio ? formio.projectUrl : (Formio.projectUrl || Formio.baseUrl);
- }
- authUrl += '/current';
- const user = Formio.getUser(options);
- if (user) {
- return Formio.pluginAlter('wrapStaticRequestPromise', NativePromise.resolve(user), {
- url: authUrl,
- method: 'GET',
- options
- });
- }
-
- const token = Formio.getToken(options);
- if ((!options || !options.external) && !token) {
- return Formio.pluginAlter('wrapStaticRequestPromise', NativePromise.resolve(null), {
- url: authUrl,
- method: 'GET',
- options
- });
- }
- this.currentUserResolved = false;
- return Formio.makeRequest(formio, 'currentUser', authUrl, 'GET', null, options)
- .then((response) => {
- this.currentUserResolved = true;
- Formio.setUser(response, options);
- return response;
- });
- }
-
- static logout(formio, options) {
- options = options || {};
- options.formio = formio;
- const projectUrl = Formio.authUrl ? Formio.authUrl : (formio ? formio.projectUrl : Formio.baseUrl);
- const logout = () => {
- Formio.setToken(null, options);
- Formio.setUser(null, options);
- Formio.clearCache();
- localStorage.removeItem('useSessionToken');
- };
- return Formio.makeRequest(formio, 'logout', `${projectUrl}/logout`)
- .then(function(result) {
- logout();
- return result;
- })
- .catch(function(err) {
- logout();
- throw err;
- });
- }
-
- static pageQuery() {
- const pageQuery = {};
- pageQuery.paths = [];
- const hashes = location.hash.substr(1).replace(/\?/g, '&').split('&');
- let parts = [];
- location.search.substr(1).split('&').forEach(function(item) {
- parts = item.split('=');
- if (parts.length > 1) {
- pageQuery[parts[0]] = parts[1] && decodeURIComponent(parts[1]);
- }
- });
-
- hashes.forEach(function(item) {
- parts = item.split('=');
- if (parts.length > 1) {
- pageQuery[parts[0]] = parts[1] && decodeURIComponent(parts[1]);
- }
- else if (item.indexOf('/') === 0) {
- pageQuery.paths = item.substr(1).split('/');
- }
- });
- return pageQuery;
- }
-
- static oAuthCurrentUser(formio, token) {
- return Formio.currentUser(formio, {
- external: true,
- headers: {
- Authorization: `Bearer ${token}`
- }
- });
- }
-
- static samlInit(options) {
- options = options || {};
- const query = Formio.pageQuery();
- if (query.saml) {
- Formio.setUser(null);
- const retVal = Formio.setToken(query.saml);
- let uri = window.location.toString();
- uri = uri.substring(0, uri.indexOf('?'));
- if (window.location.hash) {
- uri += window.location.hash;
- }
- window.history.replaceState({}, document.title, uri);
- return retVal;
- }
-
- // Set the relay if not provided.
- if (!options.relay) {
- options.relay = window.location.href;
- }
-
- // go to the saml sso endpoint for this project.
- const authUrl = Formio.authUrl || Formio.projectUrl;
- window.location.href = `${authUrl}/saml/sso?relay=${encodeURI(options.relay)}`;
- return false;
- }
-
- static oktaInit(options) {
- options = options || {};
- if (typeof OktaAuth !== undefined) {
- options.OktaAuth = OktaAuth;
- }
-
- if (typeof options.OktaAuth === undefined) {
- const errorMessage = 'Cannot find OktaAuth. Please include the Okta JavaScript SDK within your application. See https://developer.okta.com/code/javascript/okta_auth_sdk for an example.';
- console.warn(errorMessage);
- return NativePromise.reject(errorMessage);
- }
- return new NativePromise((resolve, reject) => {
- const Okta = options.OktaAuth;
- delete options.OktaAuth;
- var authClient = new Okta(options);
- authClient.tokenManager.get('accessToken')
- .then(accessToken => {
- if (accessToken) {
- resolve(Formio.oAuthCurrentUser(options.formio, accessToken.accessToken));
- }
- else if (location.hash) {
- authClient.token.parseFromUrl()
- .then(token => {
- authClient.tokenManager.add('accessToken', token);
- resolve(Formio.oAuthCurrentUser(options.formio, token.accessToken));
- })
- .catch(err => {
- console.warn(err);
- reject(err);
- });
- }
- else {
- authClient.token.getWithRedirect({
- responseType: 'token',
- scopes: options.scopes
- });
- resolve(false);
- }
- })
- .catch(error => {
- reject(error);
- });
- });
- }
-
- static ssoInit(type, options) {
- switch (type) {
- case 'saml':
- return Formio.samlInit(options);
- case 'okta':
- return Formio.oktaInit(options);
- default:
- console.warn('Unknown SSO type');
- return NativePromise.reject('Unknown SSO type');
- }
- }
-
- static requireLibrary(name, property, src, polling, onload) {
- if (!Formio.libraries.hasOwnProperty(name)) {
- Formio.libraries[name] = {};
- Formio.libraries[name].ready = new NativePromise((resolve, reject) => {
- Formio.libraries[name].resolve = resolve;
- Formio.libraries[name].reject = reject;
- });
-
- const callbackName = `${name}Callback`;
-
- if (!polling && !window[callbackName]) {
- window[callbackName] = () => Formio.libraries[name].resolve();
- }
-
- // See if the plugin already exists.
- const plugin = _get(window, property);
- if (plugin) {
- Formio.libraries[name].resolve(plugin);
- }
- else {
- src = Array.isArray(src) ? src : [src];
- src.forEach((lib) => {
- let attrs = {};
- let elementType = '';
- if (typeof lib === 'string') {
- lib = {
- type: 'script',
- src: lib,
- };
- }
- switch (lib.type) {
- case 'script':
- elementType = 'script';
- attrs = {
- src: lib.src,
- type: 'text/javascript',
- defer: true,
- async: true,
- referrerpolicy: 'origin',
- };
- break;
- case 'styles':
- elementType = 'link';
- attrs = {
- href: lib.src,
- rel: 'stylesheet',
- };
- break;
- }
-
- // Add the script to the top of the page.
- const element = document.createElement(elementType);
- if (element.setAttribute) {
- for (const attr in attrs) {
- element.setAttribute(attr, attrs[attr]);
- }
- }
-
- if (onload) {
- element.addEventListener('load', () => {
- Formio.libraries[name].loaded = true;
- onload(Formio.libraries[name].ready);
- });
- }
-
- const { head } = document;
- if (head) {
- head.appendChild(element);
- }
- });
-
- // if no callback is provided, then check periodically for the script.
- if (polling) {
- const interval = setInterval(() => {
- const plugin = _get(window, property);
- if (plugin) {
- clearInterval(interval);
- Formio.libraries[name].resolve(plugin);
- }
- }, 200);
- }
- }
- }
-
- const lib = Formio.libraries[name];
-
- return onload && lib.loaded ? onload(lib.ready) : lib.ready;
- }
-
- static libraryReady(name) {
- if (
- Formio.libraries.hasOwnProperty(name) &&
- Formio.libraries[name].ready
- ) {
- return Formio.libraries[name].ready;
- }
-
- return NativePromise.reject(`${name} library was not required.`);
- }
-
- static addToGlobal(global) {
- if (typeof global === 'object' && !global.Formio) {
- global.Formio = Formio;
- }
- }
-
- static setPathType(type) {
- if (typeof type === 'string') {
- Formio.pathType = type;
- }
- }
-
- static getPathType() {
- return Formio.pathType;
- }
-
- static get rulesEntities() {
- return {
- ValueSources: Formio.ValueSources,
- Conjunctions: Formio.Conjunctions,
- Operators: Formio.Operators,
- Transformers: Formio.Transformers,
- QuickRules: Formio.QuickRules,
- Rules: Formio.Rules,
- };
- }
-
- static get GlobalFormio() {
- if (typeof global !== 'undefined' && global.Formio) {
- return global.Formio;
- }
- else if (typeof window !== 'undefined' && window.Formio) {
- return window.Formio;
- }
-
- return Formio;
- }
-}
-
-// Define all the static properties.
-Formio.libraries = {};
-Formio.Promise = NativePromise;
-Formio.fetch = fetch;
-Formio.Headers = Headers;
-Formio.baseUrl = 'https://api.form.io';
-Formio.projectUrl = Formio.baseUrl;
-Formio.authUrl = '';
-Formio.projectUrlSet = false;
-Formio.plugins = [];
-Formio.cache = {};
-Formio.Providers = Providers;
-Formio.version = '---VERSION---';
-Formio.pathType = '';
-Formio.events = new EventEmitter();
-Formio.cdn = new CDN();
-if ((Formio.version || '').includes('rc')) {
- Formio.cdn.setBaseUrl('https://cdn.test-form.io');
-}
-
-if (typeof global !== 'undefined') {
- Formio.addToGlobal(global);
-}
-if (typeof window !== 'undefined') {
- Formio.addToGlobal(window);
-}
-
-export const GlobalFormio = Formio.GlobalFormio;
-
-export default Formio;
diff --git a/web-client/core/themes/italia/static/formio/css/src/Formio.unit.js b/web-client/core/themes/italia/static/formio/css/src/Formio.unit.js
deleted file mode 100644
index 82a769b2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Formio.unit.js
+++ /dev/null
@@ -1,2374 +0,0 @@
-import { Formio } from './index';
-import { fastCloneDeep } from './utils/utils';
-import _each from 'lodash/each';
-import assert from 'power-assert';
-import sinon from 'sinon';
-import fetchMock from 'fetch-mock/es5/server';
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-
-import Chance from 'chance';
-const chance = Chance();
-const protocol = 'https';
-const domain = 'localhost:3000';
-const baseUrl = `${protocol}://api.${domain}`;
-Formio.setBaseUrl(baseUrl);
-Formio.setToken(null);
-Formio.fetch = fetchMock.fetchHandler;
-
-const projectId = '59bbe2ec8c246100079191aa';
-const formId = '59bbe2ec8c246100079191ab';
-const submissionId = '59bbe2ec8c246100079191ac';
-const actionId = '59bbe2ec8c246100079191ad';
-
-const generateID = function() {
- return chance.string({ length: 24, pool: '0123456789abcdef' });
-};
-
-const runTests = function(fn, options) {
- const tests = {};
- const noBefore = fn(tests);
- if (!noBefore) {
- beforeEach(() => {
- Formio.setBaseUrl(baseUrl);
- Formio.projectUrlSet = false;
- Formio.projectUrl = 'https://api.form.io';
- });
- }
- _each(tests, (test, path) => {
- it(`Should initialize for ${path}`, (done) => {
- if (typeof test === 'function') {
- test();
- }
- else {
- const formio = new Formio(path, options);
- for (const param in test) {
- assert.equal(formio[param], test[param], `${param} is not equal. ${formio[param]} == ${test[param]}\n`);
- }
- }
- done();
- });
- });
-};
-
-describe('Formio.js Tests', () => {
- describe('Formio Constructor Tests', () => {
- runTests((tests) => {
- tests[`http://form.io/project/${ projectId }/form/${ formId}`] = {
- projectUrl: `http://form.io/project/${ projectId}`,
- projectsUrl: 'http://form.io/project',
- projectId: projectId,
- formsUrl: `http://form.io/project/${ projectId }/form`,
- formUrl: `http://form.io/project/${ projectId }/form/${ formId}`,
- formId: formId,
- actionsUrl: `http://form.io/project/${ projectId }/form/${ formId }/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `http://form.io/project/${ projectId }/form/${ formId }/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`http://form.io/form/${ formId}`] = {
- projectUrl: 'http://form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: '',
- formsUrl: 'http://form.io/form',
- formUrl: `http://form.io/form/${ formId}`,
- formId: formId,
- actionsUrl: `http://form.io/form/${ formId }/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `http://form.io/form/${ formId }/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`http://form.io/form/${ formId }/submission/${ submissionId}`] = {
- projectUrl: 'http://form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: '',
- formsUrl: 'http://form.io/form',
- formUrl: `http://form.io/form/${ formId}`,
- formId: formId,
- actionsUrl: `http://form.io/form/${ formId }/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `http://form.io/form/${ formId }/submission`,
- submissionUrl: `http://form.io/form/${ formId }/submission/${ submissionId}`,
- submissionId: submissionId,
- query: ''
- };
- tests[`http://form.io/form/${ formId }/action/${ actionId}`] = {
- projectUrl: 'http://form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: '',
- formsUrl: 'http://form.io/form',
- formUrl: `http://form.io/form/${ formId}`,
- formId: formId,
- actionsUrl: `http://form.io/form/${ formId }/action`,
- actionUrl: `http://form.io/form/${ formId }/action/${ actionId}`,
- actionId: actionId,
- submissionsUrl: `http://form.io/form/${ formId }/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`http://form.io/project/${ projectId }/form/${ formId }/action/${ actionId}`] = {
- projectUrl: `http://form.io/project/${ projectId}`,
- projectsUrl: 'http://form.io/project',
- projectId: projectId,
- formsUrl: `http://form.io/project/${ projectId }/form`,
- formUrl: `http://form.io/project/${ projectId }/form/${ formId}`,
- formId: formId,
- actionsUrl: `http://form.io/project/${ projectId }/form/${ formId }/action`,
- actionUrl: `http://form.io/project/${ projectId }/form/${ formId }/action/${ actionId}`,
- actionId: actionId,
- submissionsUrl: `http://form.io/project/${ projectId }/form/${ formId }/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`http://api.form.io/project/${ projectId}`] = {
- projectUrl: `http://api.form.io/project/${ projectId}`,
- projectsUrl: 'http://api.form.io/project',
- projectId: projectId,
- formsUrl: `http://api.form.io/project/${ projectId }/form`,
- formUrl: '',
- formId: '',
- actionsUrl: `http://api.form.io/project/${ projectId }/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `http://api.form.io/project/${ projectId }/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`http://form.io/project/${ projectId }/form/${ formId }/submission/${ submissionId}`] = {
- projectUrl: `http://form.io/project/${ projectId}`,
- projectsUrl: 'http://form.io/project',
- projectId: projectId,
- formsUrl: `http://form.io/project/${ projectId }/form`,
- formUrl: `http://form.io/project/${ projectId }/form/${ formId}`,
- formId: formId,
- actionsUrl: `http://form.io/project/${ projectId }/form/${ formId }/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `http://form.io/project/${ projectId }/form/${ formId }/submission`,
- submissionUrl: `http://form.io/project/${ projectId }/form/${ formId }/submission/${ submissionId}`,
- submissionId: submissionId,
- query: ''
- };
- tests[`http://form.io/project/${ projectId }/form/${ formId }?test=hello&test2=there`] = {
- projectUrl: `http://form.io/project/${ projectId}`,
- projectsUrl: 'http://form.io/project',
- projectId: projectId,
- formsUrl: `http://form.io/project/${ projectId }/form`,
- formUrl: `http://form.io/project/${ projectId }/form/${ formId}`,
- formId: formId,
- actionsUrl: `http://form.io/project/${ projectId }/form/${ formId }/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `http://form.io/project/${ projectId }/form/${ formId }/submission`,
- submissionUrl: '',
- submissionId: '',
- query: '?test=hello&test2=there'
- };
- tests['http://project.form.io/user/login'] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user/login',
- formId: 'user/login',
- actionsUrl: 'http://project.form.io/user/login/action',
- actionUrl: '',
- actionId: '',
- submissionsUrl: 'http://project.form.io/user/login/submission',
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`http://project.form.io/user/login/submission/${ submissionId}`] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user/login',
- formId: 'user/login',
- actionsUrl: 'http://project.form.io/user/login/action',
- actionUrl: '',
- actionId: '',
- submissionsUrl: 'http://project.form.io/user/login/submission',
- submissionUrl: `http://project.form.io/user/login/submission/${ submissionId}`,
- submissionId: submissionId,
- query: ''
- };
- tests[`http://project.form.io/user/login/action/${ actionId}`] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user/login',
- formId: 'user/login',
- actionsUrl: 'http://project.form.io/user/login/action',
- actionUrl: `http://project.form.io/user/login/action/${ actionId}`,
- actionId: actionId,
- submissionsUrl: 'http://project.form.io/user/login/submission',
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`http://project.form.io/user/login/action/${ actionId }?test=test2`] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user/login',
- formId: 'user/login',
- actionsUrl: 'http://project.form.io/user/login/action',
- actionUrl: `http://project.form.io/user/login/action/${ actionId}`,
- actionId: actionId,
- submissionsUrl: 'http://project.form.io/user/login/submission',
- submissionUrl: '',
- submissionId: '',
- query: '?test=test2'
- };
- tests[`http://project.form.io/user/loginform/action/${ actionId }?test=test2`] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user/loginform',
- formId: 'user/loginform',
- actionsUrl: 'http://project.form.io/user/loginform/action',
- actionUrl: `http://project.form.io/user/loginform/action/${ actionId}`,
- actionId: actionId,
- submissionsUrl: 'http://project.form.io/user/loginform/submission',
- submissionUrl: '',
- submissionId: '',
- query: '?test=test2'
- };
- tests['http://project.form.io/user/loginform/submission'] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user/loginform',
- formId: 'user/loginform',
- actionsUrl: 'http://project.form.io/user/loginform/action',
- actionUrl: '',
- actionId: '',
- submissionsUrl: 'http://project.form.io/user/loginform/submission',
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests['http://project.form.io/user'] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user',
- formId: 'user',
- actionsUrl: 'http://project.form.io/user/action',
- actionUrl: '',
- actionId: '',
- submissionsUrl: 'http://project.form.io/user/submission',
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`http://project.form.io/user/actionform/submission/${ submissionId}`] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user/actionform',
- formId: 'user/actionform',
- actionsUrl: 'http://project.form.io/user/actionform/action',
- actionUrl: '',
- actionId: '',
- submissionsUrl: 'http://project.form.io/user/actionform/submission',
- submissionUrl: `http://project.form.io/user/actionform/submission/${ submissionId}`,
- submissionId: submissionId,
- query: ''
- };
- tests['http://project.form.io/user/actionform/?test=foo'] = {
- projectUrl: 'http://project.form.io',
- projectsUrl: `${baseUrl}/project`,
- projectId: 'project',
- formsUrl: 'http://project.form.io/form',
- formUrl: 'http://project.form.io/user/actionform',
- formId: 'user/actionform',
- actionsUrl: 'http://project.form.io/user/actionform/action',
- actionUrl: '',
- actionId: '',
- submissionsUrl: 'http://project.form.io/user/actionform/submission',
- submissionUrl: '',
- submissionId: '',
- query: '?test=foo'
- };
- });
- });
-
- describe('Localhost Constructor Tests', () => {
- const testBaseUrl = 'localhost:3000';
- const projectName = 'myproject';
- const projectUrl = `${protocol}://${projectName}.${testBaseUrl}`;
- runTests((tests) => {
- tests[`${projectUrl}/user/actionform/?test=foo`] = {
- projectUrl: projectUrl,
- projectsUrl: `${baseUrl}/project`,
- projectId: projectName,
- formsUrl: `${projectUrl}/form`,
- formUrl: `${projectUrl}/user/actionform`,
- formId: 'user/actionform',
- actionsUrl: `${projectUrl}/user/actionform/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${projectUrl}/user/actionform/submission`,
- submissionUrl: '',
- submissionId: '',
- query: '?test=foo'
- };
- tests[`${projectUrl}/user`] = {
- projectUrl: projectUrl,
- projectsUrl: `${baseUrl}/project`,
- projectId: projectName,
- formsUrl: `${projectUrl}/form`,
- formUrl: `${projectUrl}/user`,
- formId: 'user',
- actionsUrl: `${projectUrl}/user/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${projectUrl}/user/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- }, { base: baseUrl });
- });
-
- describe('Subdomain Constructor Tests', () => {
- const testBaseUrl = 'foo.blah.form.io';
- const projectName = 'myproject';
- const projectUrl = `${protocol}://${projectName}.${testBaseUrl}`;
- runTests((tests) => {
- tests[`${projectUrl}/user/actionform/?test=foo`] = {
- projectUrl: projectUrl,
- projectsUrl: `${baseUrl}/project`,
- projectId: projectName,
- formsUrl: `${projectUrl}/form`,
- formUrl: `${projectUrl}/user/actionform`,
- formId: 'user/actionform',
- actionsUrl: `${projectUrl}/user/actionform/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${projectUrl}/user/actionform/submission`,
- submissionUrl: '',
- submissionId: '',
- query: '?test=foo'
- };
- tests[`${projectUrl}/user`] = {
- projectUrl: projectUrl,
- projectsUrl: `${baseUrl}/project`,
- projectId: projectName,
- formsUrl: `${projectUrl}/form`,
- formUrl: `${projectUrl}/user`,
- formId: 'user',
- actionsUrl: `${projectUrl}/user/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${projectUrl}/user/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- }, { base: baseUrl });
- });
-
- describe('Subdirectory Constructor Tests', () => {
- const testBaseUrl = 'foo.blah.form.io';
- const projectName = 'myproject';
- const projectUrl = `${protocol}://${testBaseUrl}/${projectName}`;
- runTests((tests) => {
- tests[`${projectUrl}/user/actionform/?test=foo`] = {
- projectUrl: projectUrl,
- projectsUrl: `${protocol}://${testBaseUrl}/project`,
- projectId: projectName,
- formsUrl: `${projectUrl}/form`,
- formUrl: `${projectUrl}/user/actionform`,
- formId: 'user/actionform',
- actionsUrl: `${projectUrl}/user/actionform/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${projectUrl}/user/actionform/submission`,
- submissionUrl: '',
- submissionId: '',
- query: '?test=foo'
- };
- tests[`${projectUrl}/user`] = {
- projectUrl: projectUrl,
- projectsUrl: `${protocol}://${testBaseUrl}/project`,
- projectId: projectName,
- formsUrl: `${projectUrl}/form`,
- formUrl: `${projectUrl}/user`,
- formId: 'user',
- actionsUrl: `${projectUrl}/user/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${projectUrl}/user/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[projectUrl] = {
- projectUrl: projectUrl,
- projectsUrl: `${protocol}://${testBaseUrl}/project`,
- projectId: projectName,
- formsUrl: `${projectUrl}/form`,
- formUrl: '',
- formId: '',
- actionsUrl: `${projectUrl}/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${projectUrl}/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- }, { base: `${protocol}://${testBaseUrl}` });
- });
-
- describe('Simple Form Constructor Tests', () => {
- runTests((tests) => {
- tests['init'] = () => {
- Formio.setBaseUrl('https://api.form.io');
- Formio.projectUrlSet = false;
- Formio.projectUrl = 'https://api.form.io';
- };
- tests['https://examples.form.io/example'] = {
- projectUrl: 'https://examples.form.io',
- projectsUrl: '',
- projectId: '',
- formsUrl: 'https://examples.form.io/form',
- formUrl: 'https://examples.form.io/example',
- formId: 'example',
- actionsUrl: 'https://examples.form.io/example/action',
- actionUrl: '',
- actionId: '',
- submissionsUrl: 'https://examples.form.io/example/submission',
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- return true;
- });
- });
-
- describe('Open Source Constructor Tests', () => {
- const formBaseUrl = 'http://localhost:3000';
- runTests((tests) => {
- tests[`${formBaseUrl}/user`] = {
- projectUrl: formBaseUrl,
- projectsUrl: '',
- projectId: '',
- formsUrl: `${formBaseUrl}/form`,
- formUrl: `${formBaseUrl}/user`,
- formId: 'user',
- actionsUrl: `${formBaseUrl}/user/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${formBaseUrl}/user/submission`,
- submissionUrl: '',
- submissionId: '',
- query: ''
- };
- tests[`${formBaseUrl}/user/actionform/?test=foo`] = {
- projectUrl: formBaseUrl,
- projectsUrl: '',
- projectId: '',
- formsUrl: `${formBaseUrl}/form`,
- formUrl: `${formBaseUrl}/user/actionform`,
- formId: 'user/actionform',
- actionsUrl: `${formBaseUrl}/user/actionform/action`,
- actionUrl: '',
- actionId: '',
- submissionsUrl: `${formBaseUrl}/user/actionform/submission`,
- submissionUrl: '',
- submissionId: '',
- query: '?test=foo'
- };
- }, { base: formBaseUrl, project: formBaseUrl });
- });
-
- describe('Plugins', () => {
- let plugin = null;
- beforeEach(() => {
- assert.equal(Formio.getPlugin('test-plugin'), undefined, 'No plugin may be returned under the name `test-plugin`');
- plugin = { init: sinon.spy() };
- Formio.registerPlugin(plugin, 'test-plugin');
- assert.ok(plugin.init.calledOnce, 'plugin.init must be called exactly once');
- assert.ok(plugin.init.calledOn(plugin), 'plugin.init must be called on plugin as `this`');
- assert.ok(plugin.init.calledWithExactly(Formio), 'plugin.init must be given Formio as argument');
- assert.equal(Formio.getPlugin('test-plugin'), plugin, 'getPlugin must return plugin');
- });
-
- afterEach(() => {
- assert.equal(Formio.getPlugin('test-plugin'), plugin, 'getPlugin must return plugin');
- plugin.deregister = sinon.spy();
- Formio.deregisterPlugin(plugin, 'test-plugin');
- assert.ok(plugin.deregister.calledOnce, 'plugin.deregister must be called exactly once');
- assert.ok(plugin.deregister.calledOn(plugin), 'plugin.deregister must be called on plugin as `this`');
- assert.ok(plugin.deregister.calledWithExactly(Formio), 'plugin.deregister must be given Formio as argument');
- assert.equal(Formio.getPlugin('test-plugin'), undefined, 'No plugin may be returned under the name `test-plugin`');
- });
-
- // Test a request to see if the plugin flow order is correct
- const testRequest = function testRequest(url, method, type) {
- let fnName;
- switch (method) {
- case 'GET': fnName = `load${_.capitalize(type)}`; break;
- case 'POST':
- case 'PUT': fnName = `save${_.capitalize(type)}`; break;
- case 'DELETE': fnName = `delete${_.capitalize(type)}`; break;
- }
-
- it(`Plugin ${method} ${fnName}`, (done) => {
- let step = 0;
- const formio = new Formio(url);
- method = method.toUpperCase();
- const testData = { testRequest: 'TEST_REQUEST' };
- const testOpts = { testOption: true };
- const testResult = { _id: 'TEST_ID', testResult: 'TEST_RESULT' };
-
- const expectedArgs = {
- formio: formio,
- type: type,
- method: method,
- url: formio[type + (method === 'POST' ? 'sUrl' : 'Url')],
- data: _.startsWith(fnName, 'save') ? testData : null,
- opts: testOpts
- };
-
- // Set up plugin hooks
- plugin.preRequest = function(requestArgs) {
- assert.equal(++step, 1, 'preRequest hook should be called first');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return NativePromise.resolve()
- .then(() => {
- assert.equal(++step, 3, 'preRequest promise should resolve third');
- // TODO
- });
- };
- plugin.request = function(requestArgs) {
- assert.equal(++step, 4, 'request hook should be called fourth');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return NativePromise.resolve()
- .then(() => {
- assert.equal(++step, 5, 'request promise should resolve fifth');
- return testResult;
- });
- };
- plugin.wrapRequestPromise = function(promise, requestArgs) {
- assert.equal(++step, 2, 'wrapRequestPromise hook should be called second');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return promise.then((result) => {
- assert.equal(++step, 6, 'wrapRequestPromise post-result promise should resolve sixth');
- assert.deepEqual(result, testResult, 'Result should match result from request hook');
- return result;
- });
- };
-
- let promise;
- if (_.startsWith(fnName, 'save')) {
- promise = formio[fnName](testData, testOpts);
- }
- else if (_.startsWith(fnName, 'load')) {
- promise = formio[fnName](null, testOpts);
- }
- else {
- promise = formio[fnName](testOpts);
- }
- promise.then((result) => {
- assert.equal(++step, 7, 'post request promise should resolve last');
- assert.deepEqual(result, testResult, 'Result should match result from request hook');
- done();
- });
- });
- };
-
- const tests = [
- {
- url: 'https://api.localhost:3000/project/myproject',
- method: 'GET',
- type: 'project'
- },
- {
- url: '',
- method: 'POST',
- type: 'project'
- },
- {
- url: 'https://api.localhost:3000/project/myproject',
- method: 'PUT',
- type: 'project'
- },
- {
- url: 'https://api.localhost:3000/project/myproject',
- method: 'DELETE',
- type: 'project'
- },
-
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567',
- method: 'GET',
- type: 'form'
- },
- {
- url: 'https://api.localhost:3000/project/myproject',
- method: 'POST',
- type: 'form'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567',
- method: 'PUT',
- type: 'form'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567',
- method: 'DELETE',
- type: 'form'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/',
- method: 'GET',
- type: 'forms'
- },
-
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/submission/76543210FEDCBA9876543210',
- method: 'GET',
- type: 'submission'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567',
- method: 'POST',
- type: 'submission'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/submission/76543210FEDCBA9876543210',
- method: 'PUT',
- type: 'submission'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/submission/76543210FEDCBA9876543210',
- method: 'DELETE',
- type: 'submission'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567',
- method: 'GET',
- type: 'submissions'
- },
-
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/action/76543210FEDCBA9876543210',
- method: 'GET',
- type: 'action'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567',
- method: 'POST',
- type: 'action'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/action/76543210FEDCBA9876543210',
- method: 'PUT',
- type: 'action'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/action/76543210FEDCBA9876543210',
- method: 'DELETE',
- type: 'action'
- },
- {
- url: 'https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567',
- method: 'GET',
- type: 'actions'
- }
- ];
-
- tests.forEach((test) => {
- testRequest(test.url, test.method, test.type);
- });
-
- const testStaticRequest = function testStaticRequest(fnName, url, method) {
- it(`Plugin ${fnName}`, (done) => {
- let step = 0;
- const testResult = { _id: 'TEST_ID', testResult: 'TEST_RESULT' };
- const expectedArgs = {
- url: url,
- method: method,
- data: null,
- opts: {}
- };
-
- // Set up plugin hooks
- plugin.preRequest = function(requestArgs) {
- assert.equal(++step, 1, 'preRequest hook should be called first');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return NativePromise.resolve()
- .then(() => {
- assert.equal(++step, 3, 'preRequest promise should resolve third');
- // TODO
- });
- };
- plugin.staticRequest = function(requestArgs) {
- assert.equal(++step, 4, 'request hook should be called fourth');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return NativePromise.resolve()
- .then(() => {
- assert.equal(++step, 5, 'request promise should resolve fifth');
- return testResult;
- });
- };
- plugin.wrapStaticRequestPromise = function(promise, requestArgs) {
- assert.equal(++step, 2, 'wrapRequestPromise hook should be called second');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return promise.then((result) => {
- assert.equal(++step, 6, 'wrapRequestPromise post-result promise should resolve sixth');
- assert.deepEqual(result, testResult, 'Result should match result from request hook');
- return result;
- });
- };
-
- Formio[fnName]()
- .then((result) => {
- assert.equal(++step, 7, 'post request promise should resolve last');
- assert.deepEqual(result, testResult, 'Result should match result from request hook');
- done();
- });
- });
- };
-
- const staticTests = [
- {
- fnName: 'loadProjects',
- url: 'https://api.localhost:3000/project',
- method: 'GET'
- },
- {
- fnName: 'logout',
- url: 'https://api.localhost:3000/logout',
- method: 'GET'
- }
- ];
-
- staticTests.forEach((test) => {
- testStaticRequest(test.fnName, test.url, test.method, test.type);
- });
-
- const testFileRequest = function testFileRequest(fnName, formUrl, args) {
- it(`Plugin ${fnName}`, (done) => {
- let step = 0;
- const testResult = { _id: 'TEST_ID', testResult: 'TEST_RESULT' };
- let expectedArgs;
-
- if (fnName === 'downloadFile') {
- expectedArgs = {
- method: 'download',
- file: args[0]
- };
- }
- else if (fnName === 'uploadFile') {
- expectedArgs = {
- provider: args[0],
- method: 'upload',
- file: args[1],
- fileName: args[2],
- dir: args[3]
- };
- }
-
- // Set up plugin hooks
- plugin.preRequest = function(requestArgs) {
- assert.equal(++step, 1, 'preRequest hook should be called first');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return NativePromise.resolve()
- .then(() => {
- assert.equal(++step, 3, 'preRequest promise should resolve third');
- // TODO
- });
- };
- plugin.fileRequest = function(requestArgs) {
- assert.equal(++step, 4, 'request hook should be called fourth');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return NativePromise.resolve()
- .then(() => {
- assert.equal(++step, 5, 'request promise should resolve fifth');
- return testResult;
- });
- };
- plugin.wrapFileRequestPromise = function(promise, requestArgs) {
- assert.equal(++step, 2, 'wrapFileRequestPromise hook should be called second');
- assert.deepEqual(requestArgs, expectedArgs, 'Request hook arguments match expected arguments');
- return promise.then((result) => {
- assert.equal(++step, 6, 'wrapFileRequestPromise post-result promise should resolve sixth');
- assert.deepEqual(result, testResult, 'Result should match result from request hook');
- return result;
- });
- };
-
- const formio = new Formio(formUrl);
- formio[fnName].apply(null, args)
- .then((result) => {
- assert.equal(++step, 7, 'post request promise should resolve last');
- assert.deepEqual(result, testResult, 'Result should match result from request hook');
- done();
- });
- });
- };
-
- const fileTests = [
- {
- fnName: 'uploadFile',
- formUrl: 'https://api.localhost:3000/project/123/form/123',
- args: [
- 's3',
- 'FILE',
- 'file.jpg',
- 'dir/'
- ]
- },
- {
- fnName: 'uploadFile',
- formUrl: 'https://api.localhost:3000/project/123/form/123',
- args: [
- 'dropbox',
- 'FILE',
- 'file.jpg',
- 'dir/'
- ]
- },
- {
- fnName: 'downloadFile',
- formUrl: 'https://api.localhost:3000/project/123/form/123',
- args: [
- {
- storage: 's3',
- name: 'test'
- }
- ]
- },
- {
- fnName: 'downloadFile',
- formUrl: 'https://api.localhost:3000/project/123/form/123',
- args: [
- {
- storage: 'dropbox',
- name: 'test'
- }
- ]
- }
- ];
-
- fileTests.forEach((test) => {
- testFileRequest(test.fnName, test.formUrl, test.args);
- });
- });
-
- describe('Test Formio.js capabilities', () => {
- const testCapability = function(test) {
- it(test.name, (done) => {
- // need to clear Formio cache before every test, otherwise mock results might be ignored for same URLs
- Formio.clearCache();
- if (test.mock) {
- const mock = test.mock();
- if (mock instanceof Array) {
- _.each(mock, (_mock) => {
- fetchMock.mock(_mock.url, _mock.response, { method: _mock.method });
- });
- }
- else {
- fetchMock.mock(mock.url, mock.response, { method: mock.method });
- }
- }
- NativePromise.resolve()
- .then(() => {
- return test.test();
- })
- .then(() => {
- if (test.mock) {
- fetchMock.restore();
- }
- done();
- })
- .catch((err) => {
- if (test.mock) {
- fetchMock.restore();
- }
- done(typeof err === 'string' ? new Error(err) : err);
- });
- });
- };
-
- let user;
- let userPassword;
- let userToken = chance.string({ length: 450 });
- const userFormId = generateID();
- let project;
- let form;
- let submission;
-
- const tests = [
- {
- name: 'Registering user.',
- test() {
- const req = {
- data: {
- 'user.name': chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
- }),
- 'user.email': chance.email(),
- 'user.password': chance.string({ length: 12 })
- }
- };
- Formio.setProjectUrl(Formio.getBaseUrl());
- const formio = new Formio(`${Formio.getBaseUrl()}/user/register`);
- return formio.saveSubmission(req)
- .then((response) => {
- assert.deepEqual(response, user, 'saveSubmission response should match test user');
- assert.equal(Formio.getToken(), userToken, 'Formio should save the user token');
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/current`,
- method: 'GET',
- response() {
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: user
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/user/register/submission`,
- method: 'POST',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- const userId = generateID();
- user = {
- _id: userId,
- created: new Date().toISOString(),
- modified: new Date().toISOString(),
- data: {
- email: body.data['user.email'],
- name: body.data['user.name']
- },
- externalIds: [],
- externalTokens: [],
- form: userFormId,
- owner: userId
- };
- userPassword = body.data['user.password'];
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: user
- };
- }
- }
- ];
- }
- },
- {
- name: 'Logging in.',
- test() {
- const req = {
- data: {
- 'user.email': user.data.email,
- 'user.password': userPassword
- }
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/user/login`);
- return formio.saveSubmission(req)
- .then((response) => {
- assert.deepEqual(response, user, 'saveSubmission response should match test user');
- assert.equal(Formio.getToken(), userToken, 'Formio should save the user token');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/user/login/submission`,
- method: 'POST',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- userToken = chance.string({ length: 450 });
- assert.equal(body.data['user.email'], user.data.email, 'Login email must be correct.');
- assert.equal(body.data['user.password'], userPassword, 'Login password must be correct.');
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: user
- };
- }
- };
- }
- },
- {
- name: 'Current user.',
- test() {
- return Formio.currentUser()
- .then((response) => {
- assert.deepEqual(response, user, 'currentUser response should match test user');
- return Formio.currentUser();
- })
- .then((response) => {
- assert.deepEqual(response, user, 'currentUser response should match test user');
- });
- },
- mock() {
- let called = false;
- return {
- url: `${Formio.getBaseUrl()}/current`,
- method: 'GET',
- response() {
- assert.ok(!called, 'User should be requested only once.');
- called = true;
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: user
- };
- }
- };
- }
- },
- {
- name: 'Create Project',
- test() {
- const formio = new Formio();
- const req = {
- title: chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
- }),
- name: chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyz'
- }),
- description: chance.paragraph({ sentences: 1 }),
- settings: {
- cors: '*'
- },
- template: 'http://help.form.io/templates/empty.json'
- };
- return formio.saveProject(req)
- .then((response) => {
- assert.deepEqual(response, project, 'saveProject response should match test user');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project`,
- method: 'POST',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- const projectId = generateID();
- project = {
- _id: projectId,
- created: new Date().toISOString(),
- modified: new Date().toISOString(),
- apiCalls: {
- used: 0,
- limit: 1000,
- remaining: 1000,
- reset: new Date(Date.now() + 2.628e9).toISOString() // ~1 month later
- },
- access: [],
- title: body.title,
- name: body.name,
- description: body.description,
- plan: 'basic',
- owner: user._id
- };
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: project
- };
- }
- };
- }
- },
- {
- name: 'Getting Projects',
- test() {
- return Formio.loadProjects()
- .then((projects) => {
- assert.equal(projects.length, 1, 'Should return only one project.');
- assert.equal(projects.skip, 0, 'skip should be 0.');
- assert.equal(projects.limit, 1, 'limit should be 1.');
- assert.equal(projects.serverCount, 1, 'serverCount should be 1.');
- assert.deepEqual(projects[0], project, 'Should match project');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project`,
- method: 'GET',
- response() {
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'Content-Range': '0-0/1',
- 'Range-Unit': 'items',
- 'x-jwt-token': userToken
- },
- body: [project]
- };
- }
- };
- }
- },
- {
- name: 'Read Project',
- test() {
- const formio = new Formio(`${Formio.getBaseUrl()}/project/${project._id}`);
- return formio.loadProject()
- .then((response) => {
- assert.deepEqual(response, project, 'Should match project');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}`,
- method: 'GET',
- response() {
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: project
- };
- }
- };
- }
- },
- {
- name: 'Update Project',
- test() {
- const formio = new Formio(`/project/${project._id}`);
- const newProject = fastCloneDeep(project);
- newProject.name = chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyz'
- });
- newProject.title = chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
- });
- newProject.description = chance.paragraph({ sentences: 1 });
- return formio.saveProject(newProject)
- .then((response) => {
- assert.deepEqual(response, project, 'Project should match');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}`,
- method: 'PUT',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- project = body;
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: project
- };
- }
- };
- }
- },
- {
- name: 'Create Form',
- test() {
- const formio = new Formio(`/project/${project._id}/form`);
- const req = {
- title: chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
- }),
- name: chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyz'
- }),
- path: chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyz'
- }),
- components: [
- {
- defaultValue: '',
- input: true,
- inputMask: '',
- inputType: 'text',
- isNew: false,
- key: 'fieldLabel',
- label: 'Field Label',
- multiple: false,
- persistent: true,
- placeholder: '',
- prefix: '',
- protected: false,
- suffix: '',
- tableView: true,
- type: 'textfield',
- unique: false,
- validate: {
- required: false,
- minLength: '',
- maxLength: '',
- pattern: '',
- custom: '',
- customPrivate: false
- }
- },
- {
- action: 'submit',
- block: false,
- disableOnInvalid: true,
- input: true,
- key: 'submit',
- label: 'Submit',
- leftIcon: '',
- rightIcon: '',
- size: 'md',
- tableView: false,
- theme: 'primary',
- type: 'button'
- }
- ],
- type: 'form',
- access: [],
- submissionAccess: []
- };
- return formio.saveForm(req)
- .then((response) => {
- assert.deepEqual(response, form, 'Form should match');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form`,
- method: 'POST',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- const formId = generateID();
- form = fastCloneDeep(body);
- _.assign(form, {
- _id: formId,
- created: new Date().toISOString(),
- modified: new Date().toISOString(),
- project: project._id,
- owner: user._id
- });
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: form
- };
- }
- };
- }
- },
- {
- name: 'Load Forms',
- test() {
- const formio = new Formio(`/project/${project._id}/form`);
- return formio.loadForms()
- .then((forms) => {
- assert.equal(forms.length, 1, 'Should return only one form.');
- assert.equal(forms.skip, 0, 'skip should be 0.');
- assert.equal(forms.limit, 1, 'limit should be 1.');
- assert.equal(forms.serverCount, 1, 'serverCount should be 1.');
- assert.deepEqual(forms[0], form, 'Should match form');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form`,
- method: 'GET',
- response() {
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'Content-Range': '0-0/1',
- 'Range-Unit': 'items',
- 'x-jwt-token': userToken
- },
- body: [form]
- };
- }
- };
- }
- },
- {
- name: 'Read Form',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}`);
- return formio.loadForm()
- .then((response) => {
- assert.deepEqual(response, form, 'Form should match');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}`,
- method: 'GET',
- response() {
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: form
- };
- }
- };
- }
- },
- {
- name: 'Update Form',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}`);
- const newForm = fastCloneDeep(form);
- newForm.title = chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
- });
- newForm.name = chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyz'
- });
- newForm.path = chance.string({
- length: 10,
- pool: 'abcdefghijklmnopqrstuvwxyz'
- });
- return formio.saveForm(newForm)
- .then((response) => {
- assert.deepEqual(response, form, 'Form should match');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}`,
- method: 'PUT',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- form = body;
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: form
- };
- }
- };
- }
- },
- {
- name: 'Create Submission',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}/submission`);
- const req = {
- data: {
- fieldLabel: chance.string()
- }
- };
- return formio.saveSubmission(req)
- .then((response) => {
- assert.deepEqual(response, submission, 'Submission should match');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission`,
- method: 'POST',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- const submissionId = generateID();
- submission = {
- _id: submissionId,
- created: new Date().toISOString(),
- modified: new Date().toISOString(),
- data: body.data,
- externalIds: [],
- externalTokens: [],
- form: form._id,
- owner: user._id,
- roles: []
- };
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: submission
- };
- }
- };
- }
- },
- {
- name: 'Load Submissions',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}/submission`);
- return formio.loadSubmissions()
- .then((submissions) => {
- assert.equal(submissions.length, 1, 'Should return only one submission.');
- assert.equal(submissions.skip, 0, 'skip should be 0.');
- assert.equal(submissions.limit, 1, 'limit should be 1.');
- assert.equal(submissions.serverCount, 1, 'serverCount should be 1.');
- assert.deepEqual(submissions[0], submission, 'Should match submission');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission`,
- method: 'GET',
- response() {
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'Content-Range': '0-0/1',
- 'Range-Unit': 'items',
- 'x-jwt-token': userToken
- },
- body: [submission]
- };
- }
- };
- }
- },
- {
- name: 'Read Submission',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}/submission/${submission._id}`);
- return formio.loadSubmission()
- .then((response) => {
- assert.deepEqual(response, submission, 'Submission should match');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission/${submission._id}`,
- method: 'GET',
- response() {
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: submission
- };
- }
- };
- }
- },
- {
- name: 'Update Submission',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}/submission/${submission._id}`);
- const newSubmission = fastCloneDeep(submission);
- newSubmission.data.fieldLabel = chance.string();
- return formio.saveSubmission(newSubmission)
- .then((response) => {
- assert.deepEqual(response, submission, 'Submission should match');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission/${submission._id}`,
- method: 'PUT',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- submission = body;
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: submission
- };
- }
- };
- }
- },
- {
- name: 'Update Submission without ID',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}`);
- const newSubmission = fastCloneDeep(submission);
- newSubmission.data.fieldLabel = chance.string();
- return formio.saveSubmission(newSubmission)
- .then((response) => {
- assert.deepEqual(response, submission, 'Submission should match');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission/${submission._id}`,
- method: 'PUT',
- response(url, opts) {
- const body = JSON.parse(opts.body);
- submission = body;
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'x-jwt-token': userToken
- },
- body: submission
- };
- }
- };
- }
- },
- // Actions
- // Available Actions
- // Action Info
- {
- name: 'Delete Submission',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}/submission/${submission._id}`);
- return formio.deleteSubmission()
- .then((response) => {
- assert.equal(response, 'OK', 'Submission should be deleted.');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission/${submission._id}`,
- method: 'DELETE',
- response: {
- status: 200,
- body: 'OK',
- headers: {
- 'Content-Type': 'text/plain; charset=utf-8',
- 'x-jwt-token': userToken
- }
- }
- };
- }
- },
- {
- name: 'Delete Form',
- test() {
- const formio = new Formio(`/project/${project._id}/form/${form._id}`);
- return formio.deleteForm()
- .then((response) => {
- assert.equal(response, 'OK', 'Submission should be deleted.');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}`,
- method: 'DELETE',
- response: {
- status: 200,
- body: 'OK',
- headers: {
- 'Content-Type': 'text/plain; charset=utf-8',
- 'x-jwt-token': userToken
- }
- }
- };
- }
- },
- {
- name: 'Delete Project',
- test() {
- const formio = new Formio(`/project/${project._id}`);
- return formio.deleteProject()
- .then((response) => {
- assert.equal(response, 'OK', 'Submission should be deleted.');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}`,
- method: 'DELETE',
- response: {
- status: 200,
- body: 'OK',
- headers: {
- 'Content-Type': 'text/plain; charset=utf-8',
- 'x-jwt-token': userToken
- }
- }
- };
- }
- },
- {
- name: 'Getting Projects',
- test() {
- return Formio.loadProjects()
- .then((projects) => {
- assert.equal(projects.length, 0, 'Should return no projects.');
- assert.equal(projects.skip, undefined, 'skip should be undefined.');
- assert.equal(projects.limit, undefined, 'limit should be undefined.');
- assert.equal(projects.serverCount, 0, 'serverCount should be 0.');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project`,
- method: 'GET',
- response() {
- return {
- headers: {
- 'Content-Type': 'application/json',
- 'Content-Range': '*/0',
- 'Range-Unit': 'items',
- 'x-jwt-token': userToken
- },
- body: []
- };
- }
- };
- }
- },
- {
- name: 'Temporary Token',
- test() {
- const formio = new Formio(`/project/${project._id}`);
- return formio.getTempToken(200, 'GET:/current').then((tempToken) => {
- assert.equal(tempToken, userToken);
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/project/${project._id}/token`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: userToken,
- headers: {
- 'Content-Type': 'text/plain; charset=utf-8',
- 'x-jwt-token': userToken
- }
- };
- }
- };
- }
- },
- {
- name: 'Logging Out',
- test() {
- return Formio.logout()
- .then(() => {
- assert.equal(Formio.getToken(), '', 'Logged out');
- });
- },
- mock() {
- return {
- url: `${Formio.getBaseUrl()}/logout`,
- method: 'GET',
- response() {
- userToken = null;
- return {
- status: 200,
- body: 'OK',
- headers: {
- 'Content-Type': 'text/plain; charset=utf-8',
- 'x-jwt-token': ''
- }
- };
- }
- };
- }
- },
- {
- name: 'userPermissions method should give create_all permission',
- test() {
- const user = {
- _id: 'test_user_id',
- roles: ['test_role_id']
- };
-
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return formio.userPermissions(user)
- .then(permissions => {
- assert.equal(permissions.create, true);
- assert.equal(permissions.edit, false);
- assert.equal(permissions.delete, false);
- assert.equal(permissions.read, false);
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: [
- {
- type: 'create_all',
- roles: ['test_role_id']
- }
- ]
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: []
- }
- };
- }
- },
- ];
- }
- },
- {
- name: 'userPermissions method should give create_own permission',
- test() {
- const userId = 'test_user_id';
- const user = {
- _id: userId,
- roles: ['test_role_id']
- };
- const submission = {
- owner: userId
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return formio.userPermissions(user, undefined, submission)
- .then(permissions => {
- assert.equal(permissions.create, true);
- assert.equal(permissions.edit, false);
- assert.equal(permissions.read, false);
- assert.equal(permissions.delete, false);
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: [
- {
- type: 'create_own',
- roles: ['test_role_id']
- }
- ]
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: []
- }
- };
- }
- },
- ];
- }
- },
- {
- name: 'userPermissions method should give permissions for Anonymous role',
- test() {
- const user = {
- _id: false,
- roles: [],
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return formio.userPermissions(user)
- .then(permissions => {
- assert.equal(permissions.create, true);
- assert.equal(permissions.edit, false);
- assert.equal(permissions.read, false);
- assert.equal(permissions.delete, false);
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: [
- {
- type: 'create_all',
- roles: ['test_anonymous_role_id']
- }
- ]
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: [
- {
- _id: 'test_anonymous_role_id',
- default: true
- }
- ]
- }
- };
- }
- },
- ];
- }
- },
- {
- name: 'userPermissions method should give all permissions for admin role',
- test() {
- const user = {
- roles: ['test_admin_role'],
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return formio.userPermissions(user)
- .then(permissions => {
- assert.equal(permissions.create, true);
- assert.equal(permissions.read, true);
- assert.equal(permissions.edit, true);
- assert.equal(permissions.delete, true);
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: []
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: [
- {
- _id: 'test_admin_role',
- admin: true
- }
- ]
- }
- };
- }
- },
- ];
- }
- },
- {
- name: 'userPermissions method should give only group read permission for `read` level',
- test() {
- const user = {
- roles: ['test_group_id'],
- };
- const submission = {
- data: {
- groupField: {
- _id: 'test_group_id'
- }
- }
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return formio.userPermissions(user, undefined, submission)
- .then(permissions => {
- assert.equal(permissions.create, false);
- assert.equal(permissions.read, true);
- assert.equal(permissions.edit, false);
- assert.equal(permissions.delete, false);
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: [],
- components: [
- {
- defaultPermission: 'read',
- key: 'groupField'
- }
- ]
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: []
- }
- };
- }
- },
- ];
- }
- },
- {
- name: 'userPermissions method should give group read and create permissions for `create` level',
- test() {
- const user = {
- roles: ['test_group_id'],
- };
- const submission = {
- data: {
- groupField: {
- _id: 'test_group_id'
- }
- }
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return formio.userPermissions(user, undefined, submission)
- .then(permissions => {
- assert.equal(permissions.create, true);
- assert.equal(permissions.read, true);
- assert.equal(permissions.edit, false);
- assert.equal(permissions.delete, false);
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: [],
- components: [
- {
- defaultPermission: 'create',
- key: 'groupField'
- }
- ]
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: []
- }
- };
- }
- },
- ];
- }
- },
- {
- name: 'userPermissions method should give group read, create and edit permissions for `write` level',
- test() {
- const user = {
- roles: ['test_group_id'],
- };
- const submission = {
- data: {
- groupField: {
- _id: 'test_group_id'
- }
- }
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return formio.userPermissions(user, undefined, submission)
- .then(permissions => {
- assert.equal(permissions.create, true);
- assert.equal(permissions.read, true);
- assert.equal(permissions.edit, true);
- assert.equal(permissions.delete, false);
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: [],
- components: [
- {
- defaultPermission: 'write',
- key: 'groupField'
- }
- ]
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: []
- }
- };
- }
- },
- ];
- }
- },
- {
- name: 'userPermissions method should give all group permissions for `admin` level',
- test() {
- const user = {
- roles: ['test_group_id'],
- };
- const submission = {
- data: {
- groupField: {
- _id: 'test_group_id'
- }
- }
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return formio.userPermissions(user, undefined, submission)
- .then(permissions => {
- assert.equal(permissions.create, true);
- assert.equal(permissions.read, true);
- assert.equal(permissions.edit, true);
- assert.equal(permissions.delete, true);
- });
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: [],
- components: [
- {
- defaultPermission: 'admin',
- key: 'groupField'
- }
- ]
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: []
- }
- };
- }
- },
- ];
- }
- },
- {
- name: 'userPermissions method should handle submission with multiple groups',
- test() {
- const user1 = {
- roles: ['test_group_id1'],
- };
- const user2 = {
- roles: ['test_group_id2'],
- };
- const submission = {
- data: {
- groupField: [
- {
- _id: 'test_group_id1'
- },
- {
- _id: 'test_group_id2'
- }
- ]
- }
- };
- const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
- return NativePromise.all([
- formio.userPermissions(user1, undefined, submission)
- .then(permissions => {
- assert.equal(permissions.create, false);
- assert.equal(permissions.read, true);
- assert.equal(permissions.edit, false);
- assert.equal(permissions.delete, false);
- }),
- formio.userPermissions(user2, undefined, submission)
- .then(permissions => {
- assert.equal(permissions.create, false);
- assert.equal(permissions.read, true);
- assert.equal(permissions.edit, false);
- assert.equal(permissions.delete, false);
- }),
- ]);
- },
- mock() {
- return [
- {
- url: `${Formio.getBaseUrl()}/testform`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- submissionAccess: [],
- components: [
- {
- defaultPermission: 'read',
- key: 'groupField'
- }
- ]
- },
- };
- }
- },
- {
- url: `${Formio.getBaseUrl()}/access`,
- method: 'GET',
- response() {
- return {
- status: 200,
- body: {
- roles: []
- }
- };
- }
- },
- ];
- }
- },
- ];
-
- tests.forEach(testCapability);
- });
-
- describe('Formio.currentUser', () => {
- let plugin = null;
- beforeEach(() => {
- plugin = {
- wrapStaticRequestPromise: sinon.spy((promise) => promise),
- staticRequest: sinon.spy(() => {
- // Return dummy user
- const userId = generateID();
- return NativePromise.resolve({
- _id: userId,
- created: new Date().toISOString(),
- modified: new Date().toISOString(),
- data: {
- email: 'user@place.com',
- name: 'user'
- },
- externalIds: [],
- externalTokens: [],
- form: generateID(),
- owner: userId
- });
- })
- };
- Formio.registerPlugin(plugin, 'currentUserTestPlugin');
- });
-
- afterEach(() => {
- Formio.deregisterPlugin(plugin);
- });
-
- it('Initial currentUser() should make static request', (done) => {
- // Force token
- Formio.token = chance.string({ length: 30 });
- Formio.currentUser()
- .then(() => {
- assert.ok(plugin.staticRequest.calledOnce, 'staticRequest should be called once');
- done();
- });
- assert.ok(plugin.wrapStaticRequestPromise.calledOnce, 'wrapStaticRequestPromise should be called once');
- });
-
- it('Next currentUser() should return cached value', (done) => {
- // Clear token
- Formio.currentUser()
- .then(() => {
- assert.ok(!plugin.staticRequest.called, 'staticRequest should not be called');
- done();
- });
- assert.ok(plugin.wrapStaticRequestPromise.calledOnce, 'wrapStaticRequestPromise should be called once');
- });
-
- it('Should render after form submission if renderMode = \'html\'', (done) => {
- const formJson = {
- components: [{
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- },
- {
- label: 'Phone Number',
- tableView: true,
- key: 'phoneNumber',
- type: 'phoneNumber',
- input: true
- }]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson, { renderMode: 'html' })
- .then(form => {
- const textField = form.getComponent('textField');
- const phoneNumber = form.getComponent('phoneNumber');
- assert.equal(textField.element.querySelector('[ref=value]').innerHTML, '-');
- assert.equal(phoneNumber.element.querySelector('[ref=value]').innerHTML, '-');
- form.submission = {
- data: {
- textField: 'textField',
- phoneNumber: '88005553535'
- }
- };
- setTimeout(() => {
- assert.equal(textField.element.querySelector('[ref=value]').innerHTML, 'textField');
- assert.equal(phoneNumber.element.querySelector('[ref=value]').innerHTML, '88005553535');
- done();
- }, 300);
- })
- .catch(done);
- });
-
- it('Should render after form submission if renderMode = \'html\' with Nested Form', (done) => {
- const formJson = {
- components: [
- {
- label: 'Form',
- key: 'form',
- type: 'form',
- input: true,
- components: [
- {
- label: 'Text Field',
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Password',
- key: 'password',
- type: 'password',
- input: true
- },
- ],
- },
- {
- label: 'Checkbox',
- type: 'checkbox',
- input: true
- },
- ]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson, { renderMode: 'html' })
- .then(form => {
- assert.equal(form.getComponent('textField').element.querySelector('[ref=value]').innerHTML, '-');
- assert.equal(form.getComponent('password').element.querySelector('[ref=value]').innerHTML, '-');
- form.submission = {
- data: {
- form: {
- data: {
- textField: 'textField',
- password: 'password'
- }
- }
- }
- };
- setTimeout(() => {
- assert.equal(form.getComponent('textField').element.querySelector('[ref=value]').innerHTML, 'textField');
- assert.equal(form.getComponent('password').element.querySelector('[ref=value]').innerHTML, 'password');
- done();
- }, 300);
- })
- .catch(done);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/PDF.js b/web-client/core/themes/italia/static/formio/css/src/PDF.js
deleted file mode 100644
index 69c01798..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/PDF.js
+++ /dev/null
@@ -1,332 +0,0 @@
-import NativePromise from 'native-promise-only';
-import { GlobalFormio as Formio } from './Formio';
-import Webform from './Webform';
-import { fastCloneDeep, eachComponent } from './utils/utils';
-
-export default class PDF extends Webform {
- constructor(element, options) {
- options.display = 'pdf';
- super(element, options);
- this.components = [];
- }
-
- init() {
- super.init();
-
- // Handle an iframe submission.
- this.on('iframe-submission', (submission) => this.setValue(submission, {
- fromIframe: true
- }), true);
-
- this.on('iframe-change', (submission) => this.setValue(submission, {
- fromIframe: true
- }), true);
-
- this.on('iframe-getIframePositions', (query) => {
- const iframe = document.getElementById(`iframe-${query.formId}`);
- if (iframe) {
- const iframeBoundingClientRect = iframe.getBoundingClientRect();
- this.postMessage({
- name: 'iframePositions',
- data: {
- formId: query.formId,
- iframe: {
- top: iframeBoundingClientRect.top
- },
- scrollY: window.scrollY || window.pageYOffset
- }
- });
- }
- });
-
- // Trigger when this form is ready.
- this.on('iframe-ready', () => this.iframeReadyResolve(), true);
- }
-
- render() {
- this.submitButton = this.addComponent({
- disabled: this.form.disableWizardSubmit,
- input: true,
- type: 'button',
- action: 'submit',
- internal: true,
- label: 'Submit',
- key: 'submit',
- ref: 'button',
- hidden: this.isSubmitButtonHidden()
- });
-
- return this.renderTemplate('pdf', {
- submitButton: this.submitButton.render(),
- classes: 'formio-form-pdf',
- children: this.renderComponents()
- });
- }
-
- redraw() {
- this.postMessage({ name: 'redraw' });
- return this.builderMode ? NativePromise.resolve() : super.redraw();
- }
-
- rebuild() {
- if (this.builderMode && this.component.components) {
- this.destroyComponents();
- this.addComponents();
- return NativePromise.resolve();
- }
- this.postMessage({ name: 'redraw' });
- return super.rebuild();
- }
-
- // Do not attach nested components for pdf.
- attachComponents(element, components, container) {
- components = components || this.components;
- container = container || this.component.components;
- element = this.hook('attachComponents', element, components, container, this);
- return Promise.resolve();
- }
-
- attach(element) {
- return super.attach(element).then(() => {
- this.loadRefs(element, {
- button: 'single',
- buttonMessageContainer: 'single',
- buttonMessage: 'single',
- zoomIn: 'single',
- zoomOut: 'single',
- iframeContainer: 'single'
- });
- this.submitButton.refs = { ...this.refs };
- this.submitButton.attachButton();
-
- // Reset the iframeReady promise.
- this.iframeReady = new NativePromise((resolve, reject) => {
- this.iframeReadyResolve = resolve;
- this.iframeReadyReject = reject;
- });
-
- // iframes cannot be in the template so manually create it
- this.iframeElement = this.ce('iframe', {
- src: this.getSrc(),
- id: `iframe-${this.id}`,
- seamless: true,
- class: 'formio-iframe'
- });
-
- this.iframeElement.formioContainer = this.component.components;
- this.iframeElement.formioComponent = this;
-
- // Append the iframe to the iframeContainer in the template
- this.empty(this.refs.iframeContainer);
- this.appendChild(this.refs.iframeContainer, this.iframeElement);
-
- // Post the form to the iframe
- this.form.base = Formio.getBaseUrl();
- this.form.projectUrl = Formio.getProjectUrl();
- this.postMessage({ name: 'form', data: this.form });
-
- // Hide the submit button if the associated component is hidden
- const submitButton = this.components.find(c => c.element === this.refs.button);
- if (submitButton) {
- this.refs.button.classList.toggle('hidden', !submitButton.visible);
- }
-
- this.addEventListener(this.refs.zoomIn, 'click', (event) => {
- event.preventDefault();
- this.postMessage({ name: 'zoomIn' });
- });
-
- this.addEventListener(this.refs.zoomOut, 'click', (event) => {
- event.preventDefault();
- this.postMessage({ name: 'zoomOut' });
- });
-
- const form = fastCloneDeep(this.form);
- if (this.formio) {
- form.projectUrl = this.formio.projectUrl;
- form.url = this.formio.formUrl;
- form.base = this.formio.base;
- this.postMessage({ name: 'token', data: this.formio.getToken() });
- }
-
- this.emit('attach');
- });
- }
-
- /**
- * Get the submission from the iframe.
- *
- * @return {Promise}
- */
- getSubmission() {
- return new NativePromise((resolve) => {
- this.once('iframe-submission', resolve);
- this.postMessage({ name: 'getSubmission' });
- });
- }
-
- /**
- * Ensure we have the submission from the iframe before we submit the form.
- *
- * @param options
- * @return {*}
- */
- submitForm(options = {}) {
- this.postMessage({ name: 'getErrors' });
- return this.getSubmission().then(() => super.submitForm(options));
- }
-
- getSrc() {
- if (!this._form || !this._form.settings || !this._form.settings.pdf) {
- return '';
- }
-
- let iframeSrc = `${this._form.settings.pdf.src}.html`;
- const params = [`id=${this.id}`];
-
- if (this.options.showCheckboxBackground || this._form.settings.showCheckboxBackground) {
- params.push('checkboxbackground=1');
- }
-
- if (this.options.readOnly) {
- params.push('readonly=1');
- }
-
- if (this.options.zoom) {
- params.push(`zoom=${this.options.zoom}`);
- }
-
- if (this.builderMode) {
- params.push('builder=1');
- }
-
- if (params.length) {
- iframeSrc += `?${params.join('&')}`;
- }
-
- return iframeSrc;
- }
-
- setForm(form, flags = {}) {
- return super.setForm(form, flags).then(() => {
- if (this.formio) {
- form.projectUrl = this.formio.projectUrl;
- form.url = this.formio.formUrl;
- form.base = this.formio.base;
- this.postMessage({ name: 'token', data: this.formio.getToken() });
- }
- this.postMessage({ name: 'form', data: this.form });
- });
- }
-
- /**
- * Set's the value of this form component.
- *
- * @param submission
- * @param flags
- */
- setValue(submission, flags = {}) {
- const changed = super.setValue(submission, flags);
- if (!flags || !flags.fromIframe) {
- this.once('iframe-ready', () => {
- if (changed) {
- this.postMessage({ name: 'submission', data: submission });
- }
- });
- }
- return changed;
- }
-
- postMessage(message) {
- // If we get here before the iframeReady promise is set up, it's via the superclass constructor
- if (!this.iframeReady) {
- return;
- }
-
- if (!message.type) {
- message.type = 'iframe-data';
- }
-
- this.iframeReady.then(() => {
- if (this.iframeElement && this.iframeElement.contentWindow && !(message.name === 'form' && this.iframeFormSetUp)) {
- this.iframeElement.contentWindow.postMessage(JSON.stringify(message), '*');
- this.iframeFormSetUp = message.name === 'form';
- }
- });
- }
-
- focusOnComponent(key) {
- this.postMessage({
- name: 'focusErroredField',
- data: key,
- });
- }
-
- // Do not clear the iframe.
- clear() {}
-
- showErrors(error, triggerEvent) {
- const helpBlock = document.getElementById('submit-error');
- const submitError = this.t('submitError');
- const isSubmitErrorShown = this.refs.buttonMessage?.textContent.trim() === submitError;
-
- if (!helpBlock && this.errors.length && !isSubmitErrorShown) {
- const p = this.ce('p', { class: 'help-block' });
-
- this.setContent(p, submitError);
- p.addEventListener('click', () => {
- window.scrollTo(0, 0);
- });
-
- const div = this.ce('div', { id: 'submit-error', class: 'has-error' });
-
- this.appendTo(p, div);
- this.appendTo(div, this.element);
- }
-
- if (!this.errors.length && helpBlock) {
- helpBlock.remove();
- }
-
- super.showErrors(error, triggerEvent);
- }
-
- isSubmitButtonHidden() {
- let hidden = false;
- eachComponent(this.component.components, (component) => {
- if (
- (component.type === 'button') &&
- ((component.action === 'submit') || !component.action)
- ) {
- hidden = component.hidden || false;
- }
- });
-
- return hidden;
- }
-}
-
-/**
- * Listen for window messages.
- */
-if (typeof window !== 'undefined') {
- window.addEventListener('message', (event) => {
- let eventData = null;
- try {
- eventData = JSON.parse(event.data);
- }
- catch (err) {
- eventData = null;
- }
-
- // If this form exists, then emit the event within this form.
- if (
- eventData &&
- eventData.name &&
- eventData.formId &&
- Formio.forms.hasOwnProperty(eventData.formId)
- ) {
- Formio.forms[eventData.formId].emit(`iframe-${eventData.name}`, eventData.data);
- }
- });
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.js b/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.js
deleted file mode 100644
index 50277207..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.js
+++ /dev/null
@@ -1,532 +0,0 @@
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-import { GlobalFormio as Formio } from './Formio';
-
-import WebformBuilder from './WebformBuilder';
-import { fastCloneDeep, getElementRect , getBrowserInfo } from './utils/utils';
-import { eachComponent } from './utils/formUtils';
-import BuilderUtils from './utils/builder';
-import PDF from './PDF';
-
-export default class PDFBuilder extends WebformBuilder {
- constructor() {
- let element, options;
- if (arguments[0] instanceof HTMLElement || arguments[1]) {
- element = arguments[0];
- options = arguments[1];
- }
- else {
- options = arguments[0];
- }
-
- // Force superclass to skip the automatic init; we'll trigger it manually
- options.skipInit = true;
- options.display = 'pdf';
-
- if (element) {
- super(element, options);
- }
- else {
- super(options);
- }
-
- this.dragDropEnabled = false;
- }
-
- get defaultGroups() {
- return {
- pdf: {
- title: 'PDF Fields',
- weight: 0,
- default: true,
- components: {
- textfield: true,
- number: true,
- password: true,
- email: true,
- phoneNumber: true,
- currency: true,
- checkbox: true,
- signature: true,
- select: true,
- textarea: true,
- datetime: true,
- file: true,
- htmlelement: true,
- signrequestsignature: true
- }
- },
- basic: false,
- advanced: false,
- layout: false,
- data: false,
- premium: false,
- resource: false
- };
- }
-
- get hasPDF() {
- return _.has(this.webform.form, 'settings.pdf');
- }
-
- get projectUrl() {
- return this.options.projectUrl || Formio.getProjectUrl();
- }
-
- init() {
- this.options.attachMode = 'builder';
- this.webform = this.webform || this.createForm(this.options);
- this.webform.init();
- }
-
- render() {
- const result = this.renderTemplate('pdfBuilder', {
- sidebar: this.renderTemplate('builderSidebar', {
- scrollEnabled: this.sideBarScroll,
- groupOrder: this.groupOrder,
- groupId: `builder-sidebar-${this.id}`,
- groups: this.groupOrder.map((groupKey) => this.renderTemplate('builderSidebarGroup', {
- group: this.groups[groupKey],
- groupKey,
- groupId: `builder-sidebar-${this.id}`,
- subgroups: this.groups[groupKey].subgroups.map((group) => this.renderTemplate('builderSidebarGroup', {
- group,
- groupKey: group.key,
- groupId: `group-container-${groupKey}`,
- subgroups: []
- })),
- })),
- }),
- form: this.hasPDF ?
- this.webform.render() :
- this.renderTemplate('pdfBuilderUpload', {})
- });
-
- return result;
- }
-
- attach(element) {
- // PDF Upload
- if (!this.hasPDF) {
- this.loadRefs(element, {
- 'fileDrop': 'single',
- 'fileBrowse': 'single',
- 'hiddenFileInputElement': 'single',
- 'uploadError': 'single',
- 'uploadProgress': 'single',
- 'uploadProgressWrapper': 'single',
- 'dragDropText': 'single'
- });
- this.addEventListener(this.refs['pdf-upload-button'], 'click', (event) => {
- event.preventDefault();
- });
-
- // Init the upload error.
- if (!this.projectUrl) {
- this.setUploadError('Form options.projectUrl not set. Please set the "projectUrl" property of the options for this form or use Formio.setProjectUrl(). This setting is necessary to upload a pdf background.');
- }
- else {
- this.setUploadError();
- }
-
- if (this.refs.fileDrop) {
- const element = this;
- this.addEventListener(this.refs.fileDrop, 'dragover', function(event) {
- this.className = 'fileSelector fileDragOver';
- event.preventDefault();
- });
- this.addEventListener(this.refs.fileDrop, 'dragleave', function(event) {
- this.className = 'fileSelector';
- event.preventDefault();
- });
- this.addEventListener(this.refs.fileDrop, 'drop', function(event) {
- this.className = 'fileSelector';
- event.preventDefault();
- element.upload(event.dataTransfer.files[0]);
- return false;
- });
- }
-
- if (this.refs.fileBrowse && this.refs.hiddenFileInputElement) {
- this.addEventListener(this.refs.fileBrowse, 'click', (event) => {
- event.preventDefault();
- // There is no direct way to trigger a file dialog. To work around this, create an input of type file and trigger
- // a click event on it.
- if (typeof this.refs.hiddenFileInputElement.trigger === 'function') {
- this.refs.hiddenFileInputElement.trigger('click');
- }
- else {
- this.refs.hiddenFileInputElement.click();
- }
- });
- this.addEventListener(this.refs.hiddenFileInputElement, 'change', () => {
- if (!this.refs.hiddenFileInputElement.value) {
- return;
- }
-
- this.upload(this.refs.hiddenFileInputElement.files[0]);
- this.refs.hiddenFileInputElement.value = '';
- });
- }
-
- return NativePromise.resolve();
- }
-
- // Normal PDF Builder
- return super.attach(element).then(() => {
- this.loadRefs(this.element, {
- iframeDropzone: 'single',
- 'sidebar-container': 'multiple',
- 'sidebar': 'single',
- });
-
- this.afterAttach();
- return this.element;
- });
- }
-
- afterAttach() {
- this.on('saveComponent', (component) => {
- this.webform.postMessage({ name: 'updateElement', data: component });
- });
- this.on('removeComponent', (component) => {
- this.webform.postMessage({ name: 'removeElement', data: component });
- });
- this.initIframeEvents();
- this.updateDropzoneDimensions();
-
- const sidebar = this.refs.sidebar;
- if (sidebar) {
- this.addClass(sidebar, 'disabled');
- this.webform.on('iframe-ready', () => {
- this.pdfLoaded = true;
- this.updateDragAndDrop();
- this.removeClass(sidebar, 'disabled');
- }, true);
- }
- }
-
- upload(file) {
- const formio = new Formio(this.projectUrl);
- if (this.refs.dragDropText) {
- this.refs.dragDropText.style.display = 'none';
- }
- if (this.refs.uploadProgressWrapper) {
- this.refs.uploadProgressWrapper.style.display = 'inherit';
- }
- formio.uploadFile('url', file, file, '', (event) => {
- if (this.refs.uploadProgress) {
- const progress = Math.floor((event.loaded / event.total) * 100);
- this.refs.uploadProgress.style.width = `${progress}%`;
- if (progress > 98) {
- this.refs.uploadProgress.innerHTML = this.t('Converting PDF. Please wait.');
- }
- else {
- this.refs.uploadProgress.innerHTML = `${this.t('Uploading')} ${progress}%`;
- }
- }
- }, `${this.projectUrl}/upload`, {}, 'file')
- .then((result) => {
- let autoConversionComponentsAssigned = false;
-
- if (result.data.formfields?.components && result.data.formfields.components.length) {
- const formInitState = this.webform.form.components[0]?.key === 'submit';
- const wizardInitState = this.webform.form.components[0]?.key === 'page1' &&
- this.webform.form.components[0]?.components.length === 0;
- const emptyFormState = this.webform.form.components.length === 0;
-
- if (formInitState || wizardInitState || emptyFormState) {
- autoConversionComponentsAssigned = true;
- this.webform.form.components = result.data.formfields.components;
- }
- }
- if (this.refs.dragDropText) {
- this.refs.dragDropText.style.display = 'inherit';
- }
- if (this.refs.uploadProgressWrapper) {
- this.refs.uploadProgressWrapper.style.display = 'none';
- }
-
- _.set(this.webform.form, 'settings.pdf', {
- id: result.data.file,
- src: result.data.filesServer ? `${result.data.filesServer}${result.data.path}` : `${new URL(this.projectUrl).origin}/pdf-proxy${result.data.path}`,
- nonFillableConversionUsed: autoConversionComponentsAssigned && result.data.formfields.nonFillableConversionUsed
- });
-
- this.emit('pdfUploaded', result.data);
- this.redraw();
- })
- .catch((err) => this.setUploadError(err));
- }
-
- setUploadError(message) {
- if (!this.refs.uploadError) {
- return;
- }
- this.refs.uploadError.style.display = message ? '' : 'none';
- this.refs.uploadError.innerHTML = message;
- }
-
- createForm(options) {
- // Instantiate the webform from the PDF class instead of Webform
- options.skipInit = false;
- options.hideLoader = true;
- this.webform = new PDF(this.element, options);
- this.webform.on('attach', () => {
- // If the dropzone exists but has been removed in a PDF rebuild, reinstate it
- if (this.refs.iframeDropzone && ![...this.refs.form.children].includes(this.refs.iframeDropzone)) {
- this.prependTo(this.refs.iframeDropzone, this.refs.form);
- }
- });
- return this.webform;
- }
-
- destroy(deleteFromGlobal) {
- super.destroy(deleteFromGlobal);
- this.webform.destroy(deleteFromGlobal);
- }
-
- // d8b 8888888888 888
- // Y8P 888 888
- // 888 888
- // 888 8888888 888d888 8888b. 88888b.d88b. .d88b. .d88b. 888 888 .d88b. 88888b. 888888 .d8888b
- // 888 888 888P" "88b 888 "888 "88b d8P Y8b d8P Y8b 888 888 d8P Y8b 888 "88b 888 88K
- // 888 888 888 .d888888 888 888 888 88888888 88888888 Y88 88P 88888888 888 888 888 "Y8888b.
- // 888 888 888 888 888 888 888 888 Y8b. Y8b. Y8bd8P Y8b. 888 888 Y88b. X88
- // 888 888 888 "Y888888 888 888 888 "Y8888 "Y8888 Y88P "Y8888 888 888 "Y888 88888P'
- getParentContainer(component) {
- let container = [];
- let originalComponent = null;
- eachComponent(this.webform._form.components, (comp, path, components) => {
- if (comp.id === component.component.id) {
- container = components;
- originalComponent = comp;
- return true;
- }
- }, true);
- return {
- formioComponent: component.parent,
- formioContainer: container,
- originalComponent
- };
- }
-
- initIframeEvents() {
- this.webform.off('iframe-elementUpdate');
- this.webform.off('iframe-componentUpdate');
- this.webform.off('iframe-componentClick');
- this.webform.on('iframe-elementUpdate', schema => {
- const component = this.webform.getComponentById(schema.id);
- if (component && component.component) {
- const isNew = true;
- component.component.overlay = {
- page: schema.page,
- left: schema.left,
- top: schema.top,
- height: schema.height,
- width: schema.width
- };
-
- if (!this.options.noNewEdit && !component.component.noNewEdit) {
- this.editComponent(component.component, this.getParentContainer(component), isNew);
- }
- this.emit('updateComponent', component.component);
- }
- return component;
- });
-
- this.webform.on('iframe-componentUpdate', schema => {
- const component = this.webform.getComponentById(schema.id);
- if (component && component.component) {
- component.component.overlay = {
- page: schema.overlay.page,
- left: schema.overlay.left,
- top: schema.overlay.top,
- height: schema.overlay.height,
- width: schema.overlay.width
- };
- this.emit('updateComponent', component.component);
- this.emit('change', this.form);
- }
- return component;
- });
-
- this.webform.on('iframe-componentClick', schema => {
- const component = this.webform.getComponentById(schema.id);
- if (component) {
- this.editComponent(component.component, this.getParentContainer(component));
- }
- }, true);
- }
-
- // 8888888b. 888 d8b
- // 888 "Y88b 888 Y8P
- // 888 888 888
- // 888 888 888d888 .d88b. 88888b. 88888888 .d88b. 88888b. .d88b. 888 .d88b. .d88b. 888 .d8888b
- // 888 888 888P" d88""88b 888 "88b d88P d88""88b 888 "88b d8P Y8b 888 d88""88b d88P"88b 888 d88P"
- // 888 888 888 888 888 888 888 d88P 888 888 888 888 88888888 888 888 888 888 888 888 888
- // 888 .d88P 888 Y88..88P 888 d88P d88P Y88..88P 888 888 Y8b. 888 Y88..88P Y88b 888 888 Y88b.
- // 8888888P" 888 "Y88P" 88888P" 88888888 "Y88P" 888 888 "Y8888 888 "Y88P" "Y88888 888 "Y8888P
- // 888 888
- // 888 Y8b d88P
- // 888 "Y88P"
-
- initDropzoneEvents() {
- if (!this.refs.iframeDropzone) {
- return;
- }
- // This is required per HTML spec in order for the drop event to fire
- this.removeEventListener(this.refs.iframeDropzone, 'dragover');
- this.removeEventListener(this.refs.iframeDropzone, 'drop');
- this.addEventListener(this.refs.iframeDropzone, 'dragover', (e) => {
- e.preventDefault();
- return false;
- });
-
- this.addEventListener(this.refs.iframeDropzone, 'drop', this.onDropzoneDrop.bind(this));
- }
-
- updateDragAndDrop() {
- if (!this.pdfLoaded) {
- return;
- }
- this.initDropzoneEvents();
- this.prepSidebarComponentsForDrag();
- }
-
- prepSidebarComponentsForDrag() {
- if (!this.refs['sidebar-container']) {
- return;
- }
- this.refs['sidebar-container'].forEach(container => {
- [...container.children].forEach(el => {
- el.draggable = true;
- el.setAttribute('draggable', true);
- this.removeEventListener(el, 'dragstart');
- this.removeEventListener(el, 'dragend');
- this.addEventListener(el, 'dragstart', this.onDragStart.bind(this), true);
- this.addEventListener(el, 'dragend', this.onDragEnd.bind(this), true);
- this.addEventListener(el, 'drag', (e) => {
- e.target.style.cursor = 'none';
- });
- });
- });
- }
-
- updateDropzoneDimensions() {
- if (!this.refs.iframeDropzone) {
- return;
- }
-
- const iframeRect = getElementRect(this.webform.refs.iframeContainer);
- this.refs.iframeDropzone.style.height = iframeRect && iframeRect.height ? `${iframeRect.height}px` : '1000px';
- this.refs.iframeDropzone.style.width = iframeRect && iframeRect.width ? `${iframeRect.width}px` : '100%';
- }
-
- onDragStart(e) {
- // Taking the current offset of a dragged item relative to the cursor
- const { offsetX = 0, offsetY = 0 } = e;
- this.itemOffsetX = offsetX;
- this.itemOffsetY = offsetY;
-
- e.dataTransfer.setData('text', '');
- this.updateDropzoneDimensions();
- this.addClass(this.refs.iframeDropzone, 'enabled');
- this.dropEmitted = false;
- }
-
- onDropzoneDrop(e) {
- this.dropEmitted = true;
- this.dropEvent = e;
- e.preventDefault();
- return false;
- }
-
- onDragEnd(e) {
- // IMPORTANT - must retrieve offsets BEFORE disabling the dropzone - offsets will
- // reflect absolute positioning if accessed after the target element is hidden
- const iframeRect = this.webform.refs.iframeContainer.getBoundingClientRect();
- const layerX = this.dropEvent ? this.dropEvent.layerX : null;
- const layerY = this.dropEvent ? this.dropEvent.layerY : null;
- const WIDTH = 100;
- const HEIGHT = 20;
- // Always disable the dropzone on drag end
- this.removeClass(this.refs.iframeDropzone, 'enabled');
-
- // If there hasn't been a drop event on the dropzone, we're done
- if (!this.dropEvent) {
- // a 'drop' event may not be emited in the chrome browser when using a Mac, therefore an additional check has been added
- // eslint-disable-next-line no-undef
- if (!this.dropEmitted && (getBrowserInfo().chrome || getBrowserInfo().edge) && globalThis.navigator.userAgentData.platform === 'macOS' && iframeRect.left < e.clientX && iframeRect.top < e.clientY ) {
- this.dropEvent = e;
- this.dropEvent.dataTransfer.effectAllowed = 'all';
- this.dropEmitted = true;
- }
- else {
- return;
- }
- }
-
- const element = e.target;
- const type = element.getAttribute('data-type');
- const key = element.getAttribute('data-key');
- const group = element.getAttribute('data-group');
- const schema = fastCloneDeep(this.schemas[type]);
-
- if (key && group) {
- const info = this.getComponentInfo(key, group);
- _.merge(schema, info);
- }
-
- // Set a unique key for this component.
- BuilderUtils.uniquify([this.webform._form], schema);
- this.webform._form.components.push(schema);
-
- schema.overlay = {
- top: layerY ? (layerY - this.itemOffsetY + HEIGHT) : (e.clientY - iframeRect.top - (this.itemOffsetY - HEIGHT )*2),
- left: layerX ? (layerX - this.itemOffsetX) : (e.clientX - iframeRect.left - this.itemOffsetX*2),
- width: WIDTH,
- height: HEIGHT
- };
-
- this.webform.addComponent(schema, {}, null, true);
- this.webform.postMessage({ name: 'addElement', data: schema });
-
- this.emit('addComponent', schema, this.webform, schema.key, this.webform.component.components.length, !this.options.noNewEdit && !schema.noNewEdit);
-
- // Delete the stored drop event now that it's been handled
- this.dropEvent = null;
- e.target.style.cursor = 'default';
- }
-
- highlightInvalidComponents() {
- const repeatablePaths = this.findRepeatablePaths();
-
- // update elements which path was duplicated if any pathes have been changed
- if (!_.isEqual(this.repeatablePaths, repeatablePaths)) {
- eachComponent(this.webform.getComponents(), (comp, path) => {
- if (this.repeatablePaths.includes(path)) {
- this.webform.postMessage({ name: 'updateElement', data: comp.component });
- }
- });
-
- this.repeatablePaths = repeatablePaths;
- }
-
- if (!repeatablePaths.length) {
- return;
- }
-
- eachComponent(this.webform.getComponents(), (comp, path) => {
- if (this.repeatablePaths.includes(path)) {
- this.webform.postMessage({
- name: 'showBuilderErrors',
- data: {
- compId: comp.component.id,
- errorMessage: `API Key is not unique: ${comp.key}`,
- }
- });
- }
- });
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.spec.js b/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.spec.js
deleted file mode 100644
index d0ebe9c5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.spec.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import FormBuilder from './FormBuilder';
-
-describe('Formio PDF Form Builder tests', () => {
- it('Should emit change event when component position changed', (done) => {
- const form = {
- 'type': 'form',
- 'components': [
- {
- 'input': true,
- 'label': 'Text',
- 'key': 'text',
- 'type': 'textfield',
- 'overlay': {
- 'top': 135,
- 'left': 211.516,
- 'height': 20,
- 'width': 100,
- 'page': 1
- }
- },
- {
- 'input': true,
- 'label': 'Submit',
- 'key': 'submit',
- 'action': 'submit',
- 'type': 'button'
- }
- ],
- 'display': 'pdf',
- 'name': 'testPdfForm'
- };
- const element = document.createElement('div');
- document.body.appendChild(element);
- const builder = new FormBuilder(element, form, {});
- builder.ready
- .then(function(builder) {
- let isPfdFormInitilized = false;
- builder.on('change', function() {
- if (isPfdFormInitilized) { //ignore any change events fired before initialized event
- //remove builder elements from DOM
- builder.destroy();
- try {
- document.body.removeChild(element);
- }
- catch (err) {
- console.warn(err);
- }
- done();
- }
- else {
- done();
- }
- });
- builder.pdfForm.on('initialized', () => {
- isPfdFormInitilized = true;
- const component = Object.assign({}, builder.pdfForm.getComponent('text').component);
- component.overlay = { 'top': 225, 'left': 405.516, 'height': 20, 'width': 100, 'page': 1 };
- builder.pdfForm.emit('iframe-componentUpdate', component);
- });
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.unit.js b/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.unit.js
deleted file mode 100644
index 404e0ca5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/PDFBuilder.unit.js
+++ /dev/null
@@ -1,192 +0,0 @@
-import { fake } from 'sinon';
-import { expect } from 'chai';
-
-import { GlobalFormio as Formio } from './Formio';
-import FormBuilder from './FormBuilder';
-
-describe('PDF Builder tests', () => {
- describe('PDF Auto Conversion', () => {
- const originalUploadFile = Formio.prototype.uploadFile;
- const originalLoadProject = Formio.prototype.loadProject;
-
- after(() => {
- Formio.prototype.uploadFile = originalUploadFile;
- Formio.prototype.loadProject = originalLoadProject;
- });
-
- beforeEach(() => {
- Formio.prototype.loadProject = fake.resolves(null);
- });
-
- const getUploadResponseMock = (withNonFillable) => ({
- data: {
- file: 'fileId',
- filesServer: 'http://fakeserver.test',
- path: '/path/to/pdf/file',
- formfields: {
- components: [
- {
- input: true,
- label: 'Test',
- key: 'testTextField',
- type: 'textfield',
- overlay: {
- top: 135,
- left: 211.516,
- height: 20,
- width: 100,
- page: 1,
- },
- },
- ],
- ...(withNonFillable && { nonFillableConversionUsed: true })
- },
- },
- });
-
- it('Should assign fields from PDF auto conversion to the empty form', (done) => {
- const uploadResponseMock = getUploadResponseMock();
-
- Formio.prototype.uploadFile = fake.resolves(uploadResponseMock);
-
- const form = {
- type: 'form',
- components: [],
- display: 'pdf',
- name: 'testPdfForm',
- };
- const builder = new FormBuilder(document.createElement('div'), form, {});
-
- builder.ready
- .then(function(builder) {
- builder.on('pdfUploaded', (result) => {
- expect(result).to.be.deep.equal(uploadResponseMock.data);
- expect(builder.webform.form.components).to.be.deep.equal(uploadResponseMock.data.formfields.components);
- expect(builder.webform.form.settings.pdf.nonFillableConversionUsed).to.be.undefined;
-
- done();
- });
-
- builder.upload();
- });
- });
-
- it('Should assign fields from PDF auto conversion to the initial form', (done) => {
- const uploadResponseMock = getUploadResponseMock();
-
- Formio.prototype.uploadFile = fake.resolves(uploadResponseMock);
-
- const form = {
- type: 'form',
- components: [
- {
- input: true,
- label: 'Submit',
- key: 'submit',
- action: 'submit',
- type: 'button',
- },
- ],
- display: 'pdf',
- name: 'testPdfForm',
- };
- const builder = new FormBuilder(document.createElement('div'), form, {});
-
- builder.ready
- .then(function(builder) {
- builder.on('pdfUploaded', (result) => {
- expect(result).to.be.deep.equal(uploadResponseMock.data);
- expect(builder.webform.form.components).to.be.deep.equal(uploadResponseMock.data.formfields.components);
- expect(builder.webform.form.settings.pdf.nonFillableConversionUsed).to.be.undefined;
-
- done();
- });
-
- builder.upload();
- });
- });
-
- it('Should assign fields from PDF non fillable conversion to the initial form', (done) => {
- const uploadResponseMock = getUploadResponseMock(true);
-
- Formio.prototype.uploadFile = fake.resolves(uploadResponseMock);
-
- const form = {
- type: 'form',
- components: [
- {
- input: true,
- label: 'Submit',
- key: 'submit',
- action: 'submit',
- type: 'button',
- },
- ],
- display: 'pdf',
- name: 'testPdfForm',
- };
- const builder = new FormBuilder(document.createElement('div'), form, {});
-
- builder.ready
- .then(function(builder) {
- builder.on('pdfUploaded', (result) => {
- expect(result).to.be.deep.equal(uploadResponseMock.data);
- expect(builder.webform.form.components).to.be.deep.equal(uploadResponseMock.data.formfields.components);
- expect(builder.webform.form.settings.pdf.nonFillableConversionUsed).to.be.true;
-
- done();
- });
-
- builder.upload();
- });
- });
-
- it('Should not assign fields from PDF auto conversion to non pristine form', (done) => {
- const uploadResponseMock = getUploadResponseMock(true);
-
- Formio.prototype.uploadFile = fake.resolves(uploadResponseMock);
-
- const form = {
- type: 'form',
- components: [
- {
- input: true,
- label: 'Text Field',
- key: 'textField',
- type: 'textfield',
- overlay: {
- top: 135,
- left: 211.516,
- height: 20,
- width: 100,
- page: 1,
- },
- },
- {
- input: true,
- label: 'Submit',
- key: 'submit',
- action: 'submit',
- type: 'button',
- },
- ],
- display: 'pdf',
- name: 'testPdfForm',
- };
- const builder = new FormBuilder(document.createElement('div'), form, {});
-
- builder.ready
- .then(function(builder) {
- builder.on('pdfUploaded', (result) => {
- expect(result).to.be.deep.equal(uploadResponseMock.data);
- expect(builder.webform.form.components).to.be.deep.equal(form.components);
- expect(builder.webform.form.settings.pdf.nonFillableConversionUsed).to.be.false;
-
- done();
- });
-
- builder.upload();
- });
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/Webform.js b/web-client/core/themes/italia/static/formio/css/src/Webform.js
deleted file mode 100644
index 1e480694..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Webform.js
+++ /dev/null
@@ -1,1713 +0,0 @@
-import _ from 'lodash';
-import moment from 'moment';
-import compareVersions from 'compare-versions';
-import EventEmitter from './EventEmitter';
-import i18next from 'i18next';
-import i18nDefaults from './i18n';
-import { GlobalFormio as Formio } from './Formio';
-import NativePromise from 'native-promise-only';
-import Components from './components/Components';
-import NestedDataComponent from './components/_classes/nesteddata/NestedDataComponent';
-import {
- fastCloneDeep,
- currentTimezone,
- unescapeHTML,
- getStringFromComponentPath,
- searchComponents,
- convertStringToHTMLElement,
- getArrayFromComponentPath
-} from './utils/utils';
-import { eachComponent } from './utils/formUtils';
-
-// Initialize the available forms.
-Formio.forms = {};
-
-// Allow people to register components.
-Formio.registerComponent = Components.setComponent;
-
-function getIconSet(icons) {
- if (icons === 'fontawesome') {
- return 'fa';
- }
- return icons || '';
-}
-
-function getOptions(options) {
- options = _.defaults(options, {
- submitOnEnter: false,
- iconset: getIconSet((options && options.icons) ? options.icons : Formio.icons),
- i18next,
- saveDraft: false,
- alwaysDirty: false,
- saveDraftThrottle: 5000,
- display: 'form',
- cdnUrl: Formio.cdn.baseUrl
- });
- if (!options.events) {
- options.events = new EventEmitter();
- }
- return options;
-}
-
-/**
- * Renders a Form.io form within the webpage.
- */
-export default class Webform extends NestedDataComponent {
- /**
- * Creates a new Form instance.
- *
- * @param {Object} options - The options to create a new form instance.
- * @param {boolean} options.saveDraft - Set this if you would like to enable the save draft feature.
- * @param {boolean} options.saveDraftThrottle - The throttle for the save draft feature.
- * @param {boolean} options.readOnly - Set this form to readOnly
- * @param {boolean} options.noAlerts - Set to true to disable the alerts dialog.
- * @param {boolean} options.i18n - The translation file for this rendering. @see https://github.com/formio/formio.js/blob/master/i18n.js
- * @param {boolean} options.template - Provides a way to inject custom logic into the creation of every element rendered within the form.
- */
- /* eslint-disable max-statements */
- constructor() {
- let element, options;
- if (arguments[0] instanceof HTMLElement || arguments[1]) {
- element = arguments[0];
- options = arguments[1];
- }
- else {
- options = arguments[0];
- }
- super(null, getOptions(options));
-
- this.element = element;
-
- // Keep track of all available forms globally.
- Formio.forms[this.id] = this;
-
- // Set the base url.
- if (this.options.baseUrl) {
- Formio.setBaseUrl(this.options.baseUrl);
- }
-
- /**
- * The i18n configuration for this component.
- */
- let i18n = i18nDefaults;
- if (options && options.i18n && !options.i18nReady) {
- // Support legacy way of doing translations.
- if (options.i18n.resources) {
- i18n = options.i18n;
- }
- else {
- _.each(options.i18n, (lang, code) => {
- if (code === 'options') {
- _.merge(i18n, lang);
- }
- else if (!i18n.resources[code]) {
- // extend the default translations (validations, buttons etc.) in case they are not in the options.
- i18n.resources[code] = { translation: _.assign(fastCloneDeep(i18nDefaults.resources.en.translation), lang) };
- }
- else {
- _.assign(i18n.resources[code].translation, lang);
- }
- });
- }
-
- options.i18n = i18n;
- options.i18nReady = true;
- }
-
- if (options && options.i18n) {
- this.options.i18n = options.i18n;
- }
- else {
- this.options.i18n = i18n;
- }
-
- // Set the language.
- if (this.options.language) {
- this.options.i18n.lng = this.options.language;
- }
-
- /**
- * The type of this element.
- * @type {string}
- */
- this.type = 'form';
- this._src = '';
- this._loading = false;
- this._form = {};
- this.draftEnabled = false;
- this.savingDraft = true;
- if (this.options.saveDraftThrottle) {
- this.triggerSaveDraft = _.throttle(this.saveDraft.bind(this), this.options.saveDraftThrottle);
- }
- else {
- this.triggerSaveDraft = this.saveDraft.bind(this);
- }
-
- this.customErrors = [];
-
- /**
- * Determines if this form should submit the API on submit.
- * @type {boolean}
- */
- this.nosubmit = false;
-
- /**
- * Determines if the form has tried to be submitted, error or not.
- *
- * @type {boolean}
- */
- this.submitted = false;
-
- /**
- * Determines if the form is being submitted at the moment.
- *
- * @type {boolean}
- */
- this.submitting = false;
-
- /**
- * The Formio instance for this form.
- * @type {Formio}
- */
- this.formio = null;
-
- /**
- * The loader HTML element.
- * @type {HTMLElement}
- */
- this.loader = null;
-
- /**
- * The alert HTML element
- * @type {HTMLElement}
- */
- this.alert = null;
-
- /**
- * Promise that is triggered when the submission is done loading.
- * @type {Promise}
- */
- this.onSubmission = null;
-
- /**
- * Determines if this submission is explicitly set.
- * @type {boolean}
- */
- this.submissionSet = false;
-
- /**
- * Promise that executes when the form is ready and rendered.
- * @type {Promise}
- *
- * @example
- * import Webform from 'formiojs/Webform';
- * let form = new Webform(document.getElementById('formio'));
- * form.formReady.then(() => {
- * console.log('The form is ready!');
- * });
- * form.src = 'https://examples.form.io/example';
- */
- this.formReady = new NativePromise((resolve, reject) => {
- /**
- * Called when the formReady state of this form has been resolved.
- *
- * @type {function}
- */
- this.formReadyResolve = resolve;
-
- /**
- * Called when this form could not load and is rejected.
- *
- * @type {function}
- */
- this.formReadyReject = reject;
- });
-
- /**
- * Promise that executes when the submission is ready and rendered.
- * @type {Promise}
- *
- * @example
- * import Webform from 'formiojs/Webform';
- * let form = new Webform(document.getElementById('formio'));
- * form.submissionReady.then(() => {
- * console.log('The submission is ready!');
- * });
- * form.src = 'https://examples.form.io/example/submission/234234234234234243';
- */
- this.submissionReady = new NativePromise((resolve, reject) => {
- /**
- * Called when the formReady state of this form has been resolved.
- *
- * @type {function}
- */
- this.submissionReadyResolve = resolve;
-
- /**
- * Called when this form could not load and is rejected.
- *
- * @type {function}
- */
- this.submissionReadyReject = reject;
- });
-
- this.shortcuts = [];
-
- // Set language after everything is established.
- this.localize().then(() => {
- this.language = this.options.language;
- });
-
- // See if we need to restore the draft from a user.
- if (this.options.saveDraft && !this.options.skipDraftRestore) {
- this.formReady.then(()=> {
- const user = Formio.getUser();
- // Only restore a draft if the submission isn't explicitly set.
- if (user && !this.submissionSet) {
- this.restoreDraft(user._id);
- }
- });
- }
-
- this.component.clearOnHide = false;
-
- // Ensure the root is set to this component.
- this.root = this;
- this.localRoot = this;
- }
- /* eslint-enable max-statements */
-
- get language() {
- return this.options.language;
- }
-
- get emptyValue() {
- return null;
- }
-
- componentContext() {
- return this._data;
- }
-
- /**
- * Sets the language for this form.
- *
- * @param lang
- * @return {Promise}
- */
- set language(lang) {
- this.options.language = lang;
- if (this.i18next.language === lang) {
- return;
- }
- try {
- this.i18next.changeLanguage(lang, (err) => {
- if (err) {
- return;
- }
- this.rebuild();
- this.emit('languageChanged');
- });
- }
- catch (err) {
- return;
- }
- }
-
- get componentComponents() {
- return this.form.components;
- }
-
- get shadowRoot() {
- return this.options.shadowRoot;
- }
-
- /**
- * Add a language for translations
- *
- * @param code
- * @param lang
- * @param active
- * @return {*}
- */
- addLanguage(code, lang, active = false) {
- var translations = _.assign(fastCloneDeep(i18nDefaults.resources.en.translation), lang);
- this.i18next.addResourceBundle(code, 'translation', translations, true, true);
- if (active) {
- this.language = code;
- }
- }
-
- /**
- * Perform the localization initialization.
- * @returns {*}
- */
- localize() {
- if (this.i18next.initialized) {
- return NativePromise.resolve(this.i18next);
- }
- this.i18next.initialized = true;
- return new NativePromise((resolve, reject) => {
- try {
- this.i18next.init({
- ...this.options.i18n,
- ...{ compatibilityJSON: 'v3' }
- }, (err) => {
- // Get language but remove any ;q=1 that might exist on it.
- this.options.language = this.i18next.language.split(';')[0];
- if (err) {
- return reject(err);
- }
- resolve(this.i18next);
- });
- }
- catch (err) {
- return reject(err);
- }
- });
- }
-
- keyboardCatchableElement(element) {
- if (element.nodeName === 'TEXTAREA') {
- return false;
- }
-
- if (element.nodeName === 'INPUT') {
- return [
- 'text',
- 'email',
- 'password'
- ].indexOf(element.type) === -1;
- }
-
- return true;
- }
-
- executeShortcuts = (event) => {
- const { target } = event;
- if (!this.keyboardCatchableElement(target)) {
- return;
- }
-
- const ctrl = event.ctrlKey || event.metaKey;
- const keyCode = event.keyCode;
- let char = '';
-
- if (65 <= keyCode && keyCode <= 90) {
- char = String.fromCharCode(keyCode);
- }
- else if (keyCode === 13) {
- char = 'Enter';
- }
- else if (keyCode === 27) {
- char = 'Esc';
- }
-
- _.each(this.shortcuts, (shortcut) => {
- if (shortcut.ctrl && !ctrl) {
- return;
- }
-
- if (shortcut.shortcut === char) {
- shortcut.element.click();
- event.preventDefault();
- }
- });
- };
-
- addShortcut(element, shortcut) {
- if (!shortcut || !/^([A-Z]|Enter|Esc)$/i.test(shortcut)) {
- return;
- }
-
- shortcut = _.capitalize(shortcut);
-
- if (shortcut === 'Enter' || shortcut === 'Esc') {
- // Restrict Enter and Esc only for buttons
- if (element.tagName !== 'BUTTON') {
- return;
- }
-
- this.shortcuts.push({
- shortcut,
- element
- });
- }
- else {
- this.shortcuts.push({
- ctrl: true,
- shortcut,
- element
- });
- }
- }
-
- removeShortcut(element, shortcut) {
- if (!shortcut || !/^([A-Z]|Enter|Esc)$/i.test(shortcut)) {
- return;
- }
-
- _.remove(this.shortcuts, {
- shortcut,
- element
- });
- }
-
- /**
- * Get the embed source of the form.
- *
- * @returns {string}
- */
- get src() {
- return this._src;
- }
-
- /**
- * Loads the submission if applicable.
- */
- loadSubmission() {
- this.loadingSubmission = true;
- if (this.formio.submissionId) {
- this.onSubmission = this.formio.loadSubmission().then(
- (submission) => this.setSubmission(submission),
- (err) => this.submissionReadyReject(err)
- ).catch(
- (err) => this.submissionReadyReject(err)
- );
- }
- else {
- this.submissionReadyResolve();
- }
- return this.submissionReady;
- }
-
- /**
- * Set the src of the form renderer.
- *
- * @param value
- * @param options
- */
- setSrc(value, options) {
- if (this.setUrl(value, options)) {
- this.nosubmit = false;
- return this.formio.loadForm({ params: { live: 1 } }).then(
- (form) => {
- const setForm = this.setForm(form);
- this.loadSubmission();
-
- return setForm;
- }).catch((err) => {
- console.warn(err);
- this.formReadyReject(err);
- });
- }
- return NativePromise.resolve();
- }
-
- /**
- * Set the Form source, which is typically the Form.io embed URL.
- *
- * @param {string} value - The value of the form embed url.
- *
- * @example
- * import Webform from 'formiojs/Webform';
- * let form = new Webform(document.getElementById('formio'));
- * form.formReady.then(() => {
- * console.log('The form is formReady!');
- * });
- * form.src = 'https://examples.form.io/example';
- */
- set src(value) {
- this.setSrc(value);
- }
-
- /**
- * Get the embed source of the form.
- *
- * @returns {string}
- */
- get url() {
- return this._src;
- }
-
- /**
- * Sets the url of the form renderer.
- *
- * @param value
- * @param options
- */
- setUrl(value, options) {
- if (
- !value ||
- (typeof value !== 'string') ||
- (value === this._src)
- ) {
- return false;
- }
- this._src = value;
- this.nosubmit = true;
- this.formio = this.options.formio = new Formio(value, options);
-
- if (this.type === 'form') {
- // Set the options source so this can be passed to other components.
- this.options.src = value;
- }
- return true;
- }
-
- /**
- * Set the form source but don't initialize the form and submission from the url.
- *
- * @param {string} value - The value of the form embed url.
- */
- set url(value) {
- this.setUrl(value);
- }
-
- /**
- * Called when both the form and submission have been loaded.
- *
- * @returns {Promise} - The promise to trigger when both form and submission have loaded.
- */
- get ready() {
- return this.formReady.then(() => {
- return super.ready.then(() => {
- return this.loadingSubmission ? this.submissionReady : true;
- });
- });
- }
-
- /**
- * Returns if this form is loading.
- *
- * @returns {boolean} - TRUE means the form is loading, FALSE otherwise.
- */
- get loading() {
- return this._loading;
- }
-
- /**
- * Set the loading state for this form, and also show the loader spinner.
- *
- * @param {boolean} loading - If this form should be "loading" or not.
- */
- set loading(loading) {
- if (this._loading !== loading) {
- this._loading = loading;
- if (!this.loader && loading) {
- this.loader = this.ce('div', {
- class: 'loader-wrapper'
- });
- const spinner = this.ce('div', {
- class: 'loader text-center'
- });
- this.loader.appendChild(spinner);
- }
- /* eslint-disable max-depth */
- if (this.loader) {
- try {
- if (loading) {
- this.prependTo(this.loader, this.wrapper);
- }
- else {
- this.removeChildFrom(this.loader, this.wrapper);
- }
- }
- catch (err) {
- // ingore
- }
- }
- /* eslint-enable max-depth */
- }
- }
-
- /**
- * Sets the JSON schema for the form to be rendered.
- *
- * @example
- * import Webform from 'formiojs/Webform';
- * let form = new Webform(document.getElementById('formio'));
- * form.setForm({
- * components: [
- * {
- * type: 'textfield',
- * key: 'firstName',
- * label: 'First Name',
- * placeholder: 'Enter your first name.',
- * input: true
- * },
- * {
- * type: 'textfield',
- * key: 'lastName',
- * label: 'Last Name',
- * placeholder: 'Enter your last name',
- * input: true
- * },
- * {
- * type: 'button',
- * action: 'submit',
- * label: 'Submit',
- * theme: 'primary'
- * }
- * ]
- * });
- *
- * @param {Object} form - The JSON schema of the form @see https://examples.form.io/example for an example JSON schema.
- * @param flags
- * @returns {*}
- */
- setForm(form, flags) {
- const isFormAlreadySet = this._form && this._form.components?.length;
- try {
- // Do not set the form again if it has been already set
- if (isFormAlreadySet && JSON.stringify(this._form) === JSON.stringify(form)) {
- return NativePromise.resolve();
- }
-
- // Create the form.
- this._form = flags?.keepAsReference ? form : _.cloneDeep(form);
-
- if (this.onSetForm) {
- this.onSetForm(_.cloneDeep(this._form), form);
- }
-
- if (this.parent?.component?.modalEdit) {
- return NativePromise.resolve();
- }
- }
- catch (err) {
- console.warn(err);
- // If provided form is not a valid JSON object, do not set it too
- return NativePromise.resolve();
- }
-
- // Allow the form to provide component overrides.
- if (form && form.settings && form.settings.components) {
- this.options.components = form.settings.components;
- }
-
- if (form && form.properties) {
- this.options.properties = form.properties;
- }
-
- if ('schema' in form && compareVersions(form.schema, '1.x') > 0) {
- this.ready.then(() => {
- this.setAlert('alert alert-danger', 'Form schema is for a newer version, please upgrade your renderer. Some functionality may not work.');
- });
- }
-
- // See if they pass a module, and evaluate it if so.
- if (form && form.module) {
- let formModule = null;
- if (typeof form.module === 'string') {
- try {
- formModule = this.evaluate(`return ${form.module}`);
- }
- catch (err) {
- console.warn(err);
- }
- }
- else {
- formModule = form.module;
- }
- if (formModule) {
- Formio.use(formModule);
-
- // Since we got here after instantiation, we need to manually apply form options.
- if (formModule.options && formModule.options.form) {
- this.options = Object.assign(this.options, formModule.options.form);
- }
- }
- }
-
- this.initialized = false;
- const rebuild = this.rebuild() || NativePromise.resolve();
- return rebuild.then(() => {
- this.emit('formLoad', form);
- this.triggerRecaptcha();
- // Make sure to trigger onChange after a render event occurs to speed up form rendering.
- setTimeout(() => {
- this.onChange(flags);
- this.formReadyResolve();
- }, 0);
-
- return this.formReady;
- });
- }
-
- /**
- * Gets the form object.
- *
- * @returns {Object} - The form JSON schema.
- */
- get form() {
- if (!this._form) {
- this._form = {
- components: []
- };
- }
- return this._form;
- }
-
- /**
- * Sets the form value.
- *
- * @alias setForm
- * @param {Object} form - The form schema object.
- */
- set form(form) {
- this.setForm(form);
- }
-
- /**
- * Returns the submission object that was set within this form.
- *
- * @returns {Object}
- */
- get submission() {
- return this.getValue();
- }
-
- /**
- * Sets the submission of a form.
- *
- * @example
- * import Webform from 'formiojs/Webform';
- * let form = new Webform(document.getElementById('formio'));
- * form.src = 'https://examples.form.io/example';
- * form.submission = {data: {
- * firstName: 'Joe',
- * lastName: 'Smith',
- * email: 'joe@example.com'
- * }};
- *
- * @param {Object} submission - The Form.io submission object.
- */
- set submission(submission) {
- this.setSubmission(submission);
- }
-
- /**
- * Sets a submission and returns the promise when it is ready.
- * @param submission
- * @param flags
- * @return {Promise.}
- */
- setSubmission(submission, flags = {}) {
- flags = {
- ...flags,
- fromSubmission: _.has(flags, 'fromSubmission') ? flags.fromSubmission : true,
- };
- return this.onSubmission = this.formReady.then(
- (resolveFlags) => {
- if (resolveFlags) {
- flags = {
- ...flags,
- ...resolveFlags
- };
- }
- this.submissionSet = true;
- this.triggerChange(flags);
- this.emit('beforeSetSubmission', submission);
- this.setValue(submission, flags);
- return this.submissionReadyResolve(submission);
- },
- (err) => this.submissionReadyReject(err)
- ).catch(
- (err) => this.submissionReadyReject(err)
- );
- }
-
- handleDraftError(errName, errDetails, restoreDraft) {
- const errorMessage = _.trim(`${this.t(errName)} ${errDetails || ''}`);
- console.warn(errorMessage);
- this.emit(restoreDraft ? 'restoreDraftError' : 'saveDraftError', errDetails || errorMessage);
- }
-
- /**
- * Saves a submission draft.
- */
- saveDraft() {
- if (!this.draftEnabled) {
- return;
- }
- if (!this.formio) {
- this.handleDraftError('saveDraftInstanceError');
- return;
- }
- if (!Formio.getUser()) {
- this.handleDraftError('saveDraftAuthError');
- return;
- }
- const draft = fastCloneDeep(this.submission);
- draft.state = 'draft';
-
- if (!this.savingDraft) {
- this.emit('saveDraftBegin');
- this.savingDraft = true;
- this.formio.saveSubmission(draft).then((sub) => {
- // Set id to submission to avoid creating new draft submission
- this.submission._id = sub._id;
- this.savingDraft = false;
- this.emit('saveDraft', sub);
- })
- .catch(err => {
- this.savingDraft = false;
- this.handleDraftError('saveDraftError', err);
- });
- }
- }
-
- /**
- * Restores a draft submission based on the user who is authenticated.
- *
- * @param {userId} - The user id where we need to restore the draft from.
- */
- restoreDraft(userId) {
- if (!this.formio) {
- this.handleDraftError('restoreDraftInstanceError', null, true);
- return;
- }
- this.savingDraft = true;
- this.formio.loadSubmissions({
- params: {
- state: 'draft',
- owner: userId
- }
- }).then(submissions => {
- if (submissions.length > 0 && !this.options.skipDraftRestore) {
- const draft = fastCloneDeep(submissions[0]);
- return this.setSubmission(draft).then(() => {
- this.draftEnabled = true;
- this.savingDraft = false;
- this.emit('restoreDraft', draft);
- });
- }
- // Enable drafts so that we can keep track of changes.
- this.draftEnabled = true;
- this.savingDraft = false;
- this.emit('restoreDraft', null);
- })
- .catch(err => {
- this.draftEnabled = true;
- this.savingDraft = false;
- this.handleDraftError('restoreDraftError', err, true);
- });
- }
-
- get schema() {
- const schema = fastCloneDeep(_.omit(this._form, ['components']));
- schema.components = [];
- this.eachComponent((component) => schema.components.push(component.schema));
- return schema;
- }
-
- mergeData(_this, _that) {
- _.mergeWith(_this, _that, (thisValue, thatValue) => {
- if (Array.isArray(thisValue) && Array.isArray(thatValue) && thisValue.length !== thatValue.length) {
- return thatValue;
- }
- });
- }
-
- setValue(submission, flags = {}) {
- if (!submission || !submission.data) {
- submission = { data: {} };
- }
- // Metadata needs to be available before setValue
- this._submission.metadata = submission.metadata || {};
- this.editing = !!submission._id;
-
- // Set the timezone in the options if available.
- if (
- !this.options.submissionTimezone &&
- submission.metadata &&
- submission.metadata.timezone
- ) {
- this.options.submissionTimezone = submission.metadata.timezone;
- }
-
- const changed = super.setValue(submission.data, flags);
- if (!flags.sanitize) {
- this.mergeData(this.data, submission.data);
- }
-
- submission.data = this.data;
- this._submission = submission;
- return changed;
- }
-
- getValue() {
- if (!this._submission.data) {
- this._submission.data = {};
- }
- if (this.viewOnly) {
- return this._submission;
- }
- const submission = this._submission;
- submission.data = this.data;
- return this._submission;
- }
-
- /**
- * Build the form.
- */
- init() {
- this._submission = this._submission || { data: {} };
-
- // Remove any existing components.
- if (this.components && this.components.length) {
- this.destroyComponents();
- this.components = [];
- }
-
- if (this.component) {
- this.component.components = this.form ? this.form.components : [];
- }
- else {
- this.component = this.form;
- }
- this.component.type = 'form';
- this.component.input = false;
-
- this.addComponents();
- this.on('submitButton', options => {
- this.submit(false, options).catch(e => e !== false && console.log(e));
- }, true);
-
- this.on('checkValidity', (data) => this.checkValidity(data, true, data), true);
- this.on('requestUrl', (args) => (this.submitUrl(args.url,args.headers)), true);
- this.on('resetForm', () => this.resetValue(), true);
- this.on('deleteSubmission', () => this.deleteSubmission(), true);
- this.on('refreshData', () => this.updateValue(), true);
-
- this.executeFormController();
-
- return this.formReady;
- }
-
- executeFormController() {
- // If no controller value or
- // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
- if (
- !this.form || !this.form.controller
- || ((!this.visible || this.component.hidden) && this.component.clearOnHide && !this.rootPristine)
- ) {
- return false;
- }
-
- this.formReady.then(() => {
- this.evaluate(this.form.controller, {
- components: this.components,
- instance: this,
- });
- });
- }
-
- destroy(deleteFromGlobal = false) {
- this.off('submitButton');
- this.off('checkValidity');
- this.off('requestUrl');
- this.off('resetForm');
- this.off('deleteSubmission');
- this.off('refreshData');
-
- if (deleteFromGlobal) {
- this.emit('formDelete', this.id);
- delete Formio.forms[this.id];
- }
-
- return super.destroy();
- }
-
- build(element) {
- if (element || this.element) {
- return this.ready.then(() => {
- element = element || this.element;
- super.build(element);
- });
- }
- return this.ready;
- }
-
- getClassName() {
- let classes = 'formio-form';
- if (this.options.readOnly) {
- classes += ' formio-read-only';
- }
- return classes;
- }
-
- render() {
- return super.render(this.renderTemplate('webform', {
- classes: this.getClassName(),
- children: this.renderComponents(),
- }), this.builderMode ? 'builder' : 'form', true);
- }
-
- redraw() {
- // Don't bother if we have not built yet.
- if (!this.element) {
- return NativePromise.resolve();
- }
- this.clear();
- this.setContent(this.element, this.render());
- return this.attach(this.element);
- }
-
- attach(element) {
- this.element = element;
- this.loadRefs(element, { webform: 'single' });
- const childPromise = this.attachComponents(this.refs.webform);
- this.addEventListener(document, 'keydown', this.executeShortcuts);
- this.currentForm = this;
- this.hook('attachWebform', element, this);
- return childPromise.then(() => {
- this.emit('render', this.element);
-
- return this.setValue(this._submission, {
- noUpdateEvent: true,
- });
- });
- }
-
- hasRequiredFields() {
- let result = false;
-
- eachComponent(this.form.components, (component) => {
- if (component.validate.required) {
- result = true;
- return true;
- }
- }, true);
-
- return result;
- }
-
- resetValue() {
- _.each(this.getComponents(), (comp) => (comp.resetValue()));
- this.setPristine(true);
- this.onChange({ resetValue: true });
- }
-
- /**
- * Sets a new alert to display in the error dialog of the form.
- *
- * @param {string} type - The type of alert to display. "danger", "success", "warning", etc.
- * @param {string} message - The message to show in the alert.
- * @param {Object} options
- */
- setAlert(type, message, options) {
- if (!type && this.submitted) {
- if (this.alert) {
- if (this.refs.errorRef && this.refs.errorRef.length) {
- this.refs.errorRef.forEach(el => {
- this.removeEventListener(el, 'click');
- this.removeEventListener(el, 'keypress');
- });
- }
- this.removeChild(this.alert);
- this.alert = null;
- }
- return;
- }
- if (this.options.noAlerts) {
- if (!message) {
- this.emit('error', false);
- }
- return;
- }
- if (this.alert) {
- try {
- if (this.refs.errorRef && this.refs.errorRef.length) {
- this.refs.errorRef.forEach(el => {
- this.removeEventListener(el, 'click');
- this.removeEventListener(el, 'keypress');
- });
- }
- this.removeChild(this.alert);
- this.alert = null;
- }
- catch (err) {
- // ignore
- }
- }
- if (message) {
- const attrs = {
- class: (options && options.classes) || `alert alert-${type}`,
- id: `error-list-${this.id}`,
- };
-
- const templateOptions = {
- message: message instanceof HTMLElement ? message.outerHTML : message,
- attrs: attrs,
- type
- };
-
- this.alert = convertStringToHTMLElement(this.renderTemplate('alert', templateOptions),`#${attrs.id}`);
- }
- if (!this.alert) {
- return;
- }
-
- this.loadRefs(this.alert, { errorRef: 'multiple' });
-
- if (this.refs.errorRef && this.refs.errorRef.length) {
- this.refs.errorRef.forEach(el => {
- this.addEventListener(el, 'click', (e) => {
- const key = e.currentTarget.dataset.componentKey;
- this.focusOnComponent(key);
- });
- this.addEventListener(el, 'keydown', (e) => {
- if (e.keyCode === 13) {
- e.preventDefault();
- const key = e.currentTarget.dataset.componentKey;
- this.focusOnComponent(key);
- }
- });
- });
- }
- this.prepend(this.alert);
- }
-
- /**
- * Focus on selected component.
- *
- * @param {string} key - The key of selected component.
- * @returns {*}
- */
- focusOnComponent(key) {
- if (key) {
- const component = this.getComponent(key);
- if (component) {
- component.focus();
- }
- }
- }
-
- /**
- * Show the errors of this form within the alert dialog.
- *
- * @param {Object} error - An optional additional error to display along with the component errors.
- * @returns {*}
- */
- /* eslint-disable no-unused-vars */
- showErrors(error, triggerEvent, onChange) {
- this.loading = false;
- let errors = this.errors;
- if (error) {
- if (Array.isArray(error)) {
- errors = errors.concat(error);
- }
- else {
- errors.push(error);
- }
- }
- else {
- errors = super.errors;
- }
-
- errors = errors.concat(this.customErrors);
- errors = errors.concat(this.serverErrors || []);
-
- if (!errors.length) {
- this.setAlert(false);
- return;
- }
-
- // Mark any components as invalid if in a custom message.
- errors.forEach((err) => {
- const { components = [] } = err;
-
- if (err.component) {
- components.push(err.component);
- }
-
- if (err.path) {
- components.push(err.path);
- }
-
- components.forEach((path) => {
- const originalPath = this._parentPath + getStringFromComponentPath(path);
- const component = this.getComponent(path, _.identity, originalPath);
-
- if (err.fromServer) {
- if (component.serverErrors) {
- component.serverErrors.push(err);
- }
- else {
- component.serverErrors = [err];
- }
- }
- const components = _.compact(Array.isArray(component) ? component : [component]);
-
- components.forEach((component) => component.setCustomValidity(err.message, true));
- });
- });
-
- const displayedErrors = [];
-
- errors.forEach(err => {
- if (err) {
- const createListItem = (message, index) => {
- const messageFromIndex = !_.isUndefined(index) && err.messages && err.messages[index];
- const keyOrPath = (messageFromIndex && messageFromIndex.formattedKeyOrPath || messageFromIndex.path) || (err.component && err.component.key) || err.fromServer && err.path;
-
- let formattedKeyOrPath = keyOrPath ? getStringFromComponentPath(keyOrPath) : '';
- formattedKeyOrPath = this._parentPath + formattedKeyOrPath;
- if (typeof err !== 'string' && !err.formattedKeyOrPath) {
- err.formattedKeyOrPath = formattedKeyOrPath;
- }
-
- return {
- message: unescapeHTML(message),
- keyOrPath: formattedKeyOrPath
- };
- };
-
- err.messages = _.uniqBy(err.messages, message => message.message);
-
- if (err.messages && err.messages.length) {
- const { component } = err;
- err.messages.forEach(({ message, context, fromServer }, index) => {
- const text = context?.hasLabel || fromServer
- ? this.t('alertMessage', { message: this.t(message) })
- : this.t('alertMessageWithLabel', {
- label: this.t(component.label),
- message: this.t(message),
- });
- displayedErrors.push(createListItem(text, index));
- });
- }
- else if (err) {
- const message = _.isObject(err)
- ? this.t('alertMessage', { message: this.t(err.message || '') })
- : this.t('alertMessage', { message: this.t(err) });
- displayedErrors.push(createListItem(message));
- }
- }
- });
-
- const errorsList = this.renderTemplate('errorsList', { errors: displayedErrors });
- this.root.setAlert('danger', errorsList);
-
- if (triggerEvent) {
- this.emit('error', errors);
- }
-
- return errors;
- }
- /* eslint-enable no-unused-vars */
-
- /**
- * Called when the submission has completed, or if the submission needs to be sent to an external library.
- *
- * @param {Object} submission - The submission object.
- * @param {boolean} saved - Whether or not this submission was saved to the server.
- * @returns {object} - The submission object.
- */
- onSubmit(submission, saved) {
- this.loading = false;
- this.submitting = false;
- this.setPristine(true);
- // We want to return the submitted submission and setValue will mutate the submission so cloneDeep it here.
- this.setValue(fastCloneDeep(submission), {
- noValidate: true,
- noCheck: true
- });
- this.setAlert('success', `${this.t('complete')}
`);
- // Cancel triggered saveDraft to prevent overriding the submitted state
- if (this.draftEnabled && this.triggerSaveDraft?.cancel) {
- this.triggerSaveDraft.cancel();
- }
- this.emit('submit', submission, saved);
- if (saved) {
- this.emit('submitDone', submission);
- }
- return submission;
- }
-
- normalizeError(error) {
- if (error) {
- if (typeof error === 'object' && 'details' in error) {
- error = error.details;
- }
-
- if (typeof error === 'string') {
- error = { message: error };
- }
- }
-
- return error;
- }
-
- /**
- * Called when an error occurs during the submission.
- *
- * @param {Object} error - The error that occured.
- */
- onSubmissionError(error) {
- error = this.normalizeError(error);
-
- this.submitting = false;
- this.setPristine(false);
- this.emit('submitError', error);
-
- // Allow for silent cancellations (no error message, no submit button error state)
- if (error && error.silent) {
- this.emit('change', { isValid: true }, { silent: true });
- return false;
- }
-
- let errors;
- if (this.submitted) {
- errors = this.showErrors();
- }
- else {
- errors = this.showErrors(error, true);
- }
- if (this.root && this.root.alert) {
- this.scrollIntoView(this.root.alert);
- }
- return errors;
- }
-
- /**
- * Trigger the change event for this form.
- *
- * @param changed
- * @param flags
- */
- onChange(flags, changed, modified, changes) {
- flags = flags || {};
- let isChangeEventEmitted = false;
- // For any change events, clear any custom errors for that component.
- if (changed && changed.component) {
- this.customErrors = this.customErrors.filter(err => err.component && err.component !== changed.component.key);
- }
-
- super.onChange(flags, true);
- const value = _.clone(this.submission);
- flags.changed = value.changed = changed;
- flags.changes = changes;
-
- if (modified && this.pristine) {
- this.pristine = false;
- }
-
- value.isValid = this.checkData(value.data, flags);
- this.loading = false;
- if (this.submitted) {
- this.showErrors();
- }
-
- // See if we need to save the draft of the form.
- if (modified && this.options.saveDraft) {
- this.triggerSaveDraft();
- }
-
- if (!flags || !flags.noEmit) {
- this.emit('change', value, flags, modified);
- isChangeEventEmitted = true;
- }
-
- // The form is initialized after the first change event occurs.
- if (isChangeEventEmitted && !this.initialized) {
- this.emit('initialized');
- this.initialized = true;
- }
- }
-
- checkData(data, flags = {}) {
- const valid = super.checkData(data, flags);
- if ((_.isEmpty(flags) || flags.noValidate) && this.submitted) {
- this.showErrors();
- }
- return valid;
- }
-
- /**
- * Send a delete request to the server.
- */
- deleteSubmission() {
- return this.formio.deleteSubmission()
- .then(() => {
- this.emit('submissionDeleted', this.submission);
- this.resetValue();
- });
- }
-
- /**
- * Cancels the submission.
- *
- * @alias reset
- */
- cancel(noconfirm) {
- const shouldReset = this.hook('beforeCancel', true);
- if (shouldReset && (noconfirm || confirm(this.t('confirmCancel')))) {
- this.resetValue();
- return true;
- }
- else {
- this.emit('cancelSubmit');
- return false;
- }
- }
-
- setMetadata(submission) {
- // Add in metadata about client submitting the form
- submission.metadata = submission.metadata || {};
- _.defaults(submission.metadata, {
- timezone: _.get(this, '_submission.metadata.timezone', currentTimezone()),
- offset: parseInt(_.get(this, '_submission.metadata.offset', moment().utcOffset()), 10),
- origin: document.location.origin,
- referrer: document.referrer,
- browserName: navigator.appName,
- userAgent: navigator.userAgent,
- pathName: window.location.pathname,
- onLine: navigator.onLine
- });
- }
-
- submitForm(options = {}) {
- this.clearServerErrors();
-
- return new NativePromise((resolve, reject) => {
- // Read-only forms should never submit.
- if (this.options.readOnly) {
- return resolve({
- submission: this.submission,
- saved: false
- });
- }
-
- const submission = fastCloneDeep(this.submission || {});
-
- this.setMetadata(submission);
-
- submission.state = options.state || 'submitted';
-
- const isDraft = (submission.state === 'draft');
- this.hook('beforeSubmit', { ...submission, component: options.component }, (err , data) => {
- if (err) {
- return reject(err);
- }
-
- submission._vnote = data && data._vnote ? data._vnote : '';
-
- if (!isDraft && !submission.data) {
- return reject('Invalid Submission');
- }
-
- if (!isDraft && !this.checkValidity(submission.data, true)) {
- return reject();
- }
-
- this.everyComponent((comp) => {
- const { persistent } = comp.component;
- if (persistent === 'client-only') {
- _.unset(submission.data, comp.path);
- }
- });
-
- this.hook('customValidation', { ...submission, component: options.component }, (err) => {
- if (err) {
- // If string is returned, cast to object.
- if (typeof err === 'string') {
- err = {
- message: err
- };
- }
-
- // Ensure err is an array.
- err = Array.isArray(err) ? err : [err];
-
- // Set as custom errors.
- this.customErrors = err;
-
- return reject();
- }
-
- this.loading = true;
-
- // Use the form action to submit the form if available.
- if (this._form && this._form.action) {
- const method = (submission.data._id && this._form.action.includes(submission.data._id)) ? 'PUT' : 'POST';
- return Formio.makeStaticRequest(this._form.action, method, submission, this.formio ? this.formio.options : {})
- .then((result) => resolve({
- submission: result,
- saved: true,
- }))
- .catch((error) => {
- this.setServerErrors(error);
-
- return reject(error);
- });
- }
-
- const submitFormio = this.formio;
- if (this.nosubmit || !submitFormio) {
- return resolve({
- submission,
- saved: false,
- });
- }
- // If this is an actionUrl, then make sure to save the action and not the submission.
- const submitMethod = submitFormio.actionUrl ? 'saveAction' : 'saveSubmission';
- submitFormio[submitMethod](submission)
- .then((result) => resolve({
- submission: result,
- saved: true,
- }))
- .catch((error) => {
- this.setServerErrors(error);
-
- return reject(error);
- });
- });
- });
- });
- }
-
- setServerErrors(error) {
- if (error.details) {
- this.serverErrors = error.details.filter((err) => err.level ? err.level === 'error' : err).map((err) => {
- err.fromServer = true;
- return err;
- });
- }
- else if (typeof error === 'string') {
- this.serverErrors = [{ fromServer: true, level: 'error', message: error }];
- }
- }
-
- executeSubmit(options) {
- this.submitted = true;
- this.submitting = true;
- return this.submitForm(options)
- .then(({ submission, saved }) => this.onSubmit(submission, saved))
- .then((results) => {
- this.submissionInProcess = false;
- return results;
- })
- .catch((err) => {
- this.submissionInProcess = false;
- return NativePromise.reject(this.onSubmissionError(err));
- });
- }
-
- clearServerErrors() {
- this.serverErrors?.forEach((error) => {
- if (error.path) {
- const pathArray = getArrayFromComponentPath(error.path);
- const component = this.getComponent(pathArray, _.identity, error.formattedKeyOrPath);
-
- if (component) {
- component.serverErrors = [];
- }
- }
- });
- this.serverErrors = [];
- }
-
- /**
- * Submits the form.
- *
- * @example
- * import Webform from 'formiojs/Webform';
- * let form = new Webform(document.getElementById('formio'));
- * form.src = 'https://examples.form.io/example';
- * form.submission = {data: {
- * firstName: 'Joe',
- * lastName: 'Smith',
- * email: 'joe@example.com'
- * }};
- * form.submit().then((submission) => {
- * console.log(submission);
- * });
- *
- * @param {boolean} before - If this submission occured from the before handlers.
- *
- * @returns {Promise} - A promise when the form is done submitting.
- */
- submit(before, options) {
- this.submissionInProcess = true;
- if (!before) {
- return this.beforeSubmit(options).then(() => this.executeSubmit(options));
- }
- else {
- return this.executeSubmit(options);
- }
- }
-
- submitUrl(URL, headers) {
- if (!URL) {
- return console.warn('Missing URL argument');
- }
-
- const submission = this.submission || {};
- const API_URL = URL;
- const settings = {
- method: 'POST',
- headers: {}
- };
-
- if (headers && headers.length > 0) {
- headers.map((e) => {
- if (e.header !== '' && e.value !== '') {
- settings.headers[e.header] = this.interpolate(e.value, submission);
- }
- });
- }
- if (API_URL && settings) {
- Formio.makeStaticRequest(API_URL,settings.method,submission, { headers: settings.headers }).then(() => {
- this.emit('requestDone');
- this.setAlert('success', ' Success
');
- }).catch((e) => {
- this.showErrors(`${e.statusText ? e.statusText : ''} ${e.status ? e.status : e}`);
- this.emit('error',`${e.statusText ? e.statusText : ''} ${e.status ? e.status : e}`);
- console.error(`${e.statusText ? e.statusText : ''} ${e.status ? e.status : e}`);
- this.setAlert('danger', ` ${e.statusText ? e.statusText : ''} ${e.status ? e.status : e}
`);
- });
- }
- else {
- this.emit('error', 'You should add a URL to this button.');
- this.setAlert('warning', 'You should add a URL to this button.');
- return console.warn('You should add a URL to this button.');
- }
- }
-
- triggerRecaptcha() {
- if (!this || !this.components) {
- return;
- }
- const recaptchaComponent = searchComponents(this.components, {
- 'component.type': 'recaptcha',
- 'component.eventType': 'formLoad'
- });
- if (recaptchaComponent.length > 0) {
- recaptchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
- }
- }
-
- set nosubmit(value) {
- this._nosubmit = !!value;
- this.emit('nosubmit', this._nosubmit);
- }
-
- get nosubmit() {
- return this._nosubmit || false;
- }
-
- get conditions() {
- return this.schema.settings?.conditions ?? [];
- }
-
- get variables() {
- return this.schema.settings?.variables ?? [];
- }
-}
-
-Webform.setBaseUrl = Formio.setBaseUrl;
-Webform.setApiUrl = Formio.setApiUrl;
-Webform.setAppUrl = Formio.setAppUrl;
diff --git a/web-client/core/themes/italia/static/formio/css/src/Webform.unit.js b/web-client/core/themes/italia/static/formio/css/src/Webform.unit.js
deleted file mode 100644
index 3dc678fa..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Webform.unit.js
+++ /dev/null
@@ -1,4576 +0,0 @@
-import assert from 'power-assert';
-import { expect } from 'chai';
-import sinon from 'sinon';
-import _ from 'lodash';
-import each from 'lodash/each';
-import i18next from 'i18next';
-import Harness from '../test/harness';
-import FormTests from '../test/forms';
-import Webform from './Webform';
-import 'flatpickr';
-import Formio from './Formio';
-import AllComponents from './components';
-import {
- settingErrors,
- clearOnHide,
- manualOverride,
- validationOnBlur,
- calculateValueWithManualOverride,
- calculateValueWithSubmissionMetadata,
- formWithAdvancedLogic,
- formWithPatternValidation,
- calculatedSelectboxes,
- calculateZeroValue,
- formWithConditionalLogic,
- formWithCalculatedValueWithoutOverriding,
- formWithTimeComponent,
- formWithEditGridModalDrafts,
- formWithBlurValidationInsidePanel,
- modalEditComponents,
- calculatedNotPersistentValue,
- calculateValueInEditingMode,
- initiallyCollapsedPanel,
- multipleTextareaInsideConditionalComponent,
- disabledNestedForm,
- formWithEditGridAndNestedDraftModalRow,
- formWithDateTimeComponents,
- formWithCollapsedPanel,
- formWithCustomFormatDate,
- tooltipActivateCheckbox,
- formWithObjectValueSelect
-} from '../test/formtest';
-import UpdateErrorClassesWidgets from '../test/forms/updateErrorClasses-widgets';
-import nestedModalWizard from '../test/forms/nestedModalWizard';
-import disableSubmitButton from '../test/forms/disableSubmitButton';
-import formWithAddressComponent from '../test/forms/formWithAddressComponent';
-import formWithDataGridInitEmpty from '../test/forms/dataGridWithInitEmpty';
-import nestedFormInsideDataGrid from '../test/forms/dataGrid-nestedForm';
-import formWithDataGrid from '../test/forms/formWithDataGrid';
-import translationTestForm from '../test/forms/translationTestForm';
-import formWithDataGridWithCondColumn from '../test/forms/dataGridWithConditionalColumn';
-import { nestedFormInWizard } from '../test/fixtures';
-import NativePromise from 'native-promise-only';
-import { fastCloneDeep } from '../lib/utils/utils';
-import dataGridOnBlurValidation from '../test/forms/dataGridOnBlurValidation';
-import checkBlurFocusEventForm from '../test/forms/checkBlurFocusEventForm';
-import truncateMultipleSpaces from '../test/forms/truncateMultipleSpaces';
-import calculatedValue from '../test/forms/calculatedValue';
-import conditionalDataGridWithTableAndRadio from '../test/forms/conditionalDataGridWithTableAndRadio';
-import calculateValueWithManualOverrideLableValueDataGrid
- from '../test/forms/calculateValueWithManualOverrideLableValueDataGrid';
-import deeplyNestedDataGridAndContainer from '../test/forms/nestedDataGridsAndContainers';
-import columnWithConditionalComponents from '../test/forms/columnWithConditionalComponents';
-import formWithSurvey from '../test/forms/formWithSurvey';
-import formWithSelectBoxes from '../test/forms/formWithSelectBoxes';
-import formWithDayComp from '../test/forms/formWithDayComp';
-import formWithCalcValue from '../test/forms/formWithCalcValue';
-import formWithAllowCalculateOverride from '../test/forms/formWithAllowCalculateOverride';
-import testClearOnHideInsideEditGrid from '../test/forms/clearOnHideInsideEditGrid';
-import formWithNestedDataGridInitEmpty from '../test/forms/nestedDataGridWithInitEmpty';
-import formWithEventLogicInHiddenComponent from '../test/forms/formWithEventLogicInHiddenComponent';
-import * as FormioUtils from './utils/utils';
-import htmlRenderMode from '../test/forms/htmlRenderMode';
-import optionalSanitize from '../test/forms/optionalSanitize';
-import formsWithNewSimpleConditions from '../test/forms/formsWithNewSimpleConditions';
-import formWithRadioInsideDataGrid from '../test/forms/formWithRadioInsideDataGrid';
-import formWithCheckboxRadioType from '../test/forms/formWithCheckboxRadioType';
-import formWithFormController from '../test/forms/formWithFormController';
-import calculateValueOnServerForEditGrid from '../test/forms/calculateValueOnServerForEditGrid';
-import formsWithAllowOverride from '../test/forms/formsWithAllowOverrideComps';
-
-global.requestAnimationFrame = (cb) => cb();
-global.cancelAnimationFrame = () => {};
-
-if (_.has(Formio, 'Components.setComponents')) {
- Formio.Components.setComponents(AllComponents);
-}
-
-/* eslint-disable max-statements */
-describe('Webform tests', function() {
- this.retries(3);
-
- it('Should execute form controller', function(done) {
- Formio.createForm(formWithFormController).then((form) => {
- setTimeout(() => {
- const textField = form.getComponent('textField');
-
- assert.equal(textField.getValue(), 'Hello World');
- assert.equal(textField.disabled, true);
- assert.equal(form.components[0].disabled, true);
-
- done();
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should set radio components value inside data grid correctly', function(done) {
- Formio.createForm(formWithRadioInsideDataGrid).then((form) => {
- const dataGridData = [{ radio: 'two' },{ radio: 'two' } ,{ radio: 'three' }];
- form.setValue({ data: { dataGrid: fastCloneDeep(dataGridData) } });
- setTimeout(() => {
- const dataGrid = form.getComponent('dataGrid');
- assert.deepEqual(dataGrid.dataValue, dataGridData);
- done();
- }, 200);
- }).catch((err) => done(err));
- });
-
- it('Should not fall into setValue calls loop when doing value calculation on server', done => {
- const formElement = document.createElement('div');
- // Set a spy for Edit Grid setValue method
- const spy = sinon.spy(Formio.Components.components.editgrid.prototype, 'setValue');
-
- Formio.createForm(formElement, calculateValueOnServerForEditGrid, { server: true, noDefaults: true } )
- .then(form => {
- assert.deepEqual(form.data, { editGrid: [{ fielda: undefined, fieldb: 'test' }] });
- assert.equal(spy.callCount, 1);
-
- const first = form.getComponent('first');
-
- first.setValue('test value');
-
- setTimeout(() => {
- assert.deepEqual(form.data, {
- first: 'test value',
- editGrid: [{ fielda: 'test value', fieldb: 'test' }]
- });
- assert.equal(spy.callCount, 2);
- // Remove the spy from setValue method
- Formio.Components.components.editgrid.prototype.setValue.restore();
- done();
- }, 300);
- })
- .catch(done);
- });
-
- it('Should fire blur and focus events for address and select components', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(checkBlurFocusEventForm).then(() => {
- let blurEvents = 0;
- let focusEvents = 0;
- form.on('blur', () => {
- blurEvents = blurEvents + 1;
- });
-
- form.on('focus', () => {
- focusEvents = focusEvents + 1;
- });
-
- const focusEvent = new Event('focus');
- const blurEvent = new Event('blur');
-
- const selectChoices = form.getComponent('selectChoices');
- selectChoices.focusableElement.dispatchEvent(focusEvent);
-
- setTimeout(() => {
- selectChoices.focusableElement.dispatchEvent(blurEvent);
-
- const selectHtml = form.getComponent('selectHtml');
- selectHtml.refs.selectContainer.dispatchEvent(focusEvent);
-
- setTimeout(() => {
- selectHtml.refs.selectContainer.dispatchEvent(blurEvent);
-
- const address = form.getComponent('address');
- address.refs.searchInput[0].dispatchEvent(focusEvent);
-
- setTimeout(() => {
- address.refs.searchInput[0].dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(focusEvents, 3);
- assert.equal(blurEvents, 3);
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should return correct string value for checkbox radio type', function(done) {
- Formio.createForm(formWithCheckboxRadioType).then((form) => {
- form.setValue({ data: { radio: 'value1', checkbox: true } });
- setTimeout(() => {
- const stringValues = {
- checkbox1: 'Yes',
- checkbox2: 'No',
- checkbox: 'Yes'
- };
-
- form.eachComponent((comp) => {
- assert.equal(comp.getValueAsString(comp.dataValue), stringValues[`${comp.component.key}`], `Error for string value of ${comp.component.key}`);
- });
-
- form.setValue({ data: { radio: 'value2', checkbox: false } });
-
- setTimeout(() => {
- const stringValues2 = {
- checkbox1: 'No',
- checkbox2: 'Yes',
- checkbox: 'No'
- };
-
- form.eachComponent((comp) => {
- assert.equal(comp.getValueAsString(comp.dataValue), stringValues2[`${comp.component.key}`], `Error for string value of ${comp.component.key}`);
- });
-
- done();
- }, 200);
- }, 200);
- }).catch((err) => done(err));
- });
-
- it('Should set value for hidden nested component through the logic triggered by event', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formWithEventLogicInHiddenComponent).then(() => {
- const regesteredAddress = form.getComponent('registeredAddressInformation').getComponent('streetAddress')[0];
- const address = form.getComponent('addressInformation').getComponent('streetAddress')[0];
-
- assert.equal(address.visible, true);
- assert.equal(regesteredAddress.visible, false);
-
- const value = 'Dallas';
- address.setValue(value);
-
- setTimeout(() => {
- assert.equal(address.dataValue, value);
- assert.equal(regesteredAddress.dataValue, value);
-
- const role = form.getComponent('role');
- role.setValue(['client']);
-
- setTimeout(() => {
- assert.equal(address.visible, false);
- assert.equal(regesteredAddress.visible, true);
- assert.equal(regesteredAddress.dataValue, value);
- assert.equal(address.dataValue, value);
- done();
- }, 500);
- }, 500);
- }).catch((err) => done(err));
- });
-
- it('Should recalculate value when submission is being set in edit mode', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formWithCalcValue).then(() => {
- const numberComp = form.getComponent('number');
- const checkbox = form.getComponent('checkbox');
-
- form.setSubmission({}).then(() => {
- setTimeout(() => {
- assert.equal(numberComp.dataValue, 0);
- assert.equal(checkbox.dataValue, true);
- form.setSubmission({ data: { number: 7, checkbox: true } }).then(() => {
- setTimeout(() => {
- assert.equal(numberComp.dataValue, 7);
- assert.equal(checkbox.dataValue, false);
- done();
- }, 500);
- });
- }, 500);
- });
- }).catch((err) => done(err));
- });
-
- it('Should not activate checkbox when clicking tooltip icon', function(done) {
- const element = document.createElement('div');
- const form = new Webform(element);
-
- form.setForm(tooltipActivateCheckbox).then(() => {
- const checkboxValue = form.element.querySelector('[name="data[checkbox]"]').value;
- Harness.clickElement(form, form.element.querySelector('[ref="tooltip"]'));
-
- setTimeout(() => {
- assert.equal(form.element.querySelector('[name="data[checkbox]"]').value, checkboxValue);
- done();
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should show survey values in html render mode', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { renderMode: 'html', readOnly: true });
-
- form.setForm(formWithSurvey).then(() => {
- form.setSubmission({ data: { survey: { question1: 'a3', question2: 'a1' } } }).then(() => {
- const survey = form.getComponent('survey');
- const values = survey.element.querySelectorAll('td');
-
- assert.equal(values.length, 2);
- assert.equal(values[0].innerHTML.trim(), 'a3');
- assert.equal(values[1].innerHTML.trim(), 'a1');
- done();
- });
- }).catch((err) => done(err));
- });
-
- it('Should show select boxes values in html render mode', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { renderMode: 'html', readOnly: true });
-
- form.setForm(formWithSelectBoxes).then(() => {
- form.setSubmission({ data: { selectBoxes: { a: true, b: true, c: false } } }).then(() => {
- const selectBoxes = form.getComponent('selectBoxes');
- const values = selectBoxes.element.querySelector('[ref="value"]').textContent.trim();
-
- assert.equal(values, 'a, b');
- done();
- });
- }).catch((err) => done(err));
- });
-
- it('Should show day value in html render mode', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { renderMode: 'html', readOnly: true });
-
- form.setForm(formWithDayComp).then(() => {
- form.setSubmission({ data: { day: '05/07/2020' } }).then(() => {
- const day = form.getComponent('day');
- const value = day.element.querySelector('[ref="value"]').textContent.trim();
-
- assert.equal(value, '05/07/2020');
- done();
- });
- }).catch((err) => done(err));
- });
-
- it('Should allow to input value and add rows in deeply nested conditional dataGrid', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(deeplyNestedDataGridAndContainer).then(() => {
- const parentDataGrid = form.getComponent('dataGrid6');
-
- assert.equal(parentDataGrid.rows.length, 1);
- assert.equal(parentDataGrid.rows[0].dataGrid5.visible, false);
-
- const checkbox = form.getComponent('checkbox');
- checkbox.setValue(true);
-
- setTimeout(() => {
- assert.equal(parentDataGrid.rows.length, 1);
- assert.equal(parentDataGrid.rows[0].dataGrid5.visible, true);
-
- const numberInput = parentDataGrid.rows[0].dataGrid5.rows[0].number.refs.input[0];
- numberInput.value = 555;
-
- const inputEvent = new Event('input');
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- const conditionalDataGrid = form.getComponent('dataGrid6').rows[0].dataGrid5;
- const numberComp = conditionalDataGrid.rows[0].number;
-
- assert.equal(numberComp.dataValue, 555);
- assert.equal(numberComp.refs.input[0].value, 555);
-
- const addRowBtn = conditionalDataGrid.refs[`${'datagrid-dataGrid5-addRow'}`][0];
- const clickEvent = new Event('click');
- addRowBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(conditionalDataGrid.rows.length, 2);
- done();
- }, 300);
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should adjust columns when conditional fields appear/disappear', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(columnWithConditionalComponents).then(() => {
- const selectBoxes = form.getComponent('selectBoxes');
- const columns = form.getComponent('columns');
-
- columns.columns.forEach((column, index) => {
- assert.equal(column[0].visible, false, `Column ${index + 1} component should be hidden`);
- assert.equal( columns.component.columns[index].currentWidth, 0, `Column ${index + 1} width should be 0`);
- });
-
- selectBoxes.setValue({ '1': false, '2': false, '3': true, '4': false, '5': false, '6': true });
-
- setTimeout(() => {
- columns.columns.forEach((column, index) => {
- if ([3,6].includes(index+1)) {
- assert.equal(column[0].visible, true, `Column ${index + 1} component should be visible`);
- assert.equal(columns.component.columns[index].currentWidth, 2, `Column ${index + 1} width should be 2`);
- }
- else {
- assert.equal(column[0].visible, false, `Column ${index + 1} component should be hidden`);
- assert.equal( columns.component.columns[index].currentWidth, 0, `Column ${index + 1} width should be 0`);
- }
- });
-
- const visibleTextField1 = columns.columns[2][0].refs.input[0];
- const visibleTextField2 = columns.columns[5][0].refs.input[0];
-
- visibleTextField1.value = 'test ';
- visibleTextField2.value = ' some ';
-
- const inputEvent = new Event('input');
- visibleTextField1.dispatchEvent(inputEvent);
- visibleTextField2.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- const visibleTextField1 = columns.columns[2][0].refs.input[0];
- const visibleTextField2 = columns.columns[5][0].refs.input[0];
-
- assert.equal(visibleTextField1.value,'test ', 'Should not cut whitespaces while inputting into the conditional component inside column');
- assert.equal(visibleTextField2.value,' some ', 'Should not cut whitespaces while inputting into the conditional component inside column');
- selectBoxes.setValue({ '1': false, '2': false, '3': false, '4': false, '5': false, '6': true });
-
- setTimeout(() => {
- columns.columns.forEach((column, index) => {
- if ([6].includes(index+1)) {
- assert.equal(column[0].visible, true, `Column ${index + 1} component should be visible`);
- assert.equal( columns.component.columns[index].currentWidth, 2, `Column ${index + 1} width should be 2`);
- }
- else {
- assert.equal(column[0].visible, false, `Column ${index + 1} component should be hidden`);
- assert.equal( columns.component.columns[index].currentWidth, 0, `Column ${index + 1} width should be 0`);
- }
- });
- done();
- }, 300);
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should not translate en value if _userInput option is provided and value presents in reserved translation names', done => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, {
- language: 'en'
- });
- form.setForm(translationTestForm).then(() => {
- setTimeout(() => {
- const selectComp = form.getComponent('select');
- const options = selectComp.element.querySelector('[role="listbox"]').children;
- const option1 = options[0].textContent.trim();
- const option2 = options[1].textContent.trim();
- const label = selectComp.element.querySelector('label').textContent.trim();
- assert.equal(option1, translationTestForm.components[0].data.values[0].label);
- assert.equal(option2, translationTestForm.components[0].data.values[1].label);
- assert.equal(label, translationTestForm.components[0].label);
- document.body.innerHTML = '';
- done();
- }, 100);
- }).catch(done);
- });
-
- it('Should translate in English if _userInput option is provided and value does not present in reserved translation names', done => {
- const formElement = document.createElement('div');
- const selectLabel = 'Select test label';
- const translationForm = fastCloneDeep(translationTestForm);
- translationForm.components[0].label = selectLabel;
- const form = new Webform(formElement, {
- language: 'en',
- i18n: {
- en: {
- 'Select test label': 'English Label'
- },
- fr: {
- 'Select test label': 'French Label'
- }
- }
- });
-
- form.setForm(translationForm).then(() => {
- const selectComp = form.getComponent('select');
- const label = selectComp.element.querySelector('label').textContent.trim();
-
- assert.equal(label, 'English Label');
- document.body.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should translate value in franch if _userInput option is provided and value does not present in reserved translation names', done => {
- const formElement = document.createElement('div');
- const selectLabel = 'Select test label';
- const translationForm = fastCloneDeep(translationTestForm);
- translationForm.components[0].label = selectLabel;
- const form = new Webform(formElement, {
- language: 'fr',
- i18n: {
- en: {
- 'Select test label': 'English Label'
- },
- fr: {
- 'Select test label': 'French Label'
- }
- }
- });
-
- form.setForm(translationForm).then(() => {
- const selectComp = form.getComponent('select');
- const label = selectComp.element.querySelector('label').textContent.trim();
-
- assert.equal(label, 'French Label');
- document.body.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should display dataGrid conditional column once the condition is met', function(done) {
- const formElement = document.createElement('div');
- const formWithCondDataGridColumn = new Webform(formElement);
-
- formWithCondDataGridColumn.setForm(formWithDataGridWithCondColumn).then(() => {
- const condDataGridField = formWithCondDataGridColumn.element.querySelector( '[name="data[dataGrid][0][numberCond]"]');
- assert.equal(!!condDataGridField, false);
-
- const textField = formWithCondDataGridColumn.element.querySelector( '[name="data[textField]"]');
- textField.value = 'show';
-
- const inputEvent = new Event('input');
- textField.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- const condDataGridFieldAfterFulfillingCond = formWithCondDataGridColumn.element.querySelector( '[name="data[dataGrid][0][numberCond]"]');
- assert.equal(!!condDataGridFieldAfterFulfillingCond, true);
-
- done();
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should remove dataGrid extra rows and components after setting value with less row number', function(done) {
- const formElement = document.createElement('div');
- const formWithDG = new Webform(formElement);
-
- formWithDG.setForm(formWithDataGrid.form).then(() => {
- formWithDG.setSubmission(formWithDataGrid.submission3rows);
-
- setTimeout(() => {
- assert.equal(formWithDG.components[0].rows.length, 3);
- assert.equal(formWithDG.components[0].components.length, 3);
-
- formWithDG.setSubmission(formWithDataGrid.submission1row);
-
- setTimeout(() => {
- assert.equal(formWithDG.components[0].rows.length, 1);
- assert.equal(formWithDG.components[0].components.length, 1);
-
- done();
- }, 200);
- }, 100);
- }).catch((err) => done(err));
- });
-
- it('Should not delete/change date value in dataGrid after adding new row', function(done) {
- const formElement = document.createElement('div');
- const formWithDate = new Webform(formElement);
-
- formWithDate.setForm(formWithCustomFormatDate).then(() => {
- setTimeout(() => {
- const clickEvent = new Event('click');
-
- const dateCompInputWidget = formWithDate.element.querySelector('.formio-component-textField').querySelector('.flatpickr-input').widget;
- const dateAltFormat = dateCompInputWidget.calendar.config.altFormat;
- dateCompInputWidget.calendar.setDate('30-05-2020', true, dateAltFormat);
-
- const dateCompInputWidget1 = formWithDate.element.querySelector('.formio-component-dateTime').querySelector('.flatpickr-input').widget;
- const dateAltFormat1 = dateCompInputWidget1.calendar.config.altFormat;
- dateCompInputWidget1.calendar.setDate('30-05-2020', true, dateAltFormat1);
-
- const dateCompInputWidget2 = formWithDate.element.querySelector('.formio-component-textField2').querySelector('.flatpickr-input').widget;
- const dateAltFormat2 = dateCompInputWidget2.calendar.config.altFormat;
- dateCompInputWidget2.calendar.setDate('30-05-2020', true, dateAltFormat2);
-
- setTimeout(() => {
- const dateCompAltInput = formWithDate.element.querySelector('.formio-component-textField').querySelector('.flatpickr-input');
- const dateComp = formWithDate.element.querySelector('.formio-component-textField').querySelector('[type="text"]');
-
- const dateCompAltInput1 = formWithDate.element.querySelector('.formio-component-dateTime').querySelector('.flatpickr-input');
- const dateComp1 = formWithDate.element.querySelector('.formio-component-dateTime').querySelector('[type="text"]');
-
- const dateCompAltInput2 = formWithDate.element.querySelector('.formio-component-textField2').querySelector('.flatpickr-input');
- const dateComp2 = formWithDate.element.querySelector('.formio-component-textField2').querySelector('[type="text"]');
-
- assert.equal(dateCompAltInput.value,'30-05-2020');
- assert.equal(dateComp.value,'30-05-2020');
-
- assert.equal(dateCompAltInput1.value,'2020-05-30T00:00:00');
- assert.equal(dateComp1.value,'30-05-2020');
-
- assert.equal(dateCompAltInput2.value,'2020-05-30T00:00:00');
- assert.equal(dateComp2.value,'30-05-2020');
-
- const addNewRowBtn = formWithDate.element.querySelector('.formio-button-add-row');
- addNewRowBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const dataGridRows = formWithDate.element.querySelectorAll('[ref="datagrid-dataGrid-row"]');
- assert.equal(dataGridRows.length, 2);
-
- const dateCompAltInputAfterAddingRow = formWithDate.element.querySelectorAll('.formio-component-textField')[0].querySelector('.flatpickr-input');
- const dateCompAfterAddingRow = formWithDate.element.querySelectorAll('.formio-component-textField')[0].querySelector('[type="text"]');
-
- const dateCompAltInputAfterAddingRow1 = formWithDate.element.querySelectorAll('.formio-component-dateTime')[0].querySelector('.flatpickr-input');
- const dateCompAfterAddingRow1 = formWithDate.element.querySelectorAll('.formio-component-dateTime')[0].querySelector('[type="text"]');
-
- const dateCompAltInputAfterAddingRow2 = formWithDate.element.querySelectorAll('.formio-component-textField2')[0].querySelector('.flatpickr-input');
- const dateCompAfterAddingRow2 = formWithDate.element.querySelectorAll('.formio-component-textField2')[0].querySelector('[type="text"]');
-
- assert.equal(dateCompAltInputAfterAddingRow.value,'30-05-2020');
- assert.equal(dateCompAfterAddingRow.value,'30-05-2020');
-
- assert.equal(dateCompAltInputAfterAddingRow1.value,'2020-05-30T00:00:00');
- assert.equal(dateCompAfterAddingRow1.value,'30-05-2020');
-
- assert.equal(dateCompAltInputAfterAddingRow2.value,'2020-05-30T00:00:00');
- assert.equal(dateCompAfterAddingRow2.value,'30-05-2020');
-
- done();
- }, 150);
- }, 50);
- }, 100);
- }).catch((err) => done(err));
- });
-
- it('Should open collapsed panel with invalid components inside container that is inside the panel on submit', function(done) {
- const formElement = document.createElement('div');
- const formWithPanel = new Webform(formElement);
-
- formWithPanel.setForm(formWithCollapsedPanel).then(() => {
- const clickEvent = new Event('click');
-
- assert.equal(formWithPanel.components[0].collapsed, true);
-
- const submitBtn = formWithPanel.element.querySelector('[name="data[submit]"]');
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(formWithPanel.components[0].collapsed, false);
- done();
- }, 200);
- }).catch((err) => done(err));
- });
-
- it('Should correctly set date after collapsing and openning the panel', function(done) {
- const formElement = document.createElement('div');
- const formWithDate = new Webform(formElement);
-
- formWithDate.setForm(formWithDateTimeComponents).then(() => {
- const clickEvent = new Event('click');
-
- const dateTimeCompInputWidget = formWithDate.element.querySelector('.formio-component-dateTime1').querySelector('.flatpickr-input').widget;
- const dateTimeAltFormat = dateTimeCompInputWidget.calendar.config.altFormat;
- dateTimeCompInputWidget.calendar.setDate('05-05-2020T00:00:00', true, dateTimeAltFormat);
-
- const textFieldDateCompWidget = formWithDate.element.querySelector('.formio-component-textField1').querySelector('.flatpickr-input').widget;
- const textFieldDateAltFormat = textFieldDateCompWidget.calendar.config.altFormat;
- textFieldDateCompWidget.calendar.setDate('04-04-2020T00:00:00', true, textFieldDateAltFormat);
-
- setTimeout(() => {
- const dateTimeCompAltInput = formWithDate.element.querySelector('.formio-component-dateTime1').querySelector('.flatpickr-input');
- const textFieldDateCompAltInput = formWithDate.element.querySelector('.formio-component-textField1').querySelector('.flatpickr-input');
-
- const dateTimeComp = formWithDate.element.querySelector('.formio-component-dateTime1').querySelector('[type="text"]');
- const textFieldDateComp = formWithDate.element.querySelector('.formio-component-textField1').querySelector('[type="text"]');
-
- assert.equal(dateTimeCompAltInput.value,'2020-05-05T00:00:00');
- assert.equal(textFieldDateCompAltInput.value,'2020-04-04T00:00:00');
-
- assert.equal(dateTimeComp.value,'05-05-2020');
- assert.equal(textFieldDateComp.value,'04-04-2020');
-
- const panelCollapseBtn = formWithDate.element.querySelector('.formio-collapse-icon');
- panelCollapseBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const panelBody = formWithDate.element.querySelector('.panel-body');
- assert.equal(!!panelBody, false);
-
- formWithDate.element.querySelector('.formio-collapse-icon').dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const dateTimeCompAfterOpenningPanel = formWithDate.element.querySelector('.formio-component-dateTime1').querySelector('[type="text"]');
- const textFieldDateCompAfterOpenningPanel = formWithDate.element.querySelector('.formio-component-textField1').querySelector('[type="text"]');
-
- const dateTimeCompAltInputAfterOpenningPanel = formWithDate.element.querySelector('.formio-component-dateTime1').querySelector('.flatpickr-input');
- const textFieldDateCompAltInputAfterOpenningPanel = formWithDate.element.querySelector('.formio-component-textField1').querySelector('.flatpickr-input');
-
- assert.equal(dateTimeCompAltInputAfterOpenningPanel.value,'2020-05-05T00:00:00');
- assert.equal(textFieldDateCompAltInputAfterOpenningPanel.value,'2020-04-04T00:00:00');
-
- assert.equal(dateTimeCompAfterOpenningPanel.value,'05-05-2020');
- assert.equal(textFieldDateCompAfterOpenningPanel.value,'04-04-2020');
- done();
- }, 250);
- }, 150);
- }, 50);
- }).catch((err) => done(err));
- });
-
- it(`Should show confirmation alert when clicking X btn or clicking outside modal window after editing
- editGrid modal draft row`, function(done) {
- const formElement = document.createElement('div');
- const formWithNestedDraftModals = new Webform(formElement);
-
- formWithNestedDraftModals.setForm(formWithEditGridAndNestedDraftModalRow).then(() => {
- const editGrid = formWithNestedDraftModals.getComponent('editGrid');
- const clickEvent = new Event('click');
- const inputEvent = new Event('input');
-
- const addRowBtn = formWithNestedDraftModals.element.querySelector( '[ref="editgrid-editGrid-addRow"]');
- //click to open row in modal view
- addRowBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const rowModal = document.querySelector(`.editgrid-row-modal-${editGrid.id}`);
- //checking if row modal was openned
- assert.equal(!!rowModal, true);
-
- const textField = rowModal.querySelector('[name="data[textField]"]');
- textField.value = 'test';
- //input value
- textField.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- //checking if the value was set inside the field
- assert.equal(textField.value, 'test');
-
- const saveModalBtn = rowModal.querySelector('.btn-primary');
- //clicking save button to save row draft
- saveModalBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const editGridRows = formWithNestedDraftModals.element.querySelectorAll('[ref="editgrid-editGrid-row"]');
- //checking if the editGrid row was created
- assert.equal(editGridRows.length, 1);
-
- const editRowBtn = editGridRows[0].querySelector('.editRow');
- //click the edit btn to open the row again
- editRowBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const rowModalForEditing = document.querySelector(`.editgrid-row-modal-${editGrid.id}`);
- const textFieldInputForEditing = rowModalForEditing.querySelector('[name="data[textField]"]');
- textFieldInputForEditing.value = 'changed value';
- //changing textfield value
- textFieldInputForEditing.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- //checking if the textfield value was changed
- const inputValue = textFieldInputForEditing.value;
- assert.equal(inputValue, 'changed value');
-
- const XCloseBtn = rowModalForEditing.querySelector('[ref="dialogClose"]');
- //clicking modal close btn
- XCloseBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const dialogConfirmationWindows = document.querySelectorAll(`.editgrid-row-modal-confirmation-${editGrid.id}`);
- //checking if confirmation dialog is openned
- assert.equal(dialogConfirmationWindows.length, 1);
-
- const dialogCancelBtn = dialogConfirmationWindows[0].querySelector('[ref="dialogCancelButton"]');
- //closing confirmation dialog
- dialogCancelBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const confirmationWindows = document.querySelectorAll(`.editgrid-row-modal-confirmation-${editGrid.id}`);
- //checking if confirmation dialig is closed
- assert.equal(confirmationWindows.length, 0);
-
- const dialog = document.querySelector(`.editgrid-row-modal-${editGrid.id}`);
- const overlay = dialog.querySelector('[ref="dialogOverlay"]');
- //clocking model overlay to open confirmation dialog again
- overlay.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const confirmationDialogsAfterClickingOverlay = document.querySelectorAll(`.editgrid-row-modal-confirmation-${editGrid.id}`);
- assert.equal(confirmationDialogsAfterClickingOverlay.length, 1);
-
- document.body.innerHTML = '';
- done();
- }, 190);
- }, 170);
- }, 150);
- }, 130);
- }, 110);
- }, 100);
- }, 70);
- }, 50);
- }).catch((err) => done(err));
- });
-
- it('Should not show validation errors when saving invalid draft row in dataGrid', function(done) {
- const formElement = document.createElement('div');
- const formWithDraftModals = new Webform(formElement);
-
- formWithDraftModals.setForm(formWithEditGridModalDrafts).then(() => {
- const clickEvent = new Event('click');
- const inputEvent = new Event('input');
-
- const addRowBtn = formWithDraftModals.element.querySelector( '[ref="editgrid-editGrid-addRow"]');
- //click to open row in modal view
- addRowBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const rowModal = document.querySelector('.formio-dialog-content');
- //checking if row modal was openned
- assert.equal(!!rowModal, true);
-
- const textFieldInput = rowModal.querySelector('[name="data[editGrid][0][textField]"]');
- textFieldInput.value = 'test';
- //input value in one of required row fields
- textFieldInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- //checking if the value was set inside the field
- assert.equal(textFieldInput.value, 'test');
-
- const saveModalBtn = rowModal.querySelector('.btn-primary');
- //clicking save button to save row draft
- saveModalBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const editGridRows = formWithDraftModals.element.querySelectorAll( '[ref="editgrid-editGrid-row"]');
- //checking if the editGrid row was created
- assert.equal(editGridRows.length, 1);
- const rowError = formWithDraftModals.element.querySelector('.editgrid-row-error').textContent.trim();
- const editGridError = formWithDraftModals.element.querySelector('[ref="messageContainer"]').querySelector('.error');
-
- assert.equal(!!rowError, false);
- assert.equal(!!editGridError, false);
-
- done();
- }, 200);
- }, 100);
- }, 50);
- }).catch((err) => done(err));
- });
-
- it('Should show dataGrid rows when viewing submission in dataGrid with initEmpty option', function(done) {
- const formElement = document.createElement('div');
- const formWithDataGridInitEmptyOption = new Webform(formElement);
-
- formWithDataGridInitEmptyOption.setForm(formWithDataGridInitEmpty.form).then(() => {
- formWithDataGridInitEmptyOption.setSubmission(formWithDataGridInitEmpty.submission2);
-
- setTimeout(() => {
- const dataGridRows = formWithDataGridInitEmptyOption.element.querySelectorAll('[ref = "datagrid-dataGrid-row"]');
- const dataGrid1Rows = formWithDataGridInitEmptyOption.element.querySelectorAll('[ref = "datagrid-dataGrid1-row"]');
-
- assert.equal(dataGrid1Rows.length, 1);
- assert.equal(dataGridRows.length, 1);
-
- formWithDataGridInitEmptyOption.setSubmission(formWithDataGridInitEmpty.submission3);
-
- setTimeout(() => {
- const dataGridRows1 = formWithDataGridInitEmptyOption.element.querySelectorAll('[ref = "datagrid-dataGrid-row"]');
- const dataGrid1Rows1 = formWithDataGridInitEmptyOption.element.querySelectorAll('[ref = "datagrid-dataGrid1-row"]');
- const dataGridSecondRowComponentValue = formWithDataGridInitEmptyOption.element.querySelector('[name = "data[dataGrid][1][textField]"]');
- const dataGrid1FirstRowComponentValue = formWithDataGridInitEmptyOption.element.querySelector('[name = "data[dataGrid1][0][textArea]"]');
- const dataGrid1SecondRowComponentValue = formWithDataGridInitEmptyOption.element.querySelector('[name = "data[dataGrid1][1][number]"]');
-
- assert.equal(dataGrid1Rows1.length, 2);
- assert.equal(dataGridRows1.length, 2);
- assert.equal(dataGridSecondRowComponentValue.value, 'test2');
- assert.equal(dataGrid1FirstRowComponentValue.textContent, 'test3');
- assert.equal(dataGrid1SecondRowComponentValue.value, 222);
-
- done();
- }, 300);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should not show dataGrid rows when empty submission is set for dataGrid with initEmpty', function(done) {
- const formElement = document.createElement('div');
- const formWithDataGridInitEmptyOption = new Webform(formElement);
-
- formWithDataGridInitEmptyOption.setForm(formWithDataGridInitEmpty.form).then(() => {
- formWithDataGridInitEmptyOption.setSubmission(formWithDataGridInitEmpty.submission1);
-
- setTimeout(() => {
- const dataGridRows = formWithDataGridInitEmptyOption.element.querySelectorAll('[ref = "datagrid-dataGrid-row"]');
- const dataGrid1Rows = formWithDataGridInitEmptyOption.element.querySelectorAll('[ref = "datagrid-dataGrid1-row"]');
-
- assert.equal(dataGridRows.length, 0);
- assert.equal(dataGrid1Rows.length, 0);
-
- formWithDataGridInitEmptyOption.setSubmission({ data: {} });
- setTimeout(() => {
- const dataGridRows1 = formWithDataGridInitEmptyOption.element.querySelectorAll('[ref = "datagrid-dataGrid-row"]');
- const dataGrid1Rows1 = formWithDataGridInitEmptyOption.element.querySelectorAll('[ref = "datagrid-dataGrid1-row"]');
-
- assert.equal(dataGridRows1.length, 0);
- assert.equal(dataGrid1Rows1.length, 0);
-
- done();
- }, 300);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should show address submission data inside dataGrid', function(done) {
- const formElement = document.createElement('div');
- const formWithAddress = new Webform(formElement);
-
- formWithAddress.setForm(formWithAddressComponent.form).then(() => {
- formWithAddress.setSubmission({ data: formWithAddressComponent.submission });
-
- setTimeout(() => {
- const addressInput = formWithAddress.element.querySelector('[name = "data[dataGrid][0][address]"]');
-
- assert.equal(addressInput.value, formWithAddressComponent.submission.dataGrid[0].address['formatted_address']);
-
- done();
- }, 300);
- })
- .catch((err) => done(err));
- });
-
- it('Should validate field on blur inside panel', function(done) {
- const formElement = document.createElement('div');
- const formWithBlurValidation = new Webform(formElement);
-
- formWithBlurValidation.setForm(formWithBlurValidationInsidePanel).then(() => {
- const inputEvent = new Event('input');
- const focusEvent = new Event('focus');
- const blurEvent = new Event('blur');
- const fieldWithBlurValidation = formWithBlurValidation.element.querySelector('[name="data[textField]"]');
-
- fieldWithBlurValidation.dispatchEvent(focusEvent);
- 'test'.split('').forEach(character => {
- fieldWithBlurValidation.value = fieldWithBlurValidation.value + character;
- fieldWithBlurValidation.dispatchEvent(inputEvent);
- });
-
- setTimeout(() => {
- const validationErrorBeforeBlur = formWithBlurValidation.element.querySelector('.error');
- assert.equal(!!validationErrorBeforeBlur, false);
- assert.equal(formWithBlurValidation.data.textField, 'test');
-
- fieldWithBlurValidation.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- const validationErrorAfterBlur = formWithBlurValidation.element.querySelector('.error');
-
- assert.equal(!!validationErrorAfterBlur, true);
- assert.equal(validationErrorAfterBlur.textContent, 'Text Field must have at least 5 characters.');
-
- done();
- }, 350);
- }, 300);
- })
- .catch((err) => done(err));
- });
-
- it('Should submit form with empty time field when time field is not required', function(done) {
- const formElement = document.createElement('div');
- const formWithTime = new Webform(formElement);
-
- formWithTime.setForm(formWithTimeComponent).then(() => {
- const clickEvent = new Event('click');
- const submitBtn = formWithTime.element.querySelector('[name="data[submit]"]');
-
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(formWithTime.errors.length, 0);
- assert.equal(formWithTime.data.submit, true);
-
- done();
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it(`Should show validation errors and update validation errors list when openning and editing edit grid rows
- in draft modal mode after pushing submit btn`, function(done) {
- const formElement = document.createElement('div');
- const formWithDraftModals = new Webform(formElement, { sanitize: true });
-
- formWithDraftModals.setForm(formWithEditGridModalDrafts).then(() => {
- const clickEvent = new Event('click');
- const inputEvent = new Event('input');
-
- const addRowBtn = formWithDraftModals.element.querySelector( '[ref="editgrid-editGrid-addRow"]');
- //click to open row in modal view
- addRowBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const editGrid = formWithDraftModals.getComponent('editGrid');
-
- assert.equal(editGrid.editRows.length, 1, 'Should create a row');
-
- const rowModal = editGrid.editRows[0].dialog;
- //checking if row modal was openned
- assert.equal(!!rowModal, true, 'Should open a modal window');
-
- const textFieldInput = rowModal.querySelector('[name="data[editGrid][0][textField]"]');
- textFieldInput.value = 'test';
- //input value in one of required row fields
- textFieldInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- //checking if the value was set inside the field
- assert.equal(textFieldInput.value, 'test');
-
- const saveModalBtn = rowModal.querySelector('.btn-primary');
- //clicking save button to save row draft
- saveModalBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const editGridRows = formWithDraftModals.element.querySelectorAll( '[ref="editgrid-editGrid-row"]');
- //checking if the editGrid row was created
- assert.equal(editGridRows.length, 1);
-
- const submitBtn = formWithDraftModals.element.querySelector('[name="data[submit]"]');
- //pushing submit button to trigger validation
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- //checking the number of appeared errors
- assert.equal(formWithDraftModals.errors.length, 2);
-
- const rowError = formWithDraftModals.element.querySelector('.editgrid-row-error').textContent.trim();
- const editGridError = formWithDraftModals.element.querySelector('[ref="messageContainer"]').querySelector('.error').textContent;
- //checking if right errors were shown in right places
- assert.equal(rowError, 'Invalid row. Please correct it or delete.');
- assert.equal(editGridError, 'Please correct invalid rows before proceeding.');
-
- const rowEditBtn = editGridRows[0].querySelector('.editRow');
- //open row modal again to check if there are errors
- rowEditBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const rowModalAfterValidation = editGrid.editRows[0].dialog;
-
- const alertWithErrorText = rowModalAfterValidation.querySelector('.alert-danger');
- //checking if alert with errors list appeared inside the modal
- assert.equal(!!alertWithErrorText, true, 'Should show error alert');
-
- const alertErrorMessages = rowModalAfterValidation.querySelectorAll('[ref="messageRef"]');
- assert.equal(alertErrorMessages.length, 1);
-
- const numberComponentError = rowModalAfterValidation.querySelector('.formio-component-number').querySelector('.error').textContent;
- //checking if error was shown for empty required field
- assert.equal(numberComponentError, 'Number is required');
-
- const numberInput = rowModalAfterValidation.querySelector('[name="data[editGrid][0][number]"]');
- numberInput.value = 123;
- //input value to make the field valid
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- const rowModalWithValidFields = document.querySelector(`.editgrid-row-modal-${editGrid.id}`);
- const alertErrorMessagesAfterInputtingValidValues = rowModalWithValidFields.querySelectorAll('[ref="messageRef"]');
- assert.equal(alertErrorMessagesAfterInputtingValidValues.length, 0);
-
- //input values to make all row fields invalid
- const validNumberInput = rowModalWithValidFields.querySelector('[name="data[editGrid][0][number]"]');
- validNumberInput.value = null;
- validNumberInput.dispatchEvent(inputEvent);
-
- const validTextInput = rowModalWithValidFields.querySelector('[name="data[editGrid][0][textField]"]');
- validTextInput.value = '';
- validTextInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- const alertErrorMessagesAfterInputtingInvalidValues = document
- .querySelector(`.editgrid-row-modal-${editGrid.id}`)
- .querySelectorAll('[ref="messageRef"]');
-
- assert.equal(alertErrorMessagesAfterInputtingInvalidValues.length, 2);
- document.body.innerHTML = '';
-
- done();
- }, 280);
- }, 240);
- }, 200);
- }, 160);
- }, 120);
- }, 80);
- }, 50);
- }).catch((err) => done(err));
- });
-
- it('Should not override calculated value', function(done) {
- const formElement = document.createElement('div');
- const formWithCalculatedAmount = new Webform(formElement);
-
- formWithCalculatedAmount.setForm(formWithCalculatedValueWithoutOverriding).then(() => {
- const inputEvent = new Event('input');
-
- const amountInput1 = formWithCalculatedAmount.element.querySelector('[name="data[amount1]"]');
- const amountInput2 = formWithCalculatedAmount.element.querySelector('[name="data[amount2]"]');
-
- amountInput1.value = 6;
- amountInput2.value = 4;
-
- amountInput1.dispatchEvent(inputEvent);
- amountInput2.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- const totalAmountInput = formWithCalculatedAmount.element.querySelector('[name="data[currency]"]');
- //checking if the value was calculated correctly
- assert.equal(totalAmountInput.value, '$10.00');
-
- const inputEvent = new Event('input');
- //trying to override calculated value
- totalAmountInput.value = 55;
- totalAmountInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- const totalAmountInput = formWithCalculatedAmount.element.querySelector('[name="data[currency]"]');
- //checking if the value was overridden
- assert.equal(totalAmountInput.value, '$10.00');
-
- done();
- }, 400);
- }, 300);
- })
- .catch((err) => done(err));
- });
-
- it('Should modify calculated value only if it was not manually modified when allowCalculateOverride is true', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formWithAllowCalculateOverride).then(() => {
- const labelComp = form.getComponent('label');
- const valueComp = form.getComponent('value');
-
- const inputEvent = new Event('input');
- const labelInput = labelComp.refs.input[0];
- const valueInput = valueComp.refs.input[0];
- labelInput.value = 'Hello';
- labelInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(labelComp.dataValue, 'Hello');
- assert.equal(valueComp.dataValue, 'hello');
-
- valueInput.value = 'hello123';
- valueInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(valueComp.dataValue, 'hello123');
-
- labelInput.value = 'HeLLo World';
- labelInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(labelComp.dataValue, 'HeLLo World');
- assert.equal(valueComp.dataValue, 'hello123');
- done();
- }, 500);
- }, 500);
- }, 500);
- }).catch(done);
- });
-
- it(`Should show field only in container where radio component has 'yes' value when containers contain radio
- components with the same key`, function(done) {
- const formElement = document.createElement('div');
- const formWithCondition = new Webform(formElement);
-
- formWithCondition.setForm(formWithConditionalLogic).then(() => {
- Harness.clickElement(formWithCondition, formWithCondition.element.querySelector('.formio-component-container1').querySelector('[value="yes"]'));
-
- setTimeout(() => {
- const conditionalFieldInContainer1 = formWithCondition.element.querySelector('[name="data[container1][textField]"]');
- const conditionalFieldInContainer2 = formWithCondition.element.querySelector('[name="data[container2][textField]"]');
-
- assert.equal(!!conditionalFieldInContainer1, true);
- assert.equal(!!conditionalFieldInContainer2, false);
-
- done();
- }, 400);
- })
- .catch((err) => done(err));
- });
-
- it('Should show only "required field" error when submitting empty required field with pattern validation', function(done) {
- const formElement = document.createElement('div');
- const formWithPattern = new Webform(formElement);
-
- formWithPattern.setForm(formWithPatternValidation).then(() => {
- Harness.clickElement(formWithPattern, formWithPattern.element.querySelector('[name="data[submit]"]'));
-
- setTimeout(() => {
- assert.equal(formWithPattern.element.querySelector('.formio-component-textField').querySelectorAll('.error').length, 1);
- assert.equal(formWithPattern.errors[0].messages.length, 1);
- assert.equal(formWithPattern.errors[0].messages[0].message, 'Text Field is required');
- assert.equal(formWithPattern.element.querySelector('[ref="errorRef"]').textContent.trim(), 'Text Field is required');
- done();
- }, 500);
- })
- .catch((err) => done(err));
- });
-
- it('Should disable field applying advanced logic if dot is used inside component key', function(done) {
- const formElement = document.createElement('div');
- const formWithLogic = new Webform(formElement);
-
- formWithLogic.setForm(formWithAdvancedLogic).then(() => {
- assert.equal(formWithLogic.components[1].disabled, false);
-
- Harness.clickElement(formWithLogic, formWithLogic.element.querySelector('[name="data[requestedCovers.HOUSECONTENT_JEWELRY]"]'));
-
- setTimeout(() => {
- assert.equal(formWithLogic.components[1].disabled, true);
- done();
- }, 500);
- })
- .catch((err) => done(err));
- });
-
- it('Should only scroll to alerts dialog when submitting an invalid form', function(done) {
- const formJson = {
- components: [
- {
- 'label': 'Number',
- 'inputFormat': 'plain',
- 'validate': {
- 'required': true,
- 'max': 10
- },
- 'key': 'number',
- 'type': 'number',
- 'input': true
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- saveOnEnter: false,
- }
- ]
- };
-
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- const scrollIntoView = sinon.spy(form, 'scrollIntoView');
-
- form.setForm(formJson).then(() => {
- Harness.clickElement(form, form.element.querySelector('[name="data[submit]"]'));
-
- setTimeout(() => {
- assert.equal(form.errors[0].messages.length, 1);
- assert(scrollIntoView.calledOnceWith(form.root.alert));
-
- //changes do not trigger scrolling
- const inputEvent = new Event('input');
- const input1 = form.components[0].refs.input[0];
-
- //invalid input value
- input1.value = 55;
- input1.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(form.errors[0].messages.length, 1);
- assert.equal(scrollIntoView.callCount, 1);
-
- //valid input value
- input1.value = 5;
- input1.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(form.errors.length, 0);
- assert.equal(scrollIntoView.callCount, 1);
- done();
- }, 250);
- }, 250);
- }, 250);
- })
- .catch((err) => done(err));
- });
-
- let formWithCalculatedValue;
-
- it('Should calculate the field value after validation errors appeared on submit', function(done) {
- const formElement = document.createElement('div');
- formWithCalculatedValue = new Webform(formElement);
- formWithCalculatedValue.setForm(manualOverride).then(() => {
- Harness.clickElement(formWithCalculatedValue, formWithCalculatedValue.components[2].refs.button);
- setTimeout(() => {
- const inputEvent = new Event('input');
- const input1 = formWithCalculatedValue.components[0].refs.input[0];
-
- input1.value = 55;
- input1.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- const input2 = formElement.querySelector('input[name="data[number2]"]');
- assert.equal(input2.value, '55');
- assert.equal(input1.value, 55);
- done();
- }, 250);
- }, 250);
- })
- .catch((err) => done(err));
- });
-
- it('Should calculate the value when editing set values with possibility of manual override', function(done) {
- const formElement = document.createElement('div');
- formWithCalculatedValue = new Webform(formElement);
- formWithCalculatedValue.setForm(manualOverride).then(() => {
- formWithCalculatedValue.setSubmission({
- data:{
- number1: 66,
- number2:66
- }
- }).then(()=>{
- setTimeout(()=>{
- const input1 = formElement.querySelector('input[name="data[number1]"]');
- const input2 = formElement.querySelector('input[name="data[number2]"]');
-
- assert.equal(input2.value, '66');
- assert.equal(input1.value, 66);
-
- const inputEvent = new Event('input');
-
- input1.value = `${input1.value}` + '78';
- input1.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(input2.value, '66');
- assert.equal(input1.value, 6678);
- //set a number as calculated value
- formWithCalculatedValue.components[1].calculatedValue = 6678;
- //change the value
- input1.value = +(`${input1.value}` + '90');
- input1.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(input2.value, '66');
- assert.equal(input1.value, 667890);
- done();
- }, 250);
- }, 250);
- }, 900);
- });
- });
- });
-
- let simpleForm = null;
- it('Should create a simple form', (done) => {
- const formElement = document.createElement('div');
- simpleForm = new Webform(formElement);
- simpleForm.setForm({
- title: 'Simple Form',
- components: [
- {
- type: 'textfield',
- key: 'firstName',
- input: true
- },
- {
- type: 'textfield',
- key: 'lastName',
- input: true
- }
- ]
- }).then(() => {
- Harness.testElements(simpleForm, 'input[type="text"]', 2);
- Harness.testElements(simpleForm, 'input[name="data[firstName]"]', 1);
- Harness.testElements(simpleForm, 'input[name="data[lastName]"]', 1);
- done();
- }).catch(done);
- });
-
- it('Should set a submission to the form.', () => {
- Harness.testSubmission(simpleForm, { data: {
- firstName: 'Joe',
- lastName: 'Smith'
- } });
- });
-
- it('Should translate a form from options', done => {
- const formElement = document.createElement('div');
- const translateForm = new Webform(formElement, {
- template: 'bootstrap3',
- language: 'es',
- i18n: {
- es: {
- 'Default Label': 'Spanish Label'
- }
- }
- });
- translateForm.setForm({
- title: 'Translate Form',
- components: [
- {
- type: 'textfield',
- label: 'Default Label',
- key: 'myfield',
- input: true,
- inputType: 'text',
- validate: {}
- }
- ]
- }).then(() => {
- const label = formElement.querySelector('.control-label');
- assert.equal(label.innerHTML.trim(), 'Spanish Label');
- done();
- }).catch((err) => {
- done(err);
- });
- });
-
- it('Should treat double colons as i18next namespace separators', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm({
- title: 'Test Form',
- components: []
- }).then(() => {
- const str = 'Test: this is only a test';
-
- assert.equal(form.t(str), str);
- assert.equal(form.t(`Namespace::${str}`), str);
-
- done();
- }).catch(done);
- });
-
- it('Should get the language passed via options', () => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, {
- language: 'es'
- });
-
- assert.equal(form.language, 'es');
- });
-
- it('Should translate form errors in alerts', () => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, {
- language: 'es',
- i18n: {
- es: {
- alertMessage: '{{message}}',
- required: '{{field}} es obligatorio'
- }
- }
- });
-
- return form.setForm({
- components: [
- {
- type: 'textfield',
- label: 'Field Label',
- key: 'myfield',
- input: true,
- inputType: 'text',
- validate: {
- required: true
- }
- }
- ]
- })
- .then(() => form.submit())
- .catch(() => {
- // console.warn('nooo:', error)
- })
- .then(() => {
- const ref = formElement.querySelector('[ref="errorRef"]');
- assert.equal(ref.textContent.trim(), 'Field Label es obligatorio');
- });
- });
-
- it('Should translate a form after instantiate', done => {
- const formElement = document.createElement('div');
- const translateForm = new Webform(formElement, {
- template: 'bootstrap3',
- i18n: {
- es: {
- 'Default Label': 'Spanish Label'
- }
- }
- });
- translateForm.setForm({
- title: 'Translate Form',
- components: [
- {
- type: 'textfield',
- label: 'Default Label',
- key: 'myfield',
- input: true,
- inputType: 'text',
- validate: {}
- }
- ]
- }).then(() => {
- translateForm.language = 'es';
- const label = formElement.querySelector('.control-label');
- assert.equal(label.innerHTML.trim(), 'Spanish Label');
- done();
- }).catch(done);
- });
-
- it('Should add a translation after instantiate', done => {
- const formElement = document.createElement('div');
- const translateForm = new Webform(formElement, {
- template: 'bootstrap3',
- i18n: {
- language: 'es',
- es: {
- 'Default Label': 'Spanish Label'
- },
- fr: {
- 'Default Label': 'French Label'
- }
- }
- });
- translateForm.setForm({
- title: 'Translate Form',
- components: [
- {
- type: 'textfield',
- label: 'Default Label',
- key: 'myfield',
- input: true,
- inputType: 'text',
- validate: {}
- }
- ]
- }).then(() => {
- translateForm.language = 'fr';
- const label = formElement.querySelector('.control-label');
- assert.equal(label.innerHTML.trim(), 'French Label');
- done();
- }).catch(done);
- });
-
- it('Should switch a translation after instantiate', done => {
- const formElement = document.createElement('div');
- const translateForm = new Webform(formElement, {
- template: 'bootstrap3',
- });
- translateForm.setForm({
- title: 'Translate Form',
- components: [
- {
- type: 'textfield',
- label: 'Default Label',
- key: 'myfield',
- input: true,
- inputType: 'text',
- validate: {}
- }
- ]
- }).then(() => {
- translateForm.addLanguage('es', { 'Default Label': 'Spanish Label' }, true);
- const label = formElement.querySelector('.control-label');
- assert.equal(label.innerHTML.trim(), 'Spanish Label');
- done();
- }).catch(done);
- });
-
- it('Should keep translation after redraw', done => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, {
- template: 'bootstrap3',
- });
- const schema = {
- title: 'Translate Form',
- components: [
- {
- type: 'textfield',
- label: 'Default Label',
- key: 'myfield',
- input: true,
- inputType: 'text',
- validate: {}
- }
- ]
- };
-
- try {
- form.setForm(schema)
- .then(() => {
- form.addLanguage('ru', { 'Default Label': 'Russian Label' }, true);
- return form.language = 'ru';
- }, done)
- .then(() => {
- expect(form.options.language).to.equal('ru');
- expect(formElement.querySelector('.control-label').innerHTML.trim()).to.equal('Russian Label');
- form.redraw();
- expect(form.options.language).to.equal('ru');
- expect(formElement.querySelector('.control-label').innerHTML.trim()).to.equal('Russian Label');
- done();
- }, done)
- .catch(done);
- }
- catch (error) {
- done(error);
- }
- });
-
- it('Should fire languageChanged event when language is set', done => {
- let isLanguageChangedEventFired = false;
- const formElement = document.createElement('div');
- const form = new Webform(formElement, {
- template: 'bootstrap3',
- });
- const schema = {
- title: 'Translate Form',
- components: [
- {
- type: 'textfield',
- label: 'Default Label',
- key: 'myfield',
- input: true,
- inputType: 'text',
- validate: {}
- }
- ]
- };
-
- try {
- form.setForm(schema)
- .then(() => {
- form.addLanguage('ru', { 'Default Label': 'Russian Label' }, false);
- form.on('languageChanged', () => {
- isLanguageChangedEventFired = true;
- });
- return form.language = 'ru';
- }, done)
- .then(() => {
- assert(isLanguageChangedEventFired);
- done();
- }, done)
- .catch(done);
- }
- catch (error) {
- done(error);
- }
- });
-
- it('When submitted should strip fields with persistent: client-only from submission', done => {
- const formElement = document.createElement('div');
- simpleForm = new Webform(formElement);
- /* eslint-disable quotes */
- simpleForm.setForm({
- title: 'Simple Form',
- components: [
- {
- "label": "Name",
- "allowMultipleMasks": false,
- "showWordCount": false,
- "showCharCount": false,
- "tableView": true,
- "type": "textfield",
- "input": true,
- "key": "name",
- "widget": {
- "type": ""
- }
- },
- {
- "label": "Age",
- "persistent": "client-only",
- "mask": false,
- "tableView": true,
- "type": "number",
- "input": true,
- "key": "age"
- }
- ]
- });
- /* eslint-enable quotes */
-
- Harness.testSubmission(simpleForm, {
- data: { name: 'noname', age: '1' }
- });
-
- simpleForm.submit().then((submission) => {
- assert.deepEqual(submission.data, { name: 'noname' });
- done();
- });
- });
-
- it('Should not mutate the global i18next if it gets an instance', async function() {
- await i18next.init({ lng: 'en' });
- const instance = i18next.createInstance();
-
- const formElement = document.createElement('div');
- const translateForm = new Webform(formElement, {
- template: 'bootstrap3',
- language: 'es',
- i18next: instance,
- i18n: {
- es: {
- 'Default Label': 'Spanish Label'
- }
- }
- });
-
- return translateForm.setForm({
- title: 'Translate Form',
- components: [
- {
- type: 'textfield',
- label: 'Default Label',
- key: 'myfield',
- input: true,
- inputType: 'text',
- validate: {}
- }
- ]
- }).then(() => {
- assert.equal(i18next.language, 'en');
- assert.equal(translateForm.i18next.language, 'es');
- assert.equal(translateForm.i18next, instance);
-
- const label = formElement.querySelector('.control-label');
- assert.equal(label.innerHTML.trim(), 'Spanish Label');
- });
- });
-
- it('Should keep components valid if they are pristine', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(settingErrors).then(() => {
- const inputEvent = new Event('input', { bubbles: true, cancelable: true });
- const input = form.element.querySelector('input[name="data[textField]"]');
- for (let i = 0; i < 50; i++) {
- input.value += i;
- input.dispatchEvent(inputEvent);
- }
-
- setTimeout(() => {
- assert.equal(form.errors.length, 0);
- Harness.setInputValue(form, 'data[textField]', '');
- setTimeout(() => {
- assert.equal(form.errors.length, 1);
- done();
- }, 250);
- }, 250);
- }).catch(done);
- });
-
- it('Should delete value of hidden component if clearOnHide is turned on', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(clearOnHide).then(() => {
- const visibleData = {
- data: {
- visible: 'yes',
- clearOnHideField: 'some text',
- submit: false
- },
- metadata: {}
- };
-
- const hiddenData = {
- data: {
- visible: 'no',
- submit: false
- }
- };
- const inputEvent = new Event('input', { bubbles: true, cancelable: true });
- const textField = form.element.querySelector('input[name="data[clearOnHideField]"]');
- textField.value = 'some text';
- textField.dispatchEvent(inputEvent);
- this.timeout(1000);
- setTimeout(() => {
- assert.deepEqual(form.data, visibleData.data);
- Harness.setInputValue(form, 'data[visible]', 'no');
-
- setTimeout(() => {
- assert.deepEqual(form.data, hiddenData.data);
- done();
- }, 250);
- }, 250);
- });
- });
-
- const formElement = document.createElement('div');
- const checkForErrors = function(form, flags = {}, submission, numErrors, done) {
- form.setSubmission(submission, flags).then(() => {
- setTimeout(() => {
- const errors = formElement.querySelectorAll('.formio-error-wrapper');
- expect(errors.length).to.equal(numErrors);
- expect(form.errors.length).to.equal(numErrors);
- done();
- }, 100);
- }).catch(done);
- };
-
- //BUG - uncomment once fixed (ticket FIO-6042)
- // it('Should not fire validations when fields are either protected or not persistent.', (done) => {
- // const form = new Webform(formElement,{ language: 'en', template: 'bootstrap3' });
- // form.setForm(
- // {
- // title: 'protected and persistent',
- // components: [
- // {
- // type: 'textfield',
- // label: 'A',
- // key: 'a',
- // validate: {
- // required: true
- // }
- // },
- // {
- // type: 'textfield',
- // label: 'B',
- // key: 'b',
- // protected: true,
- // validate: {
- // required: true
- // }
- // }
- // ],
- // }).then(() => {
- // checkForErrors(form, {}, {}, 0, () => {
- // checkForErrors(form, {}, {
- // data: {
- // a: 'Testing',
- // b: ''
- // }
- // }, 1, () => {
- // checkForErrors(form, {}, {
- // _id: '123123123',
- // data: {
- // a: 'Testing',
- // b: ''
- // }
- // }, 0, done);
- // });
- // });
- // });
- // });
-
- it('Should not fire validation on init.', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement,{ language: 'en', template: 'bootstrap3' });
- form.setForm(
- { title: 'noValidation flag',
- components: [{
- label: 'Number',
- validate: {
- required: true,
- min: 5
- },
- key: 'number',
- type: 'number',
- input: true
- }, {
- label: 'Text Area',
- validate: {
- required: true,
- minLength: 10
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- }],
- }).then(() => {
- checkForErrors(form, {}, {}, 0, done);
- });
- });
-
- it('Should validation on init when alwaysDirty flag is set.', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement, {
- language: 'en',
- template: 'bootstrap3',
- alwaysDirty: true
- });
- form.setForm(
- { title: 'noValidation flag',
- components: [{
- label: 'Number',
- validate: {
- required: true,
- min: 5
- },
- key: 'number',
- type: 'number',
- input: true
- }, {
- label: 'Text Area',
- validate: {
- required: true,
- minLength: 10
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- }],
- }).then(() => {
- checkForErrors(form, {}, {}, 2, done);
- });
- });
-
- it('Should validation on init when dirty flag is set.', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement, {
- language: 'en',
- template: 'bootstrap3'
- });
- form.setForm(
- { title: 'noValidation flag',
- components: [{
- label: 'Number',
- validate: {
- required: true,
- min: 5
- },
- key: 'number',
- type: 'number',
- input: true
- }, {
- label: 'Text Area',
- validate: {
- required: true,
- minLength: 10
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- }],
- }).then(() => {
- checkForErrors(form, {
- dirty: true
- }, {}, 2, done);
- });
- });
-
- it('Should not show any errors on setSubmission when providing an empty data object', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement,{ language: 'en', template: 'bootstrap3' });
- form.setForm(
- { title: 'noValidation flag',
- components: [{
- label: 'Number',
- validate: {
- required: true,
- min: 5
- },
- key: 'number',
- type: 'number',
- input: true
- }, {
- label: 'Text Area',
- validate: {
- required: true,
- minLength: 10
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- }],
- }
- ).then(() => {
- checkForErrors(form, {}, {}, 0, done);
- });
- });
-
- it('Should not show errors when providing empty data object with data set.', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement,{ language: 'en', template: 'bootstrap3' });
- form.setForm(
- { title: 'noValidation flag',
- components: [{
- label: 'Number',
- validate: {
- required: true,
- min: 5
- },
- key: 'number',
- type: 'number',
- input: true
- }, {
- label: 'Text Area',
- validate: {
- required: true,
- minLength: 10
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- }],
- }
- ).then(() => {
- checkForErrors(form, {}, { data: {} }, 0, done);
- });
- });
-
- it('Should show errors on setSubmission when providing explicit data values.', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement,{ language: 'en', template: 'bootstrap3' });
- form.setForm(
- { title: 'noValidation flag',
- components: [{
- label: 'Number',
- validate: {
- required: true,
- min: 5
- },
- key: 'number',
- type: 'number',
- input: true
- }, {
- label: 'Text Area',
- validate: {
- required: true,
- minLength: 10
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- }],
- }
- ).then(() => {
- checkForErrors(form, {}, {
- data:{
- number: 2,
- textArea: ''
- }
- }, 2, done);
- });
- });
-
- it('Should not show errors on setSubmission with noValidate:TRUE', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement,{ language: 'en', template: 'bootstrap3' });
- form.setForm(
- { title: 'noValidation flag',
- components: [{
- label: 'Number',
- validate: {
- required: true,
- min: 5
- },
- key: 'number',
- type: 'number',
- input: true
- }, {
- label: 'Text Area',
- validate: {
- required: true,
- minLength: 10
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- }],
- }
- ).then(() => {
- checkForErrors(form, {
- noValidate:true
- }, {
- data:{
- number: 2,
- textArea: ''
- }
- }, 0, done);
- });
- });
-
- it('Should set calculated value correctly', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement);
- form.setForm(calculateZeroValue).then(() => {
- const a = form.components[0];
- const b = form.components[1];
- const sum = form.components[2];
-
- a.setValue(10);
- b.setValue(5);
- setTimeout(() => {
- assert.equal(a.dataValue, 10);
- assert.equal(b.dataValue, 5);
- assert.equal(sum.dataValue, 15);
-
- a.setValue('0');
- b.setValue('0');
- setTimeout(() => {
- assert.equal(a.dataValue, 0);
- assert.equal(b.dataValue,0);
- assert.equal(sum.dataValue, 0);
-
- done();
- }, 250);
- }, 250);
- }).catch(done);
- });
-
- it('Should render Nested Modal Wizard Form correctly', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement);
- form.setForm(nestedModalWizard).then(() => {
- const openModalRef = form.element.querySelector('[ref="openModal"]');
- assert(openModalRef, 'Should render Open Modal button');
- const wizard = form.components[1].subForm;
- wizard.setPage(1);
- setTimeout(() => {
- const openModalRef = form.element.querySelector('[ref="openModal"]');
- assert(openModalRef, 'Should render Open Modal button after the page was changed');
- done();
- }, 250);
- }).catch(done);
- });
-
- it('Should set calculated value correctly', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement);
- form.setForm(disableSubmitButton).then(() => {
- const textField = form.getComponent(['textField']);
- const fileA = form.getComponent(['upload']);
- const fileB = form.getComponent(['file']);
- const submitButton = form.getComponent(['submit']);
- assert.equal(submitButton.disabled, false, 'Button should be enabled at the beginning');
-
- const simulateFileUploading = (comp, debounce = 250) => {
- const filePromise = new NativePromise((resolve) => {
- setTimeout(() => resolve(), debounce);
- });
- filePromise.then(() => comp.emit('fileUploadingEnd', filePromise));
- comp.emit('fileUploadingStart', filePromise);
- };
-
- simulateFileUploading(fileA, 1000);
- textField.setValue('12345');
- setTimeout(() => {
- assert.equal(submitButton.filesUploading.length, 1);
- assert.equal(submitButton.isDisabledOnInvalid, true, 'Should be disabled on invalid due to the invalid TextField\'s value');
- assert.equal(submitButton.disabled, true, 'Should be disabled');
- simulateFileUploading(fileB, 500);
- setTimeout(() => {
- assert.equal(submitButton.filesUploading.length, 2);
- assert.equal(submitButton.disabled, true, 'Should be disabled');
- setTimeout(() => {
- assert.equal(submitButton.filesUploading.length, 0);
- assert.equal(submitButton.disabled, true, 'Should be disabled since TextField is still invalid');
- textField.setValue('123');
- setTimeout(() => {
- assert.equal(submitButton.disabled, false, 'Should be enabled');
- done();
- }, 250);
- }, 650);
- }, 100);
- }, 250);
- }).catch(done);
- });
-
- describe('set/get nosubmit', () => {
- it('should set/get nosubmit flag and emit nosubmit event', () => {
- const form = new Webform(null, {});
- const emit = sinon.spy(form, 'emit');
- expect(form.nosubmit).to.be.false;
- form.nosubmit = true;
- expect(form.nosubmit).to.be.true;
- expect(emit.callCount).to.equal(1);
- expect(emit.args[0]).to.deep.equal(['nosubmit', true]);
- form.nosubmit = false;
- expect(form.nosubmit).to.be.false;
- expect(emit.callCount).to.equal(2);
- expect(emit.args[1]).to.deep.equal(['nosubmit', false]);
- });
- });
-
- describe('getValue and setValue', () => {
- it('should setValue and getValue', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm({
- components: [
- {
- type: 'textfield',
- key: 'a'
- },
- {
- type: 'container',
- key: 'b',
- components: [
- {
- type: 'datagrid',
- key: 'c',
- components: [
- {
- type: 'textfield',
- key: 'd'
- },
- {
- type: 'textfield',
- key: 'e'
- },
- {
- type: 'editgrid',
- key: 'f',
- components: [
- {
- type: 'textfield',
- key: 'g'
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }).then(() => {
- let count = 0;
- const onChange = form.onChange;
- form.onChange = function(...args) {
- count++;
- return onChange.apply(form, args);
- };
-
- // Ensure that it says it changes.
- assert.equal(form.setValue({
- a: 'a',
- b: {
- c: [
- { d: 'd1', e: 'e1', f: [{ g: 'g1' }] },
- { d: 'd2', e: 'e2', f: [{ g: 'g2' }] },
- ]
- }
- }), true);
-
- setTimeout(() => {
- // It should have only updated once.
- assert.equal(count, 1);
- done();
- }, 500);
- });
- });
- });
-
- describe('ReadOnly Form', () => {
- it('Should apply conditionals when in readOnly mode.', (done) => {
- done = _.once(done);
- const Conditions = require('../test/forms/conditions').default;
- const formElement = document.createElement('div');
- const form = new Webform(formElement, {
- readOnly: true,
- language: 'en',
- template: 'bootstrap3'
- });
- form.setForm(Conditions.form).then(() => {
- Harness.testConditionals(form, {
- data: {
- typeShow: 'Show',
- typeMe: 'Me',
- typeThe: 'The',
- typeMonkey: 'Monkey!'
- }
- }, [], (error) => {
- form.destroy();
- if (error) {
- throw new Error(error);
- }
- done();
- });
- });
- });
- });
-
- describe('Validate onBlur', () => {
- it('Should keep component valid onChange', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(validationOnBlur).then(() => {
- const field = form.components[0];
- const field2 = form.components[1];
- const fieldInput = field.refs.input[0];
-
- Harness.setInputValue(field, 'data[textField]', '12');
-
- setTimeout(() => {
- assert(!field.error, 'Should be valid while changing');
- const blurEvent = new Event('blur');
- fieldInput.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert(field.error, 'Should set error aftre component was blured');
- Harness.setInputValue(field2, 'data[textField1]', 'ab');
-
- setTimeout(() => {
- assert(field.error, 'Should keep error when editing another component');
- done();
- }, 250);
- }, 250);
- }, 250);
- }).catch(done);
- });
-
- it('Should keep components inside DataGrid valid onChange', (done) => {
- formElement.innerHTML = '';
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(dataGridOnBlurValidation).then(() => {
- const component = form.components[0];
- Harness.setInputValue(component, 'data[dataGrid][0][textField]', '12');
-
- setTimeout(() => {
- const textField = component.iteratableRows[0].components.textField;
- assert.equal(!!textField.error, false, 'Should stay valid on input');
- const blur = new Event('blur', { bubbles: true, cancelable: true });
- const input = textField.refs.input[0];
- input.dispatchEvent(blur);
- textField.element.dispatchEvent(blur);
- setTimeout(() => {
- assert(textField.error, 'Should be validated after blur');
- done();
- }, 250);
- }, 250);
- }).catch(done);
- });
- });
-
- describe('Reset values', () => {
- it('Should reset all values correctly.', () => {
- formElement.innerHTML = '';
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- return form.setForm(
- {
- components: [
- {
- type: 'textfield',
- key: 'firstName',
- label: 'First Name',
- placeholder: 'Enter your first name.',
- input: true,
- tooltip: 'Enter your First Name ',
- description: 'Enter your First Name '
- },
- {
- type: 'textfield',
- key: 'lastName',
- label: 'Last Name',
- placeholder: 'Enter your last name',
- input: true,
- tooltip: 'Enter your Last Name ',
- description: 'Enter your Last Name '
- },
- {
- type: 'select',
- label: 'Favorite Things',
- key: 'favoriteThings',
- placeholder: 'These are a few of your favorite things...',
- data: {
- values: [
- {
- value: 'raindropsOnRoses',
- label: 'Raindrops on roses'
- },
- {
- value: 'whiskersOnKittens',
- label: 'Whiskers on Kittens'
- },
- {
- value: 'brightCopperKettles',
- label: 'Bright Copper Kettles'
- },
- {
- value: 'warmWoolenMittens',
- label: 'Warm Woolen Mittens'
- }
- ]
- },
- dataSrc: 'values',
- template: '{{ item.label }} ',
- multiple: true,
- input: true
- },
- {
- type: 'number',
- key: 'number',
- label: 'Number',
- input: true
- },
- {
- type: 'button',
- action: 'submit',
- label: 'Submit',
- theme: 'primary'
- }
- ]
- }
- ).then(() => {
- form.setSubmission({
- data: {
- firstName: 'Joe',
- lastName: 'Bob',
- favoriteThings: ['whiskersOnKittens', 'warmWoolenMittens'],
- number: 233
- }
- }).then(() => {
- expect(form.submission).to.deep.equal({
- data: {
- firstName: 'Joe',
- lastName: 'Bob',
- favoriteThings: ['whiskersOnKittens', 'warmWoolenMittens'],
- number: 233,
- submit: false
- }
- });
- form.setSubmission({ data: {} }).then(() => {
- expect(form.submission).to.deep.equal({
- data: {
- firstName: '',
- lastName: '',
- favoriteThings: [],
- submit: false
- }
- });
- });
- });
- });
- });
- });
-
- describe('New Simple Conditions', () => {
- it('Should show field if all conditions are met', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formsWithNewSimpleConditions.form1).then(() => {
- const conditionalComponent = form.getComponent('conditionalField');
- assert.equal(conditionalComponent.visible, false, '(1) Component should be conditionally hidden');
-
- form.setValue({ data: { number: 11, email: 'test@form.io', radio: 'one' } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, true, '(2) Component should be conditionally visible');
- const emailComponent = form.getComponent('email');
-
- emailComponent.setValue('test@form1.io');
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, '(3) Component should be conditionally hidden');
- done();
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should show field if any condition is met', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- const formCopy = fastCloneDeep(formsWithNewSimpleConditions.form1);
- _.set(formCopy, 'components[0].conditional.conjunction', 'any');
-
- form.setForm(formCopy).then(() => {
- const conditionalComponent = form.getComponent('conditionalField');
- assert.equal(conditionalComponent.visible, false, '(1) Component should be conditionally hidden');
-
- form.setValue({ data: { number: 1100, email: 'test@form.io' } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, true, '(2) Component should be conditionally visible');
- form.setValue({ data: { number: 10 , email: 'test@form1.io' } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, true, '(3) Component should be conditionally visible');
- form.setValue({ data: { number: 10000 } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, '(4) Component should be conditionally hidden');
- form.setValue({ data: { radio: 'one' } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, true, '(5) Component should be conditionally visible');
-
- done();
- }, 450);
- }, 400);
- }, 350);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should hide field if any condition is met', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- const formCopy = fastCloneDeep(formsWithNewSimpleConditions.form1);
- _.set(formCopy, 'components[0].conditional.show', false);
- _.set(formCopy, 'components[0].conditional.conjunction', 'any');
-
- form.setForm(formCopy).then(() => {
- const conditionalComponent = form.getComponent('conditionalField');
- assert.equal(conditionalComponent.visible, true, 'Component should be conditionally visible');
-
- form.setValue({ data: { number: 1100, email: 'test@form.io' } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, 'Component should be conditionally hidden');
- form.setValue({ data: { number: 10 , email: 'test@form1.io' } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, 'Component should be conditionally hidden');
- form.setValue({ data: { number: 10000 } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, true, 'Component should be conditionally visible');
- form.setValue({ data: { radio: 'one' } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, 'Component should be conditionally hidden');
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should hide field if all conditions are met', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- const formCopy = fastCloneDeep(formsWithNewSimpleConditions.form1);
- _.set(formCopy, 'components[0].conditional.show', false);
-
- form.setForm(formCopy).then(() => {
- const conditionalComponent = form.getComponent('conditionalField');
- assert.equal(conditionalComponent.visible, true, 'Component should be conditionally visible');
-
- form.setValue({ data: { number: 11, email: 'test@form.io', radio: 'one' } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, 'Component should be conditionally hidden');
- const emailComponent = form.getComponent('email');
-
- emailComponent.setValue('test@form1.io');
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, true, 'Component should be conditionally visible');
- done();
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should show field if all conditions are met (test with different component types + multiple components)', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formsWithNewSimpleConditions.form2).then(() => {
- const conditionalComponent = form.getComponent('conditionalField');
- assert.equal(conditionalComponent.visible, false, 'Component should be conditionally hidden');
-
- form.setValue({
- data: {
- email: 'test@form.io',
- day: '10/06/2022',
- survey: {
- q1: 'true',
- },
- number: [100, 25, 350],
- checkbox: true,
- selectBoxes: {
- one: true,
- two: false,
- three: false,
- four: false,
- five: false,
- },
- radio: 'two',
- tags: 'test,newtag',
- selectValues: 'one',
- selectCustomWithValuesOfNumberType: 1,
- submit: true,
- currency: 35,
- }
- });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, true, 'Component should be conditionally visible');
- const dayComponent = form.getComponent('day');
-
- dayComponent.setValue('8/09/2022');
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, 'Component should be conditionally hidden');
- done();
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should show/hide field inside datagrid rows', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formsWithNewSimpleConditions.form4).then(() => {
- const dataGrid = form.getComponent('dataGrid');
-
- dataGrid.setValue([
- { number: 50 },
- { number: 55 },
- { number: 12 },
- { number: 105 },
- ]);
-
- setTimeout(() => {
- const expectedValues = {
- '0': true,
- '1': false,
- '2': true,
- '3': false
- };
-
- _.each(dataGrid.rows, (row, index) => {
- assert.equal(row['textField'].visible, expectedValues[`${index}`], `Component should be conditionally ${expectedValues[`${index}`] ? 'visible': 'hidden'} in row ${index}`);
- });
- done();
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should set component value through logic triggered by simple condition', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formsWithNewSimpleConditions.form3).then(() => {
- const componentWithLogic = form.getComponent('fieldWithLogic');
- assert.equal(componentWithLogic.isEmpty(), true, 'Component should be empty');
-
- form.setValue({
- data: {
- number: 2,
- radio: 'two'
- }
- });
-
- setTimeout(() => {
- assert.equal(componentWithLogic.dataValue, 'logic works', 'Component should have value set by logic');
- done();
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should show field if all conditions are met (test all operators)', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formsWithNewSimpleConditions.form5).then(() => {
- const conditionalComponent = form.getComponent('conditionalField');
- assert.equal(conditionalComponent.visible, false, '(1) Component should be conditionally hidden');
-
- form.setValue({ data: {
- dateTime: '2022-09-29T12:00:00+03:00',
- day: '09/29/2022',
- dateTime1: '2022-09-29T12:00:00+03:00',
- day1: '09/29/2022',
- url: 'portal.form.io',
- number: 100,
- currency: 100,
- textField1: 'some test text',
- day2: '09/29/2022',
- select: '',
- radio: 'one',
- dateTime3: '2022-09-12T12:00:00+03:00',
- textArea: 'test',
- textField2: 'test2',
- number2: [100],
- currency2: 100,
- email: 'some@form.io',
- url2: 'portal.form.io',
- } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, true, '(2) Component should be conditionally visible');
- const selectComponent = form.getComponent('select');
-
- selectComponent.setValue('one');
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, '(3) Component should be conditionally hidden');
- done();
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should show field when condition is based on the values of select resource with object value', (done) => {
- const element = document.createElement('div');
- const values = [
- {
- _id: '656daabeebc67ecca1141569',
- form: '656daab0ebc67ecca1141226',
- data: {
- number: 4,
- notes: 'notes 4',
- },
- project: '656daa20ebc67ecca1140e8d',
- state: 'submitted',
- created: '2023-12-04T10:32:30.821Z',
- modified: '2023-12-06T14:25:00.886Z',
- },
- {
- _id: '656daabbebc67ecca11414a7',
- form: '656daab0ebc67ecca1141226',
- data: {
- number: 3,
- notes: 'notes 3',
- },
- project: '656daa20ebc67ecca1140e8d',
- state: 'submitted',
- created: '2023-12-04T10:32:27.322Z',
- modified: '2023-12-06T14:25:07.494Z',
- },
- {
- _id: '656daab8ebc67ecca11413e5',
- form: '656daab0ebc67ecca1141226',
- data: {
- number: 2,
- notes: 'notes 2',
- },
- project: '656daa20ebc67ecca1140e8d',
- state: 'submitted',
- created: '2023-12-04T10:32:24.514Z',
- modified: '2023-12-06T14:25:13.610Z',
- },
- {
- _id: '656daab5ebc67ecca1141322',
- form: '656daab0ebc67ecca1141226',
- data: {
- number: 1,
- notes: 'notes 1',
- },
- project: '656daa20ebc67ecca1140e8d',
- state: 'submitted',
- created: '2023-12-04T10:32:21.205Z',
- modified: '2023-12-06T14:25:20.930Z',
- },
- ];
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- setTimeout(() => {
- resolve(values);
- }, 50);
- });
- };
-
- Formio.createForm(element, formWithObjectValueSelect)
- .then(form => {
- const numberComp = form.getComponent('number');
- assert.equal(numberComp.visible, false);
-
- const selectRef = form.getComponent('selectRef');
- selectRef.setValue(fastCloneDeep(values[3]));
- const selectNoValuePropertyMult = form.getComponent('selectNoValueProperty');
- selectNoValuePropertyMult.setValue([fastCloneDeep(values[2])]);
- const selectEntireObject = form.getComponent('selectEntireObject');
- selectEntireObject.setValue(fastCloneDeep(values[1].data));
- const selectEntireObjectMult = form.getComponent('selectEntireObjectMult');
- selectEntireObjectMult.setValue([fastCloneDeep(values[0].data)]);
-
- setTimeout(() => {
- assert.equal(numberComp.visible, true);
- selectRef.setValue(fastCloneDeep(values[2]));
- setTimeout(() => {
- assert.equal(numberComp.visible, false);
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 400);
- }, 400);
- })
- .catch(done);
- });
-
- it('Should hide field if the checkbox based condition with string value is met', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- const formCopy = fastCloneDeep(formsWithNewSimpleConditions.form7);
-
- form.setForm(formCopy).then(() => {
- const conditionalComponent = form.getComponent('textField');
- assert.equal(conditionalComponent.visible, true, 'Component should be conditionally visible');
-
- form.setValue({ data: { checkbox: true } });
-
- setTimeout(() => {
- assert.equal(conditionalComponent.visible, false, 'Component should be conditionally hidden');
- done();
- }, 300);
- }).catch((err) => done(err));
- });
- });
-
- describe('Calculate Value with allowed manual override', () => {
- const initialSubmission = {
- data: {
- dataGrid: [
- { label: 'yes', value: 'yes' },
- { label: 'no', value: 'no' },
- ],
- checkbox: false,
- submit: false
- },
- metadata: {}
- };
- const submissionWithOverridenValues = {
- data: {
- dataGrid: [
- { label: 'yes', value: 'y' },
- { label: 'no', value: 'n' },
- ],
- checkbox: false,
- submit: false
- },
- metadata: {}
- };
- const submissionWithOverridenValues2 = {
- data: {
- dataGrid: [
- { label: 'yes2', value: 'y' },
- { label: 'no', value: 'n' },
- ],
- checkbox: false,
- submit: false
- },
- metadata: {}
- };
- it('Should reset all values correctly.', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(calculateValueWithManualOverride).then(() => {
- const dataGrid = form.getComponent('dataGrid');
- dataGrid.setValue([{ label: 'yes' }, { label: 'no' }]);
- setTimeout(() => {
- expect(form.submission).to.deep.equal(initialSubmission);
- const row1Value = form.getComponent(['dataGrid', 0, 'value']);
- const row2Value = form.getComponent(['dataGrid', 1, 'value']);
- row1Value.setValue('y');
- row2Value.setValue('n');
-
- setTimeout(() => {
- expect(form.submission).to.deep.equal(submissionWithOverridenValues);
- const row1Label = form.getComponent(['dataGrid', 0, 'label']);
- row1Label.setValue('yes2');
- setTimeout(() => {
- expect(form.submission).to.deep.equal(submissionWithOverridenValues2);
- form.setSubmission(submissionWithOverridenValues).then(() => {
- setTimeout(() => {
- const tabs = form.getComponent(['tabs']);
- tabs.setTab(1);
- setTimeout(() => {
- expect(form.submission).to.deep.equal(submissionWithOverridenValues);
- done();
- }, 250);
- }, 150);
- });
- }, 250);
- }, 250);
- }, 250);
- }).catch(done);
- });
-
- it('Should apply submission metadata value in calculation.', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(calculateValueWithSubmissionMetadata).then(() => {
- const textField = form.getComponent('textField');
-
- textField.setValue('test value');
-
- form.submit(false, {});
-
- setTimeout(() => {
- expect(form.submission.metadata).to.exist;
- expect(form.submission.metadata.timezone).to.be.not.empty;
- expect(form.submission.data.textField).to.be.not.empty;
- expect(form.submission.data.textArea).to.be.not.empty;
- expect(form.submission.data.textArea).to.equal(
- form.submission.data.textField + form.submission.metadata.timezone
- );
-
- done();
- }, 250);
- }).catch(done);
- });
-
- it('Should allow to change value.', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(calculatedSelectboxes).then(() => {
- const radio = form.getComponent(['radio']);
- radio.setValue('a');
- setTimeout(() => {
- assert.equal(radio.dataValue, 'a');
- const selectBoxes = form.getComponent(['selectBoxes']);
- assert.equal(selectBoxes.dataValue['a'], true, 'Should calculate value and set it to "a"');
- selectBoxes.setValue({
- 'a': true,
- 'b': true,
- 'c': false
- });
- setTimeout(() => {
- assert.deepEqual(selectBoxes.dataValue, {
- 'a': true,
- 'b': true,
- 'c': false
- }, 'Should change the value');
- done();
- }, 250);
- }, 250);
- }).catch(done);
- });
-
- it('Should recalculate values for components with "allow override" after first and only dataGrid row is removed/reset', function(done) {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, formsWithAllowOverride.withDataGrid).then((form) => {
- const calculatedValues = {
- number: 11111,
- textField: 'test DataGrid',
- textArea: 'test',
- };
-
- const overridenValues = {
- number: 11111222,
- textField: 'test DataGrid 222',
- textArea: 'test 222',
- };
-
- const number = form.getComponent('number');
- const textArea = form.getComponent('textArea');
- const textField = form.getComponent('textField');
- const dgRadio = form.getComponent('dgRadio');
- const dataGrid = form.getComponent('dataGrid');
- // check if values are calculated on form load
- assert.deepEqual(dataGrid.dataValue, [
- {
- ...calculatedValues,
- textField: textField.emptyValue,
- dgRadio: dgRadio.emptyValue
- }
- ], 1);
-
- dgRadio.setValue('a');
-
- setTimeout(() => {
- // check if values are calculated correctly
- assert.deepEqual(dataGrid.dataValue, [
- {
- ...calculatedValues,
- dgRadio: 'a'
- }
- ]);
-
- // override calculated values
- const numberInput = number.refs.input[0];
- const textFieldInput = textField.refs.input[0];
- const textAreaInput = textArea.refs.input[0];
-
- numberInput.value = overridenValues.number;
- textFieldInput.value = overridenValues.textField;
- textAreaInput.value = overridenValues.textArea;
-
- const inputEvent = new Event('input');
-
- numberInput.dispatchEvent(inputEvent);
- textFieldInput.dispatchEvent(inputEvent);
- textAreaInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- // check if values are overriden
- assert.deepEqual(dataGrid.dataValue, [
- {
- ...overridenValues,
- dgRadio: 'a'
- }
- ], 2);
-
- // clear first row
- dataGrid.removeRow(0);
-
- setTimeout(() => {
- const dgRadio = form.getComponent('dgRadio');
- // make sure values are reset and recalculated
- assert.deepEqual(dataGrid.dataValue, [
- {
- ...calculatedValues,
- textField: textField.emptyValue,
- dgRadio: dgRadio.emptyValue
- }
- ], 3);
-
- dgRadio.setValue('a');
- setTimeout(() => {
- // check if all values are calculated correctly
- assert.deepEqual(dataGrid.dataValue, [
- {
- ...calculatedValues,
- dgRadio: 'a'
- }
- ], 4);
-
- document.body.innerHTML = '';
- done();
- }, 400);
- }, 400);
- }, 400);
- }, 400);
- }).catch((err) => done(err));
- });
-
- it('Should recalculate values for components with "allow override" after the form is reset', function(done) {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, formsWithAllowOverride.withResetBtn).then((form) => {
- const calculatedValues = {
- number: 11111,
- textField: 'test DataGrid',
- textArea: 'test',
- radio: 'one'
- };
-
- const overridenValues = {
- number: 11111222,
- textField: 'test DataGrid 222',
- textArea: 'test 222',
- radio: 'two'
- };
- const checkbox = form.getComponent('checkbox');
- const number = form.getComponent('number');
- const textArea = form.getComponent('textArea');
- const radio = form.getComponent('radio');
- const textField = form.getComponent('textField');
- const dgRadio = form.getComponent('dgRadio');
- const resetBtn = form.getComponent('reset');
-
- dgRadio.setValue('a');
- checkbox.setValue(true);
- setTimeout(() => {
- // check if values were calculated correctly
- assert.equal(number.dataValue, calculatedValues.number);
- assert.equal(textField.dataValue, calculatedValues.textField);
- assert.equal(textArea.dataValue, calculatedValues.textArea);
- assert.equal(radio.dataValue, calculatedValues.radio);
-
- // override calculated values
- const numberInput = number.refs.input[0];
- const textFieldInput = textField.refs.input[0];
- const textAreaInput = textArea.refs.input[0];
- const radioInput =radio.refs.input[1];
-
- numberInput.value = overridenValues.number;
- textFieldInput.value = overridenValues.textField;
- textAreaInput.value = overridenValues.textArea;
- radioInput.checked = true;
- const inputEvent = new Event('input');
- const clickEvent = new Event('click');
-
- numberInput.dispatchEvent(inputEvent);
- textFieldInput.dispatchEvent(inputEvent);
- textAreaInput.dispatchEvent(inputEvent);
- radioInput.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- // check if values were overriden
- assert.equal(number.getValue(), overridenValues.number);
- assert.equal(textField.dataValue, overridenValues.textField);
- assert.equal(textArea.dataValue, overridenValues.textArea);
- assert.equal(radio.dataValue, overridenValues.radio);
-
- checkbox.setValue(false);
-
- setTimeout(() => {
- // reset form
- resetBtn.refs.button.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- // make sure that values are reset
- assert.equal(number.dataValue, calculatedValues.number);
- assert.equal(textArea.dataValue, calculatedValues.textArea);
- assert.equal(textField.dataValue, textField.emptyValue);
- assert.equal(radio.dataValue, radio.emptyValue);
- assert.equal(dgRadio.dataValue, dgRadio.emptyValue);
- assert.equal(checkbox.dataValue, checkbox.emptyValue);
-
- // trigger values calculation
- dgRadio.setValue('a');
- checkbox.setValue(true);
-
- setTimeout(() => {
- // make sure that values are recalculated
- assert.equal(number.dataValue, calculatedValues.number);
- assert.equal(textField.dataValue, calculatedValues.textField);
- assert.equal(textArea.dataValue, calculatedValues.textArea);
- assert.equal(radio.dataValue, calculatedValues.radio);
- document.body.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }, 400);
- }).catch((err) => done(err));
- });
-
- it('Should recalculate values for conditional components with "allow override" and "clear on hide" enabled when components become visible again', function(done) {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, formsWithAllowOverride.withClearOnHide).then((form) => {
- const calculatedValues = {
- number: 111,
- textField: 'test',
- textArea: 'test value',
- radio: 'a'
- };
-
- const overridenValues = {
- number: 11123,
- textField: 'test123',
- textArea: 'test123',
- radio: 'b'
- };
- const checkbox = form.getComponent('checkbox');
- const number = form.getComponent('number');
- const textField = form.getComponent('textField');
- const textArea = form.getComponent('textArea');
- const radio = form.getComponent('radio');
-
- assert.equal(number.visible, false);
- assert.equal(textField.visible, false);
- assert.equal(textArea.visible, false);
- assert.equal(radio.visible, false);
-
- checkbox.setValue(true);
- setTimeout(() => {
- assert.equal(number.visible, true);
- assert.equal(textField.visible, true);
- assert.equal(textArea.visible, true);
- assert.equal(radio.visible, true);
- // check if values were calculated correctly
- assert.equal(number.dataValue, calculatedValues.number);
- assert.equal(textField.dataValue, calculatedValues.textField);
- assert.equal(textArea.dataValue, calculatedValues.textArea);
- assert.equal(radio.dataValue, calculatedValues.radio);
-
- // override calculated values
- const numberInput = number.refs.input[0];
- const textFieldInput = textField.refs.input[0];
- const textAreaInput = textArea.refs.input[0];
- const radioInput =radio.refs.input[1];
-
- numberInput.value = overridenValues.number;
- textFieldInput.value = overridenValues.textField;
- textAreaInput.value = overridenValues.textArea;
- radioInput.checked = true;
- const inputEvent = new Event('input');
- const clickEvent = new Event('click');
-
- numberInput.dispatchEvent(inputEvent);
- textFieldInput.dispatchEvent(inputEvent);
- textAreaInput.dispatchEvent(inputEvent);
- radioInput.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- // check if values were overriden
- assert.equal(number.getValue(), overridenValues.number);
- assert.equal(textField.dataValue, overridenValues.textField);
- assert.equal(textArea.dataValue, overridenValues.textArea);
- assert.equal(radio.dataValue, overridenValues.radio);
-
- checkbox.setValue(false);
-
- setTimeout(() => {
- // check if conditional components were hidden
- assert.equal(number.visible, false);
- assert.equal(textField.visible, false);
- assert.equal(textArea.visible, false);
- assert.equal(radio.visible, false);
-
- checkbox.setValue(true);
- setTimeout(() => {
- // make sure that components appear again and values were recalculated
- assert.equal(number.visible, true);
- assert.equal(textField.visible, true);
- assert.equal(textArea.visible, true);
- assert.equal(radio.visible, true);
-
- assert.equal(number.dataValue, calculatedValues.number);
- assert.equal(textField.dataValue, calculatedValues.textField);
- assert.equal(textArea.dataValue, calculatedValues.textArea);
- assert.equal(radio.dataValue, calculatedValues.radio);
- document.body.innerHTML = '';
-
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 400);
- }).catch((err) => done(err));
- });
- });
-
- describe('Modal Edit', () => {
- const submission = {
- state: 'submitted',
- data: {
- checkbox: true,
- selectBoxes: {
- a: true,
- b: true
- },
- textfield: 'My Text',
- select: 'f',
- submit: true
- }
- };
- const componentsKeys = ['checkbox', 'selectBoxes', 'select', 'textfield'];
- const expectedValues = {
- checkbox: 'Yes',
- selectBoxes: 'a, b',
- select: 'f',
- textfield: 'My Text'
- };
- it('Test rendering previews after the submission is set', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(modalEditComponents).then(() => {
- return form.setSubmission(submission, { fromSubmission: true }).then(() => {
- componentsKeys.forEach((key) => {
- const comp = form.getComponent([key]);
- assert(comp);
- const preview = comp.componentModal.refs.openModal;
- assert(preview);
- assert.equal(preview.textContent.replace(/\n|\t/g, '').trim(), expectedValues[key]);
- });
- done();
- });
- }).catch(done);
- });
-
- it('Test updating previews after aboting changes', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(modalEditComponents).then(() => {
- return form.setSubmission(submission, { fromSubmission: true }).then(() => {
- const comp = form.getComponent(['textfield']);
- comp.componentModal.openModal();
- Harness.dispatchEvent('input', comp.componentModal.refs.modalContents, '[name="data[textfield]"]', (el) => {
- el.value = 'My Text v2';
- });
- setTimeout(() => {
- const fakeEvent = {
- preventDefault: () => {}
- };
- comp.componentModal.closeModalHandler(fakeEvent);
- const preview = comp.componentModal.refs.openModal;
- assert.equal(preview.textContent.replace(/\n|\t/g, '').trim(), 'My Text');
- done();
- }, 100);
- });
- }).catch(done);
- });
- });
-
- describe('Initially Collapsed Panel', () => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(initiallyCollapsedPanel).then(() => {
- it('Should be collapsed', (done) => {
- try {
- const panelBody = form.element.querySelector('[ref=nested-panel]');
- assert.equal(panelBody, null, 'Should not render the panel\'s body when initially collapsed');
- done();
- }
- catch (err) {
- done(err);
- }
- });
- it('Should open when an Error occured', (done) => {
- form.executeSubmit().catch(() => {
- try {
- const panelBody = form.element.querySelector('[ref=nested-panel]');
- assert(panelBody, 'Should open the panel when an error occured');
- done();
- }
- catch (err) {
- done(err);
- }
- });
- });
- }).catch((err) => console.error(err));
- });
-
- describe('Calculate Value', () => {
- it('Should calculate value when set submission if the component is not persistent', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3', pdf: true });
- form.setForm(calculatedNotPersistentValue).then(() => {
- form.setSubmission({
- data:
- {
- a: 'testValue'
- },
- state: 'submitted'
- });
- setTimeout(() => {
- const persistentField = form.getComponent(['a']);
- assert.equal(persistentField.dataValue, 'testValue', 'Should set the value from the submission');
- const notPersistentFieldInput = form.element.querySelector('input[name="data[textField]"]');
- assert.equal(notPersistentFieldInput.value, 'testValue', 'Should calculate the value');
- done();
- }, 550);
- }).catch(done);
- });
- it('Should calculate value by datasouce component when editing mode is on', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3', pdf: true });
- form.setForm(calculateValueInEditingMode).then(() => {
- form.editing = true;
- form.setSubmission({
- data:
- {
- select: { label: 'Dummy #1', value: 'dummy1' },
- dataSourceDisplay: 'some value'
- },
- state: 'submitted'
- })
- .then(() => {
- const dataSource = form.getComponent('datasource');
- dataSource.dataValue = { value: 'some value' };
- form.checkData(null, { dataSourceInitialLoading: true });
- setTimeout(() => {
- const dataSourceDisplay = form.getComponent('dataSourceDisplay');
- assert.equal(dataSourceDisplay.dataValue, 'some value', 'Should set and keep the value');
- done();
- }, 1000);
- });
- }).catch(done);
- });
- it('Should calculate value properly in editing mode', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3', pdf: true });
- form.setForm(calculatedValue).then(() => {
- form.editing = true;
- form.setSubmission({
- data:
- {
- a: 4,
- b: 5,
- total: 9,
- },
- state: 'submitted'
- });
- setTimeout(() => {
- const total = form.getComponent(['total']);
- assert.equal(total.dataValue, 9, 'Should set and keep the value');
-
- const b = form.getComponent(['b']);
- Harness.dispatchEvent('input', b.element, 'input', (i) => i.value = '6');
-
- setTimeout(() => {
- assert.equal(total.dataValue, 10, 'Should recalculate the value');
- }, 300);
- done();
- }, 1000);
- }).catch(done);
- });
- it('Should not override value which was set from submission', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3', pdf: true });
- form.setForm(calculateValueWithManualOverrideLableValueDataGrid).then(() => {
- form.editing = true;
- form.setSubmission({
- state: 'submitted',
- data: {
- dataGrid: [
- { label: '1', value: '1a' },
- { label: '2', value: '2a' },
- { label: '3', value: '3a' },
- ]
- },
- });
- setTimeout(() => {
- const value1 = form.getComponent(['dataGrid', 0, 'value']);
- assert.equal(value1.dataValue, '1a', 'Should have a value set from submission');
- const value2 = form.getComponent(['dataGrid', 1, 'value']);
- assert.equal(value2.dataValue, '2a', 'Should have a value set from submission');
- const value3 = form.getComponent(['dataGrid', 2, 'value']);
- assert.equal(value3.dataValue, '3a', 'Should have a value set from submission');
- done();
- }, 1000);
- }).catch(done);
- });
- });
-
- it('Should set different ids for components inside different Table rows', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3', pdf: true });
- form.setForm(conditionalDataGridWithTableAndRadio).then(() => {
- const radioInspection0 = form.getComponent(['inspectionDataGrid', 0, 'initialExam']);
- Harness.dispatchEvent(
- 'click',
- radioInspection0.element,
- 'input[value="reject"]',
- i => i.checked = true,
- );
-
- setTimeout(() => {
- const repairDataGrid0 = form.getComponent(['inspectionDataGrid', 0, 'repairDataGrid']);
- assert.equal(radioInspection0.dataValue, 'reject', 'Should set value');
- assert.equal(repairDataGrid0.visible, true, 'Should become visible');
-
- const radioRepair0 = form.getComponent(['inspectionDataGrid', 0, 'repairDataGrid', 0, 'repairExam']);
- Harness.dispatchEvent(
- 'click',
- radioRepair0.element,
- 'input[value="accept"]',
- i => i.checked = true,
- );
-
- setTimeout(() => {
- assert.equal(radioRepair0.dataValue, 'accept', 'Should set value');
- const inspectionDataGrid = form.getComponent(['inspectionDataGrid']);
- inspectionDataGrid.addRow();
-
- setTimeout(() => {
- assert.equal(inspectionDataGrid.rows.length, 2, 'Should add a row');
-
- const radioInspection1 = form.getComponent(['inspectionDataGrid', 1, 'initialExam']);
- Harness.dispatchEvent(
- 'click',
- radioInspection1.element,
- 'input[value="reject"]',
- i => i.checked = true,
- );
-
- setTimeout(() => {
- const repairDataGrid1 = form.getComponent(['inspectionDataGrid', 1, 'repairDataGrid']);
- assert.equal(radioInspection1.dataValue, 'reject', 'Should set value');
- assert.equal(repairDataGrid1.visible, true, 'Should become visible');
-
- const radioRepair1 = form.getComponent(['inspectionDataGrid', 1, 'repairDataGrid', 0, 'repairExam']);
- Harness.dispatchEvent(
- 'click',
- form.element,
- form.element.querySelector(`#${radioRepair1.root.id}-${radioRepair1.id}-${radioRepair1.row}-accept`),
- i => i.checked = true
- );
-
- setTimeout(() => {
- assert.equal(radioRepair1.dataValue, 'accept', 'Should set value of the clicked radio');
- assert.equal(radioRepair0.dataValue, 'accept', 'Value of the radio inside another row should stay the same');
-
- done();
- }, 300);
- }, 350);
- }, 300);
- }, 250);
- }, 350);
- }).catch(done);
- });
-
- it('Should render components properly', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(multipleTextareaInsideConditionalComponent).then(() => {
- form.setSubmission({
- data: {
- textArea2: [
- 'test'
- ],
- didAnyBehavioralIssuesOccurOnYourShift: 'yes',
- submit: false,
- }
- });
- setTimeout(() => {
- const textarea = form.getComponent(['textArea2']);
- const panel = form.getComponent(['behavioralIssues']);
- assert.equal(panel.visible, true, 'Should be visible');
- assert.deepEqual(textarea.dataValue, ['test'], 'Should set the value from the submission');
- const inputRows = textarea.element.querySelectorAll('[ref="input"]');
- assert.equal(inputRows.length, 1, 'Should render all the rows of the Textarea');
- done();
- }, 750);
- }).catch(done);
- });
-
- it('Should disable all the components inside Nested Form if it is disabled', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(disabledNestedForm).then(() => {
- assert.equal(form.components[0].disabled, false, 'Component that is outside of disabled Nested Form should be editable');
- const subFormComponents = form.components[1].subForm.components;
- assert.deepEqual([subFormComponents[0].disabled, subFormComponents[1].disabled], [true, true], 'Components that are inside of disabled Nested Form should be disabled');
- done();
- }).catch(done);
- });
-
- it('Should restore value correctly if NestedForm is saved as reference', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
- form.setForm(nestedFormInsideDataGrid).then(() => {
- const nestedForm = form.getComponent(['dataGrid', 0, 'form1']);
- const submissionWithIdOnly = { _id: '1232', data: {} };
- nestedForm.dataValue = { ...submissionWithIdOnly };
- nestedForm.restoreValue();
-
- setTimeout(() => {
- assert.deepEqual(nestedForm.dataValue, submissionWithIdOnly, 'Should not set to defaultValue after restore');
- done();
- }, 350);
- }).catch(done);
- });
-
- it('Should not set the default value if there is only Radio with False value', (done) => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, nestedFormInWizard).then((form) => {
- const nestedForm = form.getComponent(['form']);
- const submission = {
- data: {
- radio: false
- }
- };
-
- nestedForm.dataValue = { ...submission };
-
- setTimeout(() => {
- assert.deepEqual(nestedForm.dataValue, submission, 'Should set submission');
- nestedForm.valueChanged = true;
- form.setPage(1);
-
- setTimeout(() => {
- assert.deepEqual(nestedForm.dataValue.data, submission.data, 'Should not set to defaultValue after restore');
- done();
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should add and clear input error classes correctly', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
-
- form.setForm(UpdateErrorClassesWidgets).then(() => {
- const checkbox = form.getComponent('showDate');
- checkbox.setValue(true);
- setTimeout(() => {
- const dateTimeComponent = form.getComponent('condtionalDate');
- const dateComponentElement = dateTimeComponent.element;
- assert.equal(!dateComponentElement.className.includes('formio-hidden'), true, 'Should not be hidden');
-
- form.submit();
-
- setTimeout(() => {
- const dateVisibleInput = dateComponentElement.querySelector('.input');
- const flatpickerInput = dateComponentElement.querySelector('.flatpickr-input');
-
- assert(dateVisibleInput.className.includes('is-invalid'), 'Visible field should have invalid class');
- assert(flatpickerInput.className.includes('is-invalid'), 'Flatpickr field should have invalid class as well');
-
- dateTimeComponent.setValue('2020-12-09T00:00:00');
-
- setTimeout(() => {
- assert.equal(dateTimeComponent.dataValue, '2020-12-09T00:00:00', 'Should set value');
- assert(!dateVisibleInput.className.includes('is-invalid'), 'Invalid class should be removed');
- assert(!flatpickerInput.className.includes('is-invalid'), 'Invalid class should be removed from flatpickr field as well');
-
- checkbox.setValue(false);
-
- setTimeout(() => {
- const dateComponentElement = dateTimeComponent.element;
- assert.equal(dateComponentElement.className.includes('formio-hidden'), true, 'Should be hidden');
- checkbox.setValue(true);
-
- setTimeout(() => {
- const dateComponentElement = dateTimeComponent.element;
- assert.equal(!dateComponentElement.className.includes('formio-hidden'), true, 'Should be visible');
- const dateVisibleInput = dateComponentElement.querySelector('.input:not([type="hidden"])');
- const flatpickerInput = dateComponentElement.querySelector('.flatpickr-input');
-
- assert(dateVisibleInput.className.includes('is-invalid'), 'Visible field should has invalid class');
- assert(flatpickerInput.className.includes('is-invalid'), 'Flatpickr field should has invalid class as well');
-
- dateTimeComponent.setValue('2020-10-19T00:00:00');
- setTimeout(() => {
- assert.equal(dateTimeComponent.dataValue, '2020-10-19T00:00:00', 'Should set value');
- assert(!dateVisibleInput.className.includes('is-invalid'), 'Invalid class should be removed');
- assert(!flatpickerInput.className.includes('is-invalid'), 'Invalid class should be removed from flatpickr field as well');
- done();
- }, 300);
- }, 400);
- }, 300);
- }, 300);
- }, 300);
- }, 350);
- }).catch(done);
- }).timeout(3000);
-
- it('Should have number and currency fields in empty form submission', function(done) {
- const formElement = document.createElement('div');
- const form= new Webform(formElement);
- const formJson = {
- components: [
- {
- label: 'Number',
- key: 'number',
- type: 'number'
- },
- {
- label: 'Currency',
- key: 'currency',
- type: 'currency'
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit'
- },
- ],
- };
-
- const emptySubmissionData = {
- submit: true
- };
-
- form.setForm(formJson).then(() => {
- const clickEvent = new Event('click');
- const submitBtn = form.element.querySelector('[name="data[submit]"]');
-
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.deepEqual(form.data, emptySubmissionData);
- done();
- }, 400);
- })
- .catch((err) => done(err));
- });
-
- it('Test Truncate Multiple Spaces', (done) => {
- const formElement = document.createElement('div');
- const form= new Webform(formElement);
-
- form.setForm(truncateMultipleSpaces).then(() => {
- const textFieldRequired = form.getComponent(['textField1']);
- const textFieldMinMaxLength = form.getComponent(['textField']);
- const textAreaMinMaxLength = form.getComponent(['textArea']);
- Harness.dispatchEvent('input', textFieldRequired.element, 'input', (i) => i.value = ' ');
- Harness.dispatchEvent(
- 'input',
- textFieldMinMaxLength.element,
- 'input',
- (i) => i.value = ' 546 456 '
- );
- Harness.dispatchEvent(
- 'input',
- textAreaMinMaxLength.element,
- 'textarea',
- (i) => i.value = ' 546 456 '
- );
-
- setTimeout(() => {
- assert.equal(textFieldRequired.dataValue, ' ', 'Should set value');
- assert.equal(textFieldMinMaxLength.dataValue, ' 546 456 ', 'Should set value');
- assert.equal(textAreaMinMaxLength.dataValue, ' 546 456 ', 'Should set value');
-
- assert.equal(textFieldRequired.errors.length, 1, 'Should be invalid since it does not have a value');
- assert.equal(
- textFieldMinMaxLength.errors.length,
- 0,
- 'Should be valid since it value does not exceed the max length after truncating spaces'
- );
- assert.equal(
- textAreaMinMaxLength.errors.length,
- 0,
- 'Should be valid since it value does not exceed the max length after truncating spaces'
- );
-
- form.submit(false, {}).finally(() => {
- assert.equal(textFieldRequired.dataValue, '', 'Should truncate the value before submit');
- assert.equal(textFieldMinMaxLength.dataValue, '546 456', 'Should truncate the value before submit');
- assert.equal(textAreaMinMaxLength.dataValue, '546 456', 'Should truncate the value before submit');
-
- done();
- });
- }, 400);
- }).catch(done);
- });
-
- it('HTML render mode for Webform', (done) => {
- const element = document.createElement('div');
-
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- setTimeout(() => {
- const values = [
- {
- _id: '5a53f8a044398b0001023eab',
- modified: '2019-02-01T16:12:06.618Z',
- data: {
- firstName: 'Bob',
- lastName: 'Thompson',
- status: 'inactive',
- email: 'bob@example.com',
- submit: true,
- },
- form: '5a53f887c8930000010f8b22',
- _fvid: 0,
- _vid: 0,
- created: '2018-01-08T23:02:56.484Z',
- externalIds: [],
- access: [],
- roles: [],
- owner: '553dbfc08d22d5cb1a7024f2',
- state: 'submitted',
- project: '5692b91fd1028f01000407e3',
- }, {
- _id: '5a53f8ad0dc919000194ab6b',
- modified: '2019-02-01T16:12:01.781Z',
- data: {
- firstName: 'Sally',
- lastName: 'Tanner',
- status: 'active',
- email: 'sally@example.com',
- submit: true,
- },
- form: '5a53f887c8930000010f8b22',
- _fvid: 0,
- _vid: 0,
- created: '2018-01-08T23:03:09.730Z',
- externalIds: [],
- access: [],
- roles: [],
- owner: '553dbfc08d22d5cb1a7024f2',
- state: 'submitted',
- project: '5692b91fd1028f01000407e3',
- }, {
- _id: '5a53f8b744398b0001023eaf',
- modified: '2019-02-01T16:11:57.139Z',
- data: {
- firstName: 'Jane',
- lastName: 'Doe',
- status: 'active',
- email: 'jane@example.com',
- submit: true,
- },
- form: '5a53f887c8930000010f8b22',
- _fvid: 0,
- _vid: 0,
- created: '2018-01-08T23:03:19.473Z',
- externalIds: [],
- access: [],
- roles: [],
- owner: '553dbfc08d22d5cb1a7024f2',
- state: 'submitted',
- project: '5692b91fd1028f01000407e3',
- },
- ];
- resolve(values);
- }, 50);
- });
- };
-
- Formio.createForm(element, htmlRenderMode, {
- readOnly: true,
- renderMode: 'html',
- })
- .then(form => {
- form.submission = {
- data: {
- textfieldonPage3: 'test',
- signature: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABTIAAACWCAYAAADt5XcLAAAgAElEQVR4Xu3dfWydV30H8NM1dLRdndIOKKJxGHSh0MalgBilpLAJyIsatQgJu4rT8peNiFOEhl0pyR8gxZHq/DGJJAhHCNbEEU5BHVWyJpWYuja0tOPdSctLQVBHWmAwkTi0lEFh+j3h3tqOG9vJvfa59/kcybKT3Ps85/mcE0f+5nfOOe/ZZ3/156QRIECAAAECBAgQIECAAAECBAgQIEAgY4HzBJkZj46uESBAgAABAgQIECBAgAABAgQIECBQCAgyTQQCBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIO1Fjhx4kQaGTlSXHbhwoXFx6WXthSfNQIECBAgQIAAAQIECBAgQIAAgTwFBJl5jotezUIggslnnjmaTpwYS/F1fBw/furrZ54Z/cufnfr9eN2Z2uLFi1Jb29J06vO16d3vvrH4WiNAgAABAgQIECBAgAABAgQIEJhfAUHm/Pq7+ywFIoj8+tcfTbt3D6fR0VMhZT3bggUL0sUXX1yEmjfddGO6+eaVxdcaAQIECBAgQIAAAQIECBAgQIDA3AoIMufW293OUmDfvgfSF7+4Oz3++DeLysrZtNbWRdWqymXLbizeGsvIr7tuYiAZoWhUcEY7dOjRdPz4ifT00z9Nzz///ITbRYXmunUfTevWdc2mG15LgAABAgQIECBAgAABAgQIECBwDgKCzHPA89b6CkSwuGfPcBoa+lJReblkyVVpyZK/T6tXr0oRSFaWfFf2u4zeRMjZ2tpa0z0v494RbEaYun//gepDR2Xm4OA2FZr1nQauToAAAQIECBAgQIAAAQIECBAoBASZJkJWAhFERlgYS8cjPIzW0tKSenq6U2fnbfO+X2WEmhGsbtmytehbVHbu3XtPEaxqBAgQIECAAAECBAgQIECAAAEC9RMQZNbP1pVnIRAB4ZYtA2nfvgNFVWWEl7H0O8LLzs6OWVxpbl4aIWtX1/o0Onpqj84NG3rTxo19c3NzdyFAgAABAgQIECBAgAABAgQIlFBAkFnCQc/pkYeGhtOOHYOpsjw8Asy1azuKADP3Q3UicF2+/JZ0+PCTBenVVy9J9903PO9VozmNr74QIECAAAECBAgQIECAAAECBGolIMislaTrzFggAsAdO3ZW976MN8aBPFHRmGP15ZkeLJ6lt3dTsZdnpe3cua043TyWnWsECBAgQIAAAQIECBAgQIAAAQK1ERBk1sbRVWYgUAkwt28frJ48vmzZu4oAs9H3mPzCF3al9ev/uaoQBxLdffdm1ZkzmBdeQoAAAQIECBAgQIAAAQIECBCYiYAgcyZKXnPOAv39A0UVZoSZ0das6SgCzMrJ4+d8gwwuEPt8trevrS41j2fbsKHxqkwzoNQFAgQIECBAgAABAgQIECBAgMBpAoJMk6KuAvv2PZDuumtTipCvWQPMyYAR2kbV6djYWPFHsVx+YGCzpeZ1nWkuToAAAQIECBAgQIAAAQIECDS7gCCz2Ud4np4vgsvu7vUpTveOFntGDgz0N1UF5ploJ59qHtWZw8O7sj/AaJ6mi9sSIECAAAECBAgQIECAAAECBKYVEGROS+QFsxGIpeNbtmwtKhKjNcsemLMxqLx28kFAcfhPT0932rCh92wu5z0ECBAgQIAAAQIECBAgQIAAgVILCDJLPfy1ffioQowqzKjGXLr0mtTT89GGO4W8tiKnrhahbiw3ryw1dxBQPZRdkwABAgQIECBAgAABAgQIEGh2AUFms4/wHDzfyMiRIqjbv/9Acbc4rXvt2g57Qo6zD6Ourp4JBwEdOHB/aZbaz8E0dAsCBAgQIECAAAECBAgQIECgyQUEmU0+wPV8vPHLyK+88rXpLW9pK9U+mLO1Da+urvXVwDeWmg8OfiZFhaZGgAABAgQIECBAgAABAgQIECBwZgFBphlyVgKxXHrPnuEUlYatrYuKU7kFcjOjHL/U3L6ZMzPzKgIECBAgQIAAAQIECBAgQICAINMcmJVABJexD2Z8jrZmTUfaunWzZeSzUkzFae5RnTk6erR4Z2dnRxoc3DbLq3g5AQIECBAgQIAAAQIECBAgQKA8AoLM8oz1OT9pBG9RhRktqjB37tyWli278ZyvW9YLxKFI3d096dChxwqCsNy79x6hcFknhOcmQIAAAQIECBAgQIAAAQIEziggyDRBphXYt++B1N19Z4o9HqOtW9eVNm7sE7hNKzf9C8I0lppv2bK1ePHixYuSQ4Cmd/MKAgQIECBAgAABAgQIECBAoHwCgszyjfmMnzhCtr6+TWloSBXmjNHO8oURFnd03FENM+Pkd3uOniWmtxEgQIAAAQIECBAgQIAAAQJNKSDIbMphPfeHij0c29vvUIV57pQzvkIsNW9vX5sOH36yqHatVL7O+AJeSIAAAQIECBAgQIAAAQIECBBoYgFBZhMP7tk+Wix1vuuuTcXb7YV5topn976ogu3t3VTdizQOU4q9SDUCBAgQIECAAAECBAgQIECAQNkFBJllnwHjnj9CtNgLM5Y5R1u27F1pcHB7sW+jNrcClaXmL3/5y9OSJVelgwe/ak/SuR0CdyNAgAABAgQIECBAgAABAgQyExBkZjYg89WdCDFXrLg1jYwcKbrgQJ/5GokX7xtjsnz5LcVS82gRZjolfv7HRQ8IECBAgAABAgQIECBAgACB+REQZM6Pe1Z3jf0wu7vXp9ijsaWlJfX0dBenkmt5CPT1bUw7duwsOhPjsmFDbx4d0wsCBAgQIECAAAECBAgQIECAwBwKCDLnEDvHW8US5lhOHtV/EWLee+8uVX8ZDlScHN/buzGNjY0V4xPVmRoBAgQIECBAgAABAgQIECBAoEwCgswyjfakZx1/qM/SpdeknTu3p7a2a0sskvejR+VsV9f6NDp6tNi3dHh4l/HKe8j0jgABAgQIECBAgAABAgQIEKihgCCzhpiNdKn+/oG0ZcvWoss337yyOBl74cKFjfQIpezr+H0zY7wGBz+TVq9eVUoLD02AAAECBAgQIECAAAECBAiUS0CQWa7xLp62vf32tH//geLrONRnYKC/hAqN+8gRZsYYHjr0WPEQ9s1s3LHUcwIECBAgQIAAAQIECBAgQGDmAoLMmVs1xSvf+c73Vk/BvvvuzcXBPlpjCoyvqo2qzKjOVFXbmGOp1wQI1E4gDq6LLTiitbVd4/ti7WhdiQABAgQIECBAgMC8Cwgy530I5qYDIyNH0gc+sDqdPPnb4oZxWEwcGqM1tkAc1tTRcUfxEDGeg4Pbiv0zNQIECJRJIMLLT32qPz300MPpV7/69YRHj72f43ujPaDLNCM8KwECBAgQIECAQLMKCDKbdWTHPVflUJ/zzjsvXXLJJemHP/yOCpUmGvcIqWOpuUOAmmhQPQoBAjMSiADzs58dTLt3D6fYduOl2po1HcVe0BoBAgQIECBAgAABAo0tIMhs7PE7Y+/jh7ru7jtTVO1Fa2lpSceO/bSJn7i8jzZ538yoPurs7CgviCcnQKDpBQ4dejR1d69PEWZO1+wHPZ2QPydAgAABAgQIECDQGAKCzMYYp1n3Mn6wW7nyluoPeELMWRM25Bv6+jamHTt2Fn2PIHPDhj5LzRtyJHWaAIEzCZwpxHzFKy5Nq1atSKOjo+n48ROprW1pcSiabTfMKQIECBAgQIAAAQKNLyDIbPwxPO0JJv+A19q6KD3++EOWkzfhWE/1SFGB29W1Po2NjRV7wg0MbLYfaknG3mMSKINA/BvX3n7HaUvJly17VxFY2v+5DLPAMxIgQIAAAQIECJRVQJDZZCM//vCXeLQIMQ8evF8lSpON83SPExW5UZ25f/+BIsCOZZXxA75GgACBRhaIEPPDH769+I+a8e3uuzennp7uRn40fSdAgAABAgQIECBAYAYCgswZIDXKS4aGhov9wsa3p576jhCzUQawDv2szImWlkvS6163OA0P7zIf6uDskgQI1F9g8pYpccfYNiUO8Vm9elX9O+AOBAgQIECAAAECBAjMu4Agc96HoDYdmBxixg939967yxK72vA29FXih//29rXp8OEni+eIH/pvvnmlrQYaelR1nkD5BGLLjD17hqsPHv9Bc++9u/07V76p4IkJECBAgAABAgRKLCDIbILBj6V2K1bcOuFJhofvUaHSBGNby0fo7x9IEXiPjh4tfvCPk80dflFLYdciQKBeApP/nfOfdfWSdl0CBAgQIECAAAECeQsIMvMen2l7N9Vy8g0beu2HOK1cOV8QYUBv78ZqdWbsmxnzRSNAgECuAlMtKbcnZq6jpV8ECBAgQIAAAQIE6isgyKyvb12vHgf7dHffOeHk1jjUZWCgv673dfHGFjhx4kTavn0wbdmytXiQqMqM6kwn/Tb2uOo9gWYUGBk5kvr6NqX4T5hKi9PJ4xA7jQABAgQIECBAgACB8gkIMht0zOOHu46O21NUqlRa7HsY+x/GKdUagekEYg51dfVUqzM7OzvSwMBm82c6OH9OgMCcCER4edttH0m/+c3x6v1aWxcVIaZtMeZkCNyEAAECBAgQIECAQHYCgszshmT6Dk21zG7p0mvSgw/eL4Sans8rJgnE3pmV6swIwbdu3ZzWrOngVAOBqH49fnysuNKll7b4+1kD02a9RMyVkZEniwr7+Dh27H/SsWP/nS6//PLi18ePx++fmkvRIsiLv6/PP//79Oyzvy1eN1274IK/Tn/84x/SokWvLeZlXHeqFtdM6c/p1a9+9YTXxOvj35+FC1uKt1144YVpwYIF6frr24pfL116bWpru3a6bkz757HaYM+evSk+j2/x79zWrf2qx6cV9AICBAgQIECAAAECzSsgyGywsZ0qxIwKlccff0hI0mBjmVN3Y151d/ekQ4ceK7oVy8w3buwVGMxgkKKy9Yknvpl+/vPRIiT6/vePpPi9lwqJIuiJACqCqMWLW6tfv+xlL0sXXXRR9Y6VQKsShL7461OBVgRbU7W47qWXLqxeN+4VwZOtA2YwmHPwkpgbP/jBj9LTT/8knTx5spgv45dNz0EX6n6LG274h/Tcc8+lWAIebfwqgZjHv//9/6Wf/ezn6eqrlxR/Fh8jI4fTj370dPrxj38y5d+deO0XvzhYk6C07gBuQIAAAQIECBAgQIBA3QQEmXWjrf2Fp1pOHiHm3r27/HBXe+5SXjEqoKJC8/DhJ4vnX716VYpDNSzjnDgdIoyJKtbwGr+9Q86T5oILLigq6KIytLW1NV133bXF5/h1rSrpcn7++ehbfM+O/xyIkC6+jg9t9gIRiMa/c7ZNmb2ddxAgQIAAAQIECBBoNgFBZoOM6FQHHrS0tKTHH/9PIVODjGEjdTMOA4pAc2xsrAgPenq6UxwkJUhIaWhoOHV3r5/X4Yy/+1F1OT5gnjw24ytCo+rvD3/4Q/rd7353xn5HtWh83HTTjend777R95ZZjHJ4P/bYE+nb3/5uOnLkqdOWRc/kUrF0OsY12hvfuKT4+3fVVW8441tPLS1/Nl1++WXT3uLFpeVX/mWp+tRVvfG6kyfH0qte9arimvFslfl1qtq3pagKPnbsl0UV8p/+9KeiqjRC/dHRF/dtnrZD07wgAsx167qL/1DRCBAgQIAAAQIECBAgEAKCzAaYB/EDYn//1gnLDx140AAD1+BdjPCit3dT2rNnuHiSsp9uHh7d3XdOGVBdcsklacmSq9KHP/yhwinCnsoS8so0qASLk6vyKkvEo2LyoosunDBrKuFRfK7VHpuVZe8ROlUqBaMPlSrc8R2IZ4kQKZalR6gkyH5RJ/z27z9QfF8Ox9lU5t5wwzvSxRf/TXr/+/+pWhnbLFXPMb8efPA/0hNP/Fe67LLL0ujo6GnfCa+44op07NixdN11S4sq1bD79a//Ny1YcH56+9vflpYvf18x75rFpMH/KdB9AgQIECBAgAABAlkJCDKzGo7TOxOVcZ/+dH967rkXK6miamfnzu2Wk2c+ds3SvVPVwBur+2eWcbn5VBXRMb4R7m3c2NcU+09G0PrIIxHKndqzsbJf6vh5XKnWLGuwefTo0RTfkytOM/k7Ht+v29qWFlWulYrXmbzPawgQIECAAAECBAgQIEDgdAFBZqazIoKEvr5Np+2p5tTWTAesBN2KJdXbt3+uqNyLSqkNG/pSZ2fzn24ewd6qVR9Mv/nN8eoox9LuCDBjyX0zt/g+FKFd7AU6VcVmJZiLoK6t7ZqmCHSnGs+YA5U9Uacb77e97fqiMjf2IHXA0nRa/pwAAQIECBAgQIAAAQKzExBkzs6r7q+uHCISVT+T2ytecWl64IF/U4lZ91Fwg5cSiPkZczNCnZaWS9LrXrc4DQ/vatoloBFgrVhx64RTlMtaET25YjP23Yw9HMe317zmivTKV/5tsQQ9KhDjc4SdsRVGIy4Tni7AjOeKsHL16pXFCfTxrBoBAgQIECBAgAABAgQI1E9AkFk/21lfOYKCCE1e6mTbgwe/qsJn1qreUA+B2NOuvX1ttUpvYKA/dXa2N90eim9601snHF7y+tf/Xdqz5wsCq79MqvH7bEb15i9+8cv09NM/fckpF2FmnJQeLSoWK3tuxu/H16eCz2uKP5+v/TjjoJ6HH/56Ghr60pTfi2M/1Ntvvy11dt5mHtTjm4trEiBAgAABAgQIECBA4AwCgsyMpsfk0GR81+6+e3PTL2PNaCh0ZYYCsdw8TjePk4qjGm1gYHPThO2TTyePSsy9e3c3ZGXhDIezZi+rnGD9zDOjfznMZbQ40GVyBeeZblip5ozXRNAZFY+VryuhZ/z6/PP/Kr3wwgtxdl1xmnblYKTxYWjloKXjx8eK6tr4OP/889MLL/yp+LpyANKZ9r6M6suY307Qrtk0cSECBAgQIECAAAECBAjMWkCQOWuy+rzhNa95w0v+kD84uK0UexHWR9ZV6y0QAVV3d0/1cJjYO3LDht5637bu13/nO987YV/Ib3zjIRV4NVAff2p6BJ3RKr/3ve8dTidPnqzBXWp3iTjQKaovy7AfbO3UXIkAAQIECBAgQIAAAQL1ERBk1sd1VleNgzQ6Ou447T1xoMi99+5qmgq3WaF4ccMJxN6Zd921qeh3VGc28t6Zk/9OrlnTkXbu3NZwY9KIHY4KyaicHB09VcUZYWd8jl8fP35i1pWdszV485uvThdeeGFxYE9UXzbi3p6zfWavJ0CAAAECBAgQIECAQKMICDIzGKmpgswIMR988H4VYBmMjy7MXCAq69rbby+WmscS36jOXLeua+YXyOSV73nP8vStb32n2hv702YyMOO6EYFnBJzRToWfsWR8rPhc+b3JvR6/J+cFF1yQLrrowmKexvvHL2XP72n1iAABAgQIECBAgAABAgRCQJCZyTwYv7Q8Qsxjx176wIxMuqwbBKYUiFCoq2t92r//QPHncapz7C3YKCc6Rzj25je/tfpsN9zwjvS1r/270SZAgAABAgQIECBAgAABAgTmWUCQOc8DMP72UZkZzWESGQ2Krpy1wORK456e7vSxj3Vnv1R3/BL5ePgdO/4lfeQjnWft4I0ECBAgQIAAAQIECBAgQIBAbQQEmbVxdBUCBKYQmFydGfsNfuhDH0yf/OSdxVLeHNuKFbdUDy6Kk6p/8IMXl5jn2F99IkCAAAECBAgQIECAAAECZREQZJZlpD0ngXkUOHTo0dTbu3HCKeADA/2ps7M9u0Bz/DYPDvmZx0nj1gQIECBAgAABAgQIECBAYJKAINOUIEBgTgSiOnPv3vvSJz7RV71fVGiuW/fRbALNoaHh1N29vtq/wcFtqbOzY0583IQAAQIECBAgQIAAAQIECBA4s4Ag0wwhQGBOBSLQ7O8fSPv2HShON4+WS6C5cuWt6ZFHHq16PPXUd7Lf03NOB8/NCBAgQIAAAQIECBAgQIDAPAoIMucR360JlFkgTgffseNzaceOnVWG2DczDgWKJd0Rbs5lm3xa+bJl70oHD94/l11wLwIECBAgQIAAAQIECBAgQOAMAoJM04MAgXkVmCrQjA6tXr0qrV69sgg156L19W2cEKred9+X0vLl75uLW7sHAQIECBAgQIAAAQIECBAgMAMBQeYMkLyEAIH6C8SS8+3bB4uPsbGx6g2jSnPt2o4i0Gxru7YuHYnDiFasuLV6bdWYdWF2UQIECBAgQIAAAQIECBAgcE4Cgsxz4vNmAgTqIbBv3wNpx47BdOjQYxMuH0Hmxz++Lq1c+f6anXY+MnKkOOAnPlfa8PA9RUWoRoAAAQIECBAgQIAAAQIECOQjIMjMZyz0hACBSQKx7Hxo6EspThOvHAxUeUmcJh5h4803rzwnt5tu+kD69re/W71GXG/v3l3ndE1vJkCAAAECBAgQIECAAAECBGovIMisvakrEiBQB4FY/v2Vr3w1ff7z/3ra1ZctuzFdffWStGDBgnT99W1p6dJrZ7QMPU5P37Jl64QQc+fObTWr9qwDg0sSIECAAAECBAgQIECAAIHSCggySzv0HpxAYwrEXpq7dw8XS88nV2lOfqIIOG+66cYi1Iy9NqP99rfPph//+On0jW88kWIJe6VdeeVr05e/PDSjALQx5fSaAAECBAgQIECAAAECBAg0toAgs7HHT+8JlFog9rWMpef79h2YNtQ8E1Rr66J08OD9afHiRaX29PAECBAgQIAAAQIECBAgQCBnAUFmzqOjbwQIzFjg6NGj6eGHH00jI4eLg3smHxT0UheKE8oHB7cLMWcs7YUECBAgQIAAAQIECBAgQGB+BASZ8+PurgQIzIFA7Kv5yCOPpjg0aHR0tLjjFVdcUXx+3/v+sVhGHh8aAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIEL7bi68AAAGrSURBVCBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv8D/A4EQEWXi+YzZAAAAAElFTkSuQmCC',
- panelDataGrid: [
- {
- panelDataGridD: 'd',
- panelDataGridC: 'c',
- panelDataGridB: 'b',
- panelDataGridA: 'a',
- }, {
- panelDataGridD: 'h',
- panelDataGridC: 'g',
- panelDataGridB: 'f',
- panelDataGridA: 'e',
- }, {
- panelDataGridD: 'l',
- panelDataGridC: 'k',
- panelDataGridB: 'j',
- panelDataGridA: 'i',
- },
- ],
- textfield: 'testing',
- page2Customer: 'bob@example.com',
- textfieldonPage2: 'test',
- numberField: 234,
- textfieldonpage1: [
- 'a', 'b', 'c',
- ],
- panelHtml5Select: 'banana',
- page3Iagreetothefollowtherules: true,
- panelText: 'hello',
- },
- };
-
- setTimeout(() => {
- const customerSelectEl = form.element.querySelector('.formio-component-page2Customer');
- const customerSelectValueEl = customerSelectEl.querySelector('[ref="value"]');
- const htmlSelectEl = form.element.querySelector('.formio-component-panelHtml5Select');
- const htmlSelectValueEl = htmlSelectEl.querySelector('[ref="value"]');
- const checkboxEl = form.element.querySelector('.formio-component-page3Iagreetothefollowtherules');
- const checkboxValueEl = checkboxEl.querySelector('[ref="value"]');
-
- assert.equal(customerSelectValueEl.textContent.trim(), 'Bob Thompson', 'Should render Select value properly');
- assert.equal(htmlSelectValueEl.textContent.trim(), 'Banana', 'Should render HTML5 Select value properly');
- assert.equal(checkboxValueEl.textContent.trim(), 'True', 'Should render Checkbox value properly');
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 400);
- })
- .catch(done);
- });
-
- it('HTML render mode for Wizard', (done) => {
- const element = document.createElement('div');
- htmlRenderMode.display = 'wizard';
-
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- setTimeout(() => {
- const values = [
- {
- _id: '5a53f8a044398b0001023eab',
- modified: '2019-02-01T16:12:06.618Z',
- data: {
- firstName: 'Bob',
- lastName: 'Thompson',
- status: 'inactive',
- email: 'bob@example.com',
- submit: true,
- },
- form: '5a53f887c8930000010f8b22',
- _fvid: 0,
- _vid: 0,
- created: '2018-01-08T23:02:56.484Z',
- externalIds: [],
- access: [],
- roles: [],
- owner: '553dbfc08d22d5cb1a7024f2',
- state: 'submitted',
- project: '5692b91fd1028f01000407e3',
- },
- {
- _id: '5a53f8ad0dc919000194ab6b',
- modified: '2019-02-01T16:12:01.781Z',
- data: {
- firstName: 'Sally',
- lastName: 'Tanner',
- status: 'active',
- email: 'sally@example.com',
- submit: true,
- },
- form: '5a53f887c8930000010f8b22',
- _fvid: 0,
- _vid: 0,
- created: '2018-01-08T23:03:09.730Z',
- externalIds: [],
- access: [],
- roles: [],
- owner: '553dbfc08d22d5cb1a7024f2',
- state: 'submitted',
- project: '5692b91fd1028f01000407e3',
- },
- {
- _id: '5a53f8b744398b0001023eaf',
- modified: '2019-02-01T16:11:57.139Z',
- data: {
- firstName: 'Jane',
- lastName: 'Doe',
- status: 'active',
- email: 'jane@example.com',
- submit: true,
- },
- form: '5a53f887c8930000010f8b22',
- _fvid: 0,
- _vid: 0,
- created: '2018-01-08T23:03:19.473Z',
- externalIds: [],
- access: [],
- roles: [],
- owner: '553dbfc08d22d5cb1a7024f2',
- state: 'submitted',
- project: '5692b91fd1028f01000407e3',
- },
- ];
- resolve(values);
- }, 50);
- });
- };
-
- Formio.createForm(element, htmlRenderMode, {
- readOnly: true,
- renderMode: 'html',
- }).then(form => {
- form.submission = {
- data: {
- textfieldonPage3: 'test',
- signature: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABTIAAACWCAYAAADt5XcLAAAgAElEQVR4Xu3dfWydV30H8NM1dLRdndIOKKJxGHSh0MalgBilpLAJyIsatQgJu4rT8peNiFOEhl0pyR8gxZHq/DGJJAhHCNbEEU5BHVWyJpWYuja0tOPdSctLQVBHWmAwkTi0lEFh+j3h3tqOG9vJvfa59/kcybKT3Ps85/mcE0f+5nfOOe/ZZ3/156QRIECAAAECBAgQIECAAAECBAgQIEAgY4HzBJkZj46uESBAgAABAgQIECBAgAABAgQIECBQCAgyTQQCBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIMECBAgQIAAAQIECBAgQIAAAQIECAgyzQECBAgQIECAAAECBAgQIECAAAECBLIXEGRmP0Q6SIAAAQIECBAgQIAAAQIECBAgQICAINMcIECAAAECBAgQIECAAAECBAgQIEAgewFBZvZDpIO1Fjhx4kQaGTlSXHbhwoXFx6WXthSfNQIECBAgQIAAAQIECBAgQIAAgTwFBJl5jotezUIggslnnjmaTpwYS/F1fBw/furrZ54Z/cufnfr9eN2Z2uLFi1Jb29J06vO16d3vvrH4WiNAgAABAgQIECBAgAABAgQIEJhfAUHm/Pq7+ywFIoj8+tcfTbt3D6fR0VMhZT3bggUL0sUXX1yEmjfddGO6+eaVxdcaAQIECBAgQIAAAQIECBAgQIDA3AoIMufW293OUmDfvgfSF7+4Oz3++DeLysrZtNbWRdWqymXLbizeGsvIr7tuYiAZoWhUcEY7dOjRdPz4ifT00z9Nzz///ITbRYXmunUfTevWdc2mG15LgAABAgQIECBAgAABAgQIECBwDgKCzHPA89b6CkSwuGfPcBoa+lJReblkyVVpyZK/T6tXr0oRSFaWfFf2u4zeRMjZ2tpa0z0v494RbEaYun//gepDR2Xm4OA2FZr1nQauToAAAQIECBAgQIAAAQIECBAoBASZJkJWAhFERlgYS8cjPIzW0tKSenq6U2fnbfO+X2WEmhGsbtmytehbVHbu3XtPEaxqBAgQIECAAAECBAgQIECAAAEC9RMQZNbP1pVnIRAB4ZYtA2nfvgNFVWWEl7H0O8LLzs6OWVxpbl4aIWtX1/o0Onpqj84NG3rTxo19c3NzdyFAgAABAgQIECBAgAABAgQIlFBAkFnCQc/pkYeGhtOOHYOpsjw8Asy1azuKADP3Q3UicF2+/JZ0+PCTBenVVy9J9903PO9VozmNr74QIECAAAECBAgQIECAAAECBGolIMislaTrzFggAsAdO3ZW976MN8aBPFHRmGP15ZkeLJ6lt3dTsZdnpe3cua043TyWnWsECBAgQIAAAQIECBAgQIAAAQK1ERBk1sbRVWYgUAkwt28frJ48vmzZu4oAs9H3mPzCF3al9ev/uaoQBxLdffdm1ZkzmBdeQoAAAQIECBAgQIAAAQIECBCYiYAgcyZKXnPOAv39A0UVZoSZ0das6SgCzMrJ4+d8gwwuEPt8trevrS41j2fbsKHxqkwzoNQFAgQIECBAgAABAgQIECBAgMBpAoJMk6KuAvv2PZDuumtTipCvWQPMyYAR2kbV6djYWPFHsVx+YGCzpeZ1nWkuToAAAQIECBAgQIAAAQIECDS7gCCz2Ud4np4vgsvu7vUpTveOFntGDgz0N1UF5ploJ59qHtWZw8O7sj/AaJ6mi9sSIECAAAECBAgQIECAAAECBKYVEGROS+QFsxGIpeNbtmwtKhKjNcsemLMxqLx28kFAcfhPT0932rCh92wu5z0ECBAgQIAAAQIECBAgQIAAgVILCDJLPfy1ffioQowqzKjGXLr0mtTT89GGO4W8tiKnrhahbiw3ryw1dxBQPZRdkwABAgQIECBAgAABAgQIEGh2AUFms4/wHDzfyMiRIqjbv/9Acbc4rXvt2g57Qo6zD6Ourp4JBwEdOHB/aZbaz8E0dAsCBAgQIECAAAECBAgQIECgyQUEmU0+wPV8vPHLyK+88rXpLW9pK9U+mLO1Da+urvXVwDeWmg8OfiZFhaZGgAABAgQIECBAgAABAgQIECBwZgFBphlyVgKxXHrPnuEUlYatrYuKU7kFcjOjHL/U3L6ZMzPzKgIECBAgQIAAAQIECBAgQICAINMcmJVABJexD2Z8jrZmTUfaunWzZeSzUkzFae5RnTk6erR4Z2dnRxoc3DbLq3g5AQIECBAgQIAAAQIECBAgQKA8AoLM8oz1OT9pBG9RhRktqjB37tyWli278ZyvW9YLxKFI3d096dChxwqCsNy79x6hcFknhOcmQIAAAQIECBAgQIAAAQIEziggyDRBphXYt++B1N19Z4o9HqOtW9eVNm7sE7hNKzf9C8I0lppv2bK1ePHixYuSQ4Cmd/MKAgQIECBAgAABAgQIECBAoHwCgszyjfmMnzhCtr6+TWloSBXmjNHO8oURFnd03FENM+Pkd3uOniWmtxEgQIAAAQIECBAgQIAAAQJNKSDIbMphPfeHij0c29vvUIV57pQzvkIsNW9vX5sOH36yqHatVL7O+AJeSIAAAQIECBAgQIAAAQIECBBoYgFBZhMP7tk+Wix1vuuuTcXb7YV5topn976ogu3t3VTdizQOU4q9SDUCBAgQIECAAAECBAgQIECAQNkFBJllnwHjnj9CtNgLM5Y5R1u27F1pcHB7sW+jNrcClaXmL3/5y9OSJVelgwe/ak/SuR0CdyNAgAABAgQIECBAgAABAgQyExBkZjYg89WdCDFXrLg1jYwcKbrgQJ/5GokX7xtjsnz5LcVS82gRZjolfv7HRQ8IECBAgAABAgQIECBAgACB+REQZM6Pe1Z3jf0wu7vXp9ijsaWlJfX0dBenkmt5CPT1bUw7duwsOhPjsmFDbx4d0wsCBAgQIECAAAECBAgQIECAwBwKCDLnEDvHW8US5lhOHtV/EWLee+8uVX8ZDlScHN/buzGNjY0V4xPVmRoBAgQIECBAgAABAgQIECBAoEwCgswyjfakZx1/qM/SpdeknTu3p7a2a0sskvejR+VsV9f6NDp6tNi3dHh4l/HKe8j0jgABAgQIECBAgAABAgQIEKihgCCzhpiNdKn+/oG0ZcvWoss337yyOBl74cKFjfQIpezr+H0zY7wGBz+TVq9eVUoLD02AAAECBAgQIECAAAECBAiUS0CQWa7xLp62vf32tH//geLrONRnYKC/hAqN+8gRZsYYHjr0WPEQ9s1s3LHUcwIECBAgQIAAAQIECBAgQGDmAoLMmVs1xSvf+c73Vk/BvvvuzcXBPlpjCoyvqo2qzKjOVFXbmGOp1wQI1E4gDq6LLTiitbVd4/ti7WhdiQABAgQIECBAgMC8Cwgy530I5qYDIyNH0gc+sDqdPPnb4oZxWEwcGqM1tkAc1tTRcUfxEDGeg4Pbiv0zNQIECJRJIMLLT32qPz300MPpV7/69YRHj72f43ujPaDLNCM8KwECBAgQIECAQLMKCDKbdWTHPVflUJ/zzjsvXXLJJemHP/yOCpUmGvcIqWOpuUOAmmhQPQoBAjMSiADzs58dTLt3D6fYduOl2po1HcVe0BoBAgQIECBAgAABAo0tIMhs7PE7Y+/jh7ru7jtTVO1Fa2lpSceO/bSJn7i8jzZ538yoPurs7CgviCcnQKDpBQ4dejR1d69PEWZO1+wHPZ2QPydAgAABAgQIECDQGAKCzMYYp1n3Mn6wW7nyluoPeELMWRM25Bv6+jamHTt2Fn2PIHPDhj5LzRtyJHWaAIEzCZwpxHzFKy5Nq1atSKOjo+n48ROprW1pcSiabTfMKQIECBAgQIAAAQKNLyDIbPwxPO0JJv+A19q6KD3++EOWkzfhWE/1SFGB29W1Po2NjRV7wg0MbLYfaknG3mMSKINA/BvX3n7HaUvJly17VxFY2v+5DLPAMxIgQIAAAQIECJRVQJDZZCM//vCXeLQIMQ8evF8lSpON83SPExW5UZ25f/+BIsCOZZXxA75GgACBRhaIEPPDH769+I+a8e3uuzennp7uRn40fSdAgAABAgQIECBAYAYCgswZIDXKS4aGhov9wsa3p576jhCzUQawDv2szImWlkvS6163OA0P7zIf6uDskgQI1F9g8pYpccfYNiUO8Vm9elX9O+AOBAgQIECAAAECBAjMu4Agc96HoDYdmBxixg939967yxK72vA29FXih//29rXp8OEni+eIH/pvvnmlrQYaelR1nkD5BGLLjD17hqsPHv9Bc++9u/07V76p4IkJECBAgAABAgRKLCDIbILBj6V2K1bcOuFJhofvUaHSBGNby0fo7x9IEXiPjh4tfvCPk80dflFLYdciQKBeApP/nfOfdfWSdl0CBAgQIECAAAECeQsIMvMen2l7N9Vy8g0beu2HOK1cOV8QYUBv78ZqdWbsmxnzRSNAgECuAlMtKbcnZq6jpV8ECBAgQIAAAQIE6isgyKyvb12vHgf7dHffOeHk1jjUZWCgv673dfHGFjhx4kTavn0wbdmytXiQqMqM6kwn/Tb2uOo9gWYUGBk5kvr6NqX4T5hKi9PJ4xA7jQABAgQIECBAgACB8gkIMht0zOOHu46O21NUqlRa7HsY+x/GKdUagekEYg51dfVUqzM7OzvSwMBm82c6OH9OgMCcCER4edttH0m/+c3x6v1aWxcVIaZtMeZkCNyEAAECBAgQIECAQHYCgszshmT6Dk21zG7p0mvSgw/eL4Sans8rJgnE3pmV6swIwbdu3ZzWrOngVAOBqH49fnysuNKll7b4+1kD02a9RMyVkZEniwr7+Dh27H/SsWP/nS6//PLi18ePx++fmkvRIsiLv6/PP//79Oyzvy1eN1274IK/Tn/84x/SokWvLeZlXHeqFtdM6c/p1a9+9YTXxOvj35+FC1uKt1144YVpwYIF6frr24pfL116bWpru3a6bkz757HaYM+evSk+j2/x79zWrf2qx6cV9AICBAgQIECAAAECzSsgyGywsZ0qxIwKlccff0hI0mBjmVN3Y151d/ekQ4ceK7oVy8w3buwVGMxgkKKy9Yknvpl+/vPRIiT6/vePpPi9lwqJIuiJACqCqMWLW6tfv+xlL0sXXXRR9Y6VQKsShL7461OBVgRbU7W47qWXLqxeN+4VwZOtA2YwmHPwkpgbP/jBj9LTT/8knTx5spgv45dNz0EX6n6LG274h/Tcc8+lWAIebfwqgZjHv//9/6Wf/ezn6eqrlxR/Fh8jI4fTj370dPrxj38y5d+deO0XvzhYk6C07gBuQIAAAQIECBAgQIBA3QQEmXWjrf2Fp1pOHiHm3r27/HBXe+5SXjEqoKJC8/DhJ4vnX716VYpDNSzjnDgdIoyJKtbwGr+9Q86T5oILLigq6KIytLW1NV133bXF5/h1rSrpcn7++ehbfM+O/xyIkC6+jg9t9gIRiMa/c7ZNmb2ddxAgQIAAAQIECBBoNgFBZoOM6FQHHrS0tKTHH/9PIVODjGEjdTMOA4pAc2xsrAgPenq6UxwkJUhIaWhoOHV3r5/X4Yy/+1F1OT5gnjw24ytCo+rvD3/4Q/rd7353xn5HtWh83HTTjend777R95ZZjHJ4P/bYE+nb3/5uOnLkqdOWRc/kUrF0OsY12hvfuKT4+3fVVW8441tPLS1/Nl1++WXT3uLFpeVX/mWp+tRVvfG6kyfH0qte9arimvFslfl1qtq3pagKPnbsl0UV8p/+9KeiqjRC/dHRF/dtnrZD07wgAsx167qL/1DRCBAgQIAAAQIECBAgEAKCzAaYB/EDYn//1gnLDx140AAD1+BdjPCit3dT2rNnuHiSsp9uHh7d3XdOGVBdcsklacmSq9KHP/yhwinCnsoS8so0qASLk6vyKkvEo2LyoosunDBrKuFRfK7VHpuVZe8ROlUqBaMPlSrc8R2IZ4kQKZalR6gkyH5RJ/z27z9QfF8Ox9lU5t5wwzvSxRf/TXr/+/+pWhnbLFXPMb8efPA/0hNP/Fe67LLL0ujo6GnfCa+44op07NixdN11S4sq1bD79a//Ny1YcH56+9vflpYvf18x75rFpMH/KdB9AgQIECBAgAABAlkJCDKzGo7TOxOVcZ/+dH967rkXK6miamfnzu2Wk2c+ds3SvVPVwBur+2eWcbn5VBXRMb4R7m3c2NcU+09G0PrIIxHKndqzsbJf6vh5XKnWLGuwefTo0RTfkytOM/k7Ht+v29qWFlWulYrXmbzPawgQIECAAAECBAgQIEDgdAFBZqazIoKEvr5Np+2p5tTWTAesBN2KJdXbt3+uqNyLSqkNG/pSZ2fzn24ewd6qVR9Mv/nN8eoox9LuCDBjyX0zt/g+FKFd7AU6VcVmJZiLoK6t7ZqmCHSnGs+YA5U9Uacb77e97fqiMjf2IHXA0nRa/pwAAQIECBAgQIAAAQKzExBkzs6r7q+uHCISVT+T2ytecWl64IF/U4lZ91Fwg5cSiPkZczNCnZaWS9LrXrc4DQ/vatoloBFgrVhx64RTlMtaET25YjP23Yw9HMe317zmivTKV/5tsQQ9KhDjc4SdsRVGIy4Tni7AjOeKsHL16pXFCfTxrBoBAgQIECBAgAABAgQI1E9AkFk/21lfOYKCCE1e6mTbgwe/qsJn1qreUA+B2NOuvX1ttUpvYKA/dXa2N90eim9601snHF7y+tf/Xdqz5wsCq79MqvH7bEb15i9+8cv09NM/fckpF2FmnJQeLSoWK3tuxu/H16eCz2uKP5+v/TjjoJ6HH/56Ghr60pTfi2M/1Ntvvy11dt5mHtTjm4trEiBAgAABAgQIECBA4AwCgsyMpsfk0GR81+6+e3PTL2PNaCh0ZYYCsdw8TjePk4qjGm1gYHPThO2TTyePSsy9e3c3ZGXhDIezZi+rnGD9zDOjfznMZbQ40GVyBeeZblip5ozXRNAZFY+VryuhZ/z6/PP/Kr3wwgtxdl1xmnblYKTxYWjloKXjx8eK6tr4OP/889MLL/yp+LpyANKZ9r6M6suY307Qrtk0cSECBAgQIECAAAECBAjMWkCQOWuy+rzhNa95w0v+kD84uK0UexHWR9ZV6y0QAVV3d0/1cJjYO3LDht5637bu13/nO987YV/Ib3zjIRV4NVAff2p6BJ3RKr/3ve8dTidPnqzBXWp3iTjQKaovy7AfbO3UXIkAAQIECBAgQIAAAQL1ERBk1sd1VleNgzQ6Ou447T1xoMi99+5qmgq3WaF4ccMJxN6Zd921qeh3VGc28t6Zk/9OrlnTkXbu3NZwY9KIHY4KyaicHB09VcUZYWd8jl8fP35i1pWdszV485uvThdeeGFxYE9UXzbi3p6zfWavJ0CAAAECBAgQIECAQKMICDIzGKmpgswIMR988H4VYBmMjy7MXCAq69rbby+WmscS36jOXLeua+YXyOSV73nP8vStb32n2hv702YyMOO6EYFnBJzRToWfsWR8rPhc+b3JvR6/J+cFF1yQLrrowmKexvvHL2XP72n1iAABAgQIECBAgAABAgRCQJCZyTwYv7Q8Qsxjx176wIxMuqwbBKYUiFCoq2t92r//QPHncapz7C3YKCc6Rzj25je/tfpsN9zwjvS1r/270SZAgAABAgQIECBAgAABAgTmWUCQOc8DMP72UZkZzWESGQ2Krpy1wORK456e7vSxj3Vnv1R3/BL5ePgdO/4lfeQjnWft4I0ECBAgQIAAAQIECBAgQIBAbQQEmbVxdBUCBKYQmFydGfsNfuhDH0yf/OSdxVLeHNuKFbdUDy6Kk6p/8IMXl5jn2F99IkCAAAECBAgQIECAAAECZREQZJZlpD0ngXkUOHTo0dTbu3HCKeADA/2ps7M9u0Bz/DYPDvmZx0nj1gQIECBAgAABAgQIECBAYJKAINOUIEBgTgSiOnPv3vvSJz7RV71fVGiuW/fRbALNoaHh1N29vtq/wcFtqbOzY0583IQAAQIECBAgQIAAAQIECBA4s4Ag0wwhQGBOBSLQ7O8fSPv2HShON4+WS6C5cuWt6ZFHHq16PPXUd7Lf03NOB8/NCBAgQIAAAQIECBAgQIDAPAoIMucR360JlFkgTgffseNzaceOnVWG2DczDgWKJd0Rbs5lm3xa+bJl70oHD94/l11wLwIECBAgQIAAAQIECBAgQOAMAoJM04MAgXkVmCrQjA6tXr0qrV69sgg156L19W2cEKred9+X0vLl75uLW7sHAQIECBAgQIAAAQIECBAgMAMBQeYMkLyEAIH6C8SS8+3bB4uPsbGx6g2jSnPt2o4i0Gxru7YuHYnDiFasuLV6bdWYdWF2UQIECBAgQIAAAQIECBAgcE4Cgsxz4vNmAgTqIbBv3wNpx47BdOjQYxMuH0Hmxz++Lq1c+f6anXY+MnKkOOAnPlfa8PA9RUWoRoAAAQIECBAgQIAAAQIECOQjIMjMZyz0hACBSQKx7Hxo6EspThOvHAxUeUmcJh5h4803rzwnt5tu+kD69re/W71GXG/v3l3ndE1vJkCAAAECBAgQIECAAAECBGovIMisvakrEiBQB4FY/v2Vr3w1ff7z/3ra1ZctuzFdffWStGDBgnT99W1p6dJrZ7QMPU5P37Jl64QQc+fObTWr9qwDg0sSIECAAAECBAgQIECAAIHSCggySzv0HpxAYwrEXpq7dw8XS88nV2lOfqIIOG+66cYi1Iy9NqP99rfPph//+On0jW88kWIJe6VdeeVr05e/PDSjALQx5fSaAAECBAgQIECAAAECBAg0toAgs7HHT+8JlFog9rWMpef79h2YNtQ8E1Rr66J08OD9afHiRaX29PAECBAgQIAAAQIECBAgQCBnAUFmzqOjbwQIzFjg6NGj6eGHH00jI4eLg3smHxT0UheKE8oHB7cLMWcs7YUECBAgQIAAAQIECBAgQGB+BASZ8+PurgQIzIFA7Kv5yCOPpjg0aHR0tLjjFVdcUXx+3/v+sVhGHh8aAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIEL7bi68AAAGrSURBVCBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv4AgM/8x0kMCBAgQIECAAAECBAgQIECAAAECpRcQZJZ+CgAgQIAAAQIECBAgQIAAAQIECBAgkL+AIDP/MdJDAgQIECBAgAABAgQIECBAgAABAqUXEGSWfgoAIECAAAECBAgQIECAAAECBAgQIJC/gCAz/zHSQwIECBAgQIAAAQIECBAgQIAAAQKlFxBkln4KACBAgAABAgQIECBAgAABAgQIECCQv8D/A4EQEWXi+YzZAAAAAElFTkSuQmCC',
- panelDataGrid: [
- {
- panelDataGridD: 'd',
- panelDataGridC: 'c',
- panelDataGridB: 'b',
- panelDataGridA: 'a'
- },
- {
- panelDataGridD: 'h',
- panelDataGridC: 'g',
- panelDataGridB: 'f',
- panelDataGridA: 'e'
- },
- {
- panelDataGridD: 'l',
- panelDataGridC: 'k',
- panelDataGridB: 'j',
- panelDataGridA: 'i'
- }
- ],
- textfield: 'testing',
- page2Customer: 'bob@example.com',
- textfieldonPage2: 'test',
- numberField: 234,
- textfieldonpage1: [
- 'a',
- 'b',
- 'c'
- ],
- panelHtml5Select: 'banana',
- page3Iagreetothefollowtherules: true,
- panelText: 'hello'
- },
- };
-
- setTimeout(() => {
- form.setPage(1);
-
- setTimeout(() => {
- const customerSelectEl = form.element.querySelector('.formio-component-page2Customer');
- const customerSelectValueEl = customerSelectEl.querySelector('[ref="value"]');
-
- assert.equal(customerSelectValueEl.textContent.trim(), 'Bob Thompson', 'Should render Select value properly');
-
- form.setPage(2);
-
- setTimeout(() => {
- const htmlSelectEl = form.element.querySelector('.formio-component-panelHtml5Select');
- const htmlSelectValueEl = htmlSelectEl.querySelector('[ref="value"]');
-
- assert.equal(htmlSelectValueEl.textContent.trim(), 'Banana', 'Should render HTML5 Select value properly');
-
- Formio.makeRequest = originalMakeRequest;
-
- done();
- }, 400);
- }, 400);
- }, 300);
- }).catch(done);
- });
-
- it('Test optional sanitize', (done) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, optionalSanitize, {
- sanitize: false,
- }).then(form => {
- const sanitize = sinon.spy(FormioUtils, 'sanitize');
- form.redraw();
- setTimeout(() => {
- assert.equal(sanitize.callCount, 0, 'Should not sanitize templates when sanitize in not turned on');
- element.innerHTML = '';
- Formio.createForm(element, optionalSanitize, {
- sanitize: true,
- }).then(form => {
- sanitize.resetHistory();
- form.redraw();
- setTimeout(() => {
- assert.equal(sanitize.callCount, 1, 'Should sanitize templates when sanitize in turned on');
- done();
- }, 250);
- }, 250);
- });
- }).catch(done);
- });
-
- it('Should execute clearOnHide if visibility of the component inside an EditGrid has changed', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { language: 'en', template: 'bootstrap3' });
-
- form.setForm(testClearOnHideInsideEditGrid).then(() => {
- form.submission = {
- state: 'submitted',
- data: {
- subsidiaryEditGrid: [
- {
- subsidiaryEntityContainer: {
- entityFullName: 'test',
- divisionNum: '',
- entityType: 'otherEntity',
- ifOtherEntityPleaseExplain: 'test',
- },
- },
- ],
- },
- };
-
- setTimeout(() => {
- const clearOnHideField = form.getComponent([
- 'subsidiaryEditGrid',
- 0,
- 'subsidiaryEntityContainer',
- 'ifOtherEntityPleaseExplain',
- ]);
- const radioTrigger = form.getComponent(['subsidiaryEditGrid', 0, 'subsidiaryEntityContainer', 'entityType']);
- assert.equal(form.rootPristine, true, 'Should not change this prop after setting a submission');
- assert.equal(clearOnHideField.visible, true, 'Should become visible');
- assert.equal(clearOnHideField.dataValue, 'test', 'Should set a value from the submission');
-
- radioTrigger.setValue('subsidiary', { modified: true });
- setTimeout(() => {
- assert.equal(clearOnHideField.visible, false, 'Should become invisible');
-
- radioTrigger.setValue('otherEntity', { modified: true });
- setTimeout(() => {
- assert.equal(clearOnHideField.visible, true, 'Should become visible');
- assert.equal(clearOnHideField.dataValue, '', 'Should clear a value due to the clearOnHide');
-
- done();
- }, 250);
- }, 250);
- }, 250);
- }).catch(done);
- });
-
- it('Should show values in editGrid rows with nested dataGrid when viewing submission with initEmpty option', function(done) {
- const formElement = document.createElement('div');
- const formWithNestedDataGridInitEmptyOption = new Webform(formElement);
-
- formWithNestedDataGridInitEmptyOption.setForm(formWithNestedDataGridInitEmpty.form).then(() => {
- formWithNestedDataGridInitEmptyOption.setSubmission(formWithNestedDataGridInitEmpty.submission);
-
- setTimeout(() => {
- const nestedDataGridFirstRowComponentValue = formWithNestedDataGridInitEmptyOption.element.querySelector(
- '[ref="editgrid-editGrid-row"]').querySelectorAll('.col-sm-2');
-
- assert.equal(nestedDataGridFirstRowComponentValue[1].textContent.trim(), 'email');
- assert.equal(nestedDataGridFirstRowComponentValue[2].textContent.trim(), 'hhh@gmail.com');
-
- done();
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should not refetch options for Select if there was an error', function(done) {
- const formElement = document.createElement('div');
- const form= new Webform(formElement);
- const formJson = {
- components: [
- {
- label: 'Select',
- widget: 'html5',
- tableView: true,
- dataSrc: 'url',
- data: {
- url: 'http://example.com',
- headers: [
- {
- key: '',
- value: '',
- },
- ],
- },
- key: 'select',
- hidden: true,
- type: 'select',
- input: true,
- disableLimit: false,
- },
- ],
- };
-
- let counter = 0;
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function() {
- return new Promise((_, reject) => {
- setTimeout(() => {
- counter++;
- const err = new Error('Failed to fetch');
- err.networkError = true;
- reject(err);
- }, 50);
- });
- };
-
- form.setForm(formJson).then(() => {
- const select = form.getComponent('select');
-
- select.visible = true;
-
- setTimeout(() => {
- setTimeout(() => {
- select.visible = false;
-
- setTimeout(() => {
- select.visible = true;
-
- setTimeout(() => {
- expect(select.networkError).to.be.true;
- expect(select.loadingError).to.be.true;
- expect(counter).to.equal(1);
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should show only one custom error when submitting empty required field with multiple validation', function(done) {
- const formJson = {
- components: [
- {
- label: 'This line',
- tableView: false,
- storage: 'base64',
- webcam: false,
- fileTypes: [{ label: '', value: '' }],
- multiple: true,
- validate: { required: true, customMessage: 'will be showed once' },
- key: 'file',
- type: 'file',
- input: true,
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- saveOnEnter: false,
- }
- ]
- };
- const element = document.createElement('div');
- const form = new Webform(element);
-
- form.setForm(formJson).then(() => {
- Harness.clickElement(form, form.element.querySelector('[name="data[submit]"]'));
-
- setTimeout(() => {
- assert.equal(form.errors[0].messages.length, 1);
- assert.equal(form.errors[0].messages[0].message, 'will be showed once');
- assert.equal(form.element.querySelector('[ref="errorRef"]').textContent.trim().includes('will be showed once'), true);
- done();
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should show validation error when submitting number with just "-" sign and required validation', function(done) {
- const formJson = {
- components: [
- {
- label: 'Number',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- validate: {
- required: true
- },
- key: 'number',
- type: 'number',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- saveOnEnter: false,
- }
- ]
- };
- const element = document.createElement('div');
- const form = new Webform(element);
-
- form.setForm(formJson).then(() => {
- Harness.setInputValue(form, 'data[number]', '-_');
- Harness.clickElement(form, form.element.querySelector('[name="data[submit]"]'));
-
- setTimeout(() => {
- assert.equal(form.errors[0].messages.length, 1);
- assert.equal(form.errors[0].messages[0].message, 'Number is required');
- assert.equal(form.element.querySelector('[ref="errorRef"]').textContent.trim().includes('Number is required'), true);
- done();
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- describe('SaveDraft functionality', () => {
- const originalMakeRequest = Formio.makeRequest;
- let saveDraftCalls = 0;
- let restoreDraftCalls = 0;
- const scenario = {
- restoreDraftError: false,
- saveDraftError: false,
- };
- const restoredDraftData = {
- textField: 'test',
- number: 1234,
- textArea: 'test',
- submit: false,
- };
-
- before((done) => {
- Formio.setUser({
- _id: '123'
- });
-
- Formio.makeRequest = (formio, type, url, method, data) => {
- if (type === 'submission' && method === 'put') {
- saveDraftCalls = ++saveDraftCalls;
- return scenario.saveDraftError
- ? Promise.reject('Save Draft Error')
- : Promise.resolve(fastCloneDeep(data));
- }
- if (type === 'form' && method === 'get') {
- return Promise.resolve(fastCloneDeep({
- _id: '65cdd69efb1b9683c216fa1d',
- title: 'test draft errors',
- name: 'testDraftErrors',
- path: 'testdrafterrors',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Text Field',
- applyMaskOn: 'change',
- tableView: true,
- validate: {
- required: true,
- },
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Number',
- applyMaskOn: 'change',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- validate: {
- min: 800,
- },
- key: 'number',
- type: 'number',
- input: true,
- },
- {
- label: 'Text Area',
- applyMaskOn: 'change',
- autoExpand: false,
- tableView: true,
- key: 'textArea',
- type: 'textarea',
- input: true,
- },
- {
- label: 'Submit',
- disableOnInvalid: true,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- saveOnEnter: false,
- },
- ],
- project: '65b0ccbaf019a907ac01a869',
- machineName: 'zarbzxibjafpcjb:testDraftErrors',
- }));
- }
-
- if (type === 'submissions' && method === 'get') {
- restoreDraftCalls = ++restoreDraftCalls;
- return scenario.restoreDraftError
- ? Promise.reject('Restore Draft Error')
- : Promise.resolve([
- fastCloneDeep({
- _id: '65d31f8da08cff1b9fc35966',
- form: '65cdd69efb1b9683c216fa1d',
- owner: '637b2e6b48c1227e60b1f910',
- data: restoredDraftData,
- project: '65b0ccbaf019a907ac01a869',
- state: 'draft',
- }),
- ]);
- }
- };
-
- done();
- });
-
- afterEach(() => {
- saveDraftCalls = 0;
- restoreDraftCalls = 0;
- scenario.restoreDraftError = false;
- scenario.saveDraftError = false;
- });
-
- after((done) => {
- Formio.makeRequest = originalMakeRequest;
- Formio.setUser();
- done();
- });
-
- it('Should restore draft', function(done) {
- const formElement = document.createElement('div');
- Formio.createForm(
- formElement,
- 'http://localhost:3000/zarbzxibjafpcjb/testdrafterrors',
- {
- saveDraft: true
- }
- ).then((form) => {
- setTimeout(() => {
- assert.equal(restoreDraftCalls, 1);
- assert.equal(saveDraftCalls, 0);
- assert.equal(form.submission.state, 'draft');
- assert.deepEqual(form.data, restoredDraftData);
- done();
- }, 200);
- }).catch((err) => done(err));
- });
-
- it('Should save draft after data is changed', function(done) {
- const formElement = document.createElement('div');
- Formio.createForm(
- formElement,
- 'http://localhost:3000/zarbzxibjafpcjb/testdrafterrors',
- {
- saveDraft: true
- }
- ).then((form) => {
- setTimeout(() => {
- assert.equal(restoreDraftCalls, 1);
- assert.equal(saveDraftCalls, 0);
- assert.equal(form.submission.state, 'draft');
- const tfInput = form.getComponent('textField').refs.input[0];
- tfInput.value = 'test resaved';
- const inputEvent = new Event('input');
- tfInput.dispatchEvent(inputEvent);
- setTimeout(() => {
- assert.equal(restoreDraftCalls, 1);
- assert.equal(saveDraftCalls, 1);
- assert.equal(form.submission.state, 'draft');
- done();
- }, 300);
- }, 200);
- }).catch((err) => done(err));
- });
-
- it('Should emit restoreDraftEvent on the restore draft error', function(done) {
- const formElement = document.createElement('div');
- Formio.createForm(
- formElement,
- 'http://localhost:3000/zarbzxibjafpcjb/testdrafterrors',
- {
- saveDraft: true
- }
- ).then((form) => {
- scenario.restoreDraftError = true;
- form.on('restoreDraftError', (err) => {
- assert.equal(err, 'Restore Draft Error');
- assert.equal(restoreDraftCalls, 1);
- assert.equal(saveDraftCalls, 0);
- done();
- });
- }).catch((err) => done(err));
- });
-
- it('Should emit saveDraftEvent on the save draft error', function(done) {
- const formElement = document.createElement('div');
- Formio.createForm(
- formElement,
- 'http://localhost:3000/zarbzxibjafpcjb/testdrafterrors',
- {
- saveDraft: true
- }
- ).then((form) => {
- scenario.saveDraftError = true;
- form.on('saveDraftError', (err) => {
- assert.equal(err, 'Save Draft Error');
- assert.equal(saveDraftCalls, 1);
- assert.equal(restoreDraftCalls, 1);
- assert.equal(form.submission.state, 'draft');
- done();
- });
-
- setTimeout(() => {
- assert.equal(saveDraftCalls, 0);
- assert.equal(restoreDraftCalls, 1);
- const tfInput = form.getComponent('textField').refs.input[0];
- tfInput.value = 'test resaved';
- const inputEvent = new Event('input');
- tfInput.dispatchEvent(inputEvent);
- }, 200);
- }).catch((err) => done(err));
- });
- });
-
- for (const formTest of FormTests) {
- const useDoneInsteadOfPromise = formTest.useDone;
-
- if (useDoneInsteadOfPromise) {
- describe(formTest.title || '', () => {
- for (const title in formTest.tests) {
- const formTestTest = formTest.tests[title];
- it(title, function(done) {
- const self = this;
- const formElement = document.createElement('div');
- let form = new Webform(formElement, _.cloneDeep(formTest.formOptions || {}));
- form.setForm(formTest.form).then(function() {
- formTestTest(form, function(error) {
- form = null;
- formElement.innerHTML = '';
- if (error) {
- return done(error);
- }
- done();
- }, self);
- }).catch(done);
- });
- }
- });
- }
- else {
- describe(formTest.title || '', () => {
- for (const title in formTest.tests) {
- const formTestTest = formTest.tests[title];
- it(title, function() {
- const formElement = document.createElement('div');
- const form = new Webform(formElement, { template: 'bootstrap3', language: 'en' });
- return form.setForm(formTest.form).then(function() {
- formTestTest(form, function(error) {
- form.destroy();
- if (error) {
- throw new Error(error);
- }
- });
- });
- });
- }
- });
- }
- }
-});
-
-// describe('Test the saveDraft and restoreDraft feature', () => {
-// APIMock.submission('https://savedraft.form.io/myform', {
-// components: [
-// {
-// type: 'textfield',
-// key: 'a',
-// label: 'A'
-// },
-// {
-// type: 'textfield',
-// key: 'b',
-// label: 'B'
-// }
-// ]
-// });
-//
-// const saveDraft = function(user, draft, newData, done) {
-// const formElement = document.createElement('div');
-// const form = new Webform(formElement, {
-// saveDraft: true,
-// saveDraftThrottle: false
-// });
-// form.src = 'https://savedraft.form.io/myform';
-// Formio.setUser(user);
-// form.on('restoreDraft', (existing) => {
-// assert.deepEqual(existing ? existing.data : null, draft);
-// form.setSubmission({ data: newData }, { modified: true });
-// });
-// form.on('saveDraft', (saved) => {
-// // Make sure the modified class was added to the components.
-// const a = form.getComponent('a');
-// const b = form.getComponent('b');
-// assert.equal(a.hasClass(a.getElement(), 'formio-modified'), true);
-// assert.equal(b.hasClass(b.getElement(), 'formio-modified'), true);
-// assert.deepEqual(saved.data, newData);
-// form.draftEnabled = false;
-// done();
-// });
-// form.formReady.then(() => {
-// assert.equal(form.savingDraft, true);
-// });
-// };
-//
-// it('Should allow a user to start a save draft session.', (done) => saveDraft({
-// _id: '1234',
-// data: {
-// firstName: 'Joe',
-// lastName: 'Smith'
-// }
-// }, null, {
-// a: 'one',
-// b: 'two'
-// }, done));
-//
-// it('Should allow a different user to start a new draft session', (done) => saveDraft({
-// _id: '2468',
-// data: {
-// firstName: 'Sally',
-// lastName: 'Thompson'
-// }
-// }, null, {
-// a: 'three',
-// b: 'four'
-// }, done));
-//
-// it('Should restore a users existing draft', (done) => saveDraft({
-// _id: '1234',
-// data: {
-// firstName: 'Joe',
-// lastName: 'Smith'
-// }
-// }, {
-// a: 'one',
-// b: 'two'
-// }, {
-// a: 'five',
-// b: 'six'
-// }, done));
-// });
-/* eslint-enable max-statements */
diff --git a/web-client/core/themes/italia/static/formio/css/src/WebformBuilder.js b/web-client/core/themes/italia/static/formio/css/src/WebformBuilder.js
deleted file mode 100644
index 8eb06671..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/WebformBuilder.js
+++ /dev/null
@@ -1,1852 +0,0 @@
-import Webform from './Webform';
-import Component from './components/_classes/component/Component';
-import tippy from 'tippy.js';
-import NativePromise from 'native-promise-only';
-import Components from './components/Components';
-import { GlobalFormio as Formio } from './Formio';
-import { fastCloneDeep, bootstrapVersion, getArrayFromComponentPath, getStringFromComponentPath } from './utils/utils';
-import { eachComponent, getComponent } from './utils/formUtils';
-import BuilderUtils from './utils/builder';
-import _ from 'lodash';
-import autoScroll from 'dom-autoscroller';
-
-require('./components/builder');
-
-let Templates = Formio.Templates;
-
-if (!Templates) {
- Templates = require('./templates/Templates').default;
-}
-
-let dragula;
-if (typeof window !== 'undefined') {
- // Import from "dist" because it would require and "global" would not be defined in Angular apps.
- dragula = require('dragula/dist/dragula');
-}
-
-export default class WebformBuilder extends Component {
- // eslint-disable-next-line max-statements
- constructor() {
- let element, options;
- if (arguments[0] instanceof HTMLElement || arguments[1]) {
- element = arguments[0];
- options = arguments[1];
- }
- else {
- options = arguments[0];
- }
- // Reset skipInit in case PDFBuilder has set it.
- options.skipInit = false;
- options.display = options.display || 'form';
-
- super(null, options);
-
- this.element = element;
-
- this.builderHeight = 0;
- this.schemas = {};
- this.repeatablePaths = [];
-
- this.sideBarScroll = _.get(this.options, 'sideBarScroll', true);
- this.sideBarScrollOffset = _.get(this.options, 'sideBarScrollOffset', 0);
- this.dragDropEnabled = true;
-
- // Setup the builder options.
- this.builder = _.defaultsDeep({}, this.options.builder, this.defaultGroups);
-
- // Turn off if explicitely said to do so...
- _.each(this.defaultGroups, (config, key) => {
- if (config === false) {
- this.builder[key] = false;
- }
- });
-
- // Add the groups.////
- this.groups = {};
- this.groupOrder = [];
- for (const group in this.builder) {
- if (this.builder[group]) {
- this.builder[group].key = group;
- this.groups[group] = this.builder[group];
- this.groups[group].components = this.groups[group].components || {};
- this.groups[group].componentOrder = this.groups[group].componentOrder || [];
- this.groups[group].subgroups = Object.keys(this.groups[group].groups || {}).map((groupKey) => {
- this.groups[group].groups[groupKey].componentOrder = Object.keys(this.groups[group].groups[groupKey].components).map((key) => key);
- return this.groups[group].groups[groupKey];
- });
- this.groupOrder.push(this.groups[group]);
- }
- }
-
- this.groupOrder = this.groupOrder
- .filter(group => group && !group.ignore)
- .sort((a, b) => a.weight - b.weight)
- .map(group => group.key);
-
- for (const type in Components.components) {
- const component = Components.components[type];
- if (component.builderInfo && component.builderInfo.schema) {
- this.schemas[type] = component.builderInfo.schema;
- component.type = type;
- const builderInfo = component.builderInfo;
- builderInfo.key = component.type;
- this.addBuilderComponentInfo(builderInfo);
- }
- }
-
- // Filter out any extra components.
- // Add the components in each group.
- for (const group in this.groups) {
- const info = this.groups[group];
- for (const key in info.components) {
- const compKey = group === 'resource' ? `component-${key}` : key;
- let comp = info.components[compKey];
- if (
- comp === true &&
- Components.components[key] &&
- Components.components[key].builderInfo
- ) {
- comp = Components.components[key].builderInfo;
- }
- if (comp && comp.schema) {
- this.schemas[key] = comp.schema;
- info.components[compKey] = comp;
- info.components[compKey].key = key;
- }
- else {
- // Do not include this component in the components array.
- delete info.components[compKey];
- }
- }
-
- // Order the components.
- this.orderComponents(info);
- }
-
- this.options.hooks = this.options.hooks || {};
-
- this.options.hooks.renderComponent = (html, { component, self }) => {
- if (self.type === 'form' && !self.key) {
- const template = this.hook('renderComponentFormTemplate', html.replace('formio-component-form', ''));
- // The main webform shouldn't have this class as it adds extra styles.
- return template;
- }
-
- if (this.options.disabled && this.options.disabled.includes(self.key) || self.parent.noDragDrop) {
- return html;
- }
-
- return this.renderTemplate('builderComponent', {
- html,
- disableBuilderActions: self?.component?.disableBuilderActions,
- childComponent: component,
- });
- };
-
- this.options.hooks.renderComponents = (html, { components, self }) => {
- // if Datagrid and already has a component, don't make it droppable.
- if (self.type === 'datagrid' && components.length > 0 || self.noDragDrop) {
- return html;
- }
-
- if (!components ||
- (!components.length && !components.nodrop) ||
- (self.type === 'form' && components.length <= 1 && (components.length === 0 || components[0].type === 'button'))
- ) {
- html = this.renderTemplate('builderPlaceholder', {
- position: 0
- }) + html;
- }
- return this.renderTemplate('builderComponents', {
- key: self.key,
- type: self.type,
- html,
- });
- };
-
- this.options.hooks.renderInput = (html, { self }) => {
- if (self.type === 'hidden') {
- return html + self.name;
- }
- return html;
- };
-
- this.options.hooks.renderLoading = (html, { self }) => {
- if (self.type === 'form' && self.key) {
- return self.name;
- }
- return html;
- };
-
- this.options.hooks.attachComponents = (element, components, container, component) => {
- // Don't attach if no element was found or component doesn't participate in drag'n'drop.
- if (!element) {
- return;
- }
- if (component.noDragDrop) {
- return element;
- }
- // Attach container and component to element for later reference.
- const containerElement = element.querySelector(`[ref="${component.component.key}-container"]`) || element;
- containerElement.formioContainer = container;
- containerElement.formioComponent = component;
-
- // Add container to draggable list.
- if (this.dragula && this.allowDrop(element)) {
- this.dragula.containers.push(containerElement);
- }
-
- // If this is an existing datagrid element, don't make it draggable.
- if ((component.type === 'datagrid' || component.type === 'datamap') && components.length > 0) {
- return element;
- }
-
- // Since we added a wrapper, need to return the original element so that we can find the components inside it.
- return element.children[0];
- };
-
- this.options.hooks.attachDatagrid = (element, component) => {
- component.loadRefs(element, {
- [`${component.key}-container`]: 'single',
- });
-
- const dataGridContainer = component.refs[`${component.key}-container`];
-
- if (dataGridContainer) {
- component.attachComponents(dataGridContainer.parentNode, [], component.component.components);
- }
- // Need to set up horizontal rearrangement of fields.
- };
-
- this.options.hooks.attachComponent = this.attachComponent.bind(this);
-
- // Load resources tagged as 'builder'
- const query = {
- params: {
- type: 'resource',
- limit: 1000000,
- select: '_id,title,name,components'
- }
- };
- if (this.options && this.options.resourceTag) {
- query.params.tags = [this.options.resourceTag];
- }
- else if (!this.options || !this.options.hasOwnProperty('resourceTag')) {
- query.params.tags = ['builder'];
- }
- const formio = new Formio(Formio.projectUrl);
- const isResourcesDisabled = this.options.builder && this.options.builder.resource === false;
-
- formio.loadProject().then((project) => {
- if (project && (_.get(project, 'settings.addConfigToForms', false) || _.get(project, 'addConfigToForms', false))) {
- const config = project.config || {};
- this.options.formConfig = config;
-
- const pathToFormConfig = 'webform._form.config';
- const webformConfig = _.get(this, pathToFormConfig);
-
- if (this.webform && !webformConfig) {
- _.set(this, pathToFormConfig, config);
- }
- }
- }).catch((err) => {
- console.warn(`Could not load project settings: ${err.message || err}`);
- });
-
- if (!formio.noProject && !isResourcesDisabled) {
- const resourceOptions = this.options.builder && this.options.builder.resource;
- formio.loadForms(query)
- .then((resources) => {
- if (resources.length) {
- this.builder.resource = {
- title: resourceOptions ? resourceOptions.title : 'Existing Resource Fields',
- key: 'resource',
- weight: resourceOptions ? resourceOptions.weight : 50,
- subgroups: [],
- components: [],
- componentOrder: []
- };
- this.groups.resource = {
- title: resourceOptions ? resourceOptions.title : 'Existing Resource Fields',
- key: 'resource',
- weight: resourceOptions ? resourceOptions.weight : 50,
- subgroups: [],
- components: [],
- componentOrder: []
- };
- if (!this.groupOrder.includes('resource')) {
- this.groupOrder.push('resource');
- }
- this.addExistingResourceFields(resources);
- }
- });
- }
-
- // Notify components if they need to modify their render.
- this.options.attachMode = 'builder';
- this.webform = this.webform || this.createForm(this.options);
-
- this.pathComponentsMapping = {};
- this.arrayDataComponentPaths = [];
- this.nestedDataComponents = [];
- this.arrayDataComponents = [];
- }
-
- allowDrop() {
- return true;
- }
-
- addExistingResourceFields(resources) {
- _.each(resources, (resource, index) => {
- const resourceKey = `resource-${resource.name}`;
- const subgroup = {
- key: resourceKey,
- title: resource.title,
- components: [],
- componentOrder: [],
- default: index === 0,
- };
-
- eachComponent(resource.components, (component) => {
- if (component.type === 'button') return;
- if (
- this.options &&
- this.options.resourceFilter &&
- (!component.tags || component.tags.indexOf(this.options.resourceFilter) === -1)
- ) return;
-
- let componentName = component.label;
- if (!componentName && component.key) {
- componentName = _.upperFirst(component.key);
- }
-
- subgroup.componentOrder.push(`component-${component.key}`);
- subgroup.components[`component-${component.key}`] = _.merge(
- fastCloneDeep(Components.components[component.type]
- ? Components.components[component.type].builderInfo
- : Components.components['unknown'].builderInfo),
- {
- key: component.key,
- title: componentName,
- group: 'resource',
- subgroup: resourceKey,
- },
- {
- schema: {
- ...component,
- label: component.label,
- key: component.key,
- lockKey: true,
- source: (!this.options.noSource ? resource._id : undefined),
- isNew: true
- }
- }
- );
- }, true);
-
- this.groups.resource.subgroups.push(subgroup);
- });
-
- this.triggerRedraw();
- }
-
- attachTooltip(component, title) {
- return tippy(component, {
- allowHTML: true,
- trigger: 'mouseenter focus',
- placement: 'top',
- delay: [200, 0],
- zIndex: 10000,
- content: title
- });
- }
-
- attachComponent(element, component) {
- if (component instanceof WebformBuilder) {
- return;
- }
-
- // Add component to element for later reference.
- element.formioComponent = component;
-
- component.loadRefs(element, {
- removeComponent: 'single',
- editComponent: 'single',
- moveComponent: 'single',
- copyComponent: 'single',
- pasteComponent: 'single',
- editJson: 'single'
- });
-
- if (component.refs.copyComponent) {
- this.attachTooltip(component.refs.copyComponent, this.t('Copy'));
-
- component.addEventListener(component.refs.copyComponent, 'click', () =>
- this.copyComponent(component));
- }
-
- if (component.refs.pasteComponent) {
- const pasteToolTip = this.attachTooltip(component.refs.pasteComponent, this.t('Paste below'));
-
- component.addEventListener(component.refs.pasteComponent, 'click', () => {
- pasteToolTip.hide();
- this.pasteComponent(component);
- });
- }
-
- if (component.refs.moveComponent) {
- this.attachTooltip(component.refs.moveComponent, this.t('Move'));
- if (this.keyboardActionsEnabled) {
- component.addEventListener(component.refs.moveComponent, 'click', () => {
- this.moveComponent(component);
- });
- }
- }
-
- const parent = this.getParentElement(element);
-
- if (component.refs.editComponent) {
- this.attachTooltip(component.refs.editComponent, this.t('Edit'));
-
- component.addEventListener(component.refs.editComponent, 'click', () =>
- this.editComponent(component.schema, parent, false, false, component.component, { inDataGrid: component.isInDataGrid }));
- }
-
- if (component.refs.editJson) {
- this.attachTooltip(component.refs.editJson, this.t('Edit JSON'));
-
- component.addEventListener(component.refs.editJson, 'click', () =>
- this.editComponent(component.schema, parent, false, true, component.component));
- }
-
- if (component.refs.removeComponent) {
- this.attachTooltip(component.refs.removeComponent, this.t('Remove'));
-
- component.addEventListener(component.refs.removeComponent, 'click', () =>
- this.removeComponent(component.schema, parent, component.component));
- }
-
- return element;
- }
-
- createForm(options) {
- this.webform = new Webform(this.element, options);
- if (this.element) {
- this.loadRefs(this.element, {
- form: 'single'
- });
- if (this.refs.form) {
- this.webform.element = this.refs.form;
- }
- }
- return this.webform;
- }
-
- /**
- * Called when everything is ready.
- *
- * @returns {Promise} - Wait for webform to be ready.
- */
- get ready() {
- return this.webform.ready;
- }
-
- get defaultGroups() {
- return {
- basic: {
- title: 'Basic',
- weight: 0,
- default: true,
- },
- advanced: {
- title: 'Advanced',
- weight: 10
- },
- layout: {
- title: 'Layout',
- weight: 20
- },
- data: {
- title: 'Data',
- weight: 30
- },
- premium: {
- title: 'Premium',
- weight: 40
- }
- };
- }
-
- redraw() {
- return Webform.prototype.redraw.call(this);
- }
-
- get form() {
- return this.webform.form;
- }
-
- get schema() {
- return this.webform.schema;
- }
-
- set form(value) {
- this.setForm(value);
- }
-
- get container() {
- return this.webform.form.components;
- }
-
- /**
- * When a component sets its api key, we need to check if it is unique within its namespace. Find the namespace root
- * so we can calculate this correctly.
- * @param component
- */
- findNamespaceRoot(component) {
- const path = getArrayFromComponentPath(component.path);
- // First get the component with nested parents.
- let comp = this.webform.getComponent(path);
- comp = Array.isArray(comp) ? comp[0] : comp;
- const namespaceKey = this.recurseNamespace(comp);
-
- // If there is no key, it is the root form.
- if (!namespaceKey || this.form.key === namespaceKey) {
- return this.form.components;
- }
-
- const componentSchema = component.component;
- // If the current component is the namespace, we don't need to find it again.
- if (namespaceKey === component.key) {
- return [...componentSchema.components, componentSchema];
- }
-
- // Get the namespace component so we have the original object.
- const namespaceComponent = getComponent(this.form.components, namespaceKey, true);
- return namespaceComponent ? namespaceComponent.components : comp.components;
- }
-
- recurseNamespace(component) {
- // If there is no parent, we are at the root level.
- if (!component) {
- return null;
- }
-
- // Some components are their own namespace.
- if (['address', 'container', 'datagrid', 'editgrid', 'dynamicWizard', 'tree'].includes(component.type) || component.tree || component.arrayTree) {
- return component.key;
- }
-
- // Anything else, keep going up.
- return this.recurseNamespace(component.parent);
- }
-
- render() {
- return this.renderTemplate('builder', {
- sidebar: this.renderTemplate('builderSidebar', {
- scrollEnabled: this.sideBarScroll,
- groupOrder: this.groupOrder,
- groupId: `builder-sidebar-${this.id}`,
- groups: this.groupOrder.map((groupKey) => this.renderTemplate('builderSidebarGroup', {
- group: this.groups[groupKey],
- groupKey,
- groupId: `builder-sidebar-${this.id}`,
- subgroups: this.groups[groupKey].subgroups.map((group) => this.renderTemplate('builderSidebarGroup', {
- group,
- groupKey: group.key,
- groupId: `group-container-${groupKey}`,
- subgroups: []
- })),
- keyboardActionsEnabled: this.keyboardActionsEnabled,
- })),
- }),
- form: this.webform.render(),
- });
- }
-
- attach(element) {
- this.on('change', (form) => {
- this.populateRecaptchaSettings(form);
- });
- return super.attach(element).then(() => {
- this.loadRefs(element, {
- form: 'single',
- sidebar: 'single',
- 'sidebar-search': 'single',
- 'sidebar-groups': 'single',
- 'container': 'multiple',
- 'sidebar-anchor': 'multiple',
- 'sidebar-group': 'multiple',
- 'sidebar-container': 'multiple',
- 'sidebar-component': 'multiple',
- });
-
- if (this.sideBarScroll && Templates.current.handleBuilderSidebarScroll) {
- Templates.current.handleBuilderSidebarScroll.call(this, this);
- }
-
- // Add the paste status in form
- if (typeof window !== 'undefined' && window.sessionStorage) {
- const data = window.sessionStorage.getItem('formio.clipboard');
- if (data) {
- this.addClass(this.refs.form, 'builder-paste-mode');
- }
- }
-
- if (!bootstrapVersion(this.options)) {
- // Initialize
- this.refs['sidebar-group'].forEach((group) => {
- group.style.display = (group.getAttribute('data-default') === 'true') ? 'inherit' : 'none';
- });
-
- // Click event
- this.refs['sidebar-anchor'].forEach((anchor, index) => {
- this.addEventListener(anchor, 'click', () => {
- const clickedParentId = anchor.getAttribute('data-parent').slice('#builder-sidebar-'.length);
- const clickedId = anchor.getAttribute('data-target').slice('#group-'.length);
-
- this.refs['sidebar-group'].forEach((group, groupIndex) => {
- const openByDefault = group.getAttribute('data-default') === 'true';
- const groupId = group.getAttribute('id').slice('group-'.length);
- const groupParent = group.getAttribute('data-parent').slice('#builder-sidebar-'.length);
-
- group.style.display =
- (
- (openByDefault && groupParent === clickedId) ||
- groupId === clickedParentId ||
- groupIndex === index
- )
- ? 'inherit' : 'none';
- });
- }, true);
- });
- }
-
- if (this.keyboardActionsEnabled) {
- this.refs['sidebar-component'].forEach((component) => {
- this.addEventListener(component, 'keydown', (event) => {
- if (event.keyCode === 13) {
- this.addNewComponent(component);
- }
- });
- });
- }
-
- this.addEventListener(this.refs['sidebar-search'], 'input',
- _.debounce((e) => {
- const searchString = e.target.value;
- this.searchFields(searchString);
- }, 300)
- );
-
- if (this.dragDropEnabled) {
- this.initDragula();
- }
-
- const drake = this.dragula;
-
- if (this.refs.form) {
- autoScroll([window], {
- margin: 20,
- maxSpeed: 6,
- scrollWhenOutside: true,
- autoScroll: function() {
- return this.down && drake?.dragging;
- }
- });
-
- return this.webform.attach(this.refs.form);
- }
- });
- }
-
- searchFields(searchString = '') {
- const searchValue = searchString.toLowerCase();
- const sidebar = this.refs['sidebar'];
- const sidebarGroups = this.refs['sidebar-groups'];
-
- if (!sidebar || !sidebarGroups) {
- return;
- }
-
- const filterGroupBy = (group, searchValue = '') => {
- const result = _.toPlainObject(group);
- const { subgroups = [], components } = result;
- const filteredComponents = [];
-
- for (const key in components) {
- const isMatchedToTitle = components[key].title.toLowerCase().match(searchValue);
- const isMatchedToKey = components[key].key.toLowerCase().match(searchValue);
-
- if (isMatchedToTitle || isMatchedToKey) {
- filteredComponents.push(components[key]);
- }
- }
-
- this.orderComponents(result, filteredComponents);
- if (searchValue) {
- result.default = true;
- }
- if (result.componentOrder.length || subgroups.length) {
- return result;
- }
- return null;
- };
-
- const filterGroupOrder = (groupOrder, searchValue) => {
- const result = _.cloneDeep(groupOrder);
- return result.filter(key => filterGroupBy(this.groups[key], searchValue));
- };
-
- const filterSubgroups = (groups, searchValue) => {
- const result = _.clone(groups);
- return result
- .map(subgroup => filterGroupBy(subgroup, searchValue))
- .filter(subgroup => !_.isNull(subgroup));
- };
-
- const toTemplate = groupKey => {
- return {
- group: filterGroupBy(this.groups[groupKey], searchValue),
- groupKey,
- groupId: sidebar.id || sidebarGroups.id,
- subgroups: filterSubgroups(this.groups[groupKey].subgroups, searchValue)
- .map((group) => this.renderTemplate('builderSidebarGroup', {
- group,
- groupKey: group.key,
- groupId: `group-container-${groupKey}`,
- subgroups: []
- })),
- };
- };
-
- sidebarGroups.innerHTML = filterGroupOrder(this.groupOrder, searchValue)
- .map(groupKey => this.renderTemplate('builderSidebarGroup', toTemplate(groupKey)))
- .join('');
-
- this.loadRefs(this.element, {
- 'sidebar-groups': 'single',
- 'sidebar-anchor': 'multiple',
- 'sidebar-group': 'multiple',
- 'sidebar-container': 'multiple',
- });
-
- this.updateDragAndDrop();
-
- if (searchValue === '') {
- this.triggerRedraw();
- }
- }
-
- orderComponents(groupInfo, foundComponents) {
- const components = foundComponents || groupInfo.components;
- const isResource = groupInfo.key.indexOf('resource-') === 0;
- if (components) {
- groupInfo.componentOrder = Object.keys(components)
- .map(key => components[key])
- .filter(component => component && !component.ignore && !component.ignoreForForm)
- .sort((a, b) => a.weight - b.weight)
- .map(component => isResource ? `component-${component.key}` : component.key);
- }
- }
-
- updateDragAndDrop() {
- if (this.dragDropEnabled) {
- this.initDragula();
- }
- if (this.refs.form) {
- return this.webform.attach(this.refs.form);
- }
- }
-
- initDragula() {
- const options = this.options;
-
- if (this.dragula) {
- this.dragula.destroy();
- }
-
- const containersArray = Array.prototype.slice.call(this.refs['sidebar-container']).filter(item => {
- return item.id !== 'group-container-resource';
- });
-
- if (!dragula) {
- return;
- }
-
- this.dragula = dragula(containersArray, {
- moves(el) {
- let moves = true;
-
- const list = Array.from(el.classList).filter(item => item.indexOf('formio-component-') === 0);
- list.forEach(item => {
- const key = item.slice('formio-component-'.length);
- if (options.disabled && options.disabled.includes(key)) {
- moves = false;
- }
- });
-
- if (el.classList.contains('no-drag')) {
- moves = false;
- }
- return moves;
- },
- copy(el) {
- return el.classList.contains('drag-copy');
- },
- accepts(el, target) {
- return !el.contains(target) && !target.classList.contains('no-drop');
- }
- }).on('drop', (element, target, source, sibling) => this.onDrop(element, target, source, sibling));
- }
-
- detach() {
- if (this.dragula) {
- this.dragula.destroy();
- }
- this.dragula = null;
- if (this.sideBarScroll && Templates.current.clearBuilderSidebarScroll) {
- Templates.current.clearBuilderSidebarScroll.call(this, this);
- }
-
- super.detach();
- }
-
- getComponentInfo(key, group) {
- let info;
- // Need to check in first order as resource component key can be the same as from webform default components
- if (group && group.slice(0, group.indexOf('-')) === 'resource') {
- // This is an existing resource field.
- const resourceGroups = this.groups.resource.subgroups;
- const resourceGroup = _.find(resourceGroups, { key: group });
- if (resourceGroup && resourceGroup.components.hasOwnProperty(`component-${key}`)) {
- info = fastCloneDeep(resourceGroup.components[`component-${key}`].schema);
- }
- }
- // This is a new component
- else if (this.schemas.hasOwnProperty(key)) {
- info = fastCloneDeep(this.schemas[key]);
- }
- else if (this.groups.hasOwnProperty(group)) {
- const groupComponents = this.groups[group].components;
- if (groupComponents.hasOwnProperty(key)) {
- info = fastCloneDeep(groupComponents[key].schema);
- }
- }
- else if (group === 'searchFields') {//Search components go into this group
- const resourceGroups = this.groups.resource.subgroups;
- for (let ix = 0; ix < resourceGroups.length; ix++) {
- const resourceGroup = resourceGroups[ix];
- if (resourceGroup.components.hasOwnProperty(`component-${key}`)) {
- info = fastCloneDeep(resourceGroup.components[`component-${key}`].schema);
- break;
- }
- }
- }
-
- if (info) {
- info.key = this.generateKey(info);
- }
-
- return info;
- }
-
- getComponentsPath(component, parent) {
- // Get path to the component in the parent component.
- let path = 'components';
- let columnIndex = 0;
- let tableRowIndex = 0;
- let tableColumnIndex = 0;
- let tabIndex = 0;
- switch (parent.type) {
- case 'table':
- tableRowIndex = _.findIndex(parent.rows, row => row.some(column => column.components.some(comp => comp.key === component.key)));
- tableColumnIndex = _.findIndex(parent.rows[tableRowIndex], (column => column.components.some(comp => comp.key === component.key)));
- path = `rows[${tableRowIndex}][${tableColumnIndex}].components`;
- break;
- case 'columns':
- columnIndex = _.findIndex(parent.columns, column => column.components.some(comp => comp.key === component.key));
- path = `columns[${columnIndex}].components`;
- break;
- case 'tabs':
- tabIndex = _.findIndex(parent.components, tab => tab.components.some(comp => comp.key === component.key));
- path = `components[${tabIndex}].components`;
- break;
- }
- return path;
- }
-
- /* eslint-disable max-statements */
- onDrop(element, target, source, sibling) {
- if (!target) {
- return;
- }
-
- // If you try to drop within itself.
- if (element.contains(target)) {
- return;
- }
-
- const key = element.getAttribute('data-key');
- const type = element.getAttribute('data-type');
- const group = element.getAttribute('data-group');
- let info, isNew, path, index;
-
- if (key && group) {
- // This is a new component.
- info = this.getComponentInfo(key, group);
- if (!info && type) {
- info = this.getComponentInfo(type, group);
- }
- isNew = true;
- }
- else if (source.formioContainer) {
- index = _.findIndex(source.formioContainer, { key: element.formioComponent.component.key });
- if (index !== -1) {
- // Grab and remove the component from the source container.
- info = source.formioContainer.splice(
- _.findIndex(source.formioContainer, { key: element.formioComponent.component.key }), 1
- );
-
- // Since splice returns an array of one object, we need to destructure it.
- info = info[0];
- }
- }
-
- // If we haven't found the component, stop.
- if (!info) {
- return;
- }
-
- // Show an error if siblings are disabled for a component and such a component already exists.
- const compKey = (group === 'resource') ? `component-${key}` : key;
- const draggableComponent = this.groups[group]?.components[compKey] || {};
-
- if (draggableComponent.disableSiblings) {
- let isCompAlreadyExists = false;
- eachComponent(this.webform.components, (component) => {
- if (component.type === draggableComponent.schema.type) {
- isCompAlreadyExists = true;
- return;
- }
- }, true);
- if (isCompAlreadyExists) {
- this.webform.redraw();
- this.webform.setAlert('danger', `You cannot add more than one ${draggableComponent.key} component to one page.`);
- return;
- }
- }
-
- if (target !== source) {
- // Ensure the key remains unique in its new container.
- BuilderUtils.uniquify(this.findNamespaceRoot(target.formioComponent), info);
- }
-
- const parent = target.formioComponent;
-
- // Insert in the new container.
- if (target.formioContainer) {
- if (sibling) {
- if (!sibling.getAttribute('data-noattach')) {
- index = _.findIndex(target.formioContainer, { key: _.get(sibling, 'formioComponent.component.key') });
- index = (index === -1) ? 0 : index;
- }
- else {
- index = sibling.getAttribute('data-position');
- }
- if (index !== -1) {
- target.formioContainer.splice(index, 0, info);
- }
- }
- else {
- target.formioContainer.push(info);
- }
- path = this.getComponentsPath(info, parent.component);
- index = _.findIndex(_.get(parent.schema, path), { key: info.key });
- if (index === -1) {
- index = 0;
- }
- }
-
- if (parent && parent.addChildComponent) {
- parent.addChildComponent(info, element, target, source, sibling);
- }
-
- const componentInDataGrid = parent.type === 'datagrid';
-
- if (isNew && !this.options.noNewEdit && !info.noNewEdit) {
- this.editComponent(info, target, isNew, null, null, { inDataGrid: componentInDataGrid });
- }
-
- // Only rebuild the parts needing to be rebuilt.
- let rebuild;
- if (target !== source) {
- if (source.formioContainer && source.contains(target)) {
- rebuild = source.formioComponent.rebuild();
- }
- else if (target.contains(source)) {
- rebuild = target.formioComponent.rebuild();
- }
- else {
- if (source.formioContainer) {
- rebuild = source.formioComponent.rebuild();
- }
- rebuild = target.formioComponent.rebuild();
- }
- }
- else {
- // If they are the same, only rebuild one.
- rebuild = target.formioComponent.rebuild();
- }
-
- if (!rebuild) {
- rebuild = NativePromise.resolve();
- }
-
- return rebuild.then(() => {
- this.emit('addComponent', info, parent, path, index, isNew && !this.options.noNewEdit && !info.noNewEdit);
- if (!isNew || this.options.noNewEdit || info.noNewEdit) {
- this.emit('change', this.form);
- }
- });
- }
-
- setForm(form) {
- if (!form.components) {
- form.components = [];
- }
-
- if (form && form.properties) {
- this.options.properties = form.properties;
- }
-
- this.keyboardActionsEnabled = _.get(this.options, 'keyboardBuilder', false) || this.options.properties?.keyboardBuilder;
-
- const isShowSubmitButton = !this.options.noDefaultSubmitButton
- && !form.components.length;
-
- // Ensure there is at least a submit button.
- if (isShowSubmitButton) {
- form.components.push({
- type: 'button',
- label: 'Submit',
- key: 'submit',
- size: 'md',
- block: false,
- action: 'submit',
- disableOnInvalid: true,
- theme: 'primary'
- });
- }
-
- if (this.webform) {
- const shouldRebuild = !this.webform.form.components ||
- (form.components.length !== this.webform.form.components.length);
- return this.webform.setForm(form, { keepAsReference: true }).then(() => {
- if (this.refs.form) {
- this.builderHeight = this.refs.form.offsetHeight;
- }
- if (!shouldRebuild) {
- return this.form;
- }
- return this.rebuild().then(() => this.form);
- });
- }
- return NativePromise.resolve(form);
- }
-
- populateRecaptchaSettings(form) {
- //populate isEnabled for recaptcha form settings
- let isRecaptchaEnabled = false;
- if (this.form.components) {
- eachComponent(form.components, component => {
- if (isRecaptchaEnabled) {
- return;
- }
- if (component.type === 'recaptcha') {
- isRecaptchaEnabled = true;
- return false;
- }
- });
- if (isRecaptchaEnabled) {
- _.set(form, 'settings.recaptcha.isEnabled', true);
- }
- else if (_.get(form, 'settings.recaptcha.isEnabled')) {
- _.set(form, 'settings.recaptcha.isEnabled', false);
- }
- }
- }
-
- removeComponent(component, parent, original) {
- if (!parent) {
- return;
- }
- let remove = true;
- const removingComponentsGroup = !component.skipRemoveConfirm &&
- (
- (Array.isArray(component.components) && component.components.length) ||
- (Array.isArray(component.rows) && component.rows.length) ||
- (Array.isArray(component.columns) && component.columns.length)
- );
-
- if (this.options.alwaysConfirmComponentRemoval || removingComponentsGroup) {
- const message = removingComponentsGroup ? 'Removing this component will also remove all of its children. Are you sure you want to do this?'
- : 'Are you sure you want to remove this component?';
- remove = window.confirm(this.t(message));
- }
- if (!original) {
- original = parent.formioContainer.find((comp) => comp.id === component.id);
- }
- const index = parent.formioContainer ? parent.formioContainer.indexOf(original) : 0;
- if (remove && index !== -1) {
- const path = this.getComponentsPath(component, parent.formioComponent.component);
- if (parent.formioContainer) {
- parent.formioContainer.splice(index, 1);
- }
- else if (parent.formioComponent && parent.formioComponent.removeChildComponent) {
- parent.formioComponent.removeChildComponent(component);
- }
- const rebuild = parent.formioComponent.rebuild() || NativePromise.resolve();
- rebuild.then(() => {
- this.emit('removeComponent', component, parent.formioComponent.schema, path, index);
- this.emit('change', this.form);
- });
- }
- return remove;
- }
-
- replaceDoubleQuotes(data, fieldsToRemoveDoubleQuotes = []) {
- if (data) {
- fieldsToRemoveDoubleQuotes.forEach((key) => {
- if (data[key]) {
- data[key] = data[key].replace(/"/g, "'");
- }
- });
- return data;
- }
- }
-
- updateComponent(component, changed) {
- // Update the preview.
- if (this.preview) {
- this.preview.form = {
- components: [_.omit({ ...component }, [
- 'hidden',
- 'conditional',
- 'calculateValue',
- 'logic',
- 'autofocus',
- 'customConditional',
- ])],
- config: this.options.formConfig || {}
- };
-
- const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
-
- this.preview.form.components.forEach(component => this.replaceDoubleQuotes(component, fieldsToRemoveDoubleQuotes));
-
- const previewElement = this.componentEdit.querySelector('[ref="preview"]');
- if (previewElement) {
- this.setContent(previewElement, this.preview.render());
- this.preview.attach(previewElement);
- }
- }
-
- // Change the "default value" field to be reflective of this component.
- const defaultValueComponent = getComponent(this.editForm.components, 'defaultValue', true);
- if (defaultValueComponent && component.type !== 'hidden') {
- const defaultChanged = changed && (
- (changed.component && changed.component.key === 'defaultValue')
- || (changed.instance && defaultValueComponent.hasComponent && defaultValueComponent.hasComponent(changed.instance))
- );
-
- if (!defaultChanged) {
- _.assign(defaultValueComponent.component, _.omit({ ...component }, [
- 'key',
- 'label',
- 'placeholder',
- 'tooltip',
- 'hidden',
- 'autofocus',
- 'validate',
- 'disabled',
- 'defaultValue',
- 'customDefaultValue',
- 'calculateValue',
- 'conditional',
- 'customConditional',
- 'id'
- ]));
- const parentComponent = defaultValueComponent.parent;
- let tabIndex = -1;
- let index = -1;
- parentComponent.tabs.some((tab, tIndex) => {
- tab.some((comp, compIndex) => {
- if (comp.id === defaultValueComponent.id) {
- tabIndex = tIndex;
- index = compIndex;
- return true;
- }
- return false;
- });
- });
-
- if (tabIndex !== -1 && index !== -1 && changed && !_.isNil(changed.value)) {
- const sibling = parentComponent.tabs[tabIndex][index + 1];
- parentComponent.removeComponent(defaultValueComponent);
- const newComp = parentComponent.addComponent(defaultValueComponent.component, defaultValueComponent.data, sibling);
- _.pull(newComp.validators, 'required');
- parentComponent.tabs[tabIndex].splice(index, 1, newComp);
- newComp.checkValidity = () => true;
- newComp.build(defaultValueComponent.element);
- }
- }
- else {
- let dataPath = changed.instance._data.key;
-
- const path = getArrayFromComponentPath(changed.instance.path);
- path.shift();
-
- if (path.length) {
- path.unshift(component.key);
- dataPath = getStringFromComponentPath(path);
- }
-
- _.set(this.preview._data, dataPath, changed.value);
- _.set(this.webform._data, dataPath, changed.value);
- }
- }
-
- // Called when we update a component.
- this.emit('updateComponent', component);
- }
-
- findRepeatablePaths() {
- const repeatablePaths = [];
- const keys = new Map();
-
- eachComponent(this.form.components, (comp, path) => {
- if (!comp.key) {
- return;
- }
-
- if (keys.has(comp.key)) {
- if (keys.get(comp.key).includes(path)) {
- repeatablePaths.push(path);
- }
- else {
- keys.set(comp.key, [...keys.get(comp.key), path]);
- }
- }
- else {
- keys.set(comp.key, [path]);
- }
- }, true);
-
- return repeatablePaths;
- }
-
- highlightInvalidComponents() {
- const repeatablePaths = this.findRepeatablePaths();
- let hasInvalidComponents = false;
-
- this.webform.everyComponent((comp) => {
- const path = comp.path;
- if (repeatablePaths.includes(path)) {
- comp.setCustomValidity(`API Key is not unique: ${comp.key}`);
- hasInvalidComponents = true;
- }
- else if (comp.error?.message?.startsWith('API Key is not unique')) {
- comp.setCustomValidity('');
- }
- });
-
- this.emit('builderFormValidityChange', hasInvalidComponents);
- }
-
- /**
- * Called when a new component is saved.
- *
- * @param parent
- * @param component
- * @return {boolean}
- */
- saveComponent(component, parent, isNew, original) {
- this.editForm.detach();
- const parentContainer = parent ? parent.formioContainer : this.container;
- const parentComponent = parent ? parent.formioComponent : this;
- this.dialog.close();
- const path = parentContainer ? this.getComponentsPath(component, parentComponent.component) : '';
- if (!original) {
- original = parent.formioContainer.find((comp) => comp.id === component.id);
- }
- const index = parentContainer ? parentContainer.indexOf(original) : 0;
- if (index !== -1) {
- let submissionData = this.editForm.submission.data;
- submissionData = submissionData.componentJson || submissionData;
- const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
-
- this.replaceDoubleQuotes(submissionData, fieldsToRemoveDoubleQuotes);
-
- this.hook('beforeSaveComponentSettings', submissionData);
-
- let comp = null;
- parentComponent.getComponents().forEach((component) => {
- if (component.component.key === original.key) {
- comp = component;
- }
- });
- const originalComp = comp.component;
- const originalComponentSchema = comp.schema;
-
- const isParentSaveChildMethod = this.isParentSaveChildMethod(parent.formioComponent);
-
- if (parentContainer && !isParentSaveChildMethod) {
- parentContainer[index] = submissionData;
- if (comp) {
- comp.component = submissionData;
- }
- }
- else if (isParentSaveChildMethod) {
- parent.formioComponent.saveChildComponent(submissionData);
- }
-
- const rebuild = parentComponent.rebuild() || NativePromise.resolve();
- return rebuild.then(() => {
- const schema = parentContainer ? parentContainer[index] : (comp ? comp.schema : []);
- this.emitSaveComponentEvent(
- schema,
- originalComp,
- parentComponent.schema,
- path,
- index,
- isNew,
- originalComponentSchema
- );
- this.emit('change', this.form);
- this.highlightInvalidComponents();
-
- if (this.isComponentCreated) {
- const component = parent.formioComponent.components[0];
- this.moveComponent(component);
- this.isComponentCreated = false;
- }
- });
- }
-
- this.highlightInvalidComponents();
- return NativePromise.resolve();
- }
-
- emitSaveComponentEvent(schema, originalComp, parentComponentSchema, path, index, isNew, originalComponentSchema) {
- this.emit('saveComponent',
- schema,
- originalComp,
- parentComponentSchema,
- path,
- index,
- isNew,
- originalComponentSchema
- );
- }
-
- attachEditComponentControls(component, parent, isNew, original, ComponentClass) {
- const cancelButtons = this.componentEdit.querySelectorAll('[ref="cancelButton"]');
- cancelButtons.forEach((cancelButton) => {
- this.editForm.addEventListener(cancelButton, 'click', (event) => {
- event.preventDefault();
- this.editForm.detach();
- this.emit('cancelComponent', component);
- this.dialog.close();
- this.highlightInvalidComponents();
- });
- });
-
- const removeButtons = this.componentEdit.querySelectorAll('[ref="removeButton"]');
- removeButtons.forEach((removeButton) => {
- this.editForm.addEventListener(removeButton, 'click', (event) => {
- event.preventDefault();
- // Since we are already removing the component, don't trigger another remove.
- this.saved = true;
- this.editForm.detach();
- this.removeComponent(component, parent, original);
- this.dialog.close();
- this.highlightInvalidComponents();
- });
- });
-
- const saveButtons = this.componentEdit.querySelectorAll('[ref="saveButton"]');
- saveButtons.forEach((saveButton) => {
- this.editForm.addEventListener(saveButton, 'click', (event) => {
- event.preventDefault();
- if (!this.editForm.checkValidity(this.editForm.data, true, this.editForm.data)) {
- this.editForm.setPristine(false);
- this.editForm.showErrors();
- return false;
- }
- this.saved = true;
- this.saveComponent(component, parent, isNew, original);
- });
- });
-
- const previewButtons = this.componentEdit.querySelectorAll('[ref="previewButton"]');
- previewButtons.forEach((previewButton) => {
- this.editForm.addEventListener(previewButton, 'click', (event) => {
- event.preventDefault();
- this.showPreview = !this.showPreview;
- this.editForm.detach();
- this.setContent(this.componentEdit, this.renderTemplate('builderEditForm', {
- componentInfo: ComponentClass.builderInfo,
- editForm: this.editForm.render(),
- preview: this.preview ? this.preview.render() : false,
- showPreview: this.showPreview,
- helplinks: this.helplinks,
- }));
- this.editForm.attach(this.componentEdit.querySelector('[ref="editForm"]'));
- this.attachEditComponentControls(component, parent, isNew, original, ComponentClass);
- });
- });
- }
-
- editComponent(component, parent, isNew, isJsonEdit, original, flags = {}) {
- if (!component.key) {
- return;
- }
- this.saved = false;
- const componentCopy = fastCloneDeep(component);
- let ComponentClass = Components.components[componentCopy.type];
- const isCustom = ComponentClass === undefined;
- isJsonEdit = isJsonEdit || isCustom;
- ComponentClass = isCustom ? Components.components.unknown : ComponentClass;
- // Make sure we only have one dialog open at a time.
- if (this.dialog) {
- this.dialog.close();
- this.highlightInvalidComponents();
- }
-
- // This is the render step.
- const editFormOptions = _.clone(_.get(this, 'options.editForm', {}));
- if (this.editForm) {
- this.editForm.destroy();
- }
-
- // Allow editForm overrides per component.
- const overrides = _.get(this.options, `editForm.${componentCopy.type}`, {});
-
- // Pass along the form being edited.
- editFormOptions.editForm = this.form;
- editFormOptions.editComponent = component;
- editFormOptions.flags = flags;
-
- this.hook('editComponentParentInstance', editFormOptions, parent);
-
- this.editForm = new Webform(
- {
- ..._.omit(this.options, ['hooks', 'builder', 'events', 'attachMode', 'skipInit']),
- language: this.options.language,
- ...editFormOptions
- }
- );
-
- this.hook('editFormProperties', parent);
-
- this.editForm.form = (isJsonEdit && !isCustom) ? {
- components: [
- {
- type: 'textarea',
- as: 'json',
- editor: 'ace',
- weight: 10,
- input: true,
- key: 'componentJson',
- label: 'Component JSON',
- tooltip: 'Edit the JSON for this component.'
- },
- {
- type: 'checkbox',
- key: 'showFullSchema',
- label: 'Full Schema'
- }
- ]
- } : ComponentClass.editForm(_.cloneDeep(overrides));
- const instanceOptions = {
- inFormBuilder: true,
- };
-
- this.hook('instanceOptionsPreview', instanceOptions);
-
- const instance = new ComponentClass(componentCopy, instanceOptions);
- const schema = this.hook('builderComponentSchema', component, instance);
-
- this.editForm.submission = isJsonEdit ? {
- data: {
- componentJson: schema,
- showFullSchema: this.options.showFullJsonSchema
- },
- } : {
- data: instance.component,
- };
-
- if (this.preview) {
- this.preview.destroy();
- }
- if (!ComponentClass.builderInfo.hasOwnProperty('preview') || ComponentClass.builderInfo.preview) {
- this.preview = new Webform(_.omit({ ...this.options, preview: true }, [
- 'hooks',
- 'builder',
- 'events',
- 'attachMode',
- 'calculateValue'
- ]));
-
- this.hook('previewFormSettitngs', schema, isJsonEdit);
- }
-
- this.showPreview = ComponentClass.builderInfo.showPreview ?? true;
-
- this.componentEdit = this.ce('div', { 'class': 'component-edit-container' });
- this.setContent(this.componentEdit, this.renderTemplate('builderEditForm', {
- componentInfo: ComponentClass.builderInfo,
- editForm: this.editForm.render(),
- preview: this.preview ? this.preview.render() : false,
- showPreview: this.showPreview,
- helplinks: this.helplinks
- }));
-
- this.dialog = this.createModal(this.componentEdit, _.get(this.options, 'dialogAttr', {}));
-
- // This is the attach step.
- this.editForm.attach(this.componentEdit.querySelector('[ref="editForm"]'));
-
- this.hook('editFormWrapper');
-
- this.updateComponent(componentCopy);
-
- this.editForm.on('change', (event) => {
- if (event.changed) {
- if (event.changed.component && event.changed.component.key === 'showFullSchema') {
- const { value } = event.changed;
- this.editForm.submission = {
- data: {
- componentJson: value ? instance.component : component,
- showFullSchema: value
- },
- };
- return;
- }
- // See if this is a manually modified key. Treat custom component keys as manually modified
- if ((event.changed.component && (event.changed.component.key === 'key')) || isJsonEdit) {
- componentCopy.keyModified = true;
- }
-
- let isComponentLabelChanged = false;
- if (event.changed.instance) {
- isComponentLabelChanged = ['label', 'title'].includes(event.changed.instance.path);
- }
- else if (event.changed.component) {
- isComponentLabelChanged = ['label', 'title'].includes(event.changed.component.key);
- }
-
- if (isComponentLabelChanged) {
- // Ensure this component has a key.
- if (isNew) {
- if (!event.data.keyModified) {
- this.editForm.everyComponent(component => {
- if (component.key === 'key' && component.parent.component.key === 'tabs') {
- component.setValue(this.updateComponentKey(event.data));
- return false;
- }
- });
- }
-
- if (this.form) {
- let formComponents = this.findNamespaceRoot(parent.formioComponent);
- // excluding component which key uniqueness is to be checked to prevent the comparing of the same keys
- formComponents = formComponents.filter(comp => editFormOptions.editComponent.id !== comp.id);
-
- // Set a unique key for this component.
- BuilderUtils.uniquify(formComponents, event.data);
- }
- }
- }
-
- // Update the component.
- this.updateComponent(event.data.componentJson || event.data, event.changed);
- }
- });
-
- this.attachEditComponentControls(component, parent, isNew, original, ComponentClass);
-
- const dialogClose = () => {
- this.editForm.destroy(true);
- if (this.preview) {
- this.preview.destroy(true);
- this.preview = null;
- }
- if (isNew && !this.saved) {
- this.removeComponent(component, parent, original);
- this.highlightInvalidComponents();
- }
- // Clean up.
- this.removeEventListener(this.dialog, 'close', dialogClose);
- this.dialog = null;
- };
- this.addEventListener(this.dialog, 'close', dialogClose);
-
- // Called when we edit a component.
- this.emit('editComponent', component);
- }
-
- updateComponentKey(data) {
- return _.camelCase(
- data.title ||
- data.label ||
- data.placeholder ||
- data.type
- ).replace(/^[0-9]*/, '');
- }
-
- moveComponent(component) {
- if (this.selectedComponent) {
- const prevSelected = this.selectedComponent;
- prevSelected.element?.classList.remove('builder-component-selected');
- this.removeEventListener(document, 'keydown');
- }
-
- component.element.focus();
- component.element.classList.add('builder-component-selected');
- this.selectedComponent = component;
- this.addEventListener(document, 'keydown', this.moveHandler.bind(this));
- }
-
- moveHandler = (e) => {
- if (e.keyCode === 38 || e.keyCode === 40 || e.keyCode === 13) {
- e.stopPropagation();
- e.preventDefault();
- }
-
- if (e.keyCode === 38) {
- this.updateComponentPlacement(true);
- }
-
- if (e.keyCode === 40) {
- this.updateComponentPlacement(false);
- }
-
- if (e.keyCode === 13) {
- this.stopMoving(this.selectedComponent);
- }
- };
-
- updateComponentPlacement(direction) {
- const component = this.selectedComponent;
- let index, info;
- const step = direction ? -1 : 1;
- if (component) {
- const element = component.element;
- const sibling = direction ? element.previousElementSibling : element.nextElementSibling;
- const source = element.parentNode;
-
- const containerLength = source.formioContainer.length;
-
- if (containerLength && containerLength <= 1) {
- return;
- }
-
- if (source.formioContainer) {
- index = _.findIndex(source.formioContainer, { key: element.formioComponent.component.key });
-
- if (index !== -1) {
- info = source.formioContainer.splice(
- _.findIndex(source.formioContainer, { key: element.formioComponent.component.key }), 1
- );
- info = info[0];
- source.removeChild(element);
- }
- }
-
- const len = source.formioComponent.components.length;
- index = (index === -1) ? 0 : index + step;
-
- if (index === -1) {
- source.formioContainer.push(info);
- source.appendChild(element);
- }
- else if (index === len) {
- const key = source.formioContainer[0].key;
- index = _.findIndex(source.formioComponent.components, { key: key });
- const firstElement = source.formioComponent.components[index].element;
- source.formioContainer.splice(0, 0, info);
- source.insertBefore(element, firstElement);
- }
- else if (index !== -1) {
- source.formioContainer.splice(index, 0, info);
- direction
- ? source.insertBefore(element, sibling)
- : source.insertBefore(element, sibling.nextElementSibling);
- }
- element.focus();
- }
- }
-
- stopMoving(comp) {
- const parent = comp.element.parentNode;
- this.removeEventListener(document, 'keydown');
- parent.formioComponent.rebuild();
- this.selectedComponent = null;
- }
-
- addNewComponent(element) {
- const source = document.querySelector('.formio-builder-form');
- const key = element.getAttribute('data-key');
- const group = element.getAttribute('data-group');
-
- const isNew = true;
- let info;
-
- if (key && group) {
- info = this.getComponentInfo(key, group);
- }
-
- if (isNew && !this.options.noNewEdit && !info.noNewEdit) {
- BuilderUtils.uniquify(this.findNamespaceRoot(source.formioComponent), info);
- this.editComponent(info, source, isNew, null, null);
- }
-
- const firstComponent = source.formioComponent.components[0]?.element;
-
- if (firstComponent) {
- source.formioContainer.splice(0, 0, info);
- }
- else {
- source.formioContainer.push(info);
- }
-
- source.formioComponent.rebuild().then(() => {
- this.isComponentCreated = true;
- });
- }
-
- /**
- * Creates copy of component schema and stores it under sessionStorage.
- * @param {Component} component
- * @return {*}
- */
- copyComponent(component) {
- if (!window.sessionStorage) {
- return console.warn('Session storage is not supported in this browser.');
- }
- this.addClass(this.refs.form, 'builder-paste-mode');
- window.sessionStorage.setItem('formio.clipboard', JSON.stringify(component.schema));
- }
-
- /**
- * Paste copied component after the current component.
- * @param {Component} component
- * @return {*}
- */
- pasteComponent(component) {
- if (!window.sessionStorage) {
- return console.warn('Session storage is not supported in this browser.');
- }
- this.removeClass(this.refs.form, 'builder-paste-mode');
- if (window.sessionStorage) {
- const data = window.sessionStorage.getItem('formio.clipboard');
- if (data) {
- const schema = JSON.parse(data);
- const parent = this.getParentElement(component.element);
- if (parent) {
- BuilderUtils.uniquify(this.findNamespaceRoot(parent.formioComponent), schema);
- let path = '';
- let index = 0;
-
- const isParentSaveChildMethod = this.isParentSaveChildMethod(parent.formioComponent);
-
- if (parent.formioContainer && !isParentSaveChildMethod) {
- index = parent.formioContainer.indexOf(component.component);
- path = this.getComponentsPath(schema, parent.formioComponent.component);
- parent.formioContainer.splice(index + 1, 0, schema);
- }
- else if (isParentSaveChildMethod) {
- parent.formioComponent.saveChildComponent(schema, false);
- }
- parent.formioComponent.rebuild();
-
- this.emitSaveComponentEvent(schema, schema, parent.formioComponent.component, path, (index + 1), true, schema);
- }
- this.emit('change', this.form);
- }
- }
- }
-
- isParentSaveChildMethod(parentComp) {
- return !!(parentComp && parentComp.saveChildComponent);
- }
-
- getParentElement(element) {
- let container = element;
- do {
- container = container.parentNode;
- } while (container && !container.formioComponent);
- return container;
- }
-
- addBuilderComponentInfo(component) {
- if (!component || !component.group || !this.groups[component.group]) {
- return;
- }
-
- component = _.clone(component);
- const groupInfo = this.groups[component.group];
- if (!groupInfo.components.hasOwnProperty(component.key)) {
- groupInfo.components[component.key] = component;
- }
- return component;
- }
-
- init() {
- if (this.webform) {
- this.webform.init();
- }
- return super.init();
- }
-
- clear() {
- if (this.webform.initialized) {
- this.webform.clear();
- }
- }
-
- destroy(deleteFromGlobal) {
- if (this.webform.initialized) {
- this.webform.destroy(deleteFromGlobal);
- }
- super.destroy(deleteFromGlobal);
- }
-
- addBuilderGroup(name, group) {
- if (!this.groups[name]) {
- this.groups[name] = group;
- this.groupOrder.push(name);
- this.triggerRedraw();
- }
- else {
- this.updateBuilderGroup(name, group);
- }
- }
-
- updateBuilderGroup(name, group) {
- if (this.groups[name]) {
- this.groups[name] = group;
- this.triggerRedraw();
- }
- }
-
- generateKey(info) {
- return info.key || _.camelCase(
- info.title ||
- info.label ||
- info.placeholder ||
- info.type
- );
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/WebformBuilder.unit.js b/web-client/core/themes/italia/static/formio/css/src/WebformBuilder.unit.js
deleted file mode 100644
index c4a88578..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/WebformBuilder.unit.js
+++ /dev/null
@@ -1,221 +0,0 @@
-import assert from 'power-assert';
-import NativePromise from 'native-promise-only';
-import Harness from '../test/harness';
-import WebformBuilder from './WebformBuilder';
-import Builders from '../lib/builders';
-import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCase } from '../test/formtest';
-import sameApiKeysLayoutComps from '../test/forms/sameApiKeysLayoutComps';
-import testApiKeysUniquifying from '../test/forms/testApiKeysUniquifying';
-import formWithFormController from '../test/forms/formWithFormController';
-
-describe('WebformBuilder tests', function() {
- this.retries(3);
- before((done) => Harness.builderBefore(done));
- afterEach(() => Harness.getBuilder().setForm({ display: 'form', components: [] }));
- after((done) => Harness.builderAfter(done));
- it('Should create a new form builder class', (done) => {
- const builder = Harness.getBuilder();
- assert(builder instanceof WebformBuilder, 'Builder must be an instance of FormioFormBuilder');
- done();
- });
-
- it('Should execute form controller', (done) => {
- const builder = Harness.getBuilder();
- builder.webform.form = formWithFormController;
-
- setTimeout(() => {
- const textF = builder.webform.getComponent('textField');
- assert.equal(textF.getValue(), 'Hello World');
- assert.equal(textF.disabled, true);
- assert.equal(builder.webform.components[0].disabled, true);
- done();
- }, 500);
- });
-
- it('Should not show unique API error when components with same keys are inside and outside of the Data component', (done) => {
- const builder = Harness.getBuilder();
- builder.webform.setForm(uniqueApiKeys).then(() => {
- builder.highlightInvalidComponents();
- const component = builder.webform.getComponent(['textField']);
- assert.equal(component.errors.length, 0);
- done();
- }).catch(done);
- });
-
- it('Should show unique API error when components inside and outside of the Layout component have same keys', (done) => {
- const builder = Harness.getBuilder();
- builder.webform.setForm(uniqueApiKeysLayout).then(() => {
- builder.highlightInvalidComponents();
- const component = builder.webform.getComponent(['textField']);
- assert.equal(component.errors.length, 1);
- done();
- }).catch(done);
- });
-
- it('Should not overwrite existing resource key in camelCase', (done) => {
- const builder = Harness.getBuilder();
- builder.setForm(resourceKeyCamelCase).then(() => {
- const component = builder.webform.getComponent('CalendarID');
- assert.equal(!!document.querySelector(`[name='data[${component.key}]']`), true);
- done();
- }).catch(done);
- });
-
- it('Should show unique API error when layout components have same keys', (done) => {
- const builder = Harness.getBuilder();
- builder.webform.setForm(sameApiKeysLayoutComps).then(() => {
- builder.highlightInvalidComponents();
- const component = builder.webform.getComponent(['tabs']);
- assert.equal(component.errors.length, 1, 'Should show Unique API Key error');
- done();
- }).catch(done);
- });
-
- it('Should allow add components', function(done) {
- const builder = Harness.getBuilder();
- builder.setForm(columnsForm).then(() => {
- const column1 = builder.webform.element.querySelector('[ref="columns-container"]');
- Harness.buildComponent('textfield', column1);
- setTimeout(() => {
- Harness.saveComponent();
- setTimeout(() => {
- const columns = builder.webform.getComponent('columns');
- assert.equal(columns.columns[0].length, 1);
- done();
- }, 150);
- }, 150);
- }).catch(done);
- });
-
- it('Should show unique API error when components on the same level have same keys', (done) => {
- const builder = Harness.getBuilder();
- builder.webform.setForm(uniqueApiKeysSameLevel).then(() => {
- builder.highlightInvalidComponents();
- const component = builder.webform.getComponent(['textField']);
- assert.equal(component.errors.length, 1);
- done();
- }).catch(done);
- });
-
- it('Should uniquify API keys when add a component to the container which already has the same type component', (done) => {
- const builder = Harness.getBuilder();
- builder.webform.setForm(testApiKeysUniquifying).then(() => {
- const ERROR_MSG = 'Should add a number to the api key of the second component of the same type';
- let containerTestsReady;
- const containerTestsPromise = new NativePromise((resolve) => containerTestsReady = resolve);
-
- const container = builder.webform.element.querySelector(['[ref="container-container"]']);
- Harness.buildComponent('editgrid', container);
-
- setTimeout(() => {
- const newEditGridApiKey = builder.editForm.getComponent('key');
- assert.equal(newEditGridApiKey.dataValue, 'editGrid1', ERROR_MSG);
- Harness.saveComponent();
-
- setTimeout(() => {
- const editGridInsideContainer = container.querySelector('[ref="editGrid-container"]');
- Harness.buildComponent('columns', editGridInsideContainer);
-
- setTimeout(() => {
- const newColumnsApiKey = builder.editForm.getComponent('key');
- assert.equal(newColumnsApiKey.dataValue, 'columns1', ERROR_MSG);
- Harness.saveComponent();
-
- setTimeout(() => {
- const columnInsideEditGridInsideContainer = editGridInsideContainer.querySelector('[ref="columns-container"]');
- Harness.buildComponent('textfield', columnInsideEditGridInsideContainer);
-
- setTimeout(() => {
- const newTextFieldApiKey = builder.editForm.getComponent('key');
- assert.equal(newTextFieldApiKey.dataValue, 'textField1', ERROR_MSG);
- Harness.saveComponent();
- containerTestsReady();
- }, 150);
- }, 150);
- }, 150);
- }, 150);
- }, 150);
-
- containerTestsPromise.then(() => {
- const panel = builder.webform.element.querySelector(['[ref="panel-container"]']);
- Harness.buildComponent('datagrid', panel);
-
- setTimeout(() => {
- const newDataGridApiKey = builder.editForm.getComponent('key');
- assert.equal(newDataGridApiKey.dataValue, 'dataGrid1', ERROR_MSG);
- Harness.saveComponent();
-
- setTimeout(() => {
- const dataGridInsidePanel = panel.querySelector('[ref="dataGrid-container"]');
- Harness.buildComponent('number', dataGridInsidePanel);
-
- setTimeout(() => {
- const newNumberApiKey = builder.editForm.getComponent('key');
- assert.equal(newNumberApiKey.dataValue, 'number1', ERROR_MSG);
- Harness.saveComponent();
-
- setTimeout(() => {
- const columnInsidefieldSetInsideDataGridInsidePanel = dataGridInsidePanel.parentElement.querySelectorAll('[ref="columns-container"]')[1];
- Harness.buildComponent('checkbox', columnInsidefieldSetInsideDataGridInsidePanel);
-
- setTimeout(() => {
- const newTextFieldApiKey = builder.editForm.getComponent('key');
- assert.equal(newTextFieldApiKey.dataValue, 'checkbox1', ERROR_MSG);
- done();
- }, 150);
- }, 150);
- }, 150);
- }, 150);
- }, 150);
- });
- }).catch(done);
- });
-
- it('Should override the way a key for new component is set', (done) => {
- const builder = Harness.getBuilder();
- builder.setForm(columnsForm).then(() => {
- Builders.builders.webform.prototype.updateComponentKey = function() {
- return 'rewrittenNumberKey';
- };
-
- const column = builder.webform.element.querySelector('[ref="columns-container"]');
-
- Harness.buildComponent('number', column);
-
- setTimeout(() => {
- const numberLabel = builder.editForm.getComponent('label');
- numberLabel.setValue('Test Number');
-
- setTimeout(() => {
- const numberKey = builder.editForm.getComponent('key');
- assert.equal(numberKey.dataValue, 'rewrittenNumberKey');
-
- done();
- }, 150);
- }, 150);
- }).catch(done);
- });
-
- it('Should keep min/max date validation settings with moment.js function', (done) => {
- const builder = Harness.getBuilder();
- builder.setForm(columnsForm).then(() => {
- const column1 = builder.webform.element.querySelector('[ref="columns-container"]');
- Harness.buildComponent('day', column1);
-
- setTimeout(() => {
- const maxDateComp = builder.editForm.getComponent('maxDate');
- maxDateComp.setValue('moment().add(10, \'days\')');
-
- setTimeout(() => {
- Harness.saveComponent();
-
- setTimeout(() => {
- const dayComp = builder.webform.getComponent(['day']);
- assert.equal(dayComp.component.maxDate, 'moment().add(10, \'days\')');
- done();
- }, 200);
- }, 200);
- }, 150);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/Wizard.js b/web-client/core/themes/italia/static/formio/css/src/Wizard.js
deleted file mode 100644
index 30b8d86f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Wizard.js
+++ /dev/null
@@ -1,1063 +0,0 @@
-import NativePromise from 'native-promise-only';
-import _ from 'lodash';
-import Webform from './Webform';
-import { GlobalFormio as Formio } from './Formio';
-import {
- fastCloneDeep,
- checkCondition,
- firstNonNil,
- uniqueKey,
- eachComponent
-} from './utils/utils';
-
-export default class Wizard extends Webform {
- /**
- * Constructor for wizard based forms
- * @param element Dom element to place this wizard.
- * @param {Object} options Options object, supported options are:
- * - breadcrumbSettings.clickable: true (default) determines if the breadcrumb bar is clickable or not
- * - buttonSettings.show*(Previous, Next, Cancel): true (default) determines if the button is shown or not
- * - allowPrevious: false (default) determines if the breadcrumb bar is clickable or not for visited tabs
- */
- constructor() {
- let element, options;
- if (arguments[0] instanceof HTMLElement || arguments[1]) {
- element = arguments[0];
- options = arguments[1] || {};
- }
- else {
- options = arguments[0] || {};
- }
-
- options.display = 'wizard';
-
- super(element, options);
- this.pages = [];
- this.prefixComps = [];
- this.suffixComps = [];
- this.components = [];
- this.originalComponents = [];
- this.page = 0;
- this.currentPanel = null;
- this.currentPanels = null;
- this.currentNextPage = 0;
- this._seenPages = [0];
- this.subWizards = [];
- this.allPages = [];
- this.lastPromise = NativePromise.resolve();
- this.enabledIndex = 0;
- this.editMode = false;
- this.originalOptions = _.cloneDeep(this.options);
- }
-
- isLastPage() {
- const next = this.getNextPage();
-
- if (_.isNumber(next)) {
- return next === -1;
- }
-
- return _.isNull(next);
- }
-
- getPages(args = {}) {
- const { all = false } = args;
- const pages = this.hasExtraPages ? this.components : this.pages;
- const filteredPages = pages
- .filter(all ? _.identity : (p, index) => this._seenPages.includes(index));
-
- return filteredPages;
- }
-
- get hasExtraPages() {
- return !_.isEmpty(this.subWizards);
- }
-
- get data() {
- return super.data;
- }
-
- get localData() {
- return this.pages[this.page]?.root?.submission.data || this.submission.data;
- }
-
- checkConditions(data, flags, row) {
- const visible = super.checkConditions(data, flags, row);
- this.establishPages(data);
- return visible;
- }
-
- set data(value) {
- this._data = value;
- _.each(this.getPages({ all: true }), (component) => {
- component.data = this.componentContext(component);
- });
- }
-
- getComponents() {
- return this.submitting
- ? this.getPages({ all: this.isLastPage() })
- : super.getComponents();
- }
-
- resetValue() {
- this.getPages({ all: true }).forEach((page) => page.resetValue());
- this.setPristine(true);
- }
-
- init() {
- // Check for and initlize button settings object
- this.options.buttonSettings = _.defaults(this.options.buttonSettings, {
- showPrevious: true,
- showNext: true,
- showSubmit: true,
- showCancel: !this.options.readOnly
- });
-
- if (!this.isSecondInit) {
- this.isClickableDefined = this.options?.breadcrumbSettings?.hasOwnProperty('clickable');
- this.isSecondInit = true;
- }
-
- this.options.breadcrumbSettings = _.defaults(this.options.breadcrumbSettings, {
- clickable: true
- });
- this.options.allowPrevious = this.options.allowPrevious || false;
-
- this.page = 0;
- const onReady = super.init();
- this.setComponentSchema();
-
- if (this.pages?.[this.page]) {
- this.component = this.pages[this.page].component;
- }
-
- this.on('subWizardsUpdated', (subForm) => {
- const subWizard = this.subWizards.find(subWizard => subForm?.id && subWizard.subForm?.id === subForm?.id);
-
- if (this.subWizards.length && subWizard) {
- subWizard.subForm.setValue(subForm._submission, {}, true);
- this.establishPages();
- this.redraw();
- }
- });
-
- return onReady;
- }
-
- get wizardKey() {
- return `wizard-${this.id}`;
- }
-
- get wizard() {
- return this.form;
- }
-
- set wizard(form) {
- this.setForm(form);
- }
-
- get buttons() {
- const buttons = {};
- [
- { name: 'cancel', method: 'cancel' },
- { name: 'previous', method: 'prevPage' },
- { name: 'next', method: 'nextPage' },
- { name: 'submit', method: 'submit' }
- ].forEach((button) => {
- if (this.hasButton(button.name)) {
- buttons[button.name] = button;
- }
- });
- return buttons;
- }
-
- get buttonOrder() {
- const defaultButtonOrder = [
- 'cancel',
- 'previous',
- 'next',
- 'submit'
- ];
- return this.options.properties?.wizardButtonOrder?.toLowerCase().split(', ') ?? defaultButtonOrder;
- }
-
- get renderContext() {
- return {
- disableWizardSubmit: this.form.disableWizardSubmit,
- wizardKey: this.wizardKey,
- isBreadcrumbClickable: this.isBreadcrumbClickable(),
- isSubForm: !!this.parent && !this.root?.component?.type === 'wizard',
- panels: this.allPages.length ? this.allPages.map(page => page.component) : this.pages.map(page => page.component),
- buttons: this.buttons,
- currentPage: this.page,
- buttonOrder: this.buttonOrder,
- };
- }
-
- prepareNavigationSettings(ctx) {
- const currentPanel = this.currentPanel;
-
- if (currentPanel && currentPanel.buttonSettings) {
- Object.keys(currentPanel.buttonSettings).forEach(() => {
- Object.keys(ctx.buttons).forEach(key => {
- if (typeof currentPanel.buttonSettings[key] !== 'undefined' && !currentPanel.buttonSettings[key] || ctx.isSubForm) {
- ctx.buttons[key] = null;
- }
- });
- });
- }
-
- return this.renderTemplate('wizardNav', ctx);
- }
-
- prepareHeaderSettings(ctx, headerType) {
- if (this.currentPanel && this.currentPanel.breadcrumb === 'none' || ctx.isSubForm) {
- return null;
- }
- return this.renderTemplate(headerType, ctx);
- }
-
- render() {
- const ctx = this.renderContext;
-
- if (this.component.key) {
- ctx.panels.map(panel => {
- if (panel.key === this.component.key) {
- this.currentPanel = panel;
- ctx.wizardPageTooltip = this.getFormattedTooltip(panel.tooltip);
- }
- });
- }
-
- const wizardNav = this.prepareNavigationSettings(ctx);
-
- const wizardHeaderType = `wizardHeader${_.get(this.form, 'settings.wizardHeaderType', '')}`;
- const wizardHeaderLocation = _.get(this.form, 'settings.wizardHeaderLocation', 'left');
- const wizardHeader = this.prepareHeaderSettings(ctx, wizardHeaderType);
-
- return this.renderTemplate('wizard', {
- ...ctx,
- className: super.getClassName(),
- wizardHeader,
- wizardHeaderType,
- wizardHeaderLocation,
- wizardNav,
- components: this.renderComponents([
- ...this.prefixComps,
- ...this.currentPage.components,
- ...this.suffixComps
- ]),
- }, this.builderMode ? 'builder' : 'form');
- }
-
- redrawNavigation() {
- if (this.element) {
- let navElement = this.element.querySelector(`#${this.wizardKey}-nav`);
- if (navElement) {
- this.detachNav();
- navElement.outerHTML = this.renderTemplate('wizardNav', this.renderContext);
- navElement = this.element.querySelector(`#${this.wizardKey}-nav`);
- this.loadRefs(navElement, {
- [`${this.wizardKey}-cancel`]: 'single',
- [`${this.wizardKey}-previous`]: 'single',
- [`${this.wizardKey}-next`]: 'single',
- [`${this.wizardKey}-submit`]: 'single',
- });
- this.attachNav();
- }
- }
- }
-
- redrawHeader() {
- if (this.element) {
- let headerElement = this.element.querySelector(`#${this.wizardKey}-header`);
- if (headerElement) {
- this.detachHeader();
- headerElement.outerHTML = this.renderTemplate(`wizardHeader${_.get(this.form, 'settings.wizardHeaderType', '')}`, this.renderContext);
- headerElement = this.element.querySelector(`#${this.wizardKey}-header`);
- this.loadRefs(headerElement, {
- [`${this.wizardKey}-link`]: 'multiple',
- [`${this.wizardKey}-tooltip`]: 'multiple'
- });
- this.attachHeader();
- }
- }
- }
-
- attach(element) {
- this.element = element;
- this.loadRefs(element, {
- [this.wizardKey]: 'single',
- [`${this.wizardKey}-header`]: 'single',
- [`${this.wizardKey}-cancel`]: 'single',
- [`${this.wizardKey}-previous`]: 'single',
- [`${this.wizardKey}-next`]: 'single',
- [`${this.wizardKey}-submit`]: 'single',
- [`${this.wizardKey}-link`]: 'multiple',
- [`${this.wizardKey}-tooltip`]: 'multiple'
- });
- if ((this.options.readOnly || this.editMode) && !this.enabledIndex) {
- this.enabledIndex = this.pages?.length - 1;
- }
-
- this.hook('attachWebform', element, this);
- const promises = this.attachComponents(this.refs[this.wizardKey], [
- ...this.prefixComps,
- ...this.currentPage.components,
- ...this.suffixComps,
- ]);
- this.attachNav();
- this.attachHeader();
- return promises.then(() => {
- this.emit('render', { component: this.currentPage, page: this.page });
- if (this.component.scrollToTop) {
- this.scrollPageToTop();
- }
- });
- }
-
- scrollPageToTop() {
- const pageTop = this.refs[`${this.wizardKey}-header`] ?? this.refs[this.wizardKey];
-
- if (!pageTop) {
- return;
- }
-
- if ('scrollIntoView' in pageTop) {
- pageTop.scrollIntoView(true);
- }
- else {
- this.scrollIntoView(pageTop);
- }
- }
-
- isBreadcrumbClickable() {
- let currentPage = null;
- this.pages.map(page => {
- if (_.isEqual(this.currentPage.component, page.component)) {
- currentPage = page;
- }
- });
-
- return this.isClickableDefined ? this.options.breadcrumbSettings.clickable : _.get(currentPage, 'component.breadcrumbClickable', true);
- }
-
- isAllowPrevious() {
- let currentPage = null;
- this.pages.map(page => {
- if (_.isEqual(this.currentPage.component, page.component)) {
- currentPage = page;
- }
- });
-
- return _.get(currentPage.component, 'allowPrevious', this.options.allowPrevious);
- }
-
- handleNaviageteOnEnter(event) {
- if (event.keyCode === 13) {
- const clickEvent = new CustomEvent('click');
- const buttonElement = this.refs[`${this.wizardKey}-${this.buttons.next.name}`];
- if (buttonElement) {
- buttonElement.dispatchEvent(clickEvent);
- }
- }
- }
-
- handleSaveOnEnter(event) {
- if (event.keyCode === 13) {
- const clickEvent = new CustomEvent('click');
- const buttonElement = this.refs[`${this.wizardKey}-${this.buttons.submit.name}`];
- if (buttonElement) {
- buttonElement.dispatchEvent(clickEvent);
- }
- }
- }
-
- attachNav() {
- if (this.component.navigateOnEnter) {
- this.addEventListener(document, 'keyup', this.handleNaviageteOnEnter.bind(this));
- }
- if (this.component.saveOnEnter) {
- this.addEventListener(document, 'keyup', this.handleSaveOnEnter.bind(this));
- }
- _.each(this.buttons, (button) => {
- const buttonElement = this.refs[`${this.wizardKey}-${button.name}`];
- this.addEventListener(buttonElement, 'click', (event) => {
- event.preventDefault();
-
- // Disable the button until done.
- buttonElement.setAttribute('disabled', 'disabled');
- this.setLoading(buttonElement, true);
-
- // Call the button method, then re-enable the button.
- this[button.method]().then(() => {
- buttonElement.removeAttribute('disabled');
- this.setLoading(buttonElement, false);
- }).catch(() => {
- buttonElement.removeAttribute('disabled');
- this.setLoading(buttonElement, false);
- });
- });
- });
- }
-
- emitWizardPageSelected(index) {
- this.emit('wizardPageSelected', this.pages[index], index);
- }
-
- attachHeader() {
- const isAllowPrevious = this.isAllowPrevious();
- this.attachTooltips(this.refs[`${this.wizardKey}-tooltip`], this.currentPanel.tooltip);
-
- if (this.isBreadcrumbClickable() || isAllowPrevious) {
- this.refs[`${this.wizardKey}-link`]?.forEach((link, index) => {
- if (!isAllowPrevious || index <= this.enabledIndex) {
- this.addEventListener(link, 'click', (event) => {
- this.emit('wizardNavigationClicked', this.pages[index]);
- event.preventDefault();
- return this.setPage(index).then(() => {
- this.emitWizardPageSelected(index);
- });
- });
- }
- });
- }
- }
-
- detachNav() {
- if (this.component.navigateOnEnter) {
- this.removeEventListener(document, 'keyup', this.handleNaviageteOnEnter.bind(this));
- }
- if (this.component.saveOnEnter) {
- this.removeEventListener(document, 'keyup', this.handleSaveOnEnter.bind(this));
- }
- _.each(this.buttons, (button) => {
- this.removeEventListener(this.refs[`${this.wizardKey}-${button.name}`], 'click');
- });
- }
-
- detachHeader() {
- if (this.refs[`${this.wizardKey}-link`]) {
- this.refs[`${this.wizardKey}-link`].forEach((link) => {
- this.removeEventListener(link, 'click');
- });
- }
- }
-
- transformPages() {
- const allComponents = [];
- const components = this.getSortedComponents(this);
- let defferedComponents = [];
- this.allPages = [];
-
- // Get all components including all nested components and line up in the correct order
- const getAllComponents = (nestedComp, compsArr, pushAllowed = true) => {
- const nestedPages = [];
- const dataArrayComponents = ['datagrid', 'editgrid', 'dynamicWizard'];
- const currentComponents = nestedComp?.subForm ? this.getSortedComponents(nestedComp.subForm) : nestedComp?.components || [];
- const visibleComponents = currentComponents.filter(comp => comp._visible);
- const filteredComponents = visibleComponents.filter(comp => !dataArrayComponents.includes(comp.component.type) && (comp.type !== 'form' || comp.isNestedWizard));
- const additionalComponents = currentComponents.filter(comp => comp.subForm?._form.display !== 'wizard');
- let hasNested = false;
-
- eachComponent(filteredComponents, (comp) => {
- if (comp && comp.component) {
- if (comp.component.type === 'panel' && comp?.parent.wizard && !getAllComponents(comp, compsArr, false)) {
- if (pushAllowed) {
- this.setRootPanelId(comp);
- nestedPages.push(comp);
- }
- hasNested = true;
- }
- if (comp.isNestedWizard && comp.subForm) {
- const hasNestedForm = getAllComponents(comp, nestedPages, pushAllowed);
- if (!hasNested) {
- hasNested = hasNestedForm;
- }
- }
- }
- }, true);
-
- if (nestedComp.component.type === 'panel') {
- if (!hasNested && pushAllowed) {
- this.setRootPanelId(nestedComp);
- compsArr.push(nestedComp);
- }
- if (hasNested && additionalComponents.length) {
- const newComp = _.clone(nestedComp);
- newComp.components = additionalComponents;
- this.setRootPanelId(newComp);
- defferedComponents.push(newComp);
- }
- }
- if (pushAllowed) {
- compsArr.push(...defferedComponents, ...nestedPages);
- defferedComponents = [];
- }
- return hasNested;
- };
-
- components.forEach((component) => {
- if (component.visible) {
- getAllComponents(component, allComponents);
- }
- }, []);
-
- // recalculate pages only for root wizards, including the situation when the wizard is in a wrapper
- if (this.localRoot && this.id === this.localRoot.id) {
- allComponents.forEach((comp, index) => {
- comp.eachComponent((component) => {
- component.page = index;
- });
- });
- }
-
- this.allPages = allComponents;
- }
-
- getSortedComponents({ components, originalComponents }) { // sorts components if they were shuffled after the conditional logic
- const currentComponents = [];
- const currentPages = [];
-
- if (components && components.length) {
- components.map(page => {
- if (page.component.type === 'panel') {
- currentPages[page.component.key || page.component.title] = page;
- }
- });
- }
-
- originalComponents?.forEach((item) => {
- if (!item.key) {
- item.key = item.title;
- }
- if (currentPages[item.key]) {
- currentComponents.push(currentPages[item.key]);
- }
- });
-
- return currentComponents;
- }
-
- findRootPanel(component) {
- return component.parent?.parent ? this.findRootPanel(component.parent) : component;
- }
-
- setRootPanelId(component) {
- if (component.rootPanelId && component.rootPanelId !== component.id) {
- return;
- }
-
- const parent = component.parent?.parent ? this.findRootPanel(component.parent) : component;
- component.rootPanelId = parent.id;
- }
-
- establishPages(data = this.data) {
- this.pages = [];
- this.prefixComps = [];
- this.suffixComps = [];
- const visible = [];
- const currentPages = {};
- const pageOptions = {
- ...(_.clone(this.options)),
- ...(this.parent ? { root: this } : {}),
- };
- if (this.components && this.components.length) {
- this.components.forEach(page => {
- if (page.component.type === 'panel') {
- currentPages[page.component.key || page.component.title] = page;
- }
- });
- }
-
- if (this.originalComponents) {
- this.originalComponents.forEach((item) => {
- if (item.type === 'panel') {
- if (!item.key) {
- item.key = item.title;
- }
- let page = currentPages[item.key];
- const forceShow = this.shouldForceShow(item);
- const forceHide = this.shouldForceHide(item);
-
- let isVisible = !page
- ? checkCondition(item, data, data, this.component, this) && !item.hidden
- : page.visible;
-
- if (forceShow) {
- isVisible = true;
- }
- else if (forceHide) {
- isVisible = false;
- }
-
- if (isVisible) {
- visible.push(item);
- if (page) {
- this.pages.push(page);
- }
- }
-
- if (!page && isVisible) {
- page = this.createComponent(item, pageOptions);
- page.visible = isVisible;
- this.pages.push(page);
- page.eachComponent((component) => {
- component.page = (this.pages.length - 1);
- });
- }
- }
- else if (item.type !== 'button') {
- if (!this.pages.length) {
- this.prefixComps.push(this.createComponent(item, pageOptions));
- }
- else {
- this.suffixComps.push(this.createComponent(item, pageOptions));
- }
- }
- });
- }
-
- if (this.pages.length) {
- this.emit('pagesChanged');
- }
-
- this.transformPages();
- if (this.allPages && this.allPages.length) {
- this.updatePages();
- }
-
- return visible;
- }
-
- updatePages() {
- this.pages = this.allPages;
- }
-
- addComponents() {
- this.establishPages();
- }
-
- setPage(num) {
- if (num === this.page) {
- return NativePromise.resolve();
- }
-
- if (num >= 0 && num < this.pages.length) {
- this.page = num;
-
- this.pageFieldLogic(num);
-
- this.getNextPage();
-
- let parentNum = num;
- if (this.hasExtraPages) {
- const pageFromPages = this.pages[num];
- const pageFromComponents = this.components[num];
- if (!pageFromComponents || pageFromPages?.id !== pageFromComponents.id) {
- parentNum = this.components.findIndex(comp => {
- return comp.id === this.pages?.[parentNum]?.rootPanelId;
- });
- }
- }
- if (!this._seenPages.includes(parentNum)) {
- this._seenPages = this._seenPages.concat(parentNum);
- }
- this.redraw().then(() => {
- this.checkData(this.submission.data);
- });
- return NativePromise.resolve();
- }
- else if (!this.pages.length) {
- this.redraw();
- return NativePromise.resolve();
- }
- return NativePromise.reject('Page not found');
- }
-
- pageFieldLogic(page) {
- if (this.pages?.[page]) {
- // Handle field logic on pages.
- this.component = this.pages[page].component;
- this.originalComponent = fastCloneDeep(this.component);
- this.fieldLogic(this.data);
- // If disabled changed, be sure to distribute the setting.
- this.disabled = this.shouldDisabled;
- }
- }
-
- get currentPage() {
- return (this.pages && (this.pages.length >= this.page)) ? this.pages[this.page] : { components: [] };
- }
-
- getNextPage() {
- if (this.pages?.[this.page]) {
- const data = this.submission.data;
- const form = this.pages[this.page].component;
- // Check conditional nextPage
- if (form) {
- const page = this.pages.length > (this.page + 1) && !this.showAllErrors ? this.page + 1 : -1;
- if (form.nextPage) {
- const next = this.evaluate(form.nextPage, {
- next: page,
- data,
- page,
- form
- }, 'next');
- if (next === null) {
- this.currentNextPage = null;
- return null;
- }
-
- const pageNum = parseInt(next, 10);
- if (!isNaN(parseInt(pageNum, 10)) && isFinite(pageNum)) {
- this.currentNextPage = pageNum;
- return pageNum;
- }
-
- this.currentNextPage = this.getPageIndexByKey(next);
- return this.currentNextPage;
- }
-
- this.currentNextPage = page;
- return page;
- }
-
- this.currentNextPage = null;
- }
-
- return null;
- }
-
- getPreviousPage() {
- return this.page - 1;
- }
-
- beforeSubmit() {
- const pages = this.getPages();
-
- return NativePromise.all(pages.map((page) => {
- page.options.beforeSubmit = true;
- return page.beforeSubmit();
- }));
- }
-
- beforePage(next) {
- return new NativePromise((resolve, reject) => {
- this.hook(next ? 'beforeNext' : 'beforePrev', this.currentPage, this.submission, (err) => {
- if (err) {
- this.showErrors(err, true);
- reject(err);
- }
-
- const form = this.currentPage;
- if (form) {
- form.beforePage(next).then(resolve).catch(reject);
- }
- else {
- resolve();
- }
- });
- });
- }
-
- emitNextPage() {
- this.emit('nextPage', { page: this.page, submission: this.submission });
- }
-
- nextPage() {
- // Read-only forms should not worry about validation before going to next page, nor should they submit.
- if (this.options.readOnly) {
- return this.beforePage(true).then(() => {
- return this.setPage(this.getNextPage()).then(() => {
- this.emitNextPage();
- });
- });
- }
-
- // Validate the form, before go to the next page
- if (this.checkValidity(this.localData, true, this.localData, true)) {
- this.checkData(this.submission.data);
- return this.beforePage(true).then(() => {
- return this.setPage(this.getNextPage()).then(() => {
- if (!(this.options.readOnly || this.editMode) && this.enabledIndex < this.page) {
- this.enabledIndex = this.page;
- this.redraw();
- }
-
- this.emitNextPage();
- });
- });
- }
- else {
- this.currentPage.components.forEach((comp) => comp.setPristine(false));
- this.scrollIntoView(this.element);
- return NativePromise.reject(this.showErrors([], true));
- }
- }
-
- emitPrevPage() {
- this.emit('prevPage', { page: this.page, submission: this.submission });
- }
-
- prevPage() {
- return this.beforePage().then(() => {
- return this.setPage(this.getPreviousPage()).then(() => {
- this.emitPrevPage();
- });
- });
- }
-
- cancel(noconfirm) {
- if (this.options.readOnly) {
- return NativePromise.resolve();
- }
-
- if (super.cancel(noconfirm)) {
- this.setPristine(true);
- return this.setPage(0).then(() => {
- if (this.enabledIndex) {
- this.enabledIndex = 0;
- }
- this.onChange({ resetValue: true });
- this.redraw();
- return this.page;
- });
- }
- return NativePromise.resolve();
- }
-
- getPageIndexByKey(key) {
- let pageIndex = this.page;
- this.pages.forEach((page, index) => {
- if (page.component.key === key) {
- pageIndex = index;
- return false;
- }
- });
- return pageIndex;
- }
-
- get schema() {
- return this.wizard;
- }
-
- setComponentSchema() {
- const pageKeys = {};
- this.originalComponents = [];
- this.component.components.map((item) => {
- if (item.type === 'panel') {
- item.key = uniqueKey(pageKeys, (item.key || 'panel'));
- pageKeys[item.key] = true;
-
- if (this.wizard.full) {
- this.options.show = this.options.show || {};
- this.options.show[item.key] = true;
- }
- else if (this.wizard.hasOwnProperty('full') && !_.isEqual(this.originalOptions.show, this.options.show)) {
- this.options.show = { ...(this.originalOptions.show || {}) };
- }
- }
- this.originalComponents.push(_.clone(item));
- });
-
- if (!Object.keys(pageKeys).length) {
- const newPage = {
- type: 'panel',
- title: 'Page 1',
- label: 'Page 1',
- key: 'page1',
- components: this.component.components
- };
- this.component.components = [newPage];
- this.originalComponents.push(_.clone(newPage));
- }
- }
-
- setForm(form, flags) {
- if (!form) {
- return;
- }
-
- return super.setForm(form, flags);
- }
-
- onSetForm(clonedForm, initialForm) {
- this.component.components = (this._parentPath ? initialForm.components : clonedForm.components) || [];
- this.setComponentSchema();
- }
-
- setEditMode(submission) {
- if (!this.editMode && submission._id && !this.options.readOnly) {
- this.editMode = true;
- this.redraw();
- }
- }
-
- setValue(submission, flags = {}, ignoreEstablishment) {
- const changed = this.getPages({ all: true }).reduce((changed, page) => {
- return this.setNestedValue(page, submission.data, flags, changed) || changed;
- }, false);
-
- this.mergeData(this.data, submission.data);
-
- if (changed) {
- this.pageFieldLogic(this.page);
- }
-
- submission.data = this.data;
- this._submission = submission;
-
- if (!ignoreEstablishment) {
- this.establishPages(submission.data);
- }
-
- this.setEditMode(submission);
-
- return changed;
- }
-
- isClickable(page, index) {
- return this.page !== index && firstNonNil([
- _.get(page, 'breadcrumbClickable'),
- this.options.breadcrumbSettings.clickable
- ]);
- }
-
- hasButton(name, nextPage = this.getNextPage()) {
- // get page options with global options as default values
- const {
- previous = this.options.buttonSettings.showPrevious,
- cancel = this.options.buttonSettings.showCancel,
- submit = this.options.buttonSettings.showSubmit,
- next = this.options.buttonSettings.showNext
- } = _.get(this.currentPage, 'component.buttonSettings', {});
-
- switch (name) {
- case 'previous':
- return previous && (this.getPreviousPage() > -1);
- case 'next':
- return next && (nextPage !== null) && (nextPage !== -1);
- case 'cancel':
- return cancel && !this.options.readOnly;
- case 'submit':
- return submit && !this.options.readOnly && ((nextPage === null) || (this.page === (this.pages.length - 1)));
- default:
- return true;
- }
- }
-
- pageId(page) {
- if (page.key) {
- // Some panels have the same key....
- return `${page.key}-${page.title}`;
- }
- else if (
- page.components &&
- page.components.length > 0
- ) {
- return this.pageId(page.components[0]);
- }
- else {
- return page.title;
- }
- }
-
- onChange(flags, changed, modified, changes) {
- super.onChange(flags, changed, modified, changes);
- if (this.alert && !this.submitted) {
- this.checkValidity(this.localData, false, this.localData, true);
- this.showErrors([], true, true);
- }
-
- // If the pages change, need to redraw the header.
- let currentPanels;
- let panels;
- const currentNextPage = this.currentNextPage;
- if (this.hasExtraPages) {
- currentPanels = this.pages.map(page => page.component.key);
- this.establishPages();
- panels = this.pages.map(page => page.component.key);
- }
- else {
- currentPanels = this.currentPanels || this.pages.map(page => page.component.key);
- panels = this.establishPages().map(panel => panel.key);
- this.currentPanels = panels;
- if (this.currentPanel?.key && this.currentPanels?.length) {
- this.setPage(this.currentPanels.findIndex(panel => panel === this.currentPanel.key));
- }
- }
-
- if (!_.isEqual(panels, currentPanels) || (flags && flags.fromSubmission)) {
- this.redrawHeader();
- }
-
- // If the next page changes, then make sure to redraw navigation.
- if (currentNextPage !== this.getNextPage()) {
- this.redrawNavigation();
- }
- if (this.options.readOnly && (this.prefixComps.length || this.suffixComps.length)) {
- this.redraw();
- }
- }
-
- redraw() {
- if (this.parent?.component?.modalEdit) {
- return this.parent.redraw();
- }
- return super.redraw();
- }
-
- checkValidity(data, dirty, row, currentPageOnly) {
- if (!this.checkCondition(row, data)) {
- this.setCustomValidity('');
- return true;
- }
-
- const components = !currentPageOnly || this.isLastPage()
- ? this.getComponents()
- : this.currentPage.components;
-
- return components.reduce(
- (check, comp) => comp.checkValidity(data, dirty, row) && check,
- true
- );
- }
-
- get errors() {
- if (!this.isLastPage()) {
- return this.currentPage.errors;
- }
-
- return super.errors;
- }
-
- focusOnComponent(key) {
- let pageIndex = 0;
-
- const [page] = this.pages.filter((page, index) => {
- let hasComponent = false;
- page.getComponent(key, (comp) => {
- if (comp.path === key) {
- pageIndex = index;
- hasComponent = true;
- }
- });
- return hasComponent;
- });
-
- if (page && page !== this.currentPage) {
- return this.setPage(pageIndex).then(() => {
- this.checkValidity(this.submission.data, true, this.submission.data);
- this.showErrors();
- super.focusOnComponent(key);
- });
- }
- return super.focusOnComponent(key);
- }
-}
-
-Wizard.setBaseUrl = Formio.setBaseUrl;
-Wizard.setApiUrl = Formio.setApiUrl;
-Wizard.setAppUrl = Formio.setAppUrl;
diff --git a/web-client/core/themes/italia/static/formio/css/src/Wizard.spec.js b/web-client/core/themes/italia/static/formio/css/src/Wizard.spec.js
deleted file mode 100644
index 80a37cc6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Wizard.spec.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import each from 'lodash/each';
-import { expect } from 'chai';
-
-import WizardTests from '../test/wizards';
-import Wizard from './Wizard';
-
-describe('Wizard Component', () => {
- describe('getPreviousPage', () => {
- it('should return previous page number or zero', () => {
- const { getPreviousPage } = Wizard.prototype;
- expect(getPreviousPage.call({ page: 3 })).to.equal(2);
- expect(getPreviousPage.call({ page: 9 })).to.equal(8);
- expect(getPreviousPage.call({ page: 199 })).to.equal(198);
- expect(getPreviousPage.call({ page: 1 })).to.equal(0);
- expect(getPreviousPage.call({ page: 0 })).to.equal(0);
- });
- });
-});
-
-describe('WizardRenderer tests', () => {
- each(WizardTests, (wizardTest) => {
- each(wizardTest.tests, (wizardTestTest, title) => {
- it(title, (done) => {
- const wizardElement = document.createElement('div');
- const wizard = new Wizard(wizardElement);
- wizard.setForm(wizardTest.form).then(() => {
- return wizardTestTest(wizard, done);
- }).catch((error) => {
- done(error);
- });
- });
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/Wizard.unit.js b/web-client/core/themes/italia/static/formio/css/src/Wizard.unit.js
deleted file mode 100644
index fd3d3358..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/Wizard.unit.js
+++ /dev/null
@@ -1,2032 +0,0 @@
-/* eslint-disable no-unused-vars */
-import Harness from '../test/harness';
-import Wizard from './Wizard';
-import Formio from './Formio';
-import assert from 'power-assert';
-import _ from 'lodash';
-import wizardCond from '../test/forms/wizardConditionalPages';
-import wizard from '../test/forms/wizardValidationOnPageChanged';
-import wizard1 from '../test/forms/wizardValidationOnNextBtn';
-import wizard2 from '../test/forms/wizardWithEditGrid';
-import wizard3 from '../test/forms/conditionalWizardPages';
-import wizard4 from '../test/forms/wizardWithSimpleConditionalPage';
-import wizard5 from '../test/forms/wizardWithCustomConditionalPage';
-import wizard6 from '../test/forms/wizardWithFirstConditionalPage';
-import wizardWithHighPages from '../test/forms/wizardWithHighPages';
-import wizardWithHiddenPanel from '../test/forms/wizardWithHiddenPanel';
-import wizardWithAllowPrevious from '../test/forms/wizardWithAllowPrevious';
-import wizardWithNestedWizard from '../test/forms/wizardWithNestedWizard';
-import formWithSignature from '../test/forms/formWithSignature';
-import wizardWithTooltip from '../test/forms/wizardWithTooltip';
-import wizardForHtmlModeTest from '../test/forms/wizardForHtmlRenderModeTest';
-import wizardTestForm from '../test/forms/wizardTestForm';
-import wizardTestFormWithNestedComponents from '../test/forms/wizardTestFormWithNestedComponents';
-import formWithNestedWizard from '../test/forms/formWIthNestedWizard';
-import wizardWithDataGridAndEditGrid from '../test/forms/wizardWithDataGridAndEditGrid';
-import customWizard from '../test/forms/customWizard';
-//import wizardChildForm from '../test/forms/wizardChildForm';
-//import wizardParentForm from '../test/forms/wizardParentForm';
-import wizardWithComponentsWithSameApi from '../test/forms/wizardWithComponentsWithSameApi';
-import wizardWithConditionallyVisiblePage from '../test/forms/conditionallyVisiblePage';
-import wizardWithPanel from '../test/forms/wizardWithPanel';
-import wizardWithWizard from '../test/forms/wizardWithWizard';
-import simpleTwoPagesWizard from '../test/forms/simpleTwoPagesWizard';
-import wizardWithNestedWizardInEditGrid from '../test/forms/wizardWithNestedWizardInEditGrid';
-import wizardNavigateOrSaveOnEnter from '../test/forms/wizardNavigateOrSaveOnEnter';
-import wizardWithFieldsValidationChild from '../test/forms/wizardWithFieldsValidationChild';
-import wizardWithFieldsValidationParent from '../test/forms/wizardWithFieldsValidationParent';
-import nestedConditionalWizard from '../test/forms/nestedConditionalWizard';
-import wizardWithPrefixComps from '../test/forms/wizardWithPrefixComps';
-import wizardPermission from '../test/forms/wizardPermission';
-import formWithFormController from '../test/forms/formWithFormController';
-import { fastCloneDeep } from './utils/utils';
-import formsWithAllowOverride from '../test/forms/formsWithAllowOverrideComps';
-
-global.requestAnimationFrame = (cb) => cb();
-global.cancelAnimationFrame = () => {};
-
-// eslint-disable-next-line max-statements
-describe('Wizard tests', () => {
- it('Should recalculate values for components with "allow override" after wizard is canceled', function(done) {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, formsWithAllowOverride.wizard).then((form) => {
- const calculatedValues = {
- number: 123,
- textField: 'test data',
- textArea: 'test data',
- radio: 'one'
- };
-
- const overridenValues = {
- number: 1233333,
- textField: 'test data3333',
- textArea: 'test data3333',
- radio: 'two'
- };
-
- const number = form.getComponent('number');
- const textArea = form.getComponent('textArea');
- const radio = form.getComponent('radio');
- const textField = form.getComponent('textField');
- const radioTrigger = form.getComponent('radio1');
-
- assert.equal(number.dataValue, number.emptyValue);
- assert.equal(textField.dataValue, textField.emptyValue);
- assert.equal(textArea.dataValue, textArea.emptyValue);
- assert.equal(radio.dataValue, calculatedValues.radio);
-
- radioTrigger.setValue('a');
- setTimeout(() => {
- // check if values are calculated correctly
- assert.equal(number.dataValue, calculatedValues.number);
- assert.equal(textField.dataValue, calculatedValues.textField);
- assert.equal(textArea.dataValue, calculatedValues.textArea);
- assert.equal(radio.dataValue, calculatedValues.radio);
-
- // override calculated values
- const numberInput = number.refs.input[0];
- const textFieldInput = textField.refs.input[0];
- const textAreaInput = textArea.refs.input[0];
- const radioInput =radio.refs.input[1];
-
- numberInput.value = overridenValues.number;
- textFieldInput.value = overridenValues.textField;
- textAreaInput.value = overridenValues.textArea;
- radioInput.checked = true;
- const inputEvent = new Event('input');
- const clickEvent = new Event('click');
-
- numberInput.dispatchEvent(inputEvent);
- textFieldInput.dispatchEvent(inputEvent);
- textAreaInput.dispatchEvent(inputEvent);
- radioInput.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- // check if values are overriden
- assert.equal(number.getValue(), overridenValues.number);
- assert.equal(textField.dataValue, overridenValues.textField);
- assert.equal(textArea.dataValue, overridenValues.textArea);
- assert.equal(radio.dataValue, overridenValues.radio);
- // reset form
- form.cancel(true);
-
- setTimeout(() => {
- // make sure that values are reset
- assert.equal(number.dataValue, number.emptyValue);
- assert.equal(textField.dataValue, textField.emptyValue);
- assert.equal(textArea.dataValue, textArea.emptyValue);
- assert.equal(radio.dataValue, calculatedValues.radio);
-
- radioTrigger.setValue('a');
- setTimeout(() => {
- // check if values are recalculated correctly
- assert.equal(number.dataValue, calculatedValues.number);
- assert.equal(textField.dataValue, calculatedValues.textField);
- assert.equal(textArea.dataValue, calculatedValues.textArea);
- assert.equal(radio.dataValue, calculatedValues.radio);
- document.body.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 400);
- }).catch((err) => done(err));
- });
-
- it('Should execute form controller', function(done) {
- const form = fastCloneDeep(formWithFormController);
- form.display = 'wizard';
- Formio.createForm(form).then((form) => {
- setTimeout(() => {
- const textField = form.getComponent('textField');
-
- assert.equal(textField.getValue(), 'Hello World');
- assert.equal(textField.disabled, true);
- assert.equal(form.components[0].disabled, true);
-
- done();
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should check correctly Permissions and disabled sumbit button', (done) => {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
-
- wizard.setForm(wizardPermission).then(() => {
- wizard.form.disableWizardSubmit = true;
- wizard.redraw();
- const btn = wizard.element.querySelector('.btn-wizard-nav-submit');
- assert.equal(btn.disabled, true);
-
- done();
- }).catch(err => done(err));
- });
-
- it('Should correctly reset values', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
-
- wizard.setForm(wizardWithDataGridAndEditGrid).then(() => {
- const dataGrid = wizard.getComponent('dataGrid');
- const editGrid = wizard.getComponent('editGrid');
-
- const checkComponents = (editGridRowsNumber, dataGridRowsNumber, editGridValue, dataGridValue) => {
- assert.equal(editGrid.editRows.length, editGridRowsNumber, `EditGrit should have ${dataGridRowsNumber} rows`);
- assert.equal(editGrid.components.length, editGridRowsNumber, `EditGrit should have ${dataGridRowsNumber} components`);
- assert.equal(dataGrid.rows.length, dataGridRowsNumber, `DataGrit should have ${dataGridRowsNumber} rows`);
- assert.equal(dataGrid.components.length, dataGridRowsNumber, `DataGrit should have ${dataGridRowsNumber} components`);
-
- if (editGridValue) {
- assert.deepEqual(editGrid.dataValue, editGridValue, 'Should set correct editGrid value');
- }
-
- if (dataGridValue) {
- assert.deepEqual(dataGrid.dataValue, dataGridValue, 'Should set correct dataGrid value');
- }
- };
-
- const event = (name, elem) => {
- const event = new Event(name);
- elem.dispatchEvent(event);
- };
-
- checkComponents(0, 1, [], [{}]);
-
- const submission = {
- data: {
- dataGrid: [{ number: 1111 }, { number: 2222 }],
- editGrid: [{ textField: 'test1' }, { textField: 'test2' }]
- }
- };
-
- wizard.submission = _.cloneDeep(submission);
-
- setTimeout(() => {
- checkComponents(2, 2, submission.data.editGrid,submission.data.dataGrid);
- wizard.cancel(true);
-
- setTimeout(() => {
- checkComponents(0, 1, [], [{}]);
- event('click', editGrid.refs['editgrid-editGrid-addRow'][0]);
-
- setTimeout(() => {
- const editGridFirstRowInput = editGrid.element.querySelector('[name="data[editGrid][0][textField]"]');
- editGridFirstRowInput.value = 'test row 1';
- event('input', editGridFirstRowInput);
- event('click', editGrid.refs['editgrid-editGrid-saveRow'][0]);
-
- const dataGridFirstRowInput = dataGrid.element.querySelector('[name="data[dataGrid][0][number]"]');
- dataGridFirstRowInput.value = 11;
- event('input', dataGridFirstRowInput);
-
- setTimeout(() => {
- checkComponents(1, 1, [{ textField:'test row 1' }], [{ number: 11 }]);
-
- event('click', editGrid.refs['editgrid-editGrid-addRow'][0]);
- event('click', dataGrid.refs['datagrid-dataGrid-addRow'][0]);
-
- setTimeout(() => {
- const editGridFirstRowInput = editGrid.element.querySelector('[name="data[editGrid][1][textField]"]');
- editGridFirstRowInput.value = 'test row 2';
- event('input', editGridFirstRowInput);
- event('click', editGrid.refs['editgrid-editGrid-saveRow'][0]);
-
- const dataGridFirstRowInput = dataGrid.element.querySelector('[name="data[dataGrid][1][number]"]');
- dataGridFirstRowInput.value = 22;
- event('input', dataGridFirstRowInput);
-
- setTimeout(() => {
- const editGridValue = [{ textField:'test row 1' }, { textField:'test row 2' }];
- const dataGridValue = [{ number: 11 }, { number: 22 }];
-
- checkComponents(2, 2, editGridValue, dataGridValue);
-
- assert.deepEqual(wizard.submission.data, {
- dataGrid: dataGridValue,
- editGrid: editGridValue
- }, 'Should contain correct submission data');
-
- done();
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- }).timeout(2500);
-
- it('Should render nested wizard, navigate pages and trigger validation', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const nestedWizard = _.cloneDeep(wizardTestForm.form);
-
- wizard.setForm(formWithNestedWizard).then(() => {
- const nestedFormComp = wizard.getComponent('formNested');
-
- nestedFormComp.loadSubForm = ()=> {
- nestedFormComp.formObj = nestedWizard;
- nestedFormComp.subFormLoading = false;
- return new Promise((resolve) => resolve(nestedWizard));
- };
-
- nestedFormComp.createSubForm();
- setTimeout(() => {
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- checkPage(0);
- assert.equal(wizard.pages.length, 5, 'Should have 5 pages');
- assert.equal(wizard.allPages.length, 5, 'Should have 5 pages');
- assert.equal(wizard.refs[`${wizard.wizardKey}-link`].length, 5, 'Should contain refs to breadcrumbs of parent and nested wizard');
-
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(1);
- assert.equal(wizard.refs[`${wizard.wizardKey}`].querySelectorAll('[ref="component"]').length, 1, 'Should not load nested wizard component of the page of nested form if this page contains other components');
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(2);
- assert.equal(wizard.refs[`${wizard.wizardKey}`].querySelectorAll('[ref="component"]').length, 4, 'Should render nested wizard first page components');
-
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(2);
- assert.equal(wizard.errors.length, 1, 'Should show validation error for required field');
- assert.equal(wizard.refs.errorRef.length, 1, 'Should show alert with error');
- clickWizardBtn('previous');
-
- setTimeout(() => {
- checkPage(1);
- assert.equal(wizard.errors.length, 0, 'Should not have validation errors');
-
- clickWizardBtn('link[4]');
-
- setTimeout(() => {
- checkPage(4);
- assert.equal(!!wizard.refs[`${wizard.wizardKey}-submit`], true, 'Should have submit btn on the last page');
- clickWizardBtn('submit');
-
- setTimeout(() => {
- checkPage(4);
- assert.equal(wizard.errors.length, 3, 'Should trigger validation errors on submit');
- assert.equal(wizard.refs.errorRef.length, 3, 'Should show alert with error on submit');
- wizard.getComponent('select').setValue('value1');
- setTimeout(() => {
- checkPage(4);
- assert.equal(wizard.errors.length, 2, 'Should remove validation error if a component is valid');
- assert.equal(wizard.refs.errorRef.length, 2, 'Should remove error from alert if component is valid');
-
- done();
- }, 500);
- }, 500);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- }).timeout(3000);
-
- it('Should set submission in wizard with nested wizard', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const nestedWizard = _.cloneDeep(wizardTestForm.form);
- const submission = {
- data: {
- selectBoxesParent: {
- a: true,
- b: false,
- c: false
- },
- formNested: {
- data: wizardTestForm.submission.data
- },
- numberParent: 1111
- }
- };
-
- wizard.setForm(formWithNestedWizard).then(() => {
- const nestedFormComp = wizard.getComponent('formNested');
-
- nestedFormComp.loadSubForm = ()=> {
- nestedFormComp.formObj = nestedWizard;
- nestedFormComp.subFormLoading = false;
- return new Promise((resolve) => resolve(nestedWizard));
- };
-
- nestedFormComp.createSubForm();
-
- setTimeout(() => {
- wizard.submission = _.cloneDeep(submission);
-
- setTimeout(() => {
- assert.deepEqual(wizard.data, submission.data, 'Should set wizard submission');
- assert.deepEqual(wizard.submission.data, submission.data, 'Should get wizard submission data');
-
- wizard.everyComponent((comp) => {
- const expectedValue = _.get(submission.data, comp.path, 'no data');
-
- if (expectedValue !== 'no data') {
- assert.deepEqual(comp.getValue(), expectedValue, `Should set value for ${comp.component.type} inside wizard`);
- assert.deepEqual(comp.dataValue, expectedValue, `Should set value for ${comp.component.type} inside wizard`);
- }
- });
-
- done();
- }, 300);
- }, 300);
- })
- .catch((err) => done(err));
- });
-
- it('Should show conditional page inside nested wizard', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const nestedWizard = _.cloneDeep(wizardTestForm.form);
- nestedWizard.components[2].conditional = { show: true, when: 'checkbox', eq: 'true' };
-
- wizard.setForm(formWithNestedWizard).then(() => {
- const nestedFormComp = wizard.getComponent('formNested');
-
- nestedFormComp.loadSubForm = ()=> {
- nestedFormComp.formObj = nestedWizard;
- nestedFormComp.subFormLoading = false;
- return new Promise((resolve) => resolve(nestedWizard));
- };
-
- nestedFormComp.createSubForm();
-
- setTimeout(() => {
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- checkPage(0);
- assert.equal(wizard.pages.length, 4, 'Should have 4 pages');
- assert.equal(wizard.allPages.length, 4, 'Should have 4 pages');
- assert.equal(wizard.refs[`${wizard.wizardKey}-link`].length, 4, 'Should contain refs to breadcrumbs of parent and nested wizard');
-
- clickWizardBtn('link[3]');
-
- setTimeout(() => {
- checkPage(3);
-
- assert.deepEqual(!!wizard.refs[`${wizard.wizardKey}-submit`], true, 'Should hav submit btn on the last page');
- wizard.getComponent('checkbox').setValue(true);
-
- setTimeout(() => {
- checkPage(3);
-
- assert.deepEqual(!!wizard.refs[`${wizard.wizardKey}-submit`], true, 'Should have submit btn on the last page');
- wizard.getComponent('checkbox').setValue(true);
-
- setTimeout(() => {
- checkPage(3);
- assert.deepEqual(!!wizard.refs[`${wizard.wizardKey}-submit`], false, 'Should not have submit btn ');
- assert.equal(wizard.pages.length, 5, 'Should show conditional page');
- assert.equal(wizard.allPages.length, 5, 'Should show conditional page');
- assert.equal(wizard.refs[`${wizard.wizardKey}-link`].length, 5, 'Should contain refs to breadcrumbs of visible conditional page');
-
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(4);
- clickWizardBtn('previous');
-
- setTimeout(() => {
- checkPage(3);
- wizard.getComponent('checkbox').setValue(false);
-
- setTimeout(() => {
- assert.equal(wizard.pages.length, 4, 'Should hide conditional page');
- assert.equal(wizard.allPages.length, 4, 'Should hide conditional page');
- assert.equal(wizard.refs[`${wizard.wizardKey}-link`].length, 4, 'Should contain refs to breadcrumbs of visible pages');
- assert.deepEqual(!!wizard.refs[`${wizard.wizardKey}-submit`], true, 'Should have submit btn on the last page');
-
- done();
- }, 500);
- }, 300);
- }, 300);
- }, 500);
- }, 300);
- }, 300);
- }, 300);
- })
- .catch((err) => done(err));
- }).timeout(3000);
-
- it('Should render values in HTML render mode', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement, {
- readOnly: true,
- renderMode: 'html'
- });
- const form = _.cloneDeep(wizardTestForm.form);
-
- wizard.setForm(form, ).then(() => {
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- const checkValues = () => {
- wizard.allPages[wizard.page].everyComponent((comp) => {
- const isParent = !!(comp.component.components || comp.component.rows || comp.component.columns);
-
- if (!isParent) {
- const isInEditGrid = comp.parent.component.type === 'editgrid';
- const value = isInEditGrid ? comp.parent.refs['editgrid-editGrid-row'][comp.rowIndex].textContent.trim() : comp.element.querySelector("[ref='value']").textContent;
- const expectedValue = _.get(wizardTestForm.htmlModeValues, comp.path, 'no data');
-
- assert.equal(value, expectedValue === 'true' ? 'True' : expectedValue, `${comp.component.key}: should render value in html render mode`);
- }
- });
- };
-
- wizard.submission = _.cloneDeep(wizardTestForm.submission);
-
- setTimeout(() => {
- checkPage(0);
- checkValues();
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(1);
- checkValues();
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(2);
- checkValues();
- done();
- }, 200);
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should render values for prefix Components', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement, {
- readOnly: true,
- });
- const form = _.cloneDeep(wizardWithPrefixComps.form);
-
- wizard.setForm(form).then(() => {
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- const checkValues = () => {
- wizard.refs[`wizard-${wizard.id}`].querySelectorAll('input').forEach((element, i)=> {
- switch (i) {
- case 0:
- assert.equal(element.value, 'prefix', 'Should render value');
- break;
- case 1:
- assert.equal(element.value, `page${wizard.page+1}`, 'Should render value');
- break;
- case 2:
- assert.equal(element.value, 'suffix', 'Should render value');
- break;
- }
- });
- };
- wizard.submission = _.cloneDeep(wizardWithPrefixComps.submission);
-
- setTimeout(() => {
- checkPage(0);
- checkValues();
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(1);
- checkValues();
- done();
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should redirect to the correct page from the Error list', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement, {
- renderMode: 'html'
- });
-
- wizard.setForm(wizardWithComponentsWithSameApi, ).then(() => {
- const clickWizardBtn = (pathPart) => {
- const [btnKey] = Object.keys(wizard.refs).filter((key) => key.indexOf(pathPart) !== -1);
- const btn = _.get(wizard.refs, btnKey);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- setTimeout(() => {
- checkPage(0);
- wizard.setPage(1);
-
- setTimeout(() => {
- checkPage(1);
- clickWizardBtn('submit');
-
- setTimeout(() => {
- assert.equal(wizard.refs.errorRef.length, 1, 'Should have an error');
- const clickEvent = new Event('click');
- wizard.refs.errorRef[0].dispatchEvent(clickEvent);
-
- setTimeout(() => {
- checkPage(0);
- done();
- }, 200);
- }, 200);
- }, 300);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should execute advanced logic for wizard pages', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const form = _.cloneDeep(wizardTestForm.form);
- _.each(form.components, (comp, index) => {
- if (index === 1) {
- comp.logic = [
- {
- name: 'simple logic',
- trigger: { type: 'simple', simple: { show: true, when: 'textField', eq: 'tooltip' } },
- actions: [
- {
- name: 'merge schema action',
- type: 'mergeComponentSchema',
- schemaDefinition: "schema = { tooltip: 'some tooltip'}"
- }
- ]
- }
- ];
- }
- if (index === 2) {
- comp.logic = [
- {
- name: 'logic test',
- trigger: { type: 'simple', simple: { show: true, when: 'checkbox', eq: 'true' } },
- actions: [
- {
- name: 'disabled',
- type: 'property',
- property: { label: 'Disabled', value: 'disabled', type: 'boolean' },
- state: true
- }
- ]
- }
- ];
- }
- });
-
- wizard.setForm(form).then(() => {
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- checkPage(0);
- wizard.getComponent('textField').setValue('tooltip');
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(1);
- assert.equal(wizard.tooltips.length, 1, 'Should have tooltip after advanced logic execution');
- assert.equal(!!wizard.refs[`${wizard.wizardKey}-tooltip`][0], true, 'Should render tooltip icon');
-
- wizard.getComponent('checkbox').setValue(true);
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(2);
- assert.equal(wizard.allPages[wizard.page].disabled, true, 'Should disable page components after advanced logic execution');
- done();
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should navigate next page according to advanced next page logic', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const form = _.cloneDeep(wizardTestForm.form);
- _.each(form.components, (comp, index) => {
- if (index === 0) {
- comp.nextPage = "next = data.textField === 'page3' ? 'page3' : 'page2'";
- }
- if (index === 1) {
- comp.nextPage = "next = data.container && data.container.select === 'value1' ? 'page1' : 'page3'";
- }
- });
-
- wizard.setForm(form).then(() => {
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
- checkPage(0);
- wizard.getComponent('textField').setValue('page3');
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(2);
- wizard.getComponent('select').setValue('value1');
- clickWizardBtn('previous');
-
- setTimeout(() => {
- checkPage(1);
- wizard.getComponent('checkbox').setValue(true);
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(0);
- done();
- }, 200);
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should NOT navigate to next page if it contains invalid nested component', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const form = _.cloneDeep(wizardTestFormWithNestedComponents.form);
-
- wizard.setForm(form).then(() => {
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
- checkPage(0);
- wizard.submission = {
- data: {
- outerContainer: {
- firstComponent: 'c',
- secondComponent: 'q',
- }
- }
- };
- wizard.nextPage();
- setTimeout(() => {
- const errors = wizard.errors;
- checkPage(0);
- assert(errors.length > 0, 'Must err before next page');
- assert.equal(errors[0].message, 'Required Component is required');
- done();
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should not render breadcrumb if it has hidden type', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const form = _.cloneDeep(wizardTestForm.form);
- _.each(form.components, (comp) => {
- comp.breadcrumb = 'none';
- });
-
- wizard.setForm(form).then(() => {
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- const checkBreadcrumb = () => {
- assert.equal(_.get(wizard.refs, `${wizard.wizardKey}-link`).length, 0, 'Should not render wizard breadcrumb');
- };
-
- checkBreadcrumb();
- wizard.setSubmission(_.cloneDeep(wizardTestForm.submission));
-
- setTimeout(() => {
- checkPage(0);
- checkBreadcrumb();
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(1);
- checkBreadcrumb();
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(2);
- checkBreadcrumb();
- done();
- }, 100);
- }, 100);
- }, 100);
- })
- .catch((err) => done(err));
- });
-
- it('Should not navigate between wizard pages on breadcrumb click if breadcrumbClickable is false', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const form = _.cloneDeep(wizardTestForm.form);
- _.each(form.components, (comp) => {
- comp.breadcrumbClickable = false;
- });
-
- wizard.setForm(form).then(() => {
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- checkPage(0);
- clickWizardBtn('link[1]');
-
- setTimeout(() => {
- checkPage(0);
- clickWizardBtn('link[2]');
-
- setTimeout(() => {
- checkPage(0);
- wizard.setSubmission(_.cloneDeep(wizardTestForm.submission));
-
- setTimeout(() => {
- checkPage(0);
- clickWizardBtn('next');
-
- setTimeout(() => {
- checkPage(1);
- clickWizardBtn('link[0]');
-
- setTimeout(() => {
- checkPage(1);
- done();
- }, 100);
- }, 100);
- }, 100);
- }, 100);
- }, 100);
- })
- .catch((err) => done(err));
- });
-
- it('Should set/get wizard submission', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
-
- wizard.setForm(wizardTestForm.form).then(() => {
- wizard.submission = _.cloneDeep(wizardTestForm.submission);
-
- setTimeout(() => {
- assert.deepEqual(wizard.data, wizardTestForm.submission.data, 'Should set wizard submission');
- assert.deepEqual(wizard.submission.data, wizardTestForm.submission.data, 'Should get wizard submission data');
-
- wizard.everyComponent((comp) => {
- const expectedValue = _.get(wizardTestForm.submission.data, comp.path, 'no data');
- if (expectedValue !== 'no data') {
- assert.deepEqual(comp.getValue(), expectedValue, `Should set value for ${comp.component.type} inside wizard`);
- assert.deepEqual(comp.dataValue, expectedValue, `Should set value for ${comp.component.type} inside wizard`);
- }
- });
- done();
- }, 300);
- })
- .catch((err) => done(err));
- });
-
- it('Should correctly render customized wizard and navigate using custom btns', function(done) {
- const formElement = document.createElement('div');
- const customizedWizard = new Wizard(formElement);
-
- customizedWizard.setForm(customWizard).then(() => {
- customizedWizard.on('goToNextPage', function() {
- customizedWizard.nextPage();
- });
- customizedWizard.on('goToPrevPage', function() {
- customizedWizard.prevPage();
- });
-
- const checkBtns = (page) => {
- assert.equal(customizedWizard.page, page, `Should set page ${page + 1}`);
- assert.equal(!!customizedWizard.refs[`${customizedWizard.wizardKey}-next`], false, 'Should not render wizard next btn');
- assert.equal(!!customizedWizard.refs[`${customizedWizard.wizardKey}-cancel`], false, 'Should not render wizard cancel btn');
- assert.equal(!!customizedWizard.refs[`${customizedWizard.wizardKey}-previous`], false, 'Should not render wizard previous btn');
- };
-
- const navigatePage = (btnKey) => {
- const customBtn = customizedWizard.components[customizedWizard.page].getComponent(btnKey).refs.button;
- const clickEvent = new Event('click');
- customBtn.dispatchEvent(clickEvent);
- };
- checkBtns(0);
- navigatePage('nextPage');
- setTimeout(() => {
- checkBtns(1);
- navigatePage('nextPage1');
- setTimeout(() => {
- checkBtns(2);
- navigatePage('prevPage1');
-
- setTimeout(() => {
- checkBtns(1);
- navigatePage('prevPage');
-
- setTimeout(() => {
- checkBtns(0);
- customizedWizard.destroy();
-
- done();
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should not create a new submission on submission of edited draft submission', function(done) {
- const formElement = document.createElement('div');
- const customizedWizard = new Wizard(formElement);
- const expectedValues = {
- '1': {
- method: 'post',
- urlEnd: 'submission',
- state: 'draft',
- data: {
- textArea1: '',
- textField: 'test'
- },
- id: undefined
- },
- '2': {
- method: 'put',
- urlEnd: 'someId',
- state: 'draft',
- data: {
- number: 111111,
- textArea1: 'test1',
- textField: 'test1'
- },
- id: 'someId'
- },
- '3': {
- method: 'put',
- urlEnd: 'someId',
- state: 'draft',
- data: {
- number: 22222,
- textArea1: 'test',
- textField: 'test1'
- },
- id: 'someId'
- },
- '4': {
- method: 'put',
- urlEnd: 'someId',
- state: 'draft',
- data: {
- number: 22222,
- textArea1: 'test1',
- textField: 'test1'
- },
- id: 'someId'
- },
- '5': {
- method: 'put',
- urlEnd: 'someId',
- state: 'submitted',
- data: {
- number: 22222,
- textArea1: 'test1',
- textField: 'test1'
- },
- id: 'someId'
- }
- };
-
- customizedWizard.setForm(customWizard).then(() => {
- const formio = new Formio('http://test.localhost/draftwizardpages', {});
- let number = 1;
-
- formio.makeRequest = (type, url, method, data) => {
- assert.equal(method, expectedValues[number].method, `Should send ${expectedValues[number].method} request`);
- assert.equal(data._id, expectedValues[number].id, `Submission data should ${expectedValues[number].id ? '' : 'not'} contain id of editted submission`);
- assert.equal(url.endsWith(expectedValues[number].urlEnd), true, `Request url should end with ${expectedValues[number].urlEnd}`);
- assert.equal(data.state, expectedValues[number].state, `Should set ${expectedValues[number].state} state for submission`);
- _.each(expectedValues[number].data, function(value, key) {
- assert.equal(data.data[key], value, `${key} field should contain "${value}" value in submission object`);
- });
-
- number = number + 1;
-
- return new Promise(resolve => resolve({
- _id: 'someId',
- data: {
- number: 22222,
- textArea1: 'test1',
- textField: 'test1'
- },
- metadata:{},
- state: data.state
- })
- );
- };
-
- customizedWizard.formio = formio;
-
- customizedWizard.on('goToNextPage', function() {
- customizedWizard.executeSubmit({ state: 'draft' }).then(() => customizedWizard.nextPage());
- });
- customizedWizard.on('goToPrevPage', function() {
- customizedWizard.executeSubmit({ state: 'draft' }).then(() => customizedWizard.prevPage());
- });
- customizedWizard.on('saveSubmission', function() {
- customizedWizard.executeSubmit();
- });
-
- const checkPage = (page) => {
- assert.equal(customizedWizard.page, page, `Should set page ${page + 1}`);
- };
-
- const navigatePage = (btnKey) => {
- const customBtn = customizedWizard.components[customizedWizard.page].getComponent(btnKey).refs.button;
- const clickEvent = new Event('click');
- customBtn.dispatchEvent(clickEvent);
- };
-
- const setPageCompValue = (compKey, value) => {
- customizedWizard.components[customizedWizard.page].getComponent(compKey).setValue(value);
- };
-
- checkPage(0);
- setPageCompValue('textField', 'test');
- navigatePage('nextPage');
-
- setTimeout(() => {
- checkPage(1);
- setPageCompValue('number', 111111);
- navigatePage('nextPage1');
-
- setTimeout(() => {
- checkPage(2);
- setPageCompValue('textArea1', 'test');
- navigatePage('prevPage1');
-
- setTimeout(() => {
- checkPage(1);
- navigatePage('nextPage1');
-
- setTimeout(() => {
- checkPage(2);
- navigatePage('save');
- setTimeout(() => {
- customizedWizard.destroy();
- done();
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should show validation alert and components` errors and navigate pages after clicking alert error', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
-
- wizard.setForm(wizardTestForm.form).then(() => {
- const clickWizardBtn = (pathPart, clickError) => {
- const btn = _.get(wizard.refs, clickError ? pathPart : `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
-
- const checkInvalidComp = (compKey, highLight) => {
- const comp = wizard.getComponent(compKey);
-
- assert.deepEqual(!!comp.error, true, `${compKey}: should have error`);
- assert.deepEqual(comp.error.message, `${comp.component.label} is required`, `${compKey}: should have correct required validation message`);
- assert.deepEqual(comp.pristine, false, `${compKey}: should set pristine to false`);
- assert.deepEqual(comp.element.classList.contains(`${highLight ? 'formio-error-wrapper' : 'has-error'}`), true, `${compKey}: should set error class`);
- assert.deepEqual(comp.refs.messageContainer.querySelector('.error').textContent.trim(), `${comp.component.label} is required`, `${compKey}: should display error message`);
- };
-
- checkPage(0);
- clickWizardBtn('link[2]');
-
- setTimeout(() => {
- checkPage(2);
- assert.equal(wizard.errors.length, 0, 'Should not have validation errors');
-
- clickWizardBtn('submit');
-
- setTimeout(() => {
- assert.equal(wizard.errors.length, 3, 'Should have validation errors');
- assert.equal(wizard.refs.errorRef.length, wizard.errors.length, 'Should show alert with validation errors');
- assert.equal(!!wizard.element.querySelector('.alert-danger'), true, 'Should have alert with validation errors');
- checkInvalidComp('select', true);
- clickWizardBtn('errorRef[0]', true);
-
- setTimeout(() => {
- checkPage(0);
-
- assert.equal(wizard.errors.length, 1, 'Should have page validation error');
- assert.equal(wizard.refs.errorRef.length, 3, 'Should keep alert with validation errors');
- checkInvalidComp('textField');
- clickWizardBtn('errorRef[1]', true);
-
- setTimeout(() => {
- checkPage(1);
-
- assert.equal(wizard.errors.length, 1, 'Should have page validation error');
- assert.equal(wizard.refs.errorRef.length, 3, 'Should keep alert with validation errors');
- checkInvalidComp('checkbox');
- wizard.getComponent('checkbox').setValue(true);
-
- setTimeout(() => {
- checkPage(1);
- assert.equal(wizard.errors.length, 0, 'Should not have page validation error');
- assert.equal(wizard.refs.errorRef.length, 2, 'Should keep alert with validation errors');
- clickWizardBtn('errorRef[1]', true);
-
- setTimeout(() => {
- checkPage(2);
-
- assert.equal(wizard.errors.length, 2, 'Should have wizard validation errors');
- assert.equal(wizard.refs.errorRef.length, 2, 'Should keep alert with validation errors');
- wizard.getComponent('select').setValue('value1');
-
- setTimeout(() => {
- assert.equal(wizard.errors.length, 1, 'Should have wizard validation error');
- assert.equal(wizard.refs.errorRef.length, 1, 'Should keep alert with validation errors');
- clickWizardBtn('errorRef[0]', true);
-
- setTimeout(() => {
- checkPage(0);
-
- assert.equal(wizard.errors.length, 1, 'Should have page validation error');
- assert.equal(wizard.refs.errorRef.length, 1, 'Should keep alert with validation errors');
- wizard.getComponent('textField').setValue('valid');
-
- setTimeout(() => {
- assert.equal(wizard.errors.length, 0, 'Should not have page validation error');
- assert.equal(!!wizard.element.querySelector('.alert-danger'), false, 'Should not have alert with validation errors');
- clickWizardBtn('link[2]');
-
- setTimeout(() => {
- clickWizardBtn('submit');
- setTimeout(() => {
- assert.equal(wizard.submission.state, 'submitted', 'Should submit the form');
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }, 100);
- }, 100);
- }, 100);
- }, 100);
- })
- .catch((err) => done(err));
- }).timeout(3500);
-
- it('Should navigate wizard pages using navigation buttons and breadcrumbs', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
-
- wizard.setForm(wizardTestForm.form).then(() => {
- const clickNavigationBtn = (pathPart) => {
- const btn = _.get(wizard.refs, `${wizard.wizardKey}-${pathPart}`);
- const clickEvent = new Event('click');
- btn.dispatchEvent(clickEvent);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
- checkPage(0);
- clickNavigationBtn('next');
-
- setTimeout(() => {
- checkPage(0);
-
- assert.equal(wizard.errors.length, 1, 'Should have validation error');
- assert.equal(wizard.refs.errorRef.length, wizard.errors.length, 'Should show alert with validation error');
-
- wizard.getComponent('textField').setValue('valid');
-
- clickNavigationBtn('next');
-
- setTimeout(() => {
- checkPage(1);
- clickNavigationBtn('next');
-
- setTimeout(() => {
- checkPage(1);
-
- assert.equal(wizard.errors.length, 1, 'Should have validation error');
- assert.equal(wizard.refs.errorRef.length, wizard.errors.length, 'Should show alert with validation error');
-
- clickNavigationBtn('previous');
-
- setTimeout(() => {
- checkPage(0);
-
- assert.equal(wizard.errors.length, 0, 'Should not have validation error');
- assert.equal(!!wizard.refs.errorRef, false, 'Should not have alert with validation error');
-
- clickNavigationBtn('next');
-
- setTimeout(() => {
- checkPage(1);
- assert.equal(wizard.errors.length, 1, 'Should have validation error');
- wizard.getComponent('checkbox').setValue(true);
-
- clickNavigationBtn('next');
-
- setTimeout(() => {
- checkPage(2);
- assert.equal(wizard.errors.length, 0, 'Should not have validation error');
- clickNavigationBtn('link[0]');
-
- setTimeout(() => {
- checkPage(0);
- assert.equal(wizard.errors.length, 0, 'Should not have validation error');
- clickNavigationBtn('link[2]');
-
- setTimeout(() => {
- checkPage(2);
- done();
- }, 50);
- }, 50);
- }, 50);
- }, 50);
- }, 50);
- }, 50);
- }, 50);
- }, 50);
- })
- .catch((err) => done(err));
- });
-
- it('Should correctly set values in HTML render mode', function(done) {
- const formElement = document.createElement('div');
- const formHTMLMode = new Wizard(formElement, {
- readOnly: true,
- renderMode: 'html'
- });
-
- formHTMLMode.setForm(wizardForHtmlModeTest.form).then(() => {
- formHTMLMode.setSubmission(wizardForHtmlModeTest.submission);
-
- setTimeout(() => {
- const numberValue = formHTMLMode.element.querySelector('[ref="value"]').textContent;
- assert.equal(+numberValue, wizardForHtmlModeTest.submission.data.number);
-
- const nextPageBtn = formHTMLMode.refs[`${formHTMLMode.wizardKey}-next`];
- const clickEvent = new Event('click');
- nextPageBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const textValue = formHTMLMode.element.querySelector('[ref="value"]').textContent;
- assert.equal(textValue, wizardForHtmlModeTest.submission.data.textField);
-
- done();
- }, 250);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
-it('Should show tooltip for wizard pages', function(done) {
- const formElement = document.createElement('div');
- const wizardWithPageTooltip = new Wizard(formElement);
-
- wizardWithPageTooltip.setForm(wizardWithTooltip).then(() => {
- const clickEvent = new Event('click');
-
- assert.equal(wizardWithPageTooltip.tooltips.length, 1);
-
- const pageTooltipIcon = wizardWithPageTooltip.refs[`${wizardWithPageTooltip.wizardKey}-tooltip`][0];
-
- assert.equal(!!pageTooltipIcon, true);
-
- pageTooltipIcon.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const tooltipText = wizardWithPageTooltip.element.querySelector('.tippy-content').textContent;
- assert.equal(tooltipText, wizardWithPageTooltip.currentPanel.tooltip);
-
- done();
- }, 300);
- })
- .catch((err) => done(err));
- });
-
- it('Should not clear wizard data when navigating between wizard pages with hidden panel', function(done) {
- const formElement = document.createElement('div');
- const formWithHiddenPage = new Wizard(formElement);
-
- formWithHiddenPage.setForm(wizardWithHiddenPanel).then(() => {
- const clickEvent = new Event('click');
- const inputEvent = new Event('input');
-
- assert.equal(formWithHiddenPage.pages.length, 2);
-
- const page1Field = formWithHiddenPage.element.querySelector('[name="data[number]"]');
-
- page1Field.value = '555';
- page1Field.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(formWithHiddenPage.element.querySelector('[name="data[number]"]').value, 555);
-
- const nextPageBtn = formWithHiddenPage.refs[`${formWithHiddenPage.wizardKey}-next`];
- nextPageBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(formWithHiddenPage.page, 1);
-
- const prevPageBtn = formWithHiddenPage.refs[`${formWithHiddenPage.wizardKey}-previous`];
- prevPageBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(formWithHiddenPage.page, 0);
- assert.equal(formWithHiddenPage.element.querySelector('[name="data[number]"]').value, 555);
-
- done();
- }, 250);
- }, 200);
- }, 100);
- })
- .catch((err) => done(err));
- });
-
- it('Should show signature submission in HTML render mode', function(done) {
- const formElement = document.createElement('div');
- const formWithSignatureHTMLMode = new Wizard(formElement, {
- readOnly: true,
- renderMode: 'html'
- });
-
- formWithSignatureHTMLMode.setForm(formWithSignature.form).then(() => {
- formWithSignatureHTMLMode.setSubmission(formWithSignature.submission);
-
- setTimeout(() => {
- const signatureImage = formWithSignatureHTMLMode.element.querySelector('[ref="signatureImage"]');
- assert.equal(signatureImage.src === formWithSignature.submission.data.signature, true);
-
- done();
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should display conditional page after setting submission', function(done) {
- const formElement = document.createElement('div');
- const wizardWithSimpleConditionalPage = new Wizard(formElement);
-
- wizardWithSimpleConditionalPage.setForm(wizard4).then(() => {
- setTimeout(() => {
- assert.equal(wizardWithSimpleConditionalPage.pages.length, 1);
- assert.equal(wizardWithSimpleConditionalPage.components.length, 1);
- const submissionData = { checkbox: true, number: 555 };
- wizardWithSimpleConditionalPage.setSubmission({ data:submissionData });
-
- setTimeout(() => {
- assert.equal(wizardWithSimpleConditionalPage.pages.length, 2);
- assert.equal(wizardWithSimpleConditionalPage.components.length, 2);
- assert.deepEqual(wizardWithSimpleConditionalPage.data, submissionData);
- done();
- }, 500);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should display submission data on page with custom conditional logic in readOnly', function(done) {
- const formElement = document.createElement('div');
- const wizardWithCustomConditionalPage = new Wizard(formElement);
-
- wizardWithCustomConditionalPage.setForm(wizard5).then(() => {
- setTimeout(() => {
- wizardWithCustomConditionalPage.disabled = true;
-
- if (wizardWithCustomConditionalPage.options) {
- wizardWithCustomConditionalPage.options.readOnly = true;
- }
- else {
- wizardWithCustomConditionalPage.options = { readOnly: true };
- }
-
- setTimeout(() => {
- assert.equal(wizardWithCustomConditionalPage.pages.length, 1);
- assert.equal(wizardWithCustomConditionalPage.components.length, 1);
-
- const submissionData = { checkbox: true, number: 555 };
-
- wizardWithCustomConditionalPage.setSubmission({ data:submissionData });
-
- setTimeout(() => {
- assert.equal(wizardWithCustomConditionalPage.pages.length, 2);
- assert.equal(wizardWithCustomConditionalPage.components.length, 2);
- assert.deepEqual(wizardWithCustomConditionalPage.data, submissionData);
-
- const clickEvent = new Event('click');
- const secondPageBtn = wizardWithCustomConditionalPage.refs[`${wizardWithCustomConditionalPage.wizardKey}-link`][1];
-
- secondPageBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(wizardWithCustomConditionalPage.page, 1);
-
- const numberComponent = wizardWithCustomConditionalPage.element.querySelector('[name="data[number]"]');
-
- assert.equal(numberComponent.value, 555);
-
- done();
- }, 400);
- }, 300);
- }, 200);
- }, 100);
- })
- .catch((err) => done(err));
- });
-
- it('Should show conditional wizard page', function(done) {
- const formElement = document.createElement('div');
- const wizardWithConditionalPage = new Wizard(formElement);
-
- wizardWithConditionalPage.setForm(wizard3).then(() => {
- setTimeout(() => {
- assert.equal(wizardWithConditionalPage.pages.length, 1);
- assert.equal(wizardWithConditionalPage.components.length, 1);
-
- const inputEvent = new Event('input');
- const numberComponent = wizardWithConditionalPage.element.querySelector('[name="data[number]"]');
-
- numberComponent.value = 5;
- numberComponent.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(wizardWithConditionalPage.pages.length, 2);
- assert.equal(wizardWithConditionalPage.components.length, 2);
-
- done();
- }, 300);
- }, 200);
- })
- .catch((err) => done(err));
- });
-
- it('Should show first conditional wizard page', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
-
- wizard.setForm(wizard6).then(() => {
- assert.equal(wizard.pages.length, 1);
- assert.equal(wizard.components.length, 1);
- assert.equal(wizard.page, 0);
- assert.equal(wizard.refs[`wizard-${wizard.id}-previous`], null);
- assert.equal(
- wizard.refs[
- `wizard-${wizard.id}-link`
- ][0].parentElement.classList.contains('active'),
- true
- );
- wizard.setValue({
- data: { b: 'true' },
- });
- setTimeout(() => {
- assert.equal(wizard.pages.length, 2);
- assert.equal(wizard.components.length, 2);
- assert.equal(wizard.page, 1);
- assert.notEqual(wizard.refs[`wizard-${wizard.id}-previous`], null);
- assert.equal(
- wizard.refs[
- `wizard-${wizard.id}-link`
- ][1].parentElement.classList.contains('active'),
- true
- );
- done();
- }, 300);
- })
- .catch((err) => done(err));
- });
-
- it('Should display editGrid submission data in readOnly mode', (done) => {
- const formElement = document.createElement('div');
- const wizardForm = new Wizard(formElement, { readOnly: true });
- wizardForm.setForm(wizard2).then(() => {
- wizardForm.setValue({ data: { editGrid: [{ textField: '111' }], number: 222 } });
- setTimeout(() => {
- assert.equal(wizardForm.element.querySelector('[name="data[number]"]').value, '222');
-
- Harness.clickElement(wizardForm, wizardForm.refs[`${wizardForm.wizardKey}-link`][1]);
-
- setTimeout(() => {
- assert.equal(wizardForm.page, 1);
-
- const ditGridRowValue = wizardForm.element.querySelector('[ref = "editgrid-editGrid-row"]').querySelector('.col-sm-2').textContent.trim();
- assert.equal(ditGridRowValue, '111');
- done();
- }, 300);
- }, 100);
- })
- .catch((err) => done(err));
- });
-
- let wizardForm = null;
- it('Should set components errors if they are after page was changed with navigation', (done) => {
- const formElement = document.createElement('div');
- wizardForm = new Wizard(formElement);
- wizardForm.setForm(wizard).then(() => {
- Harness.testErrors(wizardForm, {
- data: {
- a: '1',
- c: '',
- textField: ''
- }
- },
- [{
- component: 'a',
- message: 'a must have at least 4 characters.'
- }], done);
- Harness.clickElement(wizardForm, wizardForm.refs[`${wizardForm.wizardKey}-link`][2]);
- assert.equal(wizardForm.page, 2);
- setTimeout(() => {
- Harness.clickElement(wizardForm, wizardForm.refs[`${wizardForm.wizardKey}-link`][0]);
- assert.equal(wizardForm.page, 0);
- setTimeout(() => {
- const aInput = wizardForm.currentPage.getComponent('a');
- assert.equal(aInput.errors.length, 1);
- assert.equal(aInput.errors[0].message, 'a must have at least 4 characters.');
- done();
- }, 100);
- }, 100);
- })
- .catch((err) => done(err));
- });
-
- it('Should leave errors for invalid fields after validation on next button and entering valid data in one of the fields', function(done) {
- const formElement = document.createElement('div');
- wizardForm = new Wizard(formElement);
- wizardForm.setForm(wizard1).then(() => {
- Harness.clickElement(wizardForm, wizardForm.refs[`${wizardForm.wizardKey}-next`]);
- setTimeout(() => {
- assert.equal(wizardForm.errors.length, 2);
-
- const inputEvent = new Event('input', { bubbles: true, cancelable: true });
- const inputA = formElement.querySelector('input[name="data[a]"]');
-
- for (let i = 0; i < 5; i++) {
- inputA.value += i;
- inputA.dispatchEvent(inputEvent);
- }
-
- setTimeout(() => {
- assert.equal(wizardForm.errors.length, 1);
- done();
- }, 250);
- }, 250);
- })
- .catch((err) => done(err));
- });
-
- it('Should not set components errors if in readOnly mode', (done) => {
- const formElement = document.createElement('div');
- wizardForm = new Wizard(formElement, { readOnly: true });
- wizardForm.setForm(wizard).then(() => {
- Harness.testSubmission(wizardForm, {
- data: {
- a: '1',
- textField: 'aaa',
- c: '0'
- }
- });
-
- Harness.clickElement(wizardForm, wizardForm.refs[`${wizardForm.wizardKey}-link`][2]);
- assert.equal(wizardForm.page, 2);
- Harness.clickElement(wizardForm, wizardForm.refs[`${wizardForm.wizardKey}-link`][0]);
- assert.equal(wizardForm.page, 0);
- const aInput = wizardForm.currentPage.getComponent('a');
- assert.equal(aInput.errors.length, 0);
- done();
- });
- });
-
- it('Should keep values during validation that are conditionally visible', async() => {
- const submission = {
- data: {
- a: true,
- b: 'b',
- c: 'c'
- }
- };
-
- const form = await Formio.createForm(wizardCond, {});
-
- form.validator.config = {
- db: {},
- token: '',
- form: wizardCond,
- submission: submission
- };
-
- // Set the submission data
- form.data = submission.data;
-
- assert.deepEqual(form.data, submission.data, 'Should set data properly');
- // Perform calculations and conditions.
- form.calculateValue();
- form.checkConditions();
-
- assert(form.components[2], 'Should contain the 3rd page');
- assert.equal(form.components[2].visible, true, 'Should be visible');
-
- const textField = form.components[2].components[0];
-
- assert.equal(textField.visible, true, 'Inner components of the 3rd page should be visible');
- assert.equal(textField.parentVisible, true, 'parentVisible of the 3rd page\'s child components should be equal to true');
-
- // Reset the data
- form.data = {};
-
- form.setValue(submission, {
- sanitize: true
- });
-
- // Check the validity of the form.
- const valid = await form.checkAsyncValidity(null, true);
-
- assert(valid, 'Should be valid');
- assert.equal(form.data.c, 'c', 'Should keep the value of a conditionally visible page.');
- });
-
- it('If allowPrevious is given, the breadcrumb bar should be clickable for visited tabs.', (done) => {
- const formElement = document.createElement('div');
- wizardForm = new Wizard(formElement, { allowPrevious: true });
- wizardForm.setForm(wizardWithAllowPrevious)
- .then(() => {
- Harness.clickElement(wizardForm, wizardForm.refs[`${wizardForm.wizardKey}-link`][1]);
-
- setTimeout(() => {
- assert.equal(wizardForm.page, 0, 'Should be disabled for unvisited tabs.');
- Harness.clickElement(wizardForm, wizardForm.refs[`${wizardForm.wizardKey}-next`]);
-
- setTimeout(() => {
- assert.equal(wizardForm.enabledIndex, 1, 'Should be clickable for visited tabs.');
- done();
- }, 100);
- }, 100);
- })
- .catch(done);
- });
-
- it('Should scroll to the top of the page when the page is changed', (done) => {
- const formElement = document.createElement('div');
- wizardForm = new Wizard(formElement);
- wizardForm.setForm(wizardWithHighPages)
- .then(() => {
- wizardForm.scrollIntoView(wizardForm.refs[`${wizardForm.wizardKey}-next`]);
- wizardForm.setPage(1);
- setTimeout(() => {
- assert.equal(wizardForm.refs[wizardForm.wizardKey].scrollTop, 0, 'The top edge of the page should be aligned to the top edge of the window');
- done();
- }, 350);
- })
- .catch(done);
- });
-
- it('Should show the actual page after re-rendering due to nested wizards.', (done) => {
- const formElement = document.createElement('div');
- wizardForm = new Wizard(formElement);
- wizardForm.setForm(wizardWithNestedWizard)
- .then(() => {
- assert.equal(wizardForm.element.querySelector('.wizard-page'), wizardForm.allPages[0].components[0].element.parentNode);
- done();
- })
- .catch(done);
- });
- // BUG - uncomment once fixed (ticket FIO-6043)
- // it('Should render all pages as a part of wizard pagination', (done) => {
- // const formElement = document.createElement('div');
- // const wizard = new Wizard(formElement);
- // const childForm = _.cloneDeep(wizardChildForm);
- // const clickEvent = new Event('click');
-
- // wizard.setForm(wizardParentForm).then(() => {
- // assert.equal(wizard.components.length, 2);
- // assert.equal(wizard.allPages.length, 2);
- // assert.equal(wizard.allPages[1].component.title, 'Page 3');
-
- // const radioComp = wizard.getComponent('radio1');
-
- // radioComp.setValue('yes');
- // wizard.render();
-
- // setTimeout(() => {
- // const nestedFormComp = wizard.getComponent('formNested');
- // nestedFormComp.loadSubForm = () => {
- // nestedFormComp.formObj = childForm;
- // nestedFormComp.subFormLoading = false;
-
- // return new Promise((resolve) => resolve(childForm));
- // };
- // nestedFormComp.createSubForm();
-
- // setTimeout(() => {
- // assert.equal(wizard.components.length, 3);
- // assert.equal(wizard.allPages.length, 4);
- // assert.equal(wizard.allPages[1].component.title, 'Child Page 1');
-
- // const checboxComp = wizard.getComponent('checkbox');
-
- // checboxComp.setValue(true);
- // wizard.render();
-
- // setTimeout(() => {
- // assert.equal(wizard.components.length, 3);
- // assert.equal(wizard.allPages.length, 5);
- // assert.equal(wizard.allPages[1].component.title, 'Page 2');
- // assert.equal(wizard.element.querySelector('input[name="data[textFieldNearForm]"]'), null);
-
- // const nextPageBtn = wizard.refs[`${wizard.wizardKey}-next`];
-
- // nextPageBtn.dispatchEvent(clickEvent);
-
- // setTimeout(() => {
- // assert.equal(wizard.component.title, 'Page 2');
- // assert.ok(wizard.element.querySelector('input[name="data[textFieldNearForm]"]'));
-
- // done();
- // }, 200);
- // }, 200);
- // }, 200);
- // }, 200);
- // }).catch(done);
- // });
-
- describe('Conditional pages', () => {
- it('Should remove page from header when it is hidden', (done) => {
- const formElement = document.createElement('div');
- const form = new Wizard(formElement);
- form.setForm(wizardWithConditionallyVisiblePage)
- .then(() => {
- const textField = form.getComponent(['textField']);
- Harness.dispatchEvent(
- 'input',
- textField.element,
- '[name="data[textField]"]',
- (input) => input.value = 'hide',
- );
- assert.equal(form.refs[`wizard-${form.id}-link`].length, 3, 'Should show all the pages in header');
-
- setTimeout(() => {
- assert.equal(textField.dataValue, 'hide', 'Should set value');
- const page2 = form.getComponent(['page2']);
- assert.equal(page2.visible, false, 'Should be hidden by logic');
- assert.equal(form.refs[`wizard-${form.id}-link`].length, 2, 'Should remove invisible pages from header');
- done();
- }, 300);
- })
- .catch(done);
- });
-
- it('', (done) => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, nestedConditionalWizard).then((form) => {
- const nestedFormRadio = form.getComponent(['nestedForm']);
-
- nestedFormRadio.setValue('yes');
- setTimeout(() => {
- const secondQuestionToOpenNestedFormRadio = form.getComponent(['secondQuestionToOpenNestedForm']);
- assert(secondQuestionToOpenNestedFormRadio.visible, 'Should become visible');
- secondQuestionToOpenNestedFormRadio.setValue('openChildForm');
-
- setTimeout(() => {
- const nestedForm = form.getComponent(['form']);
- assert(nestedForm.visible, 'Should become visible');
- nestedForm.subForm.components.forEach((comp) => {
- assert.equal(comp.root, nestedForm.subForm, 'The root of the nested components should be set to the' +
- ' Wizard itself');
- });
- const nestedRadio1 = nestedForm.subForm.getComponent(['radio1']);
-
- nestedRadio1.setValue('unhidePage3');
-
- setTimeout(() => {
- const pages = form.element.querySelectorAll('.formio-form nav .pagination .page-item');
- assert.equal(pages.length, 3, 'Should show the hidden initially page');
-
- secondQuestionToOpenNestedFormRadio.setValue(2);
-
- setTimeout(() => {
- assert(!nestedForm.visible, 'Should become hidden');
- secondQuestionToOpenNestedFormRadio.setValue('openChildForm');
-
- setTimeout(() => {
- assert(nestedForm.visible, 'Should become visible again');
- secondQuestionToOpenNestedFormRadio.setValue('openChildForm');
-
- nestedForm.subForm.components.forEach((comp) => {
- assert.equal(comp.root, nestedForm.subForm, 'The root of the nested components should be set to the' +
- ' Wizard itself');
- });
- const nestedRadio1 = nestedForm.subForm.getComponent(['radio1']);
-
- nestedRadio1.setValue('unhidePage3');
-
- setTimeout(() => {
- const pages = form.element.querySelectorAll('.formio-form nav .pagination .page-item');
- assert.equal(pages.length, 3, 'Should show the hidden initially page');
-
- done();
- });
- }, 400);
- }, 500);
- }, 400);
- }, 500);
- }, 400);
- }).catch(done);
- });
- });
-
- it('Should have proper values for localRoot', (done) => {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const form = _.cloneDeep(wizardWithPanel);
- const nestedMiddleForm = _.cloneDeep(wizardWithWizard);
- const childForm = _.cloneDeep(simpleTwoPagesWizard);
-
- wizard.setForm(form).then(() => {
- const nestedMiddleFormComp = wizard.getComponent('middleForm');
- nestedMiddleFormComp.loadSubForm = () => {
- nestedMiddleFormComp.formObj = nestedMiddleForm;
- nestedMiddleFormComp.subFormLoading = false;
- return new Promise((resolve) => resolve(nestedMiddleForm));
- };
- nestedMiddleFormComp.createSubForm();
-
- setTimeout(() => {
- const middleWizard = nestedMiddleFormComp.subForm;
-
- const nestedChildFormComp = middleWizard.getComponent('childForm');
- nestedChildFormComp.loadSubForm = () => {
- nestedChildFormComp.formObj = childForm;
- nestedChildFormComp.subFormLoading = false;
- return new Promise((resolve) => resolve(childForm));
- };
- nestedChildFormComp.createSubForm();
-
- setTimeout(() => {
- const childWizard = nestedChildFormComp.subForm;
-
- assert.equal(wizard.id, wizard.root.id);
- assert.equal(wizard.id, wizard.localRoot.id);
- assert.equal(wizard.root.id, wizard.localRoot.id);
- assert.notEqual(middleWizard.id, middleWizard.root.id);
- assert.equal(middleWizard.id, middleWizard.localRoot.id);
- assert.notEqual(middleWizard.root.id, middleWizard.localRoot.id);
- assert.notEqual(childWizard.id, childWizard.root.id);
- assert.notEqual(childWizard.id, childWizard.localRoot.id);
- assert.equal(childWizard.root.id, childWizard.localRoot.id);
- done();
- }, 200);
- }, 200);
- });
- });
-
- it('Should keep wizard pages separate from edit grid inner wizard pages', (done) => {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const form = _.cloneDeep(wizardWithNestedWizardInEditGrid);
- const childForm = _.cloneDeep(simpleTwoPagesWizard);
-
- wizard.setForm(form).then(() => {
- assert.equal(wizard.components.length, 1);
- assert.equal(wizard.allPages.length, 1);
-
- const editGrid = wizard.getComponent('editGrid');
- editGrid.addRow();
-
- setTimeout(() => {
- const nestedFormComp = wizard.getComponent('formNested');
-
- nestedFormComp.loadSubForm = () => {
- nestedFormComp.formObj = childForm;
- nestedFormComp.subFormLoading = false;
-
- return new Promise((resolve) => resolve(childForm));
- };
- nestedFormComp.createSubForm();
-
- setTimeout(() => {
- assert.equal(nestedFormComp.subForm.components.length, 2);
- assert.equal(nestedFormComp.subForm.allPages.length, 2);
- assert.equal(wizard.components.length, 1);
- assert.equal(wizard.allPages.length, 1);
- done();
- }, 200);
- }, 200);
- });
- });
-
- it('Should navigate wizard pages and submit form using \'Save on Enter\' option', function(done) {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
-
- wizard.setForm(wizardNavigateOrSaveOnEnter.form).then(() => {
- const pressEnter = () => {
- const event = new KeyboardEvent('keyup', {
- bubbles : true,
- cancelable : true,
- key : 'Enter',
- keyCode : 13
- });
- document.dispatchEvent(event);
- };
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber, `Should open wizard page ${pageNumber + 1}`);
- };
- checkPage(0);
- pressEnter();
-
- setTimeout(() => {
- checkPage(1);
-
- pressEnter();
-
- setTimeout(() => {
- checkPage(2);
-
- pressEnter();
-
- setTimeout(() => {
- assert.equal(wizard.submission.state, 'submitted', 'Should submit the form');
-
- done();
- }, 50);
- }, 50);
- }, 50);
- })
- .catch((err) => done(err));
- });
-
- it('Should proper validate nested wizard fields', (done) => {
- const formElement = document.createElement('div');
- const wizard = new Wizard(formElement);
- const childForm = _.cloneDeep(wizardWithFieldsValidationChild);
- const parentForm = _.cloneDeep(wizardWithFieldsValidationParent);
- const clickEvent = new Event('click');
-
- wizard.setForm(parentForm).then(() => {
- const nestedFormComp = wizard.getComponent('formNested');
- nestedFormComp.loadSubForm = () => {
- nestedFormComp.formObj = childForm;
- nestedFormComp.subFormLoading = false;
- return new Promise((resolve) => resolve(childForm));
- };
- nestedFormComp.createSubForm();
-
- setTimeout(() => {
- const textField = wizard.getComponent('textField');
- const testValidation = wizard.getComponent('testValidation');
- textField.setValue('one');
- testValidation.setValue('two');
- wizard.render();
-
- const checkPage = (pageNumber) => {
- assert.equal(wizard.page, pageNumber);
- };
- const nextPageBtn = wizard.refs[`${wizard.wizardKey}-next`];
-
- setTimeout(() => {
- nextPageBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- checkPage(0);
- assert.equal(wizard.errors.length, 1);
- assert.equal(wizard.refs.errorRef.length, wizard.errors.length);
- testValidation.setValue('one');
- nextPageBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- checkPage(1);
- assert.equal(wizard.errors.length, 0);
- done();
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/WizardBuilder.js b/web-client/core/themes/italia/static/formio/css/src/WizardBuilder.js
deleted file mode 100644
index 17f3508a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/WizardBuilder.js
+++ /dev/null
@@ -1,312 +0,0 @@
-import WebformBuilder from './WebformBuilder';
-import Webform from './Webform';
-import BuilderUtils from './utils/builder';
-import _ from 'lodash';
-import { fastCloneDeep } from './utils/utils';
-
-let dragula;
-if (typeof window !== 'undefined') {
- // Import from "dist" because it would require and "global" would not be defined in Angular apps.
- dragula = require('dragula/dist/dragula');
-}
-
-export default class WizardBuilder extends WebformBuilder {
- constructor() {
- let element, options;
- if (arguments[0] instanceof HTMLElement || arguments[1]) {
- element = arguments[0];
- options = arguments[1];
- }
- else {
- options = arguments[0];
- }
- // Reset skipInit in case PDFBuilder has set it.
- options.skipInit = false;
- options.display = 'wizard';
-
- super(element, options);
-
- this._form = {
- components: [
- this.getPageConfig(1),
- ],
- };
-
- this.page = 0;
-
- // Need to create a component order for each group.
- for (const group in this.groups) {
- if (this.groups[group] && this.groups[group].components) {
- this.groups[group].componentOrder = Object.keys(this.groups[group].components)
- .map(key => this.groups[group].components[key])
- .filter(component => component && !component.ignore)
- .sort((a, b) => a.weight - b.weight)
- .map(component => component.key);
- }
- }
-
- const originalRenderComponentsHook = this.options.hooks.renderComponents;
- this.options.hooks.renderComponents = (html, { components, self }) => {
- if (self.type === 'form' && !self.root) {
- return html;
- }
- else {
- return originalRenderComponentsHook(html, { components, self });
- }
- };
-
- const originalAttachComponentsHook = this.options.hooks.attachComponents;
- this.options.hooks.attachComponents = (element, components, container, component) => {
- if (component.type === 'form' && !component.root) {
- return element;
- }
-
- return originalAttachComponentsHook(element, components, container, component);
- };
-
- // Wizard pages don't replace themselves in the right array. Do that here.
- this.on('saveComponent', (component, originalComponent) => {
- const webformComponents = this.webform.components.map(({ component }) => component);
- if (this._form.components.includes(originalComponent)) {
- this._form.components[this._form.components.indexOf(originalComponent)] = component;
- this.rebuild();
- }
- else if (webformComponents.includes(originalComponent)) {
- this._form.components.push(component);
- this.rebuild();
- }
- else {
- // Fallback to look for panel based on key.
- const formComponentIndex = this._form.components.findIndex((comp) => originalComponent.key === comp.key);
- if (formComponentIndex !== -1) {
- this._form.components[formComponentIndex] = component;
- this.rebuild();
- }
- }
- }, true);
- }
-
- removeComponent(component, parent, original) {
- const remove = super.removeComponent(component, parent, original);
- // If user agrees to remove the whole group of the components and it could be a Wizard page, find it and remove
- if (remove && component.type === 'panel') {
- const pageIndex = this.pages.findIndex((page) => page.key === component.key);
- const componentIndex = this._form.components.findIndex((comp) => comp.key === component.key);
- if (pageIndex !== -1) {
- this.removePage(pageIndex, componentIndex);
- }
- }
- return remove;
- }
-
- allowDrop(element) {
- return (this.webform && this.webform.refs && this.webform.refs.webform === element) ? false : true;
- }
-
- get pages() {
- return _.filter(this._form.components, { type: 'panel' });
- }
-
- get currentPage() {
- const pages = this.pages;
- return (pages && (pages.length >= this.page)) ? pages[this.page] : null;
- }
-
- set form(value) {
- this._form = value;
- if (!this._form.components || !Array.isArray(this._form.components)) {
- this._form.components = [];
- }
-
- if (this.pages.length === 0) {
- const components = this._form.components.filter((component) => component.type !== 'button');
- this._form.components = [this.getPageConfig(1, components)];
- }
- this.rebuild();
- }
-
- get form() {
- return this._form;
- }
-
- get schema() {
- _.assign(this.currentPage, this.webform._form.components[0]);
- const webform = new Webform(this.options);
- webform.setForm(this._form, { noEmit: true });
- return webform.schema;
- }
-
- render() {
- return this.renderTemplate('builderWizard', {
- sidebar: this.renderTemplate('builderSidebar', {
- scrollEnabled: this.sideBarScroll,
- groupOrder: this.groupOrder,
- groupId: `builder-sidebar-${this.id}`,
- groups: this.groupOrder.map((groupKey) => this.renderTemplate('builderSidebarGroup', {
- group: this.groups[groupKey],
- groupKey,
- groupId: `builder-sidebar-${this.id}`,
- subgroups: this.groups[groupKey].subgroups.map((group) => this.renderTemplate('builderSidebarGroup', {
- group,
- groupKey: group.key,
- groupId: `group-container-${groupKey}`,
- subgroups: []
- })),
- })),
- }),
- pages: this.pages,
- form: this.webform.render(),
- });
- }
-
- attach(element) {
- this.loadRefs(element, {
- addPage: 'multiple',
- gotoPage: 'multiple',
- });
-
- this.refs.gotoPage.forEach((page, index) => {
- page.parentNode.dragInfo = { index };
- });
-
- if (dragula) {
- this.navigationDragula = dragula([this.element.querySelector('.wizard-pages')], {
- // Don't move Add Page button
- moves: (el) => (!el.classList.contains('wizard-add-page')),
- // Don't allow dragging components after Add Page button
- accepts: (el, target, source, sibling) => (sibling ? true : false),
- })
- .on('drop', this.onReorder.bind(this));
- }
-
- this.refs.addPage.forEach(link => {
- this.addEventListener(link, 'click', (event) => {
- event.preventDefault();
- this.addPage();
- });
- });
-
- this.refs.gotoPage.forEach((link, index) => {
- this.addEventListener(link, 'click', (event) => {
- event.preventDefault();
- this.setPage(index);
- });
- });
-
- return super.attach(element);
- }
-
- detach() {
- if (this.navigationDragula) {
- this.navigationDragula.destroy();
- }
- this.navigationDragula = null;
-
- super.detach();
- }
-
- rebuild() {
- const page = this.currentPage;
- this.webform.setForm({
- display: 'form',
- type: 'form',
- components: page ? [page] : [],
- controller: this._form?.controller || ''
- }, { keepAsReference: true });
- return this.redraw();
- }
-
- addPage(page) {
- const newPage = page && page.schema ? fastCloneDeep(page.schema) : this.getPageConfig(this.pages.length + 1);
-
- BuilderUtils.uniquify(this._form.components, newPage);
- this._form.components.push(newPage);
-
- this.emitSaveComponentEvent(
- newPage,
- newPage,
- this._form,
- 'components',
- (this._form.components.length - 1),
- true,
- newPage
- );
-
- this.emit('change', this._form);
- return this.rebuild();
- }
-
- removePage(pageIndex, componentIndex) {
- this._form.components.splice(componentIndex, 1);
- this.emit('change', this._form);
-
- if (pageIndex === this.pages.length) {
- // If the last page is removed.
- if (pageIndex === 0) {
- this._form.components.push(this.getPageConfig(1));
- return this.rebuild();
- }
- else {
- return this.setPage(pageIndex - 1);
- }
- }
- else {
- return this.rebuild();
- }
- }
-
- onReorder(element, _target, _source, sibling) {
- const isSiblingAnAddPageButton = sibling?.classList.contains('wizard-add-page');
- // We still can paste before Add Page button
- if (!element.dragInfo || (sibling && !sibling.dragInfo && !isSiblingAnAddPageButton)) {
- console.warn('There is no Drag Info available for either dragged or sibling element');
- return;
- }
- const oldPosition = element.dragInfo.index;
- //should drop at next sibling position; no next sibling means drop to last position
- const newPosition = (sibling && sibling.dragInfo ? sibling.dragInfo.index : this.pages.length);
- const movedBelow = newPosition > oldPosition;
- const formComponents = fastCloneDeep(this._form.components);
- const draggedRowData = this._form.components[oldPosition];
-
- //insert element at new position
- formComponents.splice(newPosition, 0, draggedRowData);
- //remove element from old position (if was moved above, after insertion it's at +1 index)
- formComponents.splice(movedBelow ? oldPosition : oldPosition + 1, 1);
- this._form.components = fastCloneDeep(formComponents);
-
- return this.rebuild().then(() => {
- this.emit('change', this._form);
- });
- }
-
- setPage(index) {
- if (index === this.page) {
- return;
- }
- this.page = index;
- return this.rebuild();
- }
-
- getPageConfig(index, components = []) {
- return {
- title: `Page ${index}`,
- label: `Page ${index}`,
- type: 'panel',
- key: `page${index}`,
- components,
- };
- }
-
- pasteComponent(component) {
- if (component instanceof WizardBuilder) {
- return;
- }
- if (this._form.components.find(comp => _.isEqual(component.component, comp))) {
- this.addPage(component);
- }
- else {
- return super.pasteComponent(component);
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/WizardBuilder.unit.js b/web-client/core/themes/italia/static/formio/css/src/WizardBuilder.unit.js
deleted file mode 100644
index 587ab385..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/WizardBuilder.unit.js
+++ /dev/null
@@ -1,125 +0,0 @@
-import FormBuilder from './FormBuilder';
-import assert from 'power-assert';
-import Harness from '../test/harness';
-import simpleWizard from '../test/forms/simpleWizard';
-import formWithFormController from '../test/forms/formWithFormController';
-import { fastCloneDeep } from './utils/utils';
-
-global.requestAnimationFrame = (cb) => cb();
-global.cancelAnimationFrame = () => {};
-
-describe('WizardBuilder tests', function() {
- let formBuilderElement, formBuilder;
- after((done) => {
- destroyWizardBuilder();
- done();
- });
-
- function destroyWizardBuilder() {
- if (formBuilder && formBuilder.instance) {
- formBuilder.instance.destroy();
- document.body.removeChild(formBuilderElement);
- }
- }
-
- function createWizardBuilder(form = { display: 'wizard', components: [] }) {
- destroyWizardBuilder();
- formBuilderElement = document.createElement('div');
- document.body.appendChild(formBuilderElement);
- formBuilder = new FormBuilder(formBuilderElement, { ...form, components: [...form.components] }, {});
- return formBuilder;
- }
-
- it('Test page remove with cancellation', function(done) {
- const builder = createWizardBuilder(simpleWizard);
-
- setTimeout(() => {
- const panel = builder.instance.webform.components[0];
- const removeComponentRef = panel.refs.removeComponent;
- window.confirm = () => {
- return false;
- };
- Harness.clickElement(panel, removeComponentRef);
- setTimeout(() => {
- assert.equal(builder.instance._form.components.length, 5, 'Should not remove the page on cancel');
- assert.equal(builder.instance.webform.components[0].key, 'page1', 'Should stay on page 1 since we' +
- ' canceled the deletion');
- done();
- }, 300);
- }, 500);
- });
-
- it('Test page remove with confirmation', function(done) {
- const builder = createWizardBuilder(simpleWizard);
-
- setTimeout(() => {
- const panel = builder.instance.webform.components[0];
- const removeComponentRef = panel.refs.removeComponent;
- window.confirm = () => {
- return true;
- };
- Harness.clickElement(panel, removeComponentRef);
- setTimeout(() => {
- assert.equal(builder.instance._form.components.length, 4, 'Should remove the page on confirm');
- assert.equal(builder.instance.webform.components[0].key, 'page2', 'Should switch to the next page when' +
- ' deletion is confirmed');
- done();
- }, 300);
- }, 500);
- });
-
- it('Test page remove with confirmation when remove from component settings window', function(done) {
- const builder = createWizardBuilder(simpleWizard);
-
- setTimeout(() => {
- const panel = builder.instance.webform.components[0];
- const editComponentRef = panel.refs.editComponent;
- window.confirm = () => {
- return true;
- };
-
- Harness.clickElement(panel, editComponentRef);
- setTimeout(() => {
- assert(builder.instance.editForm, 'Should create the settings form on component edit');
- const removeButton = builder.instance.componentEdit.querySelector('[ref="removeButton"]');
- Harness.clickElement(panel, removeButton);
- setTimeout(() => {
- assert.equal(builder.instance._form.components.length, 4, 'Should remove the page on confirm');
- assert.equal(builder.instance.webform.components[0].key, 'page2', 'Should switch to the next page when' +
- ' deletion is confirmed');
- done();
- }, 300);
- }, 300);
- }, 500);
- });
-
- it('Should execute form controller', (done) => {
- const form = fastCloneDeep(formWithFormController);
- form.display = 'wizard';
- const builder = createWizardBuilder(form).instance;
-
- setTimeout(() => {
- const textF = builder.webform.getComponent('textField');
- assert.equal(textF.getValue(), 'Hello World');
- assert.equal(textF.disabled, true);
- assert.equal(builder.webform.components[0].disabled, true);
-
- done();
- }, 500);
- });
-
- it('Test pages reorder', (done) => {
- const builder = createWizardBuilder(simpleWizard);
-
- setTimeout(() => {
- const drake = builder.instance.navigationDragula;
- const addPageBtn = builder.instance.element.querySelector('.wizard-add-page');
- assert.equal(drake.canMove(addPageBtn), false, 'Should not be able to move Add Page button');
- const pagesElements = builder.instance.element.querySelectorAll('.wizard-pages li');
- assert.equal(pagesElements.length, 6, 'Should contain all buttons for all the pages + Add Page button');
- const firstPage = pagesElements[0];
- assert.equal(drake.canMove(firstPage), true, 'Should be able to move page button');
- done();
- }, 500);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/addons/FormioAddon.js b/web-client/core/themes/italia/static/formio/css/src/addons/FormioAddon.js
deleted file mode 100644
index 1c907684..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/addons/FormioAddon.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import Element from '../Element';
-import NativePromise from 'native-promise-only';
-import _ from 'lodash';
-
-export default class FormioAddon extends Element {
- static get info() {
- return {
- supportedComponents: [],
- name: 'formioAddon',
- components: [],
- label: 'Formio Addon',
- defaultSettings: {}
- };
- }
-
- get defaultSettings() {
- return FormioAddon.info.defaultSettings;
- }
-
- get element() {
- return this._element;
- }
-
- constructor(settings, componentInstance) {
- super(settings);
- this.namespace = 'formio.plugin';
- this.component = componentInstance || {};
- this.settings = _.merge({}, this.defaultSettings, settings || {});
- }
-
- attach(element) {
- this._element = element;
- return NativePromise.resolve();
- }
-
- destroy() {}
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/addons/PasswordStrength/PasswordStrengthAddon.form.js b/web-client/core/themes/italia/static/formio/css/src/addons/PasswordStrength/PasswordStrengthAddon.form.js
deleted file mode 100644
index 0f9e9b13..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/addons/PasswordStrength/PasswordStrengthAddon.form.js
+++ /dev/null
@@ -1,327 +0,0 @@
-import EditFormUtils from '../../components/_classes/component/editForm/utils';
-
-export default [
- {
- label: 'Strength Levels',
- reorder: false,
- addAnotherPosition: 'bottom',
- layoutFixed: false,
- enableRowGroups: false,
- initEmpty: false,
- tableView: false,
- defaultValue: [{}],
- key: 'levels',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Name',
- tableView: true,
- validate: {
- required: true
- },
- key: 'name',
- type: 'textfield',
- input: true
- },
- {
- label: 'Max Entropy',
- description: "Specifies the top boundary of the password's entropy(strength) which belongs to this level.\nCommon entropy values are:\n\n < 28 bits = Very Weak; \n 28 - 35 bits = Weak; should keep out most people; \n 36 - 59 bits = Reasonable; fairly secure passwords for network and company passwords; \n 60 - 127 bits = Strong; can be good for guarding financial information; \n > 128 bits = Very Strong; often overkill; \n \n",
- mask: false,
- spellcheck: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- validate: {
- required: true,
- min: 1,
- max: 128
- },
- key: 'maxEntropy',
- type: 'number',
- input: true
- },
- {
- label: 'Style',
- tooltip: 'Specifies the background color style using bootstrap classes',
- tableView: true,
- data: {
- values: [
- {
- label: 'Danger',
- value: 'danger'
- },
- {
- label: 'Warning',
- value: 'warning'
- },
- {
- label: 'Info',
- value: 'info'
- },
- {
- label: 'Success',
- value: 'success'
- }
- ]
- },
- selectThreshold: 0.3,
- validate: {
- onlyAvailableItems: false
- },
- key: 'style',
- type: 'select',
- indexeddb: { filter: {} },
- input: true
- },
- {
- label: 'Color',
- placeholder: '#0079c0',
- tooltip: 'Specifies a color of the indicator element',
- tableView: true,
- key: 'color',
- type: 'textfield',
- input: true
- }
- ]
- },
- {
- label: 'Update On',
- tableView: true,
- data: {
- values: [
- {
- label: 'Strength Level Change',
- value: 'levelChange'
- },
- {
- label: 'Entropy Change',
- value: 'entropyChange'
- }
- ]
- },
- selectThreshold: 0.3,
- validate: {
- onlyAvailableItems: false
- },
- key: 'updateOn',
- type: 'select',
- indexeddb: {
- filter: {}
- },
- input: true
- },
- {
- label: 'Rules',
- reorder: false,
- addAnotherPosition: 'bottom',
- layoutFixed: false,
- enableRowGroups: false,
- initEmpty: false,
- tableView: false,
- defaultValue: [
- {}
- ],
- key: 'rulesSettings',
- type: 'datagrid',
- input: true,
- components: [
- {
- label: 'Name',
- tableView: true,
- data: {
- values: [
- {
- label: 'Length',
- value: 'length'
- },
- {
- label: 'Lower Case',
- value: 'lowerCase'
- },
- {
- label: 'Upper Case',
- value: 'upperCase'
- },
- {
- label: 'Numeric',
- value: 'numeric'
- },
- {
- label: 'Symbols',
- value: 'symbols'
- }
- ]
- },
- selectThreshold: 0.3,
- validate: {
- required: true,
- onlyAvailableItems: false
- },
- key: 'name',
- type: 'select',
- indexeddb: {
- filter: {}
- },
- input: true
- },
- {
- label: 'Error Message',
- tableView: true,
- key: 'errorMessage',
- type: 'textfield',
- input: true
- },
- {
- label: 'Required',
- tableView: false,
- key: 'required',
- type: 'checkbox',
- input: true,
- defaultValue: false
- }
- ]
- },
- {
- label: 'Custom Rules',
- tableView: false,
- rowDrafts: false,
- key: 'customRules',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Name',
- tableView: true,
- validate: {
- required: true
- },
- key: 'name',
- type: 'textfield',
- input: true
- },
- EditFormUtils.javaScriptValue('Check', 'check', '', 1100,
- '
Example: valid = !value.includes(data.email) ? true : "Password should not be variation of the email";
',
- '',
- '',
- true
- ),
- {
- label: 'Increase Characters Pool Size',
- description: 'Set this to amount of characters that may be used in the password if there is a specific group of characters is used.\nE.g., if your validation checks if there is any numeric symbol in the password, then you should set it to 10 (there are 10 possible numbers).\n',
- mask: false,
- spellcheck: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'increaseCharactersPoolSize',
- type: 'number',
- input: true
- },
- {
- label: 'Required',
- tooltip: 'Check if this check is required to proceed',
- tableView: false,
- key: 'required',
- type: 'checkbox',
- input: true,
- defaultValue: false
- }
- ]
- },
- EditFormUtils.javaScriptValue('Is Valid', 'isValid', '', 1100,
- '
Example: valid = entropy > maxEntropy / 2 ; ',
- '',
- 'entropy Current entropy bits of the password. ' +
- 'level Current strength level of the password. ',
- true
- ),
- {
- label: 'Required',
- description: "Check this if you don't want to allow submitting password which does not correspond to the minimal strength requirements.",
- tableView: false,
- key: 'required',
- type: 'checkbox',
- input: true,
- defaultValue: false
- },
- {
- label: 'Black List',
- tooltip: 'Add words to search in the password. If there are some words from that list were found, the entropy of the password will be recalculated.\n',
- tableView: true,
- multiple: true,
- key: 'blackList',
- type: 'textfield',
- input: true
- },
- EditFormUtils.javaScriptValue('Custom Blacklisted Words', 'customBlackListedWords', '', 1100,
- '
Example: values = [ data.name, data.dataOfBirth, data.favoriteColor ]; ',
- '',
- '',
- true
- ),
- {
- label: 'Disable Blacklisted Words',
- tooltip: 'Check if you want to disable submitting passwords containing words form the clack list',
- tableView: false,
- key: 'disableBlacklistedWords',
- type: 'checkbox',
- input: true,
- defaultValue: false
- },
- {
- label: 'Location',
- hideLabel: false,
- tableView: false,
- key: 'location',
- type: 'container',
- input: true,
- components: [
- {
- label: 'Insert',
- tooltip: 'Specifies where the indicator will be inserted: before or aftre an element',
- tableView: true,
- data: {
- values: [
- {
- label: 'Before',
- value: 'before'
- },
- {
- label: 'After',
- value: 'after'
- }
- ]
- },
- selectThreshold: 0.3,
- validate: {
- onlyAvailableItems: false
- },
- key: 'insert',
- type: 'select',
- indexeddb: { filter: {} },
- input: true
- },
- {
- label: 'Selector',
- placeholder: "[ref='element']",
- description: 'Specifies the selector of the element which will be used as a reference to insert the indicator template',
- tableView: true,
- key: 'selector',
- type: 'textfield',
- input: true
- }
- ]
- },
- {
- label: 'Template',
- editor: 'ace',
- tableView: true,
- key: 'template',
- type: 'textarea',
- input: true,
- as: 'html'
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/addons/PasswordStrength/PasswordStrengthAddon.js b/web-client/core/themes/italia/static/formio/css/src/addons/PasswordStrength/PasswordStrengthAddon.js
deleted file mode 100644
index e1ea5578..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/addons/PasswordStrength/PasswordStrengthAddon.js
+++ /dev/null
@@ -1,451 +0,0 @@
-import _ from 'lodash';
-import FormioAddon from '../FormioAddon';
-import PasswordStrengthEditForm from './PasswordStrengthAddon.form';
-
-export default class PasswordStrengthAddon extends FormioAddon {
- static get info() {
- return {
- supportedComponents: ['password'],
- name: 'passwordStrength',
- components: PasswordStrengthEditForm,
- label: 'Password Strength',
- defaultSettings: {
- rulesSettings: [
- { name: 'length', required: false, message: 'Value should be longer' },
- { name: 'upperCase', required: false, message: 'Value should have uppercase letters' },
- { name: 'numeric', required: false, message: 'Value should have numeric symbols' },
- { name: 'lowerCase', required: false, message: 'Value should be have lowercase letters' },
- { name: 'symbols', required: false, message: 'Value should have symbols' }
- ],
- updateOn: 'levelChange',
- required: true,
- levels: [
- { name: 'Low', maxEntropy: 28, style: 'danger' },
- { name: 'Medium', maxEntropy: 45, style: 'warning' },
- { name: 'High', maxEntropy: 59, style: 'info' },
- { name: 'Very High', maxEntropy: 85, style: 'success' },
- ],
- blackList: [],
- template: `
-
- `,
- location: {
- insert: 'after',
- selector: '[ref="element"]'
- }
- }
- };
- }
-
- get defaultSettings() {
- return PasswordStrengthAddon.info.defaultSettings;
- }
-
- get rules() {
- return {
- length: {
- check: (value, options) => {
- const minLength = options.minLength || this.component.component.validate.minLength || 6;
- if (value.length < minLength) {
- return `Value must be longer than ${minLength} characters`;
- }
- return true;
- }
- },
- upperCase: {
- check: (value) => {
- if (/[A-Z]/g.test(value)) {
- return true;
- }
- return 'Value must contain uppercased alphabetical characters';
- },
- increaseCharactersPoolSize: 26
- },
- numeric: {
- check: (value) => {
- if (/[0-9]/g.test(value)) {
- return true;
- }
- return 'Value must contain numeric characters';
- },
- increaseCharactersPoolSize: 10,
- },
- lowerCase: {
- check: (value) => {
- if (/[a-z]/g.test(value)) {
- return true;
- }
- return 'Value must contain lowercased alphabetical characters';
- },
- increaseCharactersPoolSize: 26,
- },
- symbols: {
- check: (value) => {
- if (/[ `!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?~]/.test(value)) {
- return true;
- }
- return 'Value must contain symbols';
- },
- increaseCharactersPoolSize: 32,
- },
- };
- }
-
- get charactersPoolLength() {
- return this._charactersPoolLength;
- }
-
- set charactersPoolLength(value) {
- this._charactersPoolLength = value;
- }
-
- get level() {
- return this._level || this.getLevel();
- }
-
- set level(level) {
- this._level = level;
- }
-
- get entropy() {
- return this._entropy;
- }
-
- get dictionarySize() {
- return this.settings.dictionarySize || 171476;
- }
-
- set entropy(value) {
- const oldLevel = this.getLevel();
- const updateOnEntropyChange = this.settings.updateOn === 'entropyChange' && this._entropy !== value;
- this._entropy = value;
- this.level = this.getLevel();
- const updateOnLevelChange = this.settings.updateOn === 'levelChange' && oldLevel.name !== this.level.name;
- if (updateOnLevelChange || updateOnEntropyChange) {
- this.updateView();
- }
- }
-
- get template() {
- return this.settings.template;
- }
-
- get tooltip() {
- return this.level?.tooltip || `${this.level?.name} strongness`;
- }
-
- get rulesSettings() {
- return this.settings.rulesSettings || [];
- }
-
- get customRules() {
- return this.settings.customRules || [];
- }
-
- log2(value) {
- if (typeof Math.log2 === 'function') {
- return Math.log2(value);
- }
- return Math.log(value) * Math.LOG2E;
- }
-
- calculatePasswordEntropy(passwordLength, charactersPoolSize) {
- return !passwordLength || !charactersPoolSize ? 0 : this.log2(Math.pow(charactersPoolSize, passwordLength));
- }
-
- calculatePasswordEntropyWords(wordsCount) {
- return !this.dictionarySize ? 0 : this.log2(this.dictionarySize) * wordsCount;
- }
-
- render() {
- const view = this.component.interpolate(this.template, {
- entropy: this.entropy,
- maxEntropy: this.maxEntropy,
- level: this.level,
- levelName: this.level.name.replace(' ', '-').toLowerCase(),
- levels: this.levels,
- readOnly: this.component.options.readOnly,
- pristine: this.component.pristine,
- t: this.t.bind(this),
- tooltip: this.tooltip,
- });
-
- return this.component.sanitize(view);
- }
-
- checkBlackList(value) {
- const blackList = [...this.settings.blackList];
- let customBlacklistedWords = this.settings.customBlacklistedWords;
-
- if (customBlacklistedWords && typeof customBlacklistedWords === 'string') {
- customBlacklistedWords = this.evaluate(customBlacklistedWords, this.component.evalContext({ value }), 'values');
- if (customBlacklistedWords && customBlacklistedWords.length) {
- blackList.push(...customBlacklistedWords);
- }
- }
-
- let restValue = value;
- const blacklistedWords = [];
-
- for (let i = 0; i < blackList.length; i++) {
- const word = blackList[i];
- const regExp = new RegExp(`${word}`, 'gi');
-
- if (regExp.test(value)) {
- blacklistedWords.push(word);
- restValue = restValue.replace(regExp, '');
- }
-
- // If less the 3 symboles left, just stop iterating
- if (restValue.length < 3) {
- break;
- }
- }
-
- if (blacklistedWords.length) {
- // If there are some random characters except of blacklisted words in the password,
- // calculate the entropy for them
- const { charactersPoolSize } = restValue.length ? this.performChecks(restValue) : 0;
- const entropyOfNonblacklistedValue = this.calculatePasswordEntropy(restValue.length, charactersPoolSize);
- // Calculate the entropy if the biggest part of the password could be picked up from dictionary words
- const dictionaryCheckEntropy = this.calculatePasswordEntropyWords(blacklistedWords.length);
- const entropy = dictionaryCheckEntropy + entropyOfNonblacklistedValue;
- return { entropy, blacklistedWords };
- }
-
- return true;
- }
-
- /**
- * Determines is a password is secure enough to submit
- * @return {boolean}
- */
- isValid() {
- const isValidCheck = this.settings.isValid;
- if (isValidCheck && typeof isValidCheck === 'string') {
- const valid = this.evaluate(isValidCheck, this.component.evalContext({
- entropy: this.entropy,
- level: this.level
- }), 'valid');
- return valid;
- }
-
- return this.entropy >= Math.round(this.maxEntropy / 2);
- }
-
- /**
- * Handles the result of check and constructs a new error object or returns an amount of points to add to the current entropy
- * @param {boolean|number} valid - Determines if the validation was failed or an amount of points if it was passed
- * @param {*} validation - Validation configuration
- * @param {string} value - Value which was validated
- * @param {string} message - Message which should be shown if validation was not passed
- */
- handleRuleCheckResult(valid, validation, message, errors) {
- if (valid !== true) {
- errors.push({
- validation: validation.name,
- message,
- level: validation.required ? 'error' : 'warning'
- });
- }
- else if (validation.increaseCharactersPoolSize) {
- return validation.increaseCharactersPoolSize;
- }
-
- return 0;
- }
-
- performChecks(value) {
- const errors = [];
- let charactersPoolSize = 0;
-
- this.rulesSettings.forEach((settings) => {
- if (this.rules[settings.name]) {
- const rule = _.merge({}, this.rules[settings.name], settings);
- const valid = rule.check(value, settings.options || {});
- const message = settings.message || valid;
- charactersPoolSize += this.handleRuleCheckResult(valid, rule, message, errors);
- }
- });
-
- this.customRules.forEach((rule) => {
- if (rule.check && typeof rule.check === 'string') {
- const valid = this.evaluate(rule.check, this.component.evalContext({ value }), 'valid');
- const message = typeof valid === 'string' ? valid : `Password does not meet ${rule.name} validation`;
- charactersPoolSize += this.handleRuleCheckResult(valid, rule, message, errors);
- }
- });
-
- return {
- charactersPoolSize,
- errors
- };
- }
-
- /**
- * Performs checks to validate password security
- * @param {string} value - Suggested password
- */
- checkValidity(value) {
- const passwordLength = value.length;
-
- const { charactersPoolSize, errors } = this.performChecks(value);
- this.errors = errors;
-
- const entropy = this.calculatePasswordEntropy(passwordLength, charactersPoolSize);
- const blackListCheck = this.settings.blackList?.length || this.settings.customBlacklistedWords ?
- this.checkBlackList(value)
- : null;
-
- // If there were found some words from the black list
- if (blackListCheck && blackListCheck !== true) {
- this.handleBlackListCheckResult(blackListCheck);
- // Select the mininal entropy based on the dictionary check or symbolic check
- this.entropy = Math.min(entropy, blackListCheck.entropy);
- }
- else {
- this.entropy = entropy;
- }
-
- const isValid = this.isValid();
- if (!isValid) {
- this.errors.push({
- message: 'Password is not strong enough',
- level: this.settings.required ? 'error' : 'warning'
- });
- }
-
- return !this.errors.length;
- }
-
- handleBlackListCheckResult(result) {
- const blacklistedWords = result.blacklistedWords;
- const isRequired = this.settings.disableBlacklistedWords;
- const message = `Password ${isRequired ? 'must' : 'should'} not include common words: ${blacklistedWords.join(', ')}`;
- const validation = {
- name: 'blacklist',
- required: isRequired,
- };
-
- this.handleRuleCheckResult(false, validation, message, this.errors);
- }
-
- constructor(settings, componentInstance) {
- super(settings, componentInstance);
- this._entropy = 0; // Set initial value of entropy
- this.levels = [...(this.settings.levels || this.defaultSettings.levels)];
- this.levels.sort((a, b) => a.maxEntropy - b.maxEntropy); // Sort levels from the lowest one to the highest
- this.level = this.levels[0]; // Set currnt level to the lowest one
- this.maxEntropy = this.levels[this.levels.length - 1].maxEntropy; // Set maximal amount of security points based on the highest level
- }
-
- attach(element) {
- super.attach(element);
- const container = this.component.ce('div', { ref: 'passwordStrengthIndicator' });
-
- const inserted = this.insertContainer(element, container);
-
- if (!inserted) {
- this.component.append(container);
- }
-
- this._element = container;
- this.component.on('redraw', () => this.updateView());
- this.component.on('componentError', () => this.updateView());
- this.updateView();
- }
-
- insertContainer(element, container) {
- if (!element || !container) {
- return false;
- }
-
- const insert = this.settings.location?.insert;
- const selector = this.settings.location?.selector;
- let reference;
-
- if (selector) {
- reference = element.querySelector(selector);
- }
-
- if (reference) {
- const parent = reference.parentNode;
-
- switch (insert) {
- case 'after':
- if (parent) {
- parent.insertBefore(container, reference.nextSibling || null);
- return true;
- }
- return false;
- case 'before':
- if (parent) {
- parent.insertBefore(container, reference);
- return true;
- }
- return false;
- default:
- console.warn(`Unknown insert option: ${insert}`);
- return false;
- }
- }
- else {
- console.warn(`No elements found using selector: ${selector}`);
- return false;
- }
- }
-
- destroy() {
- super.destroy();
- }
-
- /**
- * Finds the level which one the passed entropy suits
- * @param {number} entropy - Points of password's security
- */
- getLevel(entropy = this.entropy) {
- const lowestLevel = this.levels[0];
- let prevMaxEntropy = lowestLevel.maxEntropy;
-
- if (entropy <= lowestLevel.maxEntropy) {
- return lowestLevel;
- }
-
- if (entropy >= this.maxEntropy) {
- return this.levels[this.levels.length - 1];
- }
-
- // Iterate through levels and find the one which the passed entropy belongs to
- for (let i = 1; i < this.levels.length; i++) {
- const level = this.levels[i];
-
- if (entropy > prevMaxEntropy && entropy <= level.maxEntropy) {
- return level;
- }
-
- prevMaxEntropy = level.maxEntropy;
- }
-
- return lowestLevel;
- }
-
- /**
- * Update the current view of the password's security indicator
- */
- updateView() {
- if (!this.element) {
- return;
- }
-
- const view = this.render();
- this.element.innerHTML = view;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/addons/index.js b/web-client/core/themes/italia/static/formio/css/src/addons/index.js
deleted file mode 100644
index 15558976..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/addons/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import PasswordStrengthAddon from './PasswordStrength/PasswordStrengthAddon';
-
-export const editForms = [
- PasswordStrengthAddon.info
-].map(({ components, name, defaultSettings }) => ({
- type: 'form',
- key: 'settings',
- display: 'form',
- input: true,
- components,
- defaultValue: {
- data: defaultSettings
- },
- customConditional({ row }) {
- return row.name.value === name;
- }
-}));
-
-export default {
- passwordStrength: PasswordStrengthAddon,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/builders/Builders.js b/web-client/core/themes/italia/static/formio/css/src/builders/Builders.js
deleted file mode 100644
index 0dcfe3ba..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/builders/Builders.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import _ from 'lodash';
-import pdf from '../PDFBuilder';
-import webform from '../WebformBuilder';
-import wizard from '../WizardBuilder';
-
-export default class Builders {
- static builders = {
- pdf,
- webform,
- wizard,
- };
-
- static addBuilder(name, builder) {
- Builders.builders[name] = builder;
- }
-
- static addBuilders(builders) {
- Builders.builders = _.merge(Builders.builders, builders);
- }
-
- static getBuilder(name) {
- return Builders.builders[name];
- }
-
- static getBuilders() {
- return Builders.builders;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/builders/index.js b/web-client/core/themes/italia/static/formio/css/src/builders/index.js
deleted file mode 100644
index ed43bacb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/builders/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Builders from './Builders';
-
-export default Builders;
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/Components.js b/web-client/core/themes/italia/static/formio/css/src/components/Components.js
deleted file mode 100644
index ff09c7bd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/Components.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import Component from './_classes/component/Component';
-import EditFormUtils from './_classes/component/editForm/utils';
-import BaseEditForm from './_classes/component/Component.form';
-import _ from 'lodash';
-export default class Components {
- static _editFormUtils = EditFormUtils
-
- static _baseEditForm = BaseEditForm;
-
- static set EditFormUtils(value) {
- Components._editFormUtils = value;
- }
-
- static get EditFormUtils() {
- return Components._editFormUtils;
- }
-
- static set baseEditForm(value) {
- Components._baseEditForm = value;
- }
-
- static get baseEditForm() {
- return Components._baseEditForm;
- }
-
- static recalculateComponents() {
- if (window && window.Formio && window.Formio.AllComponents) {
- Components.setComponents(window.Formio.AllComponents);
- }
- }
-
- static get components() {
- if (!Components._components) {
- Components._components = {};
- }
- return Components._components;
- }
-
- static setComponents(comps) {
- // Set the tableView method on BaseComponent.
- if (comps.base) {
- // Implement the tableView method.
- comps.base.tableView = function(value, options) {
- const comp = Components.create(options.component, options.options || {}, options.data || {}, true);
- return comp.getView(value);
- };
- }
- _.assign(Components.components, comps);
- }
-
- static addComponent(name, comp) {
- return Components.setComponent(name, comp);
- }
-
- static setComponent(name, comp) {
- Components.components[name] = comp;
- }
-
- static create(component, options, data) {
- let comp = null;
- if (component.type && Components.components.hasOwnProperty(component.type)) {
- comp = new Components.components[component.type](component, options, data);
- }
- else if (component.arrayTree) {
- // eslint-disable-next-line new-cap
- comp = new Components.components['datagrid'](component, options, data);
- }
- else if (component.tree) {
- // eslint-disable-next-line new-cap
- comp = new Components.components['nesteddata'](component, options, data);
- }
- else if (Array.isArray(component.components)) {
- // eslint-disable-next-line new-cap
- comp = new Components.components['nested'](component, options, data);
- }
- else if (options && options.server) {
- // eslint-disable-next-line new-cap
- comp = new Components.components['hidden'](component, options, data);
- }
- else {
- comp = new Component(component, options, data);
- }
- return comp;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.form.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.form.js
deleted file mode 100644
index 91809511..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.form.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import _ from 'lodash';
-
-import ComponentEditConditional from './editForm/Component.edit.conditional';
-import ComponentEditData from './editForm/Component.edit.data';
-import ComponentEditAPI from './editForm/Component.edit.api';
-import ComponentEditDisplay from './editForm/Component.edit.display';
-import ComponentEditLogic from './editForm/Component.edit.logic';
-import ComponentEditValidation from './editForm/Component.edit.validation';
-import ComponentEditLayout from './editForm/Component.edit.layout';
-import EditFormUtils from './editForm/utils';
-
-export default function(...extend) {
- const components = _.cloneDeep([
- {
- type: 'tabs',
- key: 'tabs',
- components: [
- {
- label: 'Display',
- key: 'display',
- weight: 0,
- components: ComponentEditDisplay
- },
- {
- label: 'Data',
- key: 'data',
- weight: 10,
- components: ComponentEditData
- },
- {
- label: 'Validation',
- key: 'validation',
- weight: 20,
- components: ComponentEditValidation
- },
- {
- label: 'API',
- key: 'api',
- weight: 30,
- components: ComponentEditAPI
- },
- {
- label: 'Conditional',
- key: 'conditional',
- weight: 40,
- components: ComponentEditConditional
- },
- {
- label: 'Logic',
- key: 'logic',
- weight: 50,
- components: ComponentEditLogic
- },
- {
- label: 'Layout',
- key: 'layout',
- weight: 60,
- components: ComponentEditLayout
- },
- ]
- }
- ]).concat(extend.map((items) => ({
- type: 'tabs',
- key: 'tabs',
- components: _.cloneDeep(items),
- })));
- return {
- components: _.unionWith(components, EditFormUtils.unifyComponents).concat({
- type: 'hidden',
- key: 'type'
- })
- };
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.js
deleted file mode 100644
index f4f18d05..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.js
+++ /dev/null
@@ -1,3673 +0,0 @@
-/* globals Quill, ClassicEditor, CKEDITOR */
-import { conformToMask } from '@formio/vanilla-text-mask';
-import NativePromise from 'native-promise-only';
-import tippy from 'tippy.js';
-import _ from 'lodash';
-import isMobile from 'ismobilejs';
-import { GlobalFormio as Formio } from '../../../Formio';
-import * as FormioUtils from '../../../utils/utils';
-import Validator from '../../../validator/Validator';
-import {
- fastCloneDeep, boolValue, getComponentPath, isInsideScopingComponent, currentTimezone
-} from '../../../utils/utils';
-import Element from '../../../Element';
-import ComponentModal from '../componentModal/ComponentModal';
-import Widgets from '../../../widgets';
-import Addons from '../../../addons';
-import { getFormioUploadAdapterPlugin } from '../../../providers/storage/uploadAdapter';
-import enTranslation from '../../../translations/en';
-
-const isIEBrowser = FormioUtils.getBrowserInfo().ie;
-
-let Templates = Formio.Templates;
-
-if (!Templates) {
- Templates = require('../../../templates/Templates').default;
-}
-
-/**
- * This is the Component class
- which all elements within the FormioForm derive from.
- */
-export default class Component extends Element {
- static schema(...sources) {
- return _.merge({
- /**
- * Determines if this component provides an input.
- */
- input: true,
-
- /**
- * The data key for this component (how the data is stored in the database).
- */
- key: '',
-
- /**
- * The input placeholder for this component.
- */
- placeholder: '',
-
- /**
- * The input prefix
- */
- prefix: '',
-
- /**
- * The custom CSS class to provide to this component.
- */
- customClass: '',
-
- /**
- * The input suffix.
- */
- suffix: '',
-
- /**
- * If this component should allow an array of values to be captured.
- */
- multiple: false,
-
- /**
- * The default value of this component.
- */
- defaultValue: null,
-
- /**
- * If the data of this component should be protected (no GET api requests can see the data)
- */
- protected: false,
-
- /**
- * Validate if the value of this component should be unique within the form.
- */
- unique: false,
-
- /**
- * If the value of this component should be persisted within the backend api database.
- */
- persistent: true,
-
- /**
- * Determines if the component should be within the form, but not visible.
- */
- hidden: false,
-
- /**
- * If the component should be cleared when hidden.
- */
- clearOnHide: true,
-
- /**
- * This will refresh this component options when this field changes.
- */
- refreshOn: '',
-
- /**
- * This will redraw the component when this field changes.
- */
- redrawOn: '',
-
- /**
- * If this component should be included as a column within a submission table.
- */
- tableView: false,
-
- /**
- * If this component should be rendering in modal.
- */
- modalEdit: false,
-
- /**
- * The input label provided to this component.
- */
- label: '',
- dataGridLabel: false,
- labelPosition: 'top',
- description: '',
- errorLabel: '',
- tooltip: '',
- hideLabel: false,
- tabindex: '',
- disabled: false,
- autofocus: false,
- dbIndex: false,
- customDefaultValue: '',
- calculateValue: '',
- calculateServer: false,
- widget: null,
-
- /**
- * Attributes that will be assigned to the input elements of this component.
- */
- attributes: {},
-
- /**
- * This will perform the validation on either "change" or "blur" of the input element.
- */
- validateOn: 'change',
-
- /**
- * The validation criteria for this component.
- */
- validate: {
- /**
- * If this component is required.
- */
- required: false,
-
- /**
- * Custom JavaScript validation.
- */
- custom: '',
-
- /**
- * If the custom validation should remain private (only the backend will see it and execute it).
- */
- customPrivate: false,
-
- /**
- * If this component should implement a strict date validation if the Calendar widget is implemented.
- */
- strictDateValidation: false,
- multiple: false,
- unique: false
- },
-
- /**
- * The simple conditional settings for a component.
- */
- conditional: {
- show: null,
- when: null,
- eq: ''
- },
- overlay: {
- style: '',
- left: '',
- top: '',
- width: '',
- height: '',
- },
- allowCalculateOverride: false,
- encrypted: false,
- showCharCount: false,
- showWordCount: false,
- properties: {},
- allowMultipleMasks: false,
- addons: [],
- }, ...sources);
- }
-
- /**
- * Return the validator as part of the component.
- *
- * @return {ValidationChecker}
- * @constructor
- */
- static get Validator() {
- return Validator;
- }
- /**
- * Return the simple condition settings as part of the component.
- *
- * @return {Object}
- *
- */
- static get conditionOperatorsSettings() {
- return {
- operators: ['isEqual', 'isNotEqual', 'isEmpty', 'isNotEmpty'],
- valueComponent() {
- return { type: 'textfield' };
- }
- };
- }
- /**
- * Return the array of possible types of component value absed on its schema.
- *
- * @param schema
- * @return {Array}
- *
- */
-
- static savedValueTypes(schema) {
- schema = schema || {};
-
- return FormioUtils.getComponentSavedTypes(schema) || [FormioUtils.componentValueTypes.any];
- }
- /**
- * Provides a table view for this component. Override if you wish to do something different than using getView
- * method of your instance.
- *
- * @param value
- * @param options
- */
- /* eslint-disable no-unused-vars */
- static tableView(value, options) {}
- /* eslint-enable no-unused-vars */
-
- /**
- * Initialize a new Component.
- *
- * @param {Object} component - The component JSON you wish to initialize.
- * @param {Object} options - The options for this component.
- * @param {Object} data - The global data submission object this component will belong.
- */
- /* eslint-disable max-statements */
- constructor(component, options, data) {
- super(Object.assign({
- renderMode: 'form',
- attachMode: 'full',
- noDefaults: false
- }, options || {}));
-
- // Restore the component id.
- if (component && component.id) {
- this.id = component.id;
- }
-
- /**
- * Determines if this component has a condition assigned to it.
- * @type {null}
- * @private
- */
- this._hasCondition = null;
-
- /**
- * References to dom elements
- */
- this.refs = {};
-
- // Allow global override for any component JSON.
- if (
- component &&
- this.options.components &&
- this.options.components[component.type]
- ) {
- _.merge(component, this.options.components[component.type]);
- }
-
- /**
- * Set the validator instance.
- */
- this.validator = Validator;
-
- /**
- * The data path to this specific component instance.
- *
- * @type {string}
- */
- this.path = '';
-
- /**
- * The Form.io component JSON schema.
- * @type {*}
- */
- this.component = this.mergeSchema(component || {});
-
- // Add the id to the component.
- this.component.id = this.id;
-
- this.afterComponentAssign();
-
- // Save off the original component to be used in logic.
- this.originalComponent = fastCloneDeep(this.component);
-
- /**
- * If the component has been attached
- */
- this.attached = false;
-
- /**
- * If the component has been rendered
- */
- this.rendered = false;
-
- /**
- * The data object in which this component resides.
- * @type {*}
- */
- this._data = data || {};
-
- /**
- * The existing error that this component has.
- * @type {string}
- */
- this.error = '';
-
- /**
- * Tool tip text after processing
- * @type {string}
- */
- this.tooltip = '';
-
- /**
- * The row path of this component.
- * @type {number}
- */
- this.row = this.options.row;
-
- /**
- * Determines if this component is disabled, or not.
- *
- * @type {boolean}
- */
- this._disabled = boolValue(this.component.disabled) ? this.component.disabled : false;
-
- /**
- * Points to the root component, usually the FormComponent.
- *
- * @type {Component}
- */
- this.root = this.options.root;
- this.localRoot = this.options.localRoot;
-
- /**
- * If this input has been input and provided value.
- *
- * @type {boolean}
- */
- this.pristine = true;
-
- /**
- * Points to the parent component.
- *
- * @type {Component}
- */
- this.parent = this.options.parent;
-
- this.options.name = this.options.name || 'data';
-
- /**
- * The validators that are assigned to this component.
- * @type {[string]}
- */
- this.validators = ['required', 'minLength', 'maxLength', 'minWords', 'maxWords', 'custom', 'pattern', 'json', 'mask'];
-
- this._path = '';
- // Nested forms don't have parents so we need to pass their path in.
- this._parentPath = this.options.parentPath || '';
-
- // Needs for Nextgen Rules Engine
- this.resetCaches();
-
- /**
- * Determines if this component is visible, or not.
- */
- this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;
- this._visible = this._parentVisible && this.conditionallyVisible(null, data);
- this._parentDisabled = false;
-
- /**
- * Used to trigger a new change in this component.
- * @type {function} - Call to trigger a change in this component.
- */
- let changes = [];
- let lastChanged = null;
- let triggerArgs = [];
- const _triggerChange = _.debounce((...args) => {
- if (this.root) {
- this.root.changing = false;
- }
- triggerArgs = [];
- if (!args[1] && lastChanged) {
- // Set the changed component if one isn't provided.
- args[1] = lastChanged;
- }
- if (_.isEmpty(args[0]) && lastChanged) {
- // Set the flags if it is empty and lastChanged exists.
- args[0] = lastChanged.flags;
- }
- lastChanged = null;
- args[3] = changes;
- const retVal = this.onChange(...args);
- changes = [];
- return retVal;
- }, 100);
- this.triggerChange = (...args) => {
- if (args[1]) {
- // Make sure that during the debounce that we always track lastChanged component, even if they
- // don't provide one later.
- lastChanged = args[1];
- changes.push(lastChanged);
- }
- if (this.root) {
- this.root.changing = true;
- }
- if (args.length) {
- triggerArgs = args;
- }
- return _triggerChange(...triggerArgs);
- };
-
- /**
- * Used to trigger a redraw event within this component.
- *
- * @type {Function}
- */
- this.triggerRedraw = _.debounce(this.redraw.bind(this), 100);
-
- /**
- * list of attached tooltips
- * @type {Array}
- */
- this.tooltips = [];
-
- /**
- * List of attached addons
- * @type {Array}
- */
- this.addons = [];
-
- // To force this component to be invalid.
- this.invalid = false;
-
- if (this.component) {
- this.type = this.component.type;
- if (this.allowData && this.key) {
- this.options.name += `[${this.key}]`;
- // If component is visible or not set to clear on hide, set the default value.
- if (this.visible || !this.component.clearOnHide) {
- if (!this.hasValue()) {
- if (this.shouldAddDefaultValue) {
- this.dataValue = this.defaultValue;
- }
- }
- else {
- // Ensure the dataValue is set.
- /* eslint-disable no-self-assign */
- this.dataValue = this.dataValue;
- /* eslint-enable no-self-assign */
- }
- }
- }
-
- /**
- * The element information for creating the input element.
- * @type {*}
- */
- this.info = this.elementInfo();
- }
-
- // Allow anyone to hook into the component creation.
- this.hook('component');
-
- if (!this.options.skipInit) {
- this.init();
- }
- }
- /* eslint-enable max-statements */
-
- get data() {
- return this._data;
- }
-
- set data(value) {
- this._data = value;
- }
-
- mergeSchema(component = {}) {
- return _.defaultsDeep(component, this.defaultSchema);
- }
-
- // Allow componets to notify when ready.
- get ready() {
- return NativePromise.resolve(this);
- }
-
- get isPDFReadOnlyMode() {
- return this.parent &&
- this.parent.form &&
- (this.parent.form.display === 'pdf') &&
- this.options.readOnly;
- }
-
- get labelInfo() {
- const label = {};
- label.hidden = this.labelIsHidden();
-
- label.className = '';
- label.labelPosition = this.component.labelPosition;
- label.tooltipClass = `${this.iconClass('question-sign')} text-muted`;
-
- const isPDFReadOnlyMode = this.isPDFReadOnlyMode;
-
- if (this.hasInput && this.component.validate && boolValue(this.component.validate.required) && !isPDFReadOnlyMode) {
- label.className += ' field-required';
- }
- if (label.hidden) {
- label.className += ' control-label--hidden';
- }
- if (this.info.attr.id) {
- label.for = this.info.attr.id;
- }
- return label;
- }
-
- init() {
- this.disabled = this.shouldDisabled;
- this._visible = this.conditionallyVisible(null, null);
- if (this.component.addons?.length) {
- this.component.addons.forEach((addon) => this.createAddon(addon));
- }
- }
-
- afterComponentAssign() {
- //implement in extended classes
- }
-
- createAddon(addonConfiguration) {
- const name = addonConfiguration.name;
- if (!name) {
- return;
- }
-
- const settings = addonConfiguration.settings?.data || {};
- const Addon = Addons[name.value];
-
- let addon = null;
-
- if (Addon) {
- const supportedComponents = Addon.info.supportedComponents;
- const supportsThisComponentType = !supportedComponents?.length ||
- supportedComponents.indexOf(this.component.type) !== -1;
- if (supportsThisComponentType) {
- addon = new Addon(settings, this);
- this.addons.push(addon);
- }
- else {
- console.warn(`Addon ${name.label} does not support component of type ${this.component.type}.`);
- }
- }
-
- return addon;
- }
-
- destroy() {
- super.destroy();
- this.detach();
- this.addons.forEach((addon) => addon.destroy());
- }
-
- get shouldDisabled() {
- return this.options.readOnly || this.component.disabled || (this.options.hasOwnProperty('disabled') && this.options.disabled[this.key]);
- }
-
- get isInputComponent() {
- return !this.component.hasOwnProperty('input') || this.component.input;
- }
-
- get allowData() {
- return this.hasInput;
- }
-
- get hasInput() {
- return this.isInputComponent || (this.refs.input && this.refs.input.length);
- }
-
- get defaultSchema() {
- return Component.schema();
- }
-
- get key() {
- return _.get(this.component, 'key', '');
- }
-
- set parentVisible(value) {
- this._parentVisible = value;
- }
-
- get parentVisible() {
- return this._parentVisible;
- }
-
- set parentDisabled(value) {
- this._parentDisabled = value;
- }
-
- get parentDisabled() {
- return this._parentDisabled;
- }
-
- shouldForceVisibility(component, visibility) {
- if (!this.options[visibility]) {
- return false;
- }
- if (!component) {
- component = this.component;
- }
- if (_.isArray(this.options[visibility])) {
- return this.options[visibility].includes(component.key);
- }
- return this.options[visibility][component.key];
- }
-
- shouldForceHide(component) {
- return this.shouldForceVisibility(component, 'hide');
- }
-
- shouldForceShow(component) {
- return this.shouldForceVisibility(component, 'show');
- }
-
- /**
- *
- * @param value {boolean}
- */
- set visible(value) {
- if (this._visible !== value) {
- // Skip if this component is set to visible and is supposed to be hidden.
- if (value && this.shouldForceHide()) {
- return;
- }
- // Skip if this component is set to hidden and is supposed to be shown.
- if (!value && this.shouldForceShow()) {
- return;
- }
- this._visible = value;
- this.clearOnHide();
- this.redraw();
- }
- }
-
- /**
- *
- * @returns {boolean}
- */
- get visible() {
- // Show only if visibility changes or if we are in builder mode or if hidden fields should be shown.
- if (this.builderMode || this.previewMode || this.options.showHiddenFields) {
- return true;
- }
- if (this.shouldForceHide()) {
- return false;
- }
- if (this.shouldForceShow()) {
- return true;
- }
- return this._visible && this._parentVisible;
- }
-
- get currentForm() {
- return this._currentForm;
- }
-
- set currentForm(instance) {
- this._currentForm = instance;
- }
-
- get fullMode() {
- return this.options.attachMode === 'full';
- }
-
- get builderMode() {
- return this.options.attachMode === 'builder';
- }
-
- get calculatedPath() {
- console.error('component.calculatedPath was deprecated, use component.path instead.');
- return this.path;
- }
-
- get labelPosition() {
- return this.component.labelPosition;
- }
-
- get labelWidth() {
- const width = this.component.labelWidth;
- return width >= 0 ? width : 30;
- }
-
- get labelMargin() {
- const margin = this.component.labelMargin;
- return margin >= 0 ? margin : 3;
- }
-
- get isAdvancedLabel() {
- return [
- 'left-left',
- 'left-right',
- 'right-left',
- 'right-right'
- ].includes(this.labelPosition);
- }
-
- get labelPositions() {
- return this.labelPosition.split('-');
- }
-
- get skipInEmail() {
- return false;
- }
-
- rightDirection(direction) {
- if (this.options.condensedMode) {
- return false;
- }
- return direction === 'right';
- }
-
- getLabelInfo(isCondensed = false) {
- const isRightPosition = this.rightDirection(this.labelPositions[0]);
- const isLeftPosition = this.labelPositions[0] === 'left' || isCondensed;
- const isRightAlign = this.rightDirection(this.labelPositions[1]);
-
- let contentMargin = '';
- if (this.component.hideLabel) {
- const margin = isCondensed ? 0 : this.labelWidth + this.labelMargin;
- contentMargin = isRightPosition ? `margin-right: ${margin}%` : '';
- contentMargin = isLeftPosition ? `margin-left: ${margin}%` : '';
- }
-
- const labelStyles = `
- flex: ${this.labelWidth};
- ${isRightPosition ? 'margin-left' : 'margin-right'}: ${this.labelMargin}%;
- `;
- const contentStyles = `
- flex: ${100 - this.labelWidth - this.labelMargin};
- ${contentMargin};
- ${this.component.hideLabel ? `max-width: ${100 - this.labelWidth - this.labelMargin}` : ''};
- `;
-
- return {
- isRightPosition,
- isRightAlign,
- labelStyles,
- contentStyles
- };
- }
-
- /**
- * Returns only the schema that is different from the default.
- *
- * @param schema
- * @param defaultSchema
- */
- getModifiedSchema(schema, defaultSchema, recursion) {
- const modified = {};
- if (!defaultSchema) {
- return schema;
- }
- _.each(schema, (val, key) => {
- if (!_.isArray(val) && _.isObject(val) && defaultSchema.hasOwnProperty(key)) {
- const subModified = this.getModifiedSchema(val, defaultSchema[key], true);
- if (!_.isEmpty(subModified)) {
- modified[key] = subModified;
- }
- }
- else if (_.isArray(val)) {
- if (val.length !== 0 && !_.isEqual(val, defaultSchema[key])) {
- modified[key] = val;
- }
- }
- else if (
- (!recursion && (key === 'type')) ||
- (!recursion && (key === 'key')) ||
- (!recursion && (key === 'label')) ||
- (!recursion && (key === 'input')) ||
- (!recursion && (key === 'tableView')) ||
- (val !== '' && !defaultSchema.hasOwnProperty(key)) ||
- (val !== '' && val !== defaultSchema[key]) ||
- (defaultSchema[key] && val !== defaultSchema[key])
- ) {
- modified[key] = val;
- }
- });
- return modified;
- }
-
- /**
- * Returns the JSON schema for this component.
- */
- get schema() {
- return fastCloneDeep(this.getModifiedSchema(_.omit(this.component, 'id'), this.defaultSchema));
- }
-
- /**
- * Returns true if component is inside DataGrid
- */
- get isInDataGrid() {
- return this.inDataGrid;
- }
-
- /**
- * Translate a text using the i18n system.
- *
- * @param {string} text - The i18n identifier.
- * @param {Object} params - The i18n parameters to use for translation.
- */
- t(text, params = {}, ...args) {
- if (!text) {
- return '';
- }
- // Use _userInput: true to ignore translations from defaults
- if (text in enTranslation && params._userInput) {
- return text;
- }
- params.data = this.rootValue;
- params.row = this.data;
- params.component = this.component;
- return super.t(text, params, ...args);
- }
-
- labelIsHidden() {
- return !this.component.label ||
- ((!this.isInDataGrid && this.component.hideLabel) ||
- (this.isInDataGrid && !this.component.dataGridLabel) ||
- this.options.inputsOnly) && !this.builderMode;
- }
-
- transform(type, value) {
- const frameworkTemplates = this.options.template ? Templates.templates[this.options.template] : Templates.current;
- return frameworkTemplates.hasOwnProperty('transform')
- ? frameworkTemplates.transform(type, value)
- : (type, value) => value;
- }
-
- getTemplate(names, modes) {
- modes = Array.isArray(modes) ? modes : [modes];
- names = Array.isArray(names) ? names : [names];
- if (!modes.includes('form')) {
- modes.push('form');
- }
-
- let result = null;
-
- if (this.options.templates) {
- result = this.checkTemplate(this.options.templates, names, modes);
- if (result) {
- return result;
- }
- }
-
- const frameworkTemplates = this.options.template ? Templates.templates[this.options.template] : Templates.current;
- result = this.checkTemplate(frameworkTemplates, names, modes);
- if (result) {
- return result;
- }
-
- // Default back to bootstrap if not defined.
- const name = names[names.length - 1];
- const templatesByName = Templates.defaultTemplates[name];
-
- if (!templatesByName) {
- return `Unknown template: ${name}`;
- }
-
- const templateByMode = this.checkTemplateMode(templatesByName, modes);
- if (templateByMode) {
- return templateByMode;
- }
-
- return templatesByName.form;
- }
-
- checkTemplate(templates, names, modes) {
- for (const name of names) {
- const templatesByName = templates[name];
-
- if (templatesByName) {
- const templateByMode = this.checkTemplateMode(templatesByName, modes);
- if (templateByMode) {
- return templateByMode;
- }
- }
- }
-
- return null;
- }
-
- checkTemplateMode(templatesByName, modes) {
- for (const mode of modes) {
- const templateByMode = templatesByName[mode];
-
- if (templateByMode) {
- return templateByMode;
- }
- }
-
- return null;
- }
-
- getFormattedAttribute(attr) {
- return attr ? this.t(attr, { _userInput: true }).replace(/"/g, '"') : '';
- }
-
- getFormattedTooltip(tooltipValue) {
- const tooltip = this.interpolate(tooltipValue || '').replace(/(?:\r\n|\r|\n)/g, ' ');
- return this.getFormattedAttribute(tooltip);
- }
-
- isHtmlRenderMode() {
- return this.options.renderMode === 'html';
- }
-
- renderTemplate(name, data = {}, modeOption) {
- // Need to make this fall back to form if renderMode is not found similar to how we search templates.
- const mode = modeOption || this.options.renderMode || 'form';
- data.component = this.component;
- data.self = this;
- data.options = this.options;
- data.readOnly = this.options.readOnly;
- data.iconClass = this.iconClass.bind(this);
- data.size = this.size.bind(this);
- data.t = this.t.bind(this);
- data.transform = this.transform.bind(this);
- data.id = data.id || this.id;
- data.key = data.key || this.key;
- data.value = data.value || this.dataValue;
- data.disabled = this.disabled;
- data.builder = this.builderMode;
- data.render = (...args) => {
- console.warn(`Form.io 'render' template function is deprecated.
- If you need to render template (template A) inside of another template (template B),
- pass pre-compiled template A (use this.renderTemplate('template_A_name') as template context variable for template B`);
- return this.renderTemplate(...args);
- };
- data.label = data.labelInfo || this.labelInfo;
- data.tooltip = this.getFormattedTooltip(this.component.tooltip);
-
- // Allow more specific template names
- const names = [
- `${name}-${this.component.type}-${this.key}`,
- `${name}-${this.component.type}`,
- `${name}-${this.key}`,
- `${name}`,
- ];
-
- // Allow template alters.
- return this.hook(
- `render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`,
- this.interpolate(this.getTemplate(names, mode), data),
- data,
- mode
- );
- }
-
- /**
- * Sanitize an html string.
- *
- * @param string
- * @returns {*}
- */
- sanitize(dirty, forceSanitize, options) {
- if (!this.shouldSanitizeValue && !forceSanitize) {
- return dirty;
- }
- return FormioUtils.sanitize(
- dirty,
- {
- sanitizeConfig: _.merge(this.options?.sanitizeConfig || {}, options || {}),
- });
- }
-
- /**
- * Render a template string into html.
- *
- * @param template
- * @param data
- * @param actions
- *
- * @return {HTMLElement|String} - The created element or an empty string if template is not specified.
- */
- renderString(template, data) {
- if (!template) {
- return '';
- }
- // Interpolate the template and populate
- return this.interpolate(template, data);
- }
-
- performInputMapping(input) {
- return input;
- }
-
- get widget() {
- const settings = this.component.widget;
-
- if (settings && this.root?.shadowRoot) {
- settings.shadowRoot = this.root.shadowRoot;
- }
-
- const widget = settings && Widgets[settings.type] ? new Widgets[settings.type](settings, this.component, this): null;
- return widget;
- }
-
- getBrowserLanguage() {
- const nav = window.navigator;
- const browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'];
- let language;
-
- // support for HTML 5.1 "navigator.languages"
- if (Array.isArray(nav.languages)) {
- for (let i = 0; i < nav.languages.length; i++) {
- language = nav.languages[i];
- if (language && language.length) {
- return language.split(';')[0];
- }
- }
- }
-
- // support for other well known properties in browsers
- for (let i = 0; i < browserLanguagePropertyKeys.length; i++) {
- language = nav[browserLanguagePropertyKeys[i]];
- if (language && language.length) {
- return language.split(';')[0];
- }
- }
-
- return null;
- }
-
- /**
- * Called before a next and previous page is triggered allowing the components
- * to perform special functions.
- *
- * @return {*}
- */
- beforePage() {
- return NativePromise.resolve(true);
- }
-
- beforeNext() {
- return this.beforePage(true);
- }
-
- /**
- * Called before a submission is triggered allowing the components
- * to perform special async functions.
- *
- * @return {*}
- */
- beforeSubmit() {
- return NativePromise.resolve(true);
- }
-
- /**
- * Return the submission timezone.
- *
- * @return {*}
- */
- get submissionTimezone() {
- this.options.submissionTimezone = this.options.submissionTimezone || _.get(this.root, 'options.submissionTimezone');
- return this.options.submissionTimezone;
- }
-
- get timezone() {
- return this.getTimezone(this.component);
- }
-
- getTimezone(settings) {
- if (settings.timezone) {
- return settings.timezone;
- }
- if (settings.displayInTimezone === 'utc') {
- return 'UTC';
- }
- const submissionTimezone = this.submissionTimezone;
- if (
- submissionTimezone &&
- (
- (settings.displayInTimezone === 'submission') ||
- ((this.options.pdf || this.options.server) && (settings.displayInTimezone === 'viewer'))
- )
- ) {
- return submissionTimezone;
- }
-
- // Return current timezone if none are provided.
- return currentTimezone();
- }
-
- loadRefs(element, refs) {
- for (const ref in refs) {
- const refType = refs[ref];
- const isString = typeof refType === 'string';
-
- const selector = isString && refType.includes('scope') ? `:scope > [ref="${ref}"]` : `[ref="${ref}"]`;
-
- if (isString && refType.startsWith('single')) {
- this.refs[ref] = element.querySelector(selector);
- }
- else {
- this.refs[ref] = element.querySelectorAll(selector);
- }
- }
- }
-
- setOpenModalElement(template) {
- this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate());
- }
-
- getModalPreviewTemplate() {
- const dataValue = this.component.type === 'password' ? this.dataValue.replace(/./g, '•') : this.dataValue;
- const message = this.error ? {
- level: 'error',
- message: this.error.message,
- } : '';
-
- let modalLabel;
-
- if (this.hasInput && this.component.validate?.required && !this.isPDFReadOnlyMode) {
- modalLabel = { className: 'field-required' };
- }
-
- return this.renderTemplate('modalPreview', {
- previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('Click to set value'),
- messages: message && this.renderTemplate('message', message),
- labelInfo: modalLabel,
- });
- }
-
- build(element) {
- element = element || this.element;
- this.empty(element);
- this.setContent(element, this.render());
- return this.attach(element);
- }
-
- get hasModalSaveButton() {
- return true;
- }
-
- render(children = `Unknown component: ${this.component.type}`, topLevel = false) {
- const isVisible = this.visible;
- this.rendered = true;
-
- if (!this.builderMode && !this.previewMode && this.component.modalEdit) {
- return ComponentModal.render(this, {
- visible: isVisible,
- showSaveButton: this.hasModalSaveButton,
- id: this.id,
- classes: this.className,
- styles: this.customStyle,
- children
- }, topLevel);
- }
- else {
- return this.renderTemplate('component', {
- visible: isVisible,
- id: this.id,
- classes: this.className,
- styles: this.customStyle,
- children
- }, topLevel);
- }
- }
-
- attachTooltips(toolTipsRefs) {
- toolTipsRefs?.forEach((tooltip, index) => {
- if (tooltip) {
- const tooltipAttribute = tooltip.getAttribute('data-tooltip');
- const tooltipDataTitle = tooltip.getAttribute('data-title');
- const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)
- .replace(/(?:\r\n|\r|\n)/g, ' ');
-
- this.tooltips[index] = tippy(tooltip, {
- allowHTML: true,
- trigger: 'mouseenter click focus',
- placement: 'right',
- zIndex: 10000,
- interactive: true,
- content: this.t(this.sanitize(tooltipText), { _userInput: true }),
- });
- }
- });
- }
-
- createComponentModal(element, modalShouldBeOpened, currentValue) {
- return new ComponentModal(this, element, modalShouldBeOpened, currentValue);
- }
-
- attach(element) {
- if (!this.builderMode && !this.previewMode && this.component.modalEdit) {
- const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;
- const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;
- const openModalTemplate = this.componentModal && modalShouldBeOpened
- ? this.componentModal.openModalTemplate
- : null;
- this.componentModal = this.createComponentModal(element, modalShouldBeOpened, currentValue);
- this.setOpenModalElement(openModalTemplate);
- }
-
- this.attached = true;
- this.element = element;
- element.component = this;
-
- // If this already has an id, get it from the dom. If SSR, it could be different from the initiated id.
- if (this.element.id) {
- this.id = this.element.id;
- this.component.id = this.id;
- }
-
- this.loadRefs(element, {
- messageContainer: 'single',
- tooltip: 'multiple'
- });
-
- this.attachTooltips(this.refs.tooltip);
-
- // Attach logic.
- this.attachLogic();
- this.autofocus();
-
- // Allow global attach.
- this.hook('attachComponent', element, this);
- // Allow attach per component type.
- const type = this.component.type;
- if (type) {
- this.hook(`attach${type.charAt(0).toUpperCase() + type.substring(1, type.length)}`, element, this);
- }
-
- this.restoreFocus();
-
- this.addons.forEach((addon) => addon.attach(element));
-
- return NativePromise.resolve();
- }
-
- restoreFocus() {
- const isFocused = this.root?.focusedComponent?.path === this.path;
- if (isFocused) {
- this.loadRefs(this.element, { input: 'multiple' });
- this.focus(this.root.currentSelection?.index);
- this.restoreCaretPosition();
- }
- }
-
- addShortcut(element, shortcut) {
- // Avoid infinite recursion.
- if (!element || !this.root || (this.root === this)) {
- return;
- }
-
- if (!shortcut) {
- shortcut = this.component.shortcut;
- }
-
- this.root.addShortcut(element, shortcut);
- }
-
- removeShortcut(element, shortcut) {
- // Avoid infinite recursion.
- if (!element || (this.root === this)) {
- return;
- }
-
- if (!shortcut) {
- shortcut = this.component.shortcut;
- }
-
- this.root.removeShortcut(element, shortcut);
- }
-
- /**
- * Remove all event handlers.
- */
- detach() {
- this.refs = {};
- this.removeEventListeners();
- this.detachLogic();
- if (this.tooltip) {
- this.tooltip.destroy();
- }
- }
-
- checkRefresh(refreshData, changed, flags) {
- const changePath = _.get(changed, 'instance.path', false);
- // Don't let components change themselves.
- if (changePath && this.path === changePath) {
- return;
- }
- if (refreshData === 'data') {
- this.refresh(this.data, changed, flags);
- }
- else if (
- (changePath && getComponentPath(changed.instance) === refreshData) && changed && changed.instance &&
- // Make sure the changed component is not in a different "context". Solves issues where refreshOn being set
- // in fields inside EditGrids could alter their state from other rows (which is bad).
- this.inContext(changed.instance)
- ) {
- this.refresh(changed.value, changed, flags);
- }
- }
-
- checkRefreshOn(changes, flags = {}) {
- changes = changes || [];
- if (flags.noRefresh) {
- return;
- }
- if (!changes.length && flags.changed) {
- changes = [flags.changed];
- }
- const refreshOn = flags.fromBlur ? this.component.refreshOnBlur : this.component.refreshOn || this.component.redrawOn;
- // If they wish to refresh on a value, then add that here.
- if (refreshOn) {
- if (Array.isArray(refreshOn)) {
- refreshOn.forEach(refreshData => changes.forEach(changed => this.checkRefresh(refreshData, changed, flags)));
- }
- else {
- changes.forEach(changed => this.checkRefresh(refreshOn, changed, flags));
- }
- }
- }
-
- /**
- * Refreshes the component with a new value.
- *
- * @param value
- */
- refresh(value) {
- if (this.hasOwnProperty('refreshOnValue')) {
- this.refreshOnChanged = !_.isEqual(value, this.refreshOnValue);
- }
- else {
- this.refreshOnChanged = true;
- }
- this.refreshOnValue = fastCloneDeep(value);
- if (this.refreshOnChanged) {
- if (this.component.clearOnRefresh) {
- this.setValue(null);
- }
- this.triggerRedraw();
- }
- }
-
- /**
- * Checks to see if a separate component is in the "context" of this component. This is determined by first checking
- * if they share the same "data" object. It will then walk up the parent tree and compare its parents data objects
- * with the components data and returns true if they are in the same context.
- *
- * Different rows of the same EditGrid, for example, are in different contexts.
- *
- * @param component
- */
- inContext(component) {
- if (component.data === this.data) {
- return true;
- }
- let parent = this.parent;
- while (parent) {
- if (parent.data === component.data) {
- return true;
- }
- parent = parent.parent;
- }
-
- return false;
- }
-
- get viewOnly() {
- return this.options.readOnly && this.options.viewAsHtml;
- }
-
- createViewOnlyElement() {
- this.element = this.ce('dl', {
- id: this.id
- });
-
- if (this.element) {
- // Ensure you can get the component info from the element.
- this.element.component = this;
- }
-
- return this.element;
- }
-
- get defaultViewOnlyValue() {
- return '-';
- }
-
- /**
- * Uses the widget to determine the output string.
- *
- * @param value
- * @return {*}
- */
- getWidgetValueAsString(value, options) {
- const noInputWidget = !this.refs.input || !this.refs.input[0] || !this.refs.input[0].widget;
- if (!value || noInputWidget) {
- if (!this.widget || !value) {
- return value;
- }
- else {
- return this.widget.getValueAsString(value);
- }
- }
- if (Array.isArray(value)) {
- const values = [];
- value.forEach((val, index) => {
- const widget = this.refs.input[index] && this.refs.input[index].widget;
- if (widget) {
- values.push(widget.getValueAsString(val, options));
- }
- });
- return values;
- }
-
- const widget = this.refs.input[0].widget;
- return widget.getValueAsString(value, options);
- }
-
- getValueAsString(value, options) {
- if (!value) {
- return '';
- }
- value = this.getWidgetValueAsString(value, options);
- if (Array.isArray(value)) {
- return value.join(', ');
- }
- if (_.isPlainObject(value)) {
- return JSON.stringify(value);
- }
- if (value === null || value === undefined) {
- return '';
- }
- const stringValue = value.toString();
- return this.sanitize(stringValue);
- }
-
- getView(value, options) {
- if (this.component.protected) {
- return '--- PROTECTED ---';
- }
- return this.getValueAsString(value, options);
- }
-
- updateItems(...args) {
- this.restoreValue();
- this.onChange(...args);
- }
-
- /**
- * @param {*} data
- * @param {boolean} [forceUseValue=false] - if true, return 'value' property of the data
- * @return {*}
- */
- itemValue(data, forceUseValue = false) {
- if (_.isObject(data) && !_.isArray(data)) {
- if (this.valueProperty) {
- return _.get(data, this.valueProperty);
- }
-
- if (forceUseValue) {
- return data.value;
- }
- }
-
- return data;
- }
-
- itemValueForHTMLMode(value) {
- if (Array.isArray(value)) {
- const values = value.map(item => Array.isArray(item) ? this.itemValueForHTMLMode(item) : this.itemValue(item));
-
- return values.join(', ');
- }
-
- return this.itemValue(value);
- }
-
- createModal(element, attr, confirm) {
- const dialog = this.ce('div', attr || {});
- this.setContent(dialog, this.renderTemplate('dialog'));
-
- // Add refs to dialog, not "this".
- dialog.refs = {};
- this.loadRefs.call(dialog, dialog, {
- dialogOverlay: 'single',
- dialogContents: 'single',
- dialogClose: 'single',
- });
-
- dialog.refs.dialogContents.appendChild(element);
- document.body.appendChild(dialog);
- document.body.classList.add('modal-open');
-
- dialog.close = () => {
- document.body.classList.remove('modal-open');
- dialog.dispatchEvent(new CustomEvent('close'));
- };
- this.addEventListener(dialog, 'close', () => this.removeChildFrom(dialog, document.body));
-
- const close = (event) => {
- event.preventDefault();
- dialog.close();
- };
-
- const handleCloseClick = (e) => {
- if (confirm) {
- confirm().then(() => close(e))
- .catch(() => {});
- }
- else {
- close(e);
- }
- };
-
- this.addEventListener(dialog.refs.dialogOverlay, 'click', handleCloseClick);
- this.addEventListener(dialog.refs.dialogClose, 'click', handleCloseClick);
-
- return dialog;
- }
-
- get optimizeRedraw() {
- if (this.options.optimizeRedraw && this.element && !this.visible) {
- this.addClass(this.element, 'formio-removed');
- return true;
- }
- return false;
- }
-
- /**
- * Retrieves the CSS class name of this component.
- * @returns {string} - The class name of this component.
- */
- get className() {
- 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') {
- className += `formio-component-${this.key} `;
- }
- if (this.component.multiple) {
- className += 'formio-component-multiple ';
- }
- if (this.component.customClass) {
- className += this.component.customClass;
- }
- if (this.hasInput && this.component.validate && boolValue(this.component.validate.required)) {
- className += ' required';
- }
- if (this.labelIsHidden()) {
- className += ' formio-component-label-hidden';
- }
- if (!this.visible) {
- className += ' formio-hidden';
- }
- return className;
- }
-
- /**
- * Build the custom style from the layout values
- * @return {string} - The custom style
- */
- get customStyle() {
- let customCSS = '';
- _.each(this.component.style, (value, key) => {
- if (value !== '') {
- customCSS += `${key}:${value};`;
- }
- });
- return customCSS;
- }
-
- static get serverConditionSettings() {
- return Component.conditionOperatorsSettings;
- }
-
- get isMobile() {
- return isMobile();
- }
-
- /**
- * Returns the outside wrapping element of this component.
- * @returns {HTMLElement}
- */
- getElement() {
- return this.element;
- }
-
- /**
- * Create an evaluation context for all script executions and interpolations.
- *
- * @param additional
- * @return {*}
- */
- evalContext(additional) {
- return super.evalContext(Object.assign({
- component: this.component,
- row: this.data,
- rowIndex: this.rowIndex,
- data: this.rootValue,
- iconClass: this.iconClass.bind(this),
- // Bind the translate function to the data context of any interpolated string.
- // It is useful to translate strings in different scenarions (eg: custom edit grid templates, custom error messages etc.)
- // and desirable to be publicly available rather than calling the internal {instance.t} function in the template string.
- t: this.t.bind(this),
- submission: (this.root ? this.root._submission : {
- data: this.rootValue
- }),
- form: this.root ? this.root._form : {},
- options: this.options,
- }, additional));
- }
-
- /**
- * Sets the pristine flag for this component.
- *
- * @param pristine {boolean} - TRUE to make pristine, FALSE not pristine.
- */
- setPristine(pristine) {
- this.pristine = pristine;
- }
-
- get isPristine() {
- return this.pristine;
- }
-
- setDirty(dirty) {
- this.dirty = dirty;
- }
-
- get isDirty() {
- return this.dirty;
- }
-
- /**
- * Removes a value out of the data array and rebuild the rows.
- * @param {number} index - The index of the data element to remove.
- */
- removeValue(index) {
- this.splice(index);
- this.redraw();
- this.restoreValue();
- this.triggerRootChange();
- }
-
- iconClass(name, spinning) {
- const iconset = this.options.iconset || Templates.current.defaultIconset || 'fa';
- return Templates.current.hasOwnProperty('iconClass')
- ? Templates.current.iconClass(iconset, name, spinning)
- : this.options.iconset === 'fa' ? Templates.defaultTemplates.iconClass(iconset, name, spinning) : name;
- }
-
- size(size) {
- return Templates.current.hasOwnProperty('size')
- ? Templates.current.size(size)
- : size;
- }
-
- /**
- * The readible name for this component.
- * @returns {string} - The name of the component.
- */
- get name() {
- return this.t(this.component.label || this.component.placeholder || this.key, { _userInput: true });
- }
-
- /**
- * Returns the error label for this component.
- * @return {*}
- */
- get errorLabel() {
- return this.t(this.component.errorLabel
- || this.component.label
- || this.component.placeholder
- || this.key);
- }
-
- /**
- * Get the error message provided a certain type of error.
- * @param type
- * @return {*}
- */
- errorMessage(type) {
- return (this.component.errors && this.component.errors[type]) ? this.component.errors[type] : type;
- }
-
- setContent(element, content, forceSanitize, sanitizeOptions) {
- if (element instanceof HTMLElement) {
- element.innerHTML = this.sanitize(content, forceSanitize, sanitizeOptions);
- return true;
- }
- return false;
- }
-
- restoreCaretPosition() {
- if (this.root?.currentSelection) {
- if (this.refs.input?.length) {
- const { selection, index } = this.root.currentSelection;
- let input = this.refs.input[index];
- const isInputRangeSelectable = (i) => /text|search|password|tel|url/i.test(i?.type || '');
- if (input) {
- if (isInputRangeSelectable(input)) {
- input.setSelectionRange(...selection);
- }
- }
- else {
- input = this.refs.input[this.refs.input.length];
- const lastCharacter = input.value?.length || 0;
- if (isInputRangeSelectable(input)) {
- input.setSelectionRange(lastCharacter, lastCharacter);
- }
- }
- }
- }
- }
-
- redraw() {
- // Don't bother if we have not built yet.
- if (!this.element || !this.element.parentNode || this.optimizeRedraw) {
- // Return a non-resolving promise.
- return NativePromise.resolve();
- }
- this.detach();
- this.emit('redraw');
- // Since we are going to replace the element, we need to know it's position so we can find it in the parent's children.
- const parent = this.element.parentNode;
- const index = Array.prototype.indexOf.call(parent.children, this.element);
- this.element.outerHTML = this.sanitize(this.render());
- this.element = parent.children[index];
- return this.attach(this.element);
- }
-
- rebuild() {
- this.destroy();
- this.init();
- this.visible = this.conditionallyVisible(null, null);
- return this.redraw();
- }
-
- removeEventListeners() {
- super.removeEventListeners();
- this.tooltips.forEach(tooltip => tooltip.destroy());
- this.tooltips = [];
- }
-
- hasClass(element, className) {
- if (!element) {
- return;
- }
-
- return super.hasClass(element, this.transform('class', className));
- }
-
- addClass(element, className) {
- if (!element) {
- return;
- }
-
- return super.addClass(element, this.transform('class', className));
- }
-
- removeClass(element, className) {
- if (!element) {
- return;
- }
-
- return super.removeClass(element, this.transform('class', className));
- }
-
- /**
- * Determines if this component has a condition defined.
- *
- * @return {null}
- */
- hasCondition() {
- if (this._hasCondition !== null) {
- return this._hasCondition;
- }
-
- this._hasCondition = FormioUtils.hasCondition(this.component);
- return this._hasCondition;
- }
-
- /**
- * Check if this component is conditionally visible.
- *
- * @param data
- * @return {boolean}
- */
- conditionallyVisible(data, row) {
- data = data || this.rootValue;
- row = row || this.data;
- if (this.builderMode || this.previewMode || !this.hasCondition()) {
- return !this.component.hidden;
- }
- data = data || (this.root ? this.root.data : {});
- return this.checkCondition(row, data);
- }
-
- /**
- * Checks the condition of this component.
- *
- * TODO: Switch row and data parameters to be consistent with other methods.
- *
- * @param row - The row contextual data.
- * @param data - The global data object.
- * @return {boolean} - True if the condition applies to this component.
- */
- checkCondition(row, data) {
- return FormioUtils.checkCondition(
- this.component,
- row || this.data,
- data || this.rootValue,
- this.root ? this.root._form : {},
- this
- );
- }
-
- /**
- * Check for conditionals and hide/show the element based on those conditions.
- */
- checkComponentConditions(data, flags, row) {
- data = data || this.rootValue;
- flags = flags || {};
- row = row || this.data;
-
- if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {
- this.redraw();
- }
-
- // Check advanced conditions
- const visible = this.conditionallyVisible(data, row);
-
- if (this.visible !== visible) {
- this.visible = visible;
- }
-
- return visible;
- }
-
- /**
- * Checks conditions for this component and any sub components.
- * @param args
- * @return {boolean}
- */
- checkConditions(data, flags, row) {
- data = data || this.rootValue;
- flags = flags || {};
- row = row || this.data;
- return this.checkComponentConditions(data, flags, row);
- }
-
- get logic() {
- return this.component.logic || [];
- }
-
- /**
- * Check all triggers and apply necessary actions.
- *
- * @param data
- */
- fieldLogic(data, row) {
- data = data || this.rootValue;
- row = row || this.data;
- const logics = this.logic;
-
- // If there aren't logic, don't go further.
- if (logics.length === 0) {
- return;
- }
-
- const newComponent = fastCloneDeep(this.originalComponent);
-
- let changed = logics.reduce((changed, logic) => {
- const result = FormioUtils.checkTrigger(
- newComponent,
- logic.trigger,
- row,
- data,
- this.root ? this.root._form : {},
- this,
- );
-
- return (result ? this.applyActions(newComponent, logic.actions, result, row, data) : false) || changed;
- }, false);
-
- // If component definition changed, replace and mark as changed.
- if (!_.isEqual(this.component, newComponent)) {
- this.component = newComponent;
- changed = true;
- const disabled = this.shouldDisabled;
- // Change disabled state if it has changed
- if (this.disabled !== disabled) {
- this.disabled = disabled;
- }
- }
-
- return changed;
- }
-
- isIE() {
- if (typeof window === 'undefined') {
- return false;
- }
-
- const userAgent = window.navigator.userAgent;
-
- const msie = userAgent.indexOf('MSIE ');
- if (msie > 0) {
- // IE 10 or older => return version number
- return parseInt(userAgent.substring(msie + 5, userAgent.indexOf('.', msie)), 10);
- }
-
- const trident = userAgent.indexOf('Trident/');
- if (trident > 0) {
- // IE 11 => return version number
- const rv = userAgent.indexOf('rv:');
- return parseInt(userAgent.substring(rv + 3, userAgent.indexOf('.', rv)), 10);
- }
-
- const edge = userAgent.indexOf('Edge/');
- if (edge > 0) {
- // IE 12 (aka Edge) => return version number
- return parseInt(userAgent.substring(edge + 5, userAgent.indexOf('.', edge)), 10);
- }
-
- // other browser
- return false;
- }
-
- defineActionValue(action, argsObject) {
- return this.evaluate(
- action.value,
- argsObject,
- 'value',
- );
- }
-
- applyActions(newComponent, actions, result, row, data) {
- data = data || this.rootValue;
- row = row || this.data;
-
- return actions.reduce((changed, action) => {
- switch (action.type) {
- case 'property': {
- FormioUtils.setActionProperty(newComponent, action, result, row, data, this);
-
- const property = action.property.value;
- if (!_.isEqual(_.get(this.component, property), _.get(newComponent, property))) {
- changed = true;
- }
-
- break;
- }
- case 'value': {
- const oldValue = this.getValue();
- const newValue = this.defineActionValue(
- action,
- {
- value: _.clone(oldValue),
- data,
- row,
- component: newComponent,
- result,
- }
- );
-
- if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && !this.visible)) {
- this.setValue(newValue);
-
- if (this.viewOnly) {
- this.dataValue = newValue;
- }
-
- changed = true;
- }
-
- break;
- }
- case 'mergeComponentSchema': {
- const schema = this.evaluate(
- action.schemaDefinition,
- {
- value: _.clone(this.getValue()),
- data,
- row,
- component: newComponent,
- result,
- },
- 'schema',
- );
-
- _.assign(newComponent, schema);
-
- if (!_.isEqual(this.component, newComponent)) {
- changed = true;
- }
-
- break;
- }
- case 'customAction': {
- const oldValue = this.getValue();
- const newValue = this.evaluate(action.customAction, {
- value: _.clone(oldValue),
- data,
- row,
- input: oldValue,
- component: newComponent,
- result,
- },
- 'value');
-
- if (!_.isEqual(oldValue, newValue) && !(this.component.clearOnHide && !this.visible)) {
- this.setValue(newValue);
-
- if (this.viewOnly) {
- this.dataValue = newValue;
- }
-
- changed = true;
- }
-
- break;
- }
- }
-
- return changed;
- }, false);
- }
-
- // Deprecated
- addInputError(message, dirty, elements) {
- this.addMessages(message);
- this.setErrorClasses(elements, dirty, !!message);
- }
-
- // Deprecated
- removeInputError(elements) {
- this.setErrorClasses(elements, true, false);
- }
-
- /**
- * Add a new input error to this element.
- *
- * @param message
- * @param dirty
- */
- addMessages(messages) {
- if (!messages) {
- return;
- }
-
- // Standardize on array of objects for message.
- if (typeof messages === 'string') {
- messages = {
- messages,
- level: 'error',
- };
- }
-
- if (!Array.isArray(messages)) {
- messages = [messages];
- }
-
- messages = _.uniqBy(messages, message => message.message);
-
- if (this.refs.messageContainer) {
- this.setContent(this.refs.messageContainer, messages.map((message) => {
- if (message.message && typeof message.message === 'string') {
- message.message = message.message.replaceAll('<', '<').replaceAll('>', '>');
- }
- return this.renderTemplate('message', message);
- }
- ).join(''));
- }
- }
-
- setErrorClasses(elements, dirty, hasErrors, hasMessages, element = this.element) {
- this.clearErrorClasses();
- elements.forEach((element) => {
- this.setElementInvalid(this.performInputMapping(element), false);
- });
- this.setInputWidgetErrorClasses(elements, hasErrors);
-
- if (hasErrors) {
- // Add error classes
- elements.forEach((input) => {
- this.setElementInvalid(this.performInputMapping(input), true);
- });
-
- if (dirty && this.options.highlightErrors) {
- this.addClass(element, this.options.componentErrorClass);
- }
- else {
- this.addClass(element, 'has-error');
- }
- }
- if (hasMessages) {
- this.addClass(element, 'has-message');
- }
- }
-
- setElementInvalid(element, invalid) {
- if (!element) return;
-
- if (invalid) {
- this.addClass(element, 'is-invalid');
- }
- else {
- this.removeClass(element, 'is-invalid');
- }
- element.setAttribute('aria-invalid', invalid ? 'true' : 'false');
- }
-
- clearOnHide() {
- // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.
- if (
- // if change happens inside EditGrid's row, it doesn't trigger change on the root level, so rootPristine will be true
- (!this.rootPristine || this.options.server || isInsideScopingComponent(this)) &&
- this.component.clearOnHide !== false &&
- !this.options.readOnly &&
- !this.options.showHiddenFields
- ) {
- if (!this.visible) {
- this.deleteValue();
- }
- else if (!this.hasValue() && this.shouldAddDefaultValue) {
- // If shown, ensure the default is set.
- this.setValue(this.defaultValue, {
- noUpdateEvent: true
- });
- }
- }
- }
-
- triggerRootChange(...args) {
- if (this.options.onChange) {
- this.options.onChange(...args);
- }
- else if (this.root) {
- this.root.triggerChange(...args);
- }
- }
-
- onChange(flags, fromRoot) {
- flags = flags || {};
- if (flags.modified) {
- if (!flags.noPristineChangeOnModified) {
- this.pristine = false;
- }
- this.addClass(this.getElement(), 'formio-modified');
- }
-
- // If we are supposed to validate on blur, then don't trigger validation yet.
- if (this.component.validateOn === 'blur' && !this.errors.length) {
- flags.noValidate = true;
- }
-
- if (this.component.onChange) {
- this.evaluate(this.component.onChange, {
- flags
- });
- }
-
- // Set the changed variable.
- const changed = {
- instance: this,
- component: this.component,
- value: this.dataValue,
- flags: flags
- };
-
- // Emit the change.
- this.emit('componentChange', changed);
-
- // Do not propogate the modified flag.
- let modified = false;
- if (flags.modified) {
- modified = true;
- delete flags.modified;
- }
-
- // Bubble this change up to the top.
- if (!fromRoot) {
- this.triggerRootChange(flags, changed, modified);
- }
- return changed;
- }
-
- get wysiwygDefault() {
- return {
- quill: {
- theme: 'snow',
- placeholder: this.t(this.component.placeholder, { _userInput: true }),
- modules: {
- toolbar: [
- [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
- [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
- [{ 'font': [] }],
- ['bold', 'italic', 'underline', 'strike', { 'script': 'sub' }, { 'script': 'super' }, 'clean'],
- [{ 'color': [] }, { 'background': [] }],
- [{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }, { 'align': [] }],
- ['blockquote', 'code-block'],
- ['link', 'image', 'video', 'formula', 'source']
- ]
- }
- },
- ace: {
- theme: 'ace/theme/xcode',
- maxLines: 12,
- minLines: 12,
- tabSize: 2,
- mode: 'ace/mode/javascript',
- placeholder: this.t(this.component.placeholder, { _userInput: true })
- },
- ckeditor: {
- image: {
- toolbar: [
- 'imageTextAlternative',
- '|',
- 'imageStyle:full',
- 'imageStyle:alignLeft',
- 'imageStyle:alignCenter',
- 'imageStyle:alignRight'
- ],
- styles: [
- 'full',
- 'alignLeft',
- 'alignCenter',
- 'alignRight'
- ]
- },
- extraPlugins: []
- },
- default: {}
- };
- }
-
- addCKE(element, settings, onChange) {
- settings = _.isEmpty(settings) ? {} : settings;
- settings.base64Upload = this.component.isUploadEnabled ? false : true;
- settings.mediaEmbed = { previewsInData: true };
- settings = _.merge(this.wysiwygDefault.ckeditor, _.get(this.options, 'editors.ckeditor.settings', {}), settings);
-
- if (this.component.isUploadEnabled) {
- settings.extraPlugins.push(getFormioUploadAdapterPlugin(this.fileService, this));
- }
-
- return Formio.requireLibrary(
- 'ckeditor',
- isIEBrowser ? 'CKEDITOR' : 'ClassicEditor',
- _.get(this.options, 'editors.ckeditor.src',
- `${Formio.cdn.ckeditor}/ckeditor.js`
- ), true)
- .then(() => {
- if (!element.parentNode) {
- return NativePromise.reject();
- }
- if (isIEBrowser) {
- const editor = CKEDITOR.replace(element);
- editor.on('change', () => onChange(editor.getData()));
- return NativePromise.resolve(editor);
- }
- else {
- return ClassicEditor.create(element, settings).then(editor => {
- editor.model.document.on('change', () => onChange(editor.data.get()));
- return editor;
- });
- }
- });
- }
-
- addQuill(element, settings, onChange) {
- settings = _.isEmpty(settings) ? this.wysiwygDefault.quill : settings;
- settings = _.merge(this.wysiwygDefault.quill, _.get(this.options, 'editors.quill.settings', {}), settings);
- settings = {
- ...settings,
- modules: {
- table: true,
- ...settings.modules
- }
- };
- // Lazy load the quill css.
- Formio.requireLibrary(`quill-css-${settings.theme}`, 'Quill', [
- { type: 'styles', src: `${Formio.cdn.quill}/quill.${settings.theme}.css` }
- ], true);
-
- // Lazy load the quill library.
- return Formio.requireLibrary('quill', 'Quill', _.get(this.options, 'editors.quill.src', `${Formio.cdn.quill}/quill.min.js`), true)
- .then(() => {
- return Formio.requireLibrary('quill-table', 'Quill', `${Formio.cdn.baseUrl}/quill/quill-table.js`, true)
- .then(() => {
- if (!element.parentNode) {
- return NativePromise.reject();
- }
- this.quill = new Quill(element, isIEBrowser ? { ...settings, modules: {} } : settings);
-
- /** This block of code adds the [source] capabilities. See https://codepen.io/anon/pen/ZyEjrQ **/
- const txtArea = document.createElement('textarea');
- txtArea.setAttribute('class', 'quill-source-code');
- this.quill.addContainer('ql-custom').appendChild(txtArea);
- const qlSource = element.parentNode.querySelector('.ql-source');
- if (qlSource) {
- this.addEventListener(qlSource, 'click', (event) => {
- event.preventDefault();
- if (txtArea.style.display === 'inherit') {
- this.quill.setContents(this.quill.clipboard.convert({ html: txtArea.value }));
- }
- txtArea.style.display = (txtArea.style.display === 'none') ? 'inherit' : 'none';
- });
- }
- /** END CODEBLOCK **/
-
- // Make sure to select cursor when they click on the element.
- this.addEventListener(element, 'click', () => this.quill.focus());
-
- // Allows users to skip toolbar items when tabbing though form
- const elm = document.querySelectorAll('.ql-formats > button');
- for (let i = 0; i < elm.length; i++) {
- elm[i].setAttribute('tabindex', '-1');
- }
-
- this.quill.on('text-change', () => {
- txtArea.value = this.quill.root.innerHTML;
- onChange(txtArea);
- });
- return this.quill;
- });
- });
- }
-
- get shouldSanitizeValue() {
- // Sanitize value if sanitizing for thw whole content is turned off
- return (this.options?.sanitize !== false);
- }
-
- addAce(element, settings, onChange) {
- if (!settings || (settings.theme === 'snow')) {
- const mode = settings ? settings.mode : '';
- settings = {};
- if (mode) {
- settings.mode = mode;
- }
- }
- settings = _.merge(this.wysiwygDefault.ace, _.get(this.options, 'editors.ace.settings', {}), settings || {});
- return Formio.requireLibrary('ace', 'ace', _.get(this.options, 'editors.ace.src', `${Formio.cdn.ace}/ace.js`), true)
- .then((editor) => {
- editor = editor.edit(element);
- editor.removeAllListeners('change');
- editor.setOptions(settings);
- editor.getSession().setMode(settings.mode);
- editor.on('change', () => onChange(editor.getValue()));
- if (settings.isUseWorkerDisabled) {
- editor.session.setUseWorker(false);
- }
- return editor;
- });
- }
-
- get tree() {
- return this.component.tree || false;
- }
-
- /**
- * The empty value for this component.
- *
- * @return {null}
- */
- get emptyValue() {
- return null;
- }
-
- /**
- * Returns if this component has a value set.
- *
- */
- hasValue(data) {
- return !_.isUndefined(_.get(data || this.data, this.key));
- }
-
- /**
- * Get the data value at the root level.
- *
- * @return {*}
- */
- get rootValue() {
- return this.root ? this.root.data : this.data;
- }
-
- get rootPristine() {
- return _.get(this, 'root.pristine', false);
- }
-
- /**
- * Get the static value of this component.
- * @return {*}
- */
- get dataValue() {
- if (
- !this.key ||
- (!this.visible && this.component.clearOnHide && !this.rootPristine)
- ) {
- return this.emptyValue;
- }
- if (!this.hasValue() && this.shouldAddDefaultValue) {
- const empty = this.component.multiple ? [] : this.emptyValue;
- if (!this.rootPristine) {
- this.dataValue = empty;
- }
- return empty;
- }
- return _.get(this._data, this.key);
- }
-
- /**
- * Sets the static value of this component.
- *
- * @param value
- */
- set dataValue(value) {
- if (
- !this.allowData ||
- !this.key ||
- (!this.visible && this.component.clearOnHide && !this.rootPristine)
- ) {
- return;
- }
- if ((value !== null) && (value !== undefined)) {
- value = this.hook('setDataValue', value, this.key, this._data);
- }
- if ((value === null) || (value === undefined)) {
- this.unset();
- return;
- }
- _.set(this._data, this.key, value);
- return;
- }
-
- /**
- * Splice a value from the dataValue.
- *
- * @param index
- */
- splice(index, flags = {}) {
- if (this.hasValue()) {
- const dataValue = this.dataValue || [];
- if (_.isArray(dataValue) && dataValue.hasOwnProperty(index)) {
- dataValue.splice(index, 1);
- this.dataValue = dataValue;
- this.triggerChange(flags);
- }
- }
- }
-
- unset() {
- _.unset(this._data, this.key);
- }
-
- /**
- * Deletes the value of the component.
- */
- deleteValue() {
- this.setValue(null, {
- noUpdateEvent: true,
- noDefault: true
- });
- this.unset();
- }
-
- getCustomDefaultValue(defaultValue) {
- if (this.component.customDefaultValue && !this.options.preview) {
- defaultValue = this.evaluate(
- this.component.customDefaultValue,
- { value: '' },
- 'value'
- );
- }
- return defaultValue;
- }
-
- get shouldAddDefaultValue() {
- return !this.options.noDefaults || (this.component.defaultValue && !this.isEmpty(this.component.defaultValue)) || this.component.customDefaultValue;
- }
-
- get defaultValue() {
- let defaultValue = this.emptyValue;
- if (this.component.defaultValue) {
- defaultValue = this.component.defaultValue;
- }
-
- defaultValue = this.getCustomDefaultValue(defaultValue);
-
- const checkMask = (value) => {
- if (typeof value === 'string') {
- const placeholderChar = this.placeholderChar;
-
- value = conformToMask(value, this.defaultMask, { placeholderChar }).conformedValue;
- if (!FormioUtils.matchInputMask(value, this.defaultMask)) {
- value = '';
- }
- }
- else {
- value = '';
- }
- return value;
- };
-
- if (this.defaultMask) {
- if (Array.isArray(defaultValue)) {
- defaultValue = defaultValue.map(checkMask);
- }
- else {
- defaultValue = checkMask(defaultValue);
- }
- }
-
- // Clone so that it creates a new instance.
- return _.cloneDeep(defaultValue);
- }
-
- /**
- * Get the input value of this component.
- *
- * @return {*}
- */
- getValue() {
- if (!this.hasInput || this.viewOnly || !this.refs.input || !this.refs.input.length) {
- return this.dataValue;
- }
- const values = [];
- for (const i in this.refs.input) {
- if (this.refs.input.hasOwnProperty(i)) {
- if (!this.component.multiple) {
- return this.getValueAt(i);
- }
- values.push(this.getValueAt(i));
- }
- }
- if (values.length === 0 && !this.component.multiple) {
- return '';
- }
-
- return values;
- }
-
- /**
- * Get the value at a specific index.
- *
- * @param index
- * @returns {*}
- */
- getValueAt(index) {
- const input = this.performInputMapping(this.refs.input[index]);
- return input ? input.value : undefined;
- }
-
- /**
- * Set the value of this component.
- *
- * @param value
- * @param flags
- *
- * @return {boolean} - If the value changed.
- */
- setValue(value, flags = {}) {
- const changed = this.updateValue(value, flags);
- value = this.dataValue;
- if (!this.hasInput) {
- return changed;
- }
- const isArray = Array.isArray(value);
- const valueInput = this.refs.fileLink || this.refs.input;
- if (
- isArray &&
- Array.isArray(this.defaultValue) &&
- this.refs.hasOwnProperty('input') &&
- valueInput &&
- (valueInput.length !== value.length) &&
- this.visible
- ) {
- this.redraw();
- }
- if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {
- this.redraw();
- return changed;
- }
- for (const i in this.refs.input) {
- if (this.refs.input.hasOwnProperty(i)) {
- this.setValueAt(i, isArray ? value[i] : value, flags);
- }
- }
- return changed;
- }
-
- /**
- * Set the value at a specific index.
- *
- * @param index
- * @param value
- */
- setValueAt(index, value, flags = {}) {
- if (!flags.noDefault && (value === null || value === undefined) && !this.component.multiple) {
- value = this.defaultValue;
- }
-
- const input = this.performInputMapping(this.refs.input[index]);
- const valueMaskInput = this.refs.valueMaskInput;
-
- if (valueMaskInput?.mask) {
- valueMaskInput.mask.textMaskInputElement.update(value);
- }
-
- if (input.mask) {
- input.mask.textMaskInputElement.update(value);
- }
- else if (input.widget && input.widget.setValue) {
- input.widget.setValue(value);
- }
- else {
- input.value = value;
- }
- }
-
- get hasSetValue() {
- return this.hasValue() && !this.isEmpty(this.dataValue);
- }
-
- setDefaultValue() {
- if (this.defaultValue && this.shouldAddDefaultValue) {
- const defaultValue = (this.component.multiple && !this.dataValue.length) ? [] : this.defaultValue;
- this.setValue(defaultValue, {
- noUpdateEvent: true
- });
- }
- }
-
- /**
- * Restore the value of a control.
- */
- restoreValue() {
- if (this.hasSetValue) {
- this.setValue(this.dataValue, {
- noUpdateEvent: true
- });
- }
- else {
- this.setDefaultValue();
- }
- }
-
- /**
- * Normalize values coming into updateValue.
- *
- * @param value
- * @return {*}
- */
- normalizeValue(value) {
- if (this.component.multiple && !Array.isArray(value)) {
- value = value ? [value] : [];
- }
- return value;
- }
-
- /**
- * Update a value of this component.
- *
- * @param flags
- */
- updateComponentValue(value, flags = {}) {
- let newValue = (!flags.resetValue && (value === undefined || value === null)) ? this.getValue() : value;
- newValue = this.normalizeValue(newValue, flags);
- const oldValue = this.dataValue;
- let changed = ((newValue !== undefined) ? this.hasChanged(newValue, oldValue) : false);
- if (changed) {
- this.dataValue = newValue;
- changed = this.dataValue !== oldValue;
- this.updateOnChange(flags, changed);
- }
- if (this.componentModal && flags && flags.fromSubmission) {
- this.componentModal.setValue(value);
- }
- return changed;
- }
-
- /**
- * Updates the value of this component plus all sub-components.
- *
- * @param args
- * @return {boolean}
- */
- updateValue(...args) {
- return this.updateComponentValue(...args);
- }
-
- getIcon(name, content, styles, ref = 'icon') {
- return this.renderTemplate('icon', {
- className: this.iconClass(name),
- ref,
- styles,
- content
- });
- }
-
- /**
- * Resets the value of this component.
- */
- resetValue() {
- this.unset();
- this.setValue(this.emptyValue, {
- noUpdateEvent: true,
- noValidate: true,
- resetValue: true
- });
- }
-
- /**
- * Determine if the value of this component has changed.
- *
- * @param newValue
- * @param oldValue
- * @return {boolean}
- */
- hasChanged(newValue, oldValue) {
- if (
- ((newValue === undefined) || (newValue === null)) &&
- ((oldValue === undefined) || (oldValue === null) || this.isEmpty(oldValue))
- ) {
- return false;
- }
- // If we do not have a value and are getting set to anything other than undefined or null, then we changed.
- if (
- newValue !== undefined &&
- newValue !== null &&
- this.allowData &&
- !this.hasValue()
- ) {
- return true;
- }
- return !_.isEqual(newValue, oldValue);
- }
-
- /**
- * Update the value on change.
- *
- * @param flags
- */
- updateOnChange(flags = {}, changed = false) {
- if (!flags.noUpdateEvent && changed) {
- this.triggerChange(flags);
- return true;
- }
- return false;
- }
-
- /**
- * Perform a calculated value operation.
- *
- * @param data - The global data object.
- *
- * @return {boolean} - If the value changed during calculation.
- */
-
- convertNumberOrBoolToString(value) {
- 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');
- }
-
- /* eslint-disable max-statements */
- calculateComponentValue(data, flags, row) {
- // Skip value calculation for the component if we don't have entire form data set
- if (_.isUndefined(_.get(this, 'root.data'))) {
- return false;
- }
- // If no calculated value or
- // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)
- const { clearOnHide } = this.component;
- const shouldBeCleared = !this.visible && clearOnHide;
- const allowOverride = _.get(this.component, 'allowCalculateOverride', false);
-
- if (shouldBeCleared) {
- // remove calculated value so that the value is recalculated once component becomes visible
- if (this.hasOwnProperty('calculatedValue') && allowOverride) {
- _.unset(this, 'calculatedValue');
- }
- return false;
- }
-
- // Handle all cases when calculated values should not fire.
- if (
- (this.options.readOnly && !this.options.pdf && !this.component.calculateValue) ||
- !(this.component.calculateValue || this.component.calculateValueVariable) ||
- (this.options.server && !this.component.calculateServer) ||
- (flags.dataSourceInitialLoading && allowOverride)
- ) {
- return false;
- }
-
- const dataValue = this.dataValue;
- // Calculate the new value.
- let calculatedValue = this.doValueCalculation(dataValue, data, row, flags);
-
- if (this.options.readOnly && dataValue && !calculatedValue) {
- return false;
- }
-
- if (_.isNil(calculatedValue)) {
- calculatedValue = this.emptyValue;
- }
-
- const changed = !_.isEqual(dataValue, calculatedValue);
-
- // Do not override calculations on server if they have calculateServer set.
- if (allowOverride) {
- // The value is considered locked if it is not empty and comes from a submission value.
- const fromSubmission = (flags.fromSubmission && this.component.persistent === true);
- if (this.isEmpty(dataValue)) {
- // Reset the calculation lock if ever the data is cleared.
- this.calculationLocked = false;
- }
- else if (this.calculationLocked || fromSubmission) {
- this.calculationLocked = true;
- return false;
- }
-
- const firstPass = (this.calculatedValue === undefined) || flags.resetValue;
- if (firstPass) {
- this.calculatedValue = null;
- }
- const newCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(calculatedValue));
- const previousCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(this.calculatedValue));
- const normalizedDataValue = this.normalizeValue(this.convertNumberOrBoolToString(dataValue));
- const calculationChanged = !_.isEqual(previousCalculatedValue, newCalculatedValue);
- const previousChanged = !_.isEqual(normalizedDataValue, previousCalculatedValue);
-
- if (calculationChanged && previousChanged && !firstPass) {
- return false;
- }
-
- // Check to ensure that the calculated value is different than the previously calculated value.
- if (previousCalculatedValue && previousChanged && !calculationChanged) {
- return false;
- }
-
- if (flags.isReordered || !calculationChanged) {
- return false;
- }
-
- if (fromSubmission) {
- // If we set value from submission and it differs from calculated one, set the calculated value to prevent overriding dataValue in the next pass
- this.calculatedValue = fastCloneDeep(calculatedValue);
- return false;
- }
-
- // If this is the firstPass, and the dataValue is different than to the calculatedValue.
- if (firstPass && !this.isEmpty(dataValue) && changed && calculationChanged) {
- // Return that we have a change so it will perform another pass.
- return true;
- }
- }
-
- this.calculatedValue = fastCloneDeep(calculatedValue);
-
- if (changed) {
- if (!flags.noPristineChangeOnModified) {
- this.pristine = false;
- }
-
- flags.triggeredComponentId = this.id;
- return this.setValue(calculatedValue, flags);
- }
- return false;
- }
- /* eslint-enable max-statements */
-
- /**
- * Performs calculations in this component plus any child components.
- *
- * @param args
- * @return {boolean}
- */
- calculateValue(data, flags, row) {
- data = data || this.rootValue;
- flags = flags || {};
- row = row || this.data;
- return this.calculateComponentValue(data, flags, row);
- }
-
- /**
- * Get this component's label text.
- *
- */
- get label() {
- return this.component.label;
- }
-
- /**
- * Set this component's label text and render it.
- *
- * @param value - The new label text.
- */
- set label(value) {
- this.component.label = value;
- if (this.labelElement) {
- this.labelElement.innerText = value;
- }
- }
-
- /**
- * Get FormioForm element at the root of this component tree.
- *
- */
- getRoot() {
- return this.root;
- }
-
- /**
- * Returns the invalid message, or empty string if the component is valid.
- *
- * @param data
- * @param dirty
- * @return {*}
- */
- invalidMessage(data, dirty, ignoreCondition, row) {
- if (!ignoreCondition && !this.checkCondition(row, data)) {
- return '';
- }
-
- // See if this is forced invalid.
- if (this.invalid) {
- return this.invalid;
- }
-
- // No need to check for errors if there is no input or if it is pristine.
- if (!this.hasInput || (!dirty && this.pristine)) {
- return '';
- }
-
- return _.map(Validator.checkComponent(this, data), 'message').join('\n\n');
- }
-
- /**
- * Returns if the component is valid or not.
- *
- * @param data
- * @param dirty
- * @return {boolean}
- */
- isValid(data, dirty) {
- return !this.invalidMessage(data, dirty);
- }
-
- setComponentValidity(messages, dirty, silentCheck) {
- const hasErrors = !!messages.filter(message => message.level === 'error' && !message.fromServer).length;
- if (messages.length && (!silentCheck || this.error) && (!this.isEmpty(this.defaultValue) || dirty || !this.pristine)) {
- this.setCustomValidity(messages, dirty);
- }
- else if (!silentCheck) {
- this.setCustomValidity('');
- }
-
- return !hasErrors;
- }
-
- /**
- * Checks the validity of this component and sets the error message if it is invalid.
- *
- * @param data
- * @param dirty
- * @param row
- * @return {boolean}
- */
- checkComponentValidity(data, dirty, row, options = {}) {
- data = data || this.rootValue;
- row = row || this.data;
- const { async = false, silentCheck = false } = options;
-
- if (this.shouldSkipValidation(data, dirty, row)) {
- this.setCustomValidity('');
- return async ? NativePromise.resolve(true) : true;
- }
-
- const check = Validator.checkComponent(this, data, row, true, async);
- let validations = check;
-
- if (this.serverErrors?.length) {
- validations = check.concat(this.serverErrors);
- }
- return async ?
- validations.then((messages) => this.setComponentValidity(messages, dirty, silentCheck)) :
- this.setComponentValidity(validations, dirty, silentCheck);
- }
-
- checkValidity(data, dirty, row, silentCheck) {
- data = data || this.rootValue;
- row = row || this.data;
- const isValid = this.checkComponentValidity(data, dirty, row, { silentCheck });
- this.checkModal();
- return isValid;
- }
-
- checkAsyncValidity(data, dirty, row, silentCheck) {
- return NativePromise.resolve(this.checkComponentValidity(data, dirty, row, { async: true, silentCheck }));
- }
-
- /**
- * Check the conditions, calculations, and validity of a single component and triggers an update if
- * something changed.
- *
- * @param data - The root data of the change event.
- * @param flags - The flags from this change event.
- *
- * @return boolean - If component is valid or not.
- */
- checkData(data, flags, row) {
- data = data || this.rootValue;
- flags = flags || {};
- row = row || this.data;
-
- // Needs for Nextgen Rules Engine
- this.resetCaches();
-
- // Do not trigger refresh if change was triggered on blur event since components with Refresh on Blur have their own listeners
- if (!flags.fromBlur) {
- this.checkRefreshOn(flags.changes, flags);
- }
-
- if (flags.noCheck) {
- return true;
- }
-
- this.checkComponentConditions(data, flags, row);
-
- if (this.id !== flags.triggeredComponentId) {
- this.calculateComponentValue(data, flags, row);
- }
-
- if (flags.noValidate && !flags.validateOnInit && !flags.fromIframe) {
- if (flags.fromSubmission && this.rootPristine && this.pristine && this.error && flags.changed) {
- this.checkComponentValidity(data, !!this.options.alwaysDirty, row, true);
- }
- return true;
- }
-
- let isDirty = false;
-
- // We need to set dirty if they explicitly set noValidate to false.
- if (this.options.alwaysDirty || flags.dirty) {
- isDirty = true;
- }
-
- // See if they explicitely set the values with setSubmission.
- if (flags.fromSubmission && this.hasValue(data)) {
- isDirty = true;
- }
-
- this.setDirty(isDirty);
-
- if (this.component.validateOn === 'blur' && flags.fromSubmission) {
- return true;
- }
- const isValid = this.checkComponentValidity(data, isDirty, row, flags);
- this.checkModal();
- return isValid;
- }
-
- checkModal(isValid = true, dirty = false) {
- if (!this.component.modalEdit || !this.componentModal) {
- return;
- }
- if (dirty && !isValid) {
- this.setErrorClasses([this.refs.openModal], dirty, !isValid, !!this.errors.length, this.refs.openModalWrapper);
- }
- else {
- this.clearErrorClasses(this.refs.openModalWrapper);
- }
- }
-
- get validationValue() {
- return this.dataValue;
- }
-
- isEmpty(value = this.dataValue) {
- const isEmptyArray = (_.isArray(value) && value.length === 1) ? _.isEqual(value[0], this.emptyValue) : false;
- return value == null || value.length === 0 || _.isEqual(value, this.emptyValue) || isEmptyArray;
- }
-
- isEqual(valueA, valueB = this.dataValue) {
- return (this.isEmpty(valueA) && this.isEmpty(valueB)) || _.isEqual(valueA, valueB);
- }
-
- /**
- * Check if a component is eligible for multiple validation
- *
- * @return {boolean}
- */
- validateMultiple() {
- return true;
- }
-
- get errors() {
- return this.error ? [this.error] : [];
- }
-
- clearErrorClasses(element = this.element) {
- this.removeClass(element, this.options.componentErrorClass);
- this.removeClass(element, 'alert alert-danger');
- this.removeClass(element, 'has-error');
- this.removeClass(element, 'has-message');
- }
-
- setInputWidgetErrorClasses(inputRefs, hasErrors) {
- if (!this.isInputComponent || !this.component.widget || !inputRefs?.length) {
- return;
- }
-
- inputRefs.forEach((input) => {
- if (input?.widget && input.widget.setErrorClasses) {
- input.widget.setErrorClasses(hasErrors);
- }
- });
- }
-
- addFocusBlurEvents(element) {
- this.addEventListener(element, 'focus', () => {
- if (this.root.focusedComponent !== this) {
- if (this.root.pendingBlur) {
- this.root.pendingBlur();
- }
-
- this.root.focusedComponent = this;
-
- this.emit('focus', this);
- }
- else if (this.root.focusedComponent === this && this.root.pendingBlur) {
- this.root.pendingBlur.cancel();
- this.root.pendingBlur = null;
- }
- });
- this.addEventListener(element, 'blur', () => {
- this.root.pendingBlur = FormioUtils.delay(() => {
- this.emit('blur', this);
- if (this.component.validateOn === 'blur') {
- this.root.triggerChange({ fromBlur: true }, {
- instance: this,
- component: this.component,
- value: this.dataValue,
- flags: { fromBlur: true }
- });
- }
- this.root.focusedComponent = null;
- this.root.pendingBlur = null;
- });
- });
- }
-
- setCustomValidity(messages, dirty, external) {
- const inputRefs = this.isInputComponent ? this.refs.input || [] : null;
-
- if (typeof messages === 'string' && messages) {
- messages = {
- level: 'error',
- message: messages,
- };
- }
-
- if (!Array.isArray(messages)) {
- if (messages) {
- messages = [messages];
- }
- else {
- messages = [];
- }
- }
-
- const hasErrors = !!messages.filter(message => message.level === 'error').length;
-
- let invalidInputRefs = inputRefs;
- if (this.component.multiple) {
- const inputRefsArray = Array.from(inputRefs);
- inputRefsArray.forEach((input) => {
- this.setElementInvalid(this.performInputMapping(input), false);
- });
- this.setInputWidgetErrorClasses(inputRefsArray, false);
-
- invalidInputRefs = inputRefsArray.filter((ref) => {
- return messages.some?.((msg) => {
- return msg?.context?.input === ref;
- });
- });
- }
- if (messages.length) {
- if (this.refs.messageContainer) {
- this.empty(this.refs.messageContainer);
- }
- this.error = {
- component: this.component,
- message: messages[0].message,
- messages,
- external: !!external,
- };
- this.emit('componentError', this.error);
- this.addMessages(messages, dirty, invalidInputRefs);
- if (invalidInputRefs) {
- this.setErrorClasses(invalidInputRefs, dirty, hasErrors, !!messages.length);
- }
- }
- else if (!this.error || (this.error && this.error.external === !!external)) {
- if (this.refs.messageContainer) {
- this.empty(this.refs.messageContainer);
- }
- if (this.refs.modalMessageContainer) {
- this.empty(this.refs.modalMessageContainer);
- }
- this.error = null;
- if (invalidInputRefs) {
- this.setErrorClasses(invalidInputRefs, dirty, hasErrors, !!messages.length);
- }
- this.clearErrorClasses();
- }
-
- // if (!this.refs.input) {
- // return;
- // }
- // this.refs.input.forEach(input => {
- // input = this.performInputMapping(input);
- // if (typeof input.setCustomValidity === 'function') {
- // input.setCustomValidity(message, dirty);
- // }
- // });
- }
-
- /**
- * Determines if the value of this component is hidden from the user as if it is coming from the server, but is
- * protected.
- *
- * @return {boolean|*}
- */
- isValueHidden() {
- if (this.component.protected && this.root.editing) {
- return false;
- }
- if (!this.root || !this.root.hasOwnProperty('editing')) {
- return false;
- }
- if (!this.root || !this.root.editing) {
- return false;
- }
- return (this.component.protected || !this.component.persistent || (this.component.persistent === 'client-only'));
- }
-
- shouldSkipValidation(data, dirty, row) {
- const rules = [
- // Force valid if component is read-only
- () => this.options.readOnly,
- // Do not check validations if component is not an input component.
- () => !this.hasInput,
- // Check to see if we are editing and if so, check component persistence.
- () => this.isValueHidden(),
- // Force valid if component is hidden.
- () => !this.visible,
- // Force valid if component is conditionally hidden.
- () => !this.checkCondition(row, data)
- ];
-
- return rules.some(pred => pred());
- }
-
- // Maintain reverse compatibility.
- whenReady() {
- console.warn('The whenReady() method has been deprecated. Please use the dataReady property instead.');
- return this.dataReady;
- }
-
- get dataReady() {
- return NativePromise.resolve();
- }
-
- /**
- * Prints out the value of this component as a string value.
- */
- asString(value) {
- value = value || this.getValue();
- return (Array.isArray(value) ? value : [value]).map(_.toString).join(', ');
- }
-
- /**
- * Return if the component is disabled.
- * @return {boolean}
- */
- get disabled() {
- return this._disabled || this.parentDisabled;
- }
-
- /**
- * Disable this component.
- *
- * @param {boolean} disabled
- */
- set disabled(disabled) {
- this._disabled = disabled;
- }
-
- setDisabled(element, disabled) {
- if (!element) {
- return;
- }
- element.disabled = disabled;
- if (disabled) {
- element.setAttribute('disabled', 'disabled');
- }
- else {
- element.removeAttribute('disabled');
- }
- }
-
- setLoading(element, loading) {
- if (!element || (element.loading === loading)) {
- return;
- }
-
- element.loading = loading;
- if (!element.loader && loading) {
- element.loader = this.ce('i', {
- class: `${this.iconClass('refresh', true)} button-icon-right`
- });
- }
- if (element.loader) {
- if (loading) {
- this.appendTo(element.loader, element);
- }
- else {
- this.removeChildFrom(element.loader, element);
- }
- }
- }
-
- selectOptions(select, tag, options, defaultValue) {
- _.each(options, (option) => {
- const attrs = {
- value: option.value
- };
- if (defaultValue !== undefined && (option.value === defaultValue)) {
- attrs.selected = 'selected';
- }
- const optionElement = this.ce('option', attrs);
- optionElement.appendChild(this.text(option.label));
- select.appendChild(optionElement);
- });
- }
-
- setSelectValue(select, value) {
- const options = select.querySelectorAll('option');
- _.each(options, (option) => {
- if (option.value === value) {
- option.setAttribute('selected', 'selected');
- }
- else {
- option.removeAttribute('selected');
- }
- });
- if (select.onchange) {
- select.onchange();
- }
- if (select.onselect) {
- select.onselect();
- }
- }
-
- getRelativePath(path) {
- const keyPart = `.${this.key}`;
- const thisPath = this.isInputComponent ? this.path
- : this.path.slice(0).replace(keyPart, '');
- return path.replace(thisPath, '');
- }
-
- clear() {
- this.detach();
- this.empty(this.getElement());
- }
-
- append(element) {
- this.appendTo(element, this.element);
- }
-
- prepend(element) {
- this.prependTo(element, this.element);
- }
-
- removeChild(element) {
- this.removeChildFrom(element, this.element);
- }
-
- detachLogic() {
- this.logic.forEach(logic => {
- if (logic.trigger.type === 'event') {
- const event = this.interpolate(logic.trigger.event);
- this.off(event); // only applies to callbacks on this component
- }
- });
- }
-
- attachLogic() {
- // Do not attach logic during builder mode.
- if (this.builderMode) {
- return;
- }
- this.logic.forEach((logic) => {
- if (logic.trigger.type === 'event') {
- const event = this.interpolate(logic.trigger.event);
- this.on(event, (...args) => {
- const newComponent = fastCloneDeep(this.originalComponent);
- if (this.applyActions(newComponent, logic.actions, args)) {
- // If component definition changed, replace it.
- if (!_.isEqual(this.component, newComponent)) {
- this.component = newComponent;
- const visible = this.conditionallyVisible(null, null);
- const disabled = this.shouldDisabled;
-
- // Change states which won't be recalculated during redrawing
- if (this.visible !== visible) {
- this.visible = visible;
- }
- if (this.disabled !== disabled) {
- this.disabled = disabled;
- }
-
- this.redraw();
- }
- }
- }, true);
- }
- });
- }
-
- /**
- * Get the element information.
- */
- elementInfo() {
- const attributes = {
- name: this.options.name,
- type: this.component.inputType || 'text',
- class: 'form-control',
- lang: this.options.language
- };
-
- if (this.component.placeholder) {
- attributes.placeholder = this.t(this.component.placeholder, { _userInput: true });
- }
-
- if (this.component.tabindex) {
- attributes.tabindex = this.component.tabindex;
- }
-
- if (this.disabled) {
- attributes.disabled = 'disabled';
- }
-
- _.defaults(attributes, this.component.attributes);
-
- return {
- type: 'input',
- component: this.component,
- changeEvent: 'change',
- attr: attributes
- };
- }
-
- autofocus() {
- const hasAutofocus = this.component.autofocus && !this.builderMode && !this.options.preview;
-
- if (hasAutofocus) {
- this.on('render', () => this.focus(), true);
- }
- }
-
- scrollIntoView(element = this.element) {
- if (!element) {
- return;
- }
- const { left, top } = element.getBoundingClientRect();
- window.scrollTo(left + window.scrollX, top + window.scrollY);
- }
-
- focus(index) {
- if ('beforeFocus' in this.parent) {
- this.parent.beforeFocus(this);
- }
-
- if (this.refs.input?.length) {
- const focusingInput = typeof index === 'number' && this.refs.input[index]
- ? this.refs.input[index]
- : this.refs.input[this.refs.input.length - 1];
-
- if (this.component.widget?.type === 'calendar') {
- const sibling = focusingInput.nextSibling;
-
- if (sibling) {
- sibling.focus();
- }
- }
- else {
- focusingInput.focus();
- }
- }
-
- if (this.refs.openModal) {
- this.refs.openModal.focus();
- }
-
- if (this.parent.refs.openModal) {
- this.parent.refs.openModal.focus();
- }
- }
-
- /**
- * Get `Formio` instance for working with files
- */
- get fileService() {
- if (this.options.fileService) {
- return this.options.fileService;
- }
- if (this.options.formio) {
- return this.options.formio;
- }
- if (this.root && this.root.formio) {
- return this.root.formio;
- }
- const formio = new Formio();
- // If a form is loaded, then make sure to set the correct formUrl.
- if (this.root && this.root._form && this.root._form._id) {
- formio.formUrl = `${formio.projectUrl}/form/${this.root._form._id}`;
- }
- return formio;
- }
-
- resetCaches() {}
-
- get previewMode() {
- return false;
- }
-}
-
-Component.externalLibraries = {};
-Component.requireLibrary = function(name, property, src, polling) {
- if (!Component.externalLibraries.hasOwnProperty(name)) {
- Component.externalLibraries[name] = {};
- Component.externalLibraries[name].ready = new NativePromise((resolve, reject) => {
- Component.externalLibraries[name].resolve = resolve;
- Component.externalLibraries[name].reject = reject;
- });
-
- const callbackName = `${name}Callback`;
-
- if (!polling && !window[callbackName]) {
- window[callbackName] = function() {
- this.resolve();
- }.bind(Component.externalLibraries[name]);
- }
- // See if the plugin already exists.
- const plugin = _.get(window, property);
- if (plugin) {
- Component.externalLibraries[name].resolve(plugin);
- }
- else {
- src = Array.isArray(src) ? src : [src];
- src.forEach((lib) => {
- let attrs = {};
- let elementType = '';
- if (typeof lib === 'string') {
- lib = {
- type: 'script',
- src: lib
- };
- }
- switch (lib.type) {
- case 'script':
- elementType = 'script';
- attrs = {
- src: lib.src,
- type: 'text/javascript',
- defer: true,
- async: true
- };
- break;
- case 'styles':
- elementType = 'link';
- attrs = {
- href: lib.src,
- rel: 'stylesheet'
- };
- break;
- }
-
- // Add the script to the top page.
- const script = document.createElement(elementType);
- for (const attr in attrs) {
- script.setAttribute(attr, attrs[attr]);
- }
- document.getElementsByTagName('head')[0].appendChild(script);
- });
-
- // if no callback is provided, then check periodically for the script.
- if (polling) {
- setTimeout(function checkLibrary() {
- const plugin = _.get(window, property);
- if (plugin) {
- Component.externalLibraries[name].resolve(plugin);
- }
- else {
- // check again after 200 ms.
- setTimeout(checkLibrary, 200);
- }
- }, 200);
- }
- }
- }
- return Component.externalLibraries[name].ready;
-};
-
-Component.libraryReady = function(name) {
- if (
- Component.externalLibraries.hasOwnProperty(name) &&
- Component.externalLibraries[name].ready
- ) {
- return Component.externalLibraries[name].ready;
- }
-
- return NativePromise.reject(`${name} library was not required.`);
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.unit.js
deleted file mode 100644
index 46606065..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/Component.unit.js
+++ /dev/null
@@ -1,373 +0,0 @@
-'use strict';
-import assert from 'power-assert';
-import { expect } from 'chai';
-import sinon from 'sinon';
-import Component from './Component';
-import Webform from '../../../Webform';
-import Harness from '../../../../test/harness';
-import { comp1 } from './fixtures';
-import _merge from 'lodash/merge';
-import comp3 from './fixtures/comp3';
-import comp4 from './fixtures/comp4';
-import comp5 from './fixtures/comp5';
-
-describe('Component', () => {
- it('Should create a Component', (done) => {
- const component = new Component();
-
- // Test that we have a proper constructed component.
- assert.equal(component.options.renderMode, 'form');
- assert.equal(component.options.attachMode, 'full');
- assert.equal(component.attached, false);
- assert.equal(component.rendered, false);
- done();
- });
-
- it('Should build a base component', () => {
- return Harness.testCreate(Component, { type: 'base' }).then((component) => {
- const element = component.element.querySelector('[ref="component"]');
- assert.equal(element.textContent.trim(), 'Unknown component: base');
- });
- });
-
- it('Should provide required validation', (done) => {
- Harness.testCreate(Component, _merge({}, comp1, {
- validate: { required: true }
- })).then((component) => Harness.testComponent(component, {
- bad: {
- value: '',
- field: 'firstName',
- error: 'First Name is required'
- },
- good: {
- value: 'te'
- }
- }, done)).catch(done);
- });
-
- it('Should provide minLength validation', (done) => {
- Harness.testCreate(Component, _merge({}, comp1, {
- validate: { minLength: 2 }
- })).then((component) => Harness.testComponent(component, {
- bad: {
- value: 't',
- field: 'firstName',
- error: 'First Name must have at least 2 characters.'
- },
- good: {
- value: 'te'
- }
- }, done));
- });
-
- it('Should provide maxLength validation', (done) => {
- Harness.testCreate(Component, _merge({}, comp1, {
- validate: { maxLength: 5 }
- })).then((component) => Harness.testComponent(component, {
- bad: {
- value: 'testte',
- field: 'firstName',
- error: 'First Name must have no more than 5 characters.'
- },
- good: {
- value: 'te'
- }
- }, done));
- });
-
- it('Should provide maxWords validation', (done) => {
- Harness.testCreate(Component, _merge({}, comp1, {
- validate: { maxWords: 2 }
- })).then((component) => Harness.testComponent(component, {
- bad: {
- value: 'test test test',
- field: 'firstName',
- error: 'First Name must have no more than 2 words.'
- },
- good: {
- value: 'te st'
- }
- }, done));
- });
-
- it('Should provide minWords validation', (done) => {
- Harness.testCreate(Component, _merge({}, comp1, {
- validate: { minWords: 2 }
- })).then((component) => Harness.testComponent(component, {
- bad: {
- value: 'test',
- field: 'firstName',
- error: 'First Name must have at least 2 words.'
- },
- good: {
- value: 'te st'
- }
- }, done));
- });
-
- it('Should provide custom validation', (done) => {
- Harness.testCreate(Component, _merge({}, comp1, {
- validate: {
- custom: 'valid = (input !== "Joe") ? true : "You cannot be Joe"'
- }
- })).then((component) => Harness.testComponent(component, {
- bad: {
- value: 'Joe',
- field: 'firstName',
- error: 'You cannot be Joe'
- },
- good: {
- value: 'Tom'
- }
- }, done));
- });
-
- it('Should provide json validation', (done) => {
- Harness.testCreate(Component, _merge({}, comp1, {
- validate: {
- json: {
- 'if': [
- {
- '===': [
- { var: 'data.firstName' },
- 'Joe'
- ]
- },
- true,
- 'You must be Joe'
- ]
- }
- }
- })).then((component) => Harness.testComponent(component, {
- bad: {
- value: 'Tom',
- field: 'firstName',
- error: 'You must be Joe'
- },
- good: {
- value: 'Joe'
- }
- }, done));
- });
-
- it('Should mark as invalid calculated fields that are invalid', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- const formJson = {
- components: [
- {
- label: 'A',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'a',
- type: 'number',
- input: true
- },
- {
- label: 'B',
- mask: false,
- disabled: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- calculateValue: 'value = data.a + 1;',
- validate: {
- custom: 'valid = input <= 10 ? true : \'B should be less or equal to 10\';'
- },
- key: 'b',
- type: 'number',
- input: true
- }
- ],
- };
-
- form.setForm(formJson).then(() => {
- return form.setSubmission({
- data: {
- a: 1
- }
- });
- })
- .then(() => {
- setTimeout(() => {
- const a = form.getComponent('a');
- a.updateComponentValue(10);
- setTimeout(()=> {
- const b = form.getComponent('b');
- expect(b.refs.messageContainer?.innerHTML.indexOf('B should be less or equal to 10') > -1).to.be.true;
- expect(b.refs.input[0].classList.contains('is-invalid')).to.be.true;
- done();
- }, 300);
- }, 300);
- })
- .catch(done);
- });
-
- describe('shouldSkipValidation', () => {
- it('should return true if component is hidden', done => {
- Harness.testCreate(Component, comp1)
- .then(cmp => {
- cmp.visible = false;
- cmp.checkCondition = () => true;
- expect(cmp.visible).to.be.false;
- expect(cmp.checkCondition()).to.be.true;
- expect(cmp.shouldSkipValidation()).to.be.true;
- done();
- }, done)
- .catch(done);
- });
-
- it('should return true if component is conditionally hidden', done => {
- Harness.testCreate(Component, comp1)
- .then(cmp => {
- cmp.visible = true;
- cmp.checkCondition = () => false;
- expect(cmp.visible).to.be.true;
- expect(cmp.checkCondition()).to.be.false;
- expect(cmp.shouldSkipValidation()).to.be.true;
- done();
- }, done)
- .catch(done);
- });
-
- it('should return false if not hidden', done => {
- Harness.testCreate(Component, comp1)
- .then(cmp => {
- cmp.visible = true;
- cmp.checkCondition = () => true;
- expect(cmp.visible).to.be.true;
- expect(cmp.checkCondition()).to.be.true;
- expect(cmp.shouldSkipValidation()).to.be.false;
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('Component Modal', () => {
- it('Modal window should stay opened after redrawing component if it was opened ont hte moment of calling', (done) => {
- Harness.testCreate(Component, comp3).then((component) => {
- component.componentModal.openModal();
- component.redraw().then(() => {
- const isVisible = !component.componentModal.refs.modalWrapper.classList.contains('component-rendering-hidden');
- assert(isVisible);
- done();
- }).catch(done);
- }).catch(done);
- });
- });
-
- it('Should return value for HTML mode', () => {
- return Harness.testCreate(Component, comp1).then((component) => {
- assert.equal(component.itemValueForHTMLMode(['option 1', 'option 2', 'option 3']), 'option 1, option 2, option 3');
- assert.equal(component.itemValueForHTMLMode(['option 1', ['option 2', 'option 3']]), 'option 1, option 2, option 3');
- assert.equal(component.itemValueForHTMLMode(['2020-03-18T15:00:00.000Z', '2020-03-31T09:05:00.000Z']), '2020-03-18T15:00:00.000Z, 2020-03-31T09:05:00.000Z');
- assert.equal(component.itemValueForHTMLMode('test'), 'test');
- });
- });
-
- it('Should protect against change loops', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- const formJson = {
- components: [
- {
- key: 'textField',
- label: 'Text Field',
- type: 'textfield',
- calculateValue: "value = value + '_calculated'",
- },
- ],
- };
-
- form.setForm(formJson).then(() => {
- const textField = form.getComponent('textField');
- const spy = sinon.spy(textField, 'calculateComponentValue');
- form.onChange({ textField: 'test' });
-
- setTimeout(() => {
- expect(spy.calledOnce).to.be.true;
-
- done();
- }, 500);
- })
- .catch((err) => done(err));
- });
-
- it('Should mark as invalid only invalid fields in multiple components', function(done) {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- const formJson = {
- components: [
- {
- label: 'Email',
- tableView: true,
- multiple: true,
- validate: {
- required: true
- },
- key: 'email',
- type: 'email',
- input: true
- },
- ],
- };
-
- form.setForm(formJson).then(() => {
- return form.setSubmission({
- data: {
- email: [
- 'oleg@form.io',
- 'oleg@form',
- '',
- ]
- }
- });
- })
- .then(() => {
- setTimeout(() => {
- const email = form.getComponent('email');
- expect(email.refs.input[0].classList.contains('is-invalid')).to.be.false;
- expect(email.refs.input[1].classList.contains('is-invalid')).to.be.true;
- expect(email.refs.input[2].classList.contains('is-invalid')).to.be.true;
- done();
- }, 300);
- })
- .catch(done);
- });
-
- it('Should sanitize HTML even if options.pdf is set', (done) => {
- const component = new Component({}, { pdf: true });
- assert.equal(component.sanitize(' '), ' ');
- done();
- });
-
- describe('shouldDisplayRedAsterisk', () => {
- it('modalPreview template should have className "field-required" if component is required', done => {
- Harness.testCreate(Component, _merge({}, comp4, {
- validate: { required: true }
- })).then(cmp => {
- assert.equal(!!cmp.element.querySelector('.field-required'), true);
- done();
- }, done)
- .catch(done);
- });
- });
-
- it('Should not execute code inside Tooltips/Description', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(comp5).then(() => {
- setTimeout(() => {
- assert.equal(window._ee, undefined, 'Should not execute code inside Tooltips/Description');
- done();
- }, 200);
- })
- .catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.addons.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.addons.js
deleted file mode 100644
index b3ac3f7d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.addons.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import { editForms } from '../../../../addons';
-import Addons from '../../../../addons';
-
-export default [
- {
- type: 'editgrid',
- addAnother: 'Add Addon',
- saveRow: 'Save Addon',
- weight: 28,
- input: true,
- key: 'addons',
- label: 'Addons',
- components: [
- {
- label: 'Name',
- tableView: true,
- key: 'name',
- type: 'select',
- dataSrc: 'custom',
- data: {
- custom: function({ instance }) {
- const componentType = instance?.root?.data?.type;
- const availableAddons = Object.keys(Addons).filter((key) => {
- if (Addons[key]?.info?.supportedComponents?.includes(componentType)) {
- return true;
- }
- return false;
- });
- return availableAddons.map((addonKey) => ({
- value: addonKey,
- label: Addons[addonKey].info.label || addonKey,
- }));
- },
- },
- input: true
- },
- ...editForms,
- ]
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.api.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.api.js
deleted file mode 100644
index d1cb45af..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.api.js
+++ /dev/null
@@ -1,38 +0,0 @@
-export default [
- {
- weight: 0,
- type: 'textfield',
- input: true,
- key: 'key',
- label: 'Property Name',
- tooltip: 'The name of this field in the API endpoint.',
- validate: {
- pattern: '(\\w|\\w[\\w-.]*\\w)',
- patternMessage: 'The property name must only contain alphanumeric characters, underscores, dots and dashes and should not be ended by dash or dot.',
- required: true
- }
- },
- {
- weight: 100,
- type: 'tags',
- input: true,
- label: 'Field Tags',
- storeas: 'array',
- tooltip: 'Tag the field for use in custom logic.',
- key: 'tags'
- },
- {
- weight: 200,
- type: 'datamap',
- label: 'Custom Properties',
- tooltip: 'This allows you to configure any custom properties for this component.',
- key: 'properties',
- valueComponent: {
- type: 'textfield',
- key: 'value',
- label: 'Value',
- placeholder: 'Value',
- input: true
- }
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.conditional.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.conditional.js
deleted file mode 100644
index 4a6f6917..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.conditional.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import EditFormUtils from './utils';
-import { getContextComponents } from '../../../../utils/utils';
-/* eslint-disable quotes, max-len */
-export default [
- {
- type: 'panel',
- title: 'Simple',
- key: 'simple-conditional',
- theme: 'default',
- weight: 105,
- components: [
- {
- type: 'select',
- input: true,
- label: 'This component should Display:',
- key: 'conditional.show',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'True', value: 'true' },
- { label: 'False', value: 'false' }
- ]
- }
- },
- {
- type: 'select',
- input: true,
- label: 'When the form component:',
- key: 'conditional.when',
- dataSrc: 'custom',
- valueProperty: 'value',
- data: {
- custom(context) {
- return getContextComponents(context);
- }
- }
- },
- {
- type: 'textfield',
- input: true,
- label: 'Has the value:',
- key: 'conditional.eq'
- }
- ]
- },
- EditFormUtils.javaScriptValue('Advanced Conditions', 'customConditional', 'conditional.json', 110,
- 'You must assign the show variable a boolean result.
' +
- 'Note: Advanced Conditional logic will override the results of the Simple Conditional logic.
' +
- 'Example show = !!data.showMe; ',
- 'Click here for an example
'
- )
-];
-/* eslint-enable quotes, max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.data.js
deleted file mode 100644
index 6e8c94d7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.data.js
+++ /dev/null
@@ -1,163 +0,0 @@
-import EditFormUtils from './utils';
-/* eslint-disable max-len */
-export default [
- {
- weight: 0,
- type: 'checkbox',
- label: 'Multiple Values',
- tooltip: 'Allows multiple values to be entered for this field.',
- key: 'multiple',
- input: true
- },
- {
- type: 'textfield',
- label: 'Default Value',
- key: 'defaultValue',
- weight: 5,
- placeholder: 'Default Value',
- tooltip: 'The Default Value will be the value for this field, before user interaction. Having a default value will override the placeholder text.',
- input: true
- },
- {
- weight: 30,
- type: 'radio',
- label: 'Persistent',
- tooltip: 'A persistent field will be stored in database when the form is submitted.',
- key: 'persistent',
- input: true,
- inline: true,
- defaultValue: true,
- values: [
- { label: 'None', value: false },
- { label: 'Server', value: true },
- { label: 'Client', value: 'client-only' },
- ]
- },
- {
- weight: 150,
- type: 'checkbox',
- label: 'Protected',
- tooltip: 'A protected field will not be returned when queried via API.',
- key: 'protected',
- input: true
- },
- {
- type: 'checkbox',
- input: true,
- weight: 200,
- key: 'dbIndex',
- label: 'Database Index',
- tooltip: 'Set this field as an index within the database. Increases performance for submission queries.'
- },
- {
- weight: 400,
- type: 'checkbox',
- label: 'Encrypted',
- tooltip: 'Encrypt this field on the server. This is two way encryption which is not suitable for passwords.',
- key: 'encrypted',
- input: true,
- logic: [
- {
- name: 'disabled',
- trigger: {
- type: 'javascript',
- javascript: 'result = !instance.root.options.sac;'
- },
- actions: [
- {
- name: 'disabled',
- type: 'property',
- property: {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean'
- },
- state: true
- }
- ]
- },
- {
- name: 'disabledToolTip',
- trigger: {
- type: 'javascript',
- javascript: 'result = !instance.root.options.sac;'
- },
- actions: [
- {
- name: 'addDisabledTooltip',
- type: 'property',
- property: {
- label: 'Tooltip',
- value: 'tooltip',
- type: 'string'
- },
- text: 'Only available with Security Module. Contact sales@form.io for more information.'
- }
- ]
- }
- ]
- },
- {
- type: 'select',
- input: true,
- key: 'redrawOn',
- label: 'Redraw On',
- weight: 600,
- tooltip: 'Redraw this component if another component changes. This is useful if interpolating parts of the component like the label.',
- dataSrc: 'custom',
- valueProperty: 'value',
- data: {
- custom(context) {
- var values = [];
- values.push({ label: 'Any Change', value: 'data' });
- context.utils.eachComponent(context.instance.options.editForm.components, function(component, path) {
- if (component.key !== context.data.key) {
- values.push({
- label: component.label || component.key,
- value: path
- });
- }
- });
- return values;
- }
- },
- conditional: {
- json: { '!' : [{ var: 'data.dataSrc' }] },
- },
- },
- {
- weight: 700,
- type: 'checkbox',
- label: 'Clear Value When Hidden',
- key: 'clearOnHide',
- defaultValue: true,
- tooltip: 'When a field is hidden, clear the value.',
- input: true
- },
- EditFormUtils.javaScriptValue('Custom Default Value', 'customDefaultValue', 'customDefaultValue', 1000,
- '
Example: value = data.firstName + " " + data.lastName; ',
- '
Example: {"cat": [{"var": "data.firstName"}, " ", {"var": "data.lastName"}]} '
- ),
- EditFormUtils.javaScriptValue('Calculated Value', 'calculateValue', 'calculateValue', 1100,
- '
Example: value = data.a + data.b + data.c; ',
- '
Example: {"+": [{"var": "data.a"}, {"var": "data.b"}, {"var": "data.c"}]} Click here for an example
',
-'token The decoded JWT token for the authenticated user. '
- ),
- {
- type: 'checkbox',
- input: true,
- weight: 1100,
- key: 'calculateServer',
- label: 'Calculate Value on server',
- tooltip: 'Checking this will run the calculation on the server. This is useful if you wish to override the values submitted with the calculations performed on the server.'
- },
- {
- type: 'checkbox',
- input: true,
- weight: 1200,
- key: 'allowCalculateOverride',
- label: 'Allow Manual Override of Calculated Value',
- tooltip: 'When checked, this will allow the user to manually override the calculated value.'
- },
-];
-/* eslint-enable max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.display.js
deleted file mode 100644
index b6159d9d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.display.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/* eslint-disable max-len */
-export default [
- {
- weight: 0,
- type: 'textfield',
- input: true,
- key: 'label',
- label: 'Label',
- placeholder: 'Field Label',
- tooltip: 'The label for this field that will appear next to it.',
- validate: {
- required: true
- },
- autofocus: true,
- },
- {
- type: 'select',
- input: true,
- key: 'labelPosition',
- label: 'Label Position',
- tooltip: 'Position for the label for this field.',
- weight: 20,
- defaultValue: 'top',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Top', value: 'top' },
- { label: 'Left (Left-aligned)', value: 'left-left' },
- { label: 'Left (Right-aligned)', value: 'left-right' },
- { label: 'Right (Left-aligned)', value: 'right-left' },
- { label: 'Right (Right-aligned)', value: 'right-right' },
- { label: 'Bottom', value: 'bottom' }
- ]
- }
- },
- {
- type: 'number',
- input: true,
- key: 'labelWidth',
- label: 'Label Width',
- tooltip: 'The width of label on line in percentages.',
- clearOnHide: false,
- weight: 30,
- placeholder: '30',
- suffix: '%',
- validate: {
- min: 0,
- max: 100
- },
- conditional: {
- json: {
- and: [
- { '!==': [{ var: 'data.labelPosition' }, 'top'] },
- { '!==': [{ var: 'data.labelPosition' }, 'bottom'] },
- ]
- }
- }
- },
- {
- type: 'number',
- input: true,
- key: 'labelMargin',
- label: 'Label Margin',
- tooltip: 'The width of label margin on line in percentages.',
- clearOnHide: false,
- weight: 30,
- placeholder: '3',
- suffix: '%',
- validate: {
- min: 0,
- max: 100
- },
- conditional: {
- json: {
- and: [
- { '!==': [{ var: 'data.labelPosition' }, 'top'] },
- { '!==': [{ var: 'data.labelPosition' }, 'bottom'] },
- ]
- }
- }
- },
- {
- weight: 100,
- type: 'textfield',
- input: true,
- key: 'placeholder',
- label: 'Placeholder',
- placeholder: 'Placeholder',
- tooltip: 'The placeholder text that will appear when this field is empty.'
- },
- {
- weight: 200,
- type: 'textarea',
- input: true,
- key: 'description',
- label: 'Description',
- placeholder: 'Description for this field.',
- tooltip: 'The description is text that will appear below the input field.',
- editor: 'ace',
- as: 'html',
- wysiwyg: {
- minLines: 3,
- isUseWorkerDisabled: true,
- },
- },
- {
- weight: 300,
- type: 'textarea',
- input: true,
- key: 'tooltip',
- label: 'Tooltip',
- placeholder: 'To add a tooltip to this field, enter text here.',
- tooltip: 'Adds a tooltip to the side of this field.',
- editor: 'ace',
- as: 'html',
- wysiwyg: {
- minLines: 3,
- isUseWorkerDisabled: true,
- },
- },
- {
- weight: 500,
- type: 'textfield',
- input: true,
- key: 'customClass',
- label: 'Custom CSS Class',
- placeholder: 'Custom CSS Class',
- tooltip: 'Custom CSS class to add to this component.'
- },
- {
- weight: 600,
- type: 'textfield',
- input: true,
- key: 'tabindex',
- label: 'Tab Index',
- placeholder: '0',
- tooltip: 'Sets the tabindex attribute of this component to override the tab order of the form. See the MDN documentation on tabindex for more information.'
- },
- {
- weight: 1100,
- type: 'checkbox',
- label: 'Hidden',
- tooltip: 'A hidden field is still a part of the form, but is hidden from view.',
- key: 'hidden',
- input: true
- },
- {
- weight: 1200,
- type: 'checkbox',
- label: 'Hide Label',
- tooltip: 'Hide the label (title, if no label) of this component. This allows you to show the label in the form builder, but not when it is rendered.',
- key: 'hideLabel',
- input: true
- },
- {
- weight: 1350,
- type: 'checkbox',
- label: 'Initial Focus',
- tooltip: 'Make this field the initially focused element on this form.',
- key: 'autofocus',
- input: true
- },
- {
- weight: 1370,
- type: 'checkbox',
- label: 'Show Label in DataGrid',
- tooltip: 'Show the label inside each row when in a Datagrid.',
- key: 'dataGridLabel',
- input: true,
- customConditional(context) {
- return context.instance.options?.flags?.inDataGrid;
- }
- },
- {
- weight: 1400,
- type: 'checkbox',
- label: 'Disabled',
- tooltip: 'Disable the form input.',
- key: 'disabled',
- input: true
- },
- {
- weight: 1500,
- type: 'checkbox',
- label: 'Table View',
- tooltip: 'Shows this value within the table view of the submissions.',
- key: 'tableView',
- input: true
- },
- {
- weight: 1600,
- type: 'checkbox',
- label: 'Modal Edit',
- tooltip: 'Opens up a modal to edit the value of this component.',
- key: 'modalEdit',
- input: true
- },
-];
-/* eslint-enable max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.layout.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.layout.js
deleted file mode 100644
index de2da8f0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.layout.js
+++ /dev/null
@@ -1,78 +0,0 @@
-export default [
- {
- label: 'HTML Attributes',
- type: 'datamap',
- input: true,
- key: 'attributes',
- keyLabel: 'Attribute Name',
- valueComponent: {
- type: 'textfield',
- key: 'value',
- label: 'Attribute Value',
- input: true
- },
- tooltip: 'Provide a map of HTML attributes for component\'s input element (attributes provided by other component settings or other attributes generated by form.io take precedence over attributes in this grid)',
- addAnother: 'Add Attribute',
- },
- {
- type: 'panel',
- legend: 'PDF Overlay',
- title: 'PDF Overlay',
- key: 'overlay',
- tooltip: 'The settings inside apply only to the PDF forms.',
- weight: 2000,
- collapsible: true,
- collapsed: true,
- components: [
- {
- type: 'textfield',
- input: true,
- key: 'overlay.style',
- label: 'Style',
- placeholder: '',
- tooltip: 'Custom styles that should be applied to this component when rendered in PDF.'
- },
- {
- type: 'textfield',
- input: true,
- key: 'overlay.page',
- label: 'Page',
- placeholder: '',
- tooltip: 'The PDF page to place this component.'
- },
- {
- type: 'textfield',
- input: true,
- key: 'overlay.left',
- label: 'Left',
- placeholder: '',
- tooltip: 'The left margin within a page to place this component.'
- },
- {
- type: 'textfield',
- input: true,
- key: 'overlay.top',
- label: 'Top',
- placeholder: '',
- tooltip: 'The top margin within a page to place this component.'
- },
- {
- type: 'textfield',
- input: true,
- key: 'overlay.width',
- label: 'Width',
- placeholder: '',
- tooltip: 'The width of the component (in pixels).'
- },
- {
- type: 'textfield',
- input: true,
- key: 'overlay.height',
- label: 'Height',
- placeholder: '',
- tooltip: 'The height of the component (in pixels).'
- },
-
- ]
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.logic.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.logic.js
deleted file mode 100644
index 28b046c7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.logic.js
+++ /dev/null
@@ -1,413 +0,0 @@
-import EditFormUtils from './utils';
-import { getContextComponents } from '../../../../utils/utils';
-
-/* eslint-disable quotes, max-len */
-export default [
- {
- weight: 0,
- input: true,
- label: 'Advanced Logic',
- key: 'logic',
- templates: {
- header: ' \n
\n {{ value.length }} {{ ctx.t("Advanced Logic Configured") }} \n
\n
',
- row: ' \n
\n
\n
\n {{ ctx.t("Edit") }} \n {{ ctx.t("Delete") }} \n
\n
\n
',
- footer: '',
- },
- type: 'editgrid',
- addAnother: 'Add Logic',
- saveRow: 'Save Logic',
- components: [
- {
- weight: 0,
- input: true,
- inputType: 'text',
- label: 'Logic Name',
- key: 'name',
- validate: {
- required: true,
- },
- type: 'textfield',
- },
- {
- weight: 10,
- key: 'triggerPanel',
- input: false,
- title: 'Trigger',
- tableView: false,
- components: [
- {
- weight: 0,
- input: true,
- tableView: false,
- components: [
- {
- weight: 0,
- input: true,
- label: 'Type',
- key: 'type',
- tableView: false,
- data: {
- values: [
- {
- value: 'simple',
- label: 'Simple',
- },
- {
- value: 'javascript',
- label: 'Javascript',
- },
- {
- value: 'json',
- label: 'JSON Logic',
- },
- {
- value: 'event',
- label: 'Event',
- },
- ],
- },
- dataSrc: 'values',
- template: '{{ item.label }} ',
- type: 'select',
- },
- {
- weight: 10,
- label: '',
- key: 'simple',
- type: 'container',
- tableView: false,
- customConditional({ row }) {
- return row.type === 'simple';
- },
- components: [
- {
- input: true,
- key: 'show',
- label: 'Show',
- type: 'hidden',
- tableView: false,
- calculateValue() {
- return true;
- },
- },
- {
- type: 'select',
- input: true,
- label: 'When the form component:',
- key: 'when',
- dataSrc: 'custom',
- valueProperty: 'value',
- tableView: false,
- data: {
- custom(context) {
- return getContextComponents(context);
- },
- },
- },
- {
- type: 'textfield',
- input: true,
- label: 'Has the value:',
- key: 'eq',
- tableView: false,
- },
- ],
- },
- {
- weight: 10,
- type: 'textarea',
- key: 'javascript',
- rows: 5,
- editor: 'ace',
- as: 'javascript',
- input: true,
- tableView: false,
- placeholder: `result = (data['mykey'] > 1);`,
- description: '"row", "data", and "component" variables are available. Return "result".',
- customConditional({ row }) {
- return row.type === 'javascript';
- },
- },
- {
- weight: 10,
- type: 'textarea',
- key: 'json',
- rows: 5,
- editor: 'ace',
- label: 'JSON Logic',
- as: 'json',
- input: true,
- tableView: false,
- placeholder: `{ ... }`,
- description: '"row", "data", "component" and "_" variables are available. Return the result to be passed to the action if truthy.',
- customConditional({ row }) {
- return row.type === 'json';
- },
- },
- {
- weight: 10,
- type: 'textfield',
- key: 'event',
- label: 'Event Name',
- placeholder: 'event',
- description: 'The event that will trigger this logic. You can trigger events externally or via a button.',
- tableView: false,
- customConditional({ row }) {
- return row.type === 'event';
- },
- },
- ],
- key: 'trigger',
- type: 'container',
- },
- ],
- type: 'panel',
- },
- {
- weight: 20,
- input: true,
- label: 'Actions',
- key: 'actions',
- tableView: false,
- templates: {
- header: ' \n
{{ value.length }} {{ ctx.t("actions") }}
\n
',
- row: ' \n
\n
\n
\n {{ ctx.t("Edit") }} \n {{ ctx.t("Delete") }} \n
\n
\n
',
- footer: '',
- },
- type: 'editgrid',
- addAnother: 'Add Action',
- saveRow: 'Save Action',
- components: [
- {
- weight: 0,
- title: 'Action',
- input: false,
- key: 'actionPanel',
- type: 'panel',
- components: [
- {
- weight: 0,
- input: true,
- inputType: 'text',
- label: 'Action Name',
- key: 'name',
- validate: {
- required: true,
- },
- type: 'textfield',
- },
- {
- weight: 10,
- input: true,
- label: 'Type',
- key: 'type',
- data: {
- values: [
- {
- value: 'property',
- label: 'Property',
- },
- {
- value: 'value',
- label: 'Value',
- },
- {
- label: 'Merge Component Schema',
- value: 'mergeComponentSchema',
- },
- {
- label: 'Custom Action',
- value: 'customAction',
- },
- ],
- },
- dataSrc: 'values',
- template: '{{ item.label }} ',
- type: 'select',
- },
- {
- weight: 20,
- type: 'select',
- template: '{{ item.label }} ',
- dataSrc: 'json',
- tableView: false,
- data: {
- json: [
- {
- label: 'Hidden',
- value: 'hidden',
- type: 'boolean',
- },
- {
- label: 'Required',
- value: 'validate.required',
- type: 'boolean',
- },
- {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean',
- },
- {
- label: 'Label',
- value: 'label',
- type: 'string',
- },
- {
- label: 'Title',
- value: 'title',
- type: 'string',
- },
- {
- label: 'Prefix',
- value: 'prefix',
- type: 'string',
- },
- {
- label: 'Suffix',
- value: 'suffix',
- type: 'string',
- },
- {
- label: 'Tooltip',
- value: 'tooltip',
- type: 'string',
- },
- {
- label: 'Description',
- value: 'description',
- type: 'string',
- },
- {
- label: 'Placeholder',
- value: 'placeholder',
- type: 'string',
- },
- {
- label: 'Input Mask',
- value: 'inputMask',
- type: 'string',
- },
- {
- label: 'CSS Class',
- value: 'className',
- type: 'string',
- },
- {
- label: 'Container Custom Class',
- value: 'customClass',
- type: 'string',
- },
- ],
- },
- key: 'property',
- label: 'Component Property',
- input: true,
- customConditional({ row }) {
- return row.type === 'property';
- },
- },
- {
- weight: 30,
- input: true,
- label: 'Set State',
- key: 'state',
- tableView: false,
- data: {
- values: [
- {
- label: 'True',
- value: 'true',
- },
- {
- label: 'False',
- value: 'false',
- },
- ],
- },
- dataSrc: 'values',
- template: '{{ item.label }} ',
- type: 'select',
- customConditional({ row }) {
- return row.type === 'property' &&
- row.hasOwnProperty('property') &&
- row.property.type === 'boolean';
- },
- },
- {
- weight: 30,
- type: 'textfield',
- key: 'text',
- label: 'Text',
- inputType: 'text',
- input: true,
- tableView: false,
- description: 'Can use templating with {{ data.myfield }}. "data", "row", "component" and "result" variables are available.',
- customConditional({ row }) {
- return row.type === 'property' &&
- row.hasOwnProperty('property') &&
- row.property.type === 'string' &&
- !row.property.component;
- },
- },
- {
- weight: 20,
- input: true,
- label: 'Value (Javascript)',
- key: 'value',
- editor: 'ace',
- as: 'javascript',
- rows: 5,
- placeholder: `value = data.myfield;`,
- type: 'textarea',
- tableView: false,
- description: '"row", "data", "component", and "result" variables are available. Return the value.',
- customConditional({ row }) {
- return row.type === 'value';
- },
- },
- {
- weight: 20,
- input: true,
- label: 'Schema Defenition',
- key: 'schemaDefinition',
- editor: 'ace',
- as: 'javascript',
- rows: 5,
- placeholder: `schema = { label: 'Updated' };`,
- type: 'textarea',
- tableView: false,
- description: '"row", "data", "component", and "result" variables are available. Return the schema.',
- customConditional({ row }) {
- return row.type === 'mergeComponentSchema';
- },
- },
- Object.assign(EditFormUtils.logicVariablesTable('input The value that was input into this component '),
- {
- customConditional({ row }) {
- return row.type === 'customAction';
- }
- }
- ),
- {
- weight: 20,
- input: true,
- label: 'Custom Action (Javascript)',
- key: 'customAction',
- editor: 'ace',
- rows: 5,
- placeholder: `value = data.myfield;`,
- type: 'textarea',
- tableView: false,
- customConditional({ row }) {
- return row.type === 'customAction';
- },
- },
- ],
- },
- ],
- },
- ],
- },
-];
-/* eslint-enable quotes, max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.validation.js
deleted file mode 100644
index cba0f612..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/Component.edit.validation.js
+++ /dev/null
@@ -1,205 +0,0 @@
-import EditFormUtils from './utils';
-import Evaluator from '../../../../utils/Evaluator';
-
-/* eslint-disable quotes, max-len */
-export default [
- {
- weight: 10,
- type: 'checkbox',
- label: 'Required',
- tooltip: 'A required field must be filled in before the form can be submitted.',
- key: 'validate.required',
- input: true
- },
- {
- weight: 100,
- type: 'checkbox',
- label: 'Unique',
- tooltip: 'Makes sure the data submitted for this field is unique, and has not been submitted before.',
- key: 'unique',
- input: true
- },
- {
- weight: 0,
- type: 'select',
- key: 'validateOn',
- defaultValue: 'change',
- input: true,
- label: 'Validate On',
- tooltip: 'Determines when this component should trigger front-end validation.',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Change', value: 'change' },
- { label: 'Blur', value: 'blur' }
- ]
- }
- },
- {
- weight: 190,
- type: 'textfield',
- input: true,
- key: 'errorLabel',
- label: 'Error Label',
- placeholder: 'Error Label',
- tooltip: 'The label for this field when an error occurs.'
- },
- {
- weight: 200,
- key: 'validate.customMessage',
- label: 'Custom Error Message',
- placeholder: 'Custom Error Message',
- type: 'textfield',
- tooltip: 'Error message displayed if any error occurred.',
- input: true
- },
- {
- type: 'panel',
- title: 'Custom Validation',
- collapsible: true,
- collapsed: true,
- style: { 'margin-bottom': '10px' },
- key: 'custom-validation-js',
- weight: 300,
- customConditional() {
- return !Evaluator.noeval || Evaluator.protectedEval;
- },
- components: [
- EditFormUtils.logicVariablesTable('input The value that was input into this component '),
- {
- type: 'textarea',
- key: 'validate.custom',
- rows: 5,
- editor: 'ace',
- hideLabel: true,
- as: 'javascript',
- input: true
- },
- {
- type: 'htmlelement',
- tag: 'div',
- content: `
-
- Enter custom validation code.
- You must assign the valid variable as either true or an error message if validation fails.
- Example:
- valid = (input === 'Joe') ? true : 'Your name must be "Joe"';
- `
- },
- {
- type: 'well',
- components: [
- {
- weight: 100,
- type: 'checkbox',
- label: 'Secret Validation',
- tooltip: 'Check this if you wish to perform the validation ONLY on the server side. This keeps your validation logic private and secret.',
- description: 'Check this if you wish to perform the validation ONLY on the server side. This keeps your validation logic private and secret.',
- key: 'validate.customPrivate',
- input: true
- }
- ]
- }
- ]
- },
- {
- type: 'panel',
- title: 'JSONLogic Validation',
- collapsible: true,
- collapsed: true,
- key: 'json-validation-json',
- weight: 400,
- components: [
- {
- type: 'htmlelement',
- tag: 'div',
- /* eslint-disable prefer-template */
- content: 'Execute custom logic using JSONLogic .
' +
- 'Example: ' +
- '' + JSON.stringify({
- "if": [
- { "===": [{ "var": "input" }, "Bob"] },
- true,
- "Your name must be 'Bob'!"
- ]
- }, null, 2) + ' '
- /* eslint-enable prefer-template */
- },
- {
- type: 'textarea',
- key: 'validate.json',
- hideLabel: true,
- rows: 5,
- editor: 'ace',
- as: 'json',
- input: true
- }
- ]
- },
- {
- type: 'panel',
- title: 'Custom Errors',
- collapsible: true,
- collapsed: true,
- key: 'errors',
- weight: 400,
- components: [
- {
- type: 'textarea',
- key: 'errors',
- hideLabel: true,
- rows: 5,
- editor: 'ace',
- as: 'json',
- input: true
- },
- {
- type: 'htmlelement',
- tag: 'div',
- content: `
- This allows you to set different custom error messages for different errors
- (in contrast to “Custom Error Message”, which only allows you to set one
- error message for all errors). E.g.
-
-{
- "required": "{ { field }} is required. Try again.",
- "maxLength": "{ { field }} is too long. Try again."
-}
-
- You can set the following keys (among others):
-
- r equired
- m in
- m ax
- m inLength
- m axLength
- m inWords
- m axWords
- i nvalid_email
- i nvalid_date
- i nvalid_day
- i nvalid_regex
- m ask
- p attern
- c ustom
-
-
- Depending on the error message some of the following template variables can be used in the script:
-
- { { f ield }}
is replaced with the label of the field.
- { { m in }}
- { { m ax }}
- { { l ength }}
- { { p attern }}
- { { m inDate }}
- { { m axDate }}
- { { m inYear }}
- { { m axYear }}
- { { r egex }}
-
- `
- }
- ]
- }
-];
-/* eslint-enable quotes, max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/utils.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/utils.js
deleted file mode 100644
index 1451da71..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/utils.js
+++ /dev/null
@@ -1,138 +0,0 @@
-import _ from 'lodash';
-import Evaluator from '../../../../utils/Evaluator';
-const EditFormUtils = {
- sortAndFilterComponents(components) {
- return _.filter(_.sortBy(components, 'weight'), (item) => !item.ignore);
- },
- unifyComponents(objValue, srcValue) {
- if (objValue.key && srcValue.key) {
- if (objValue.skipMerge || srcValue.skipMerge) {
- return false;
- }
- if (objValue.key === srcValue.key) {
- // Create complete objects by including missing keys.
- _.each(objValue, (value, prop) => {
- if (objValue.overrideEditForm || !srcValue.hasOwnProperty(prop)) {
- srcValue[prop] = value;
- }
- });
- _.each(srcValue, (value, prop) => {
- if (srcValue.overrideEditForm || !objValue.hasOwnProperty(prop)) {
- objValue[prop] = value;
- }
- });
-
- if (objValue.components) {
- srcValue.components = EditFormUtils.sortAndFilterComponents(
- _.unionWith(objValue.components, srcValue.components, EditFormUtils.unifyComponents)
- );
- }
- return true;
- }
- else {
- return false;
- }
- }
- return _.isEqual(objValue, srcValue);
- },
- logicVariablesTable(additional) {
- additional = additional || '';
- return {
- type: 'htmlelement',
- tag: 'div',
- /* eslint-disable prefer-template */
- content: 'The following variables are available in all scripts.
' +
- '' +
- additional +
- 'form The complete form JSON object ' +
- 'submission The complete submission object. ' +
- 'data The complete submission data object. ' +
- 'row Contextual "row" data, used within DataGrid, EditGrid, and Container components ' +
- 'component The current component JSON ' +
- 'instance The current component instance. ' +
- 'value The current value of the component. ' +
- 'moment The moment.js library for date manipulation. ' +
- '_ An instance of Lodash . ' +
- 'utils An instance of the FormioUtils object. ' +
- 'util An alias for "utils". ' +
- '
'
- /* eslint-enable prefer-template */
- };
- },
- javaScriptValue(title, property, propertyJSON, weight, exampleHTML, exampleJSON, additionalParams = '', excludeJSONLogic) {
- const components = [
- this.logicVariablesTable(additionalParams),
- {
- type: 'panel',
- title: 'JavaScript',
- collapsible: true,
- collapsed: false,
- style: { 'margin-bottom': '10px' },
- key: `${property}-js`,
- customConditional() {
- return !Evaluator.noeval || Evaluator.protectedEval;
- },
- components: [
- {
- type: 'textarea',
- key: property,
- rows: 5,
- editor: 'ace',
- hideLabel: true,
- as: 'javascript',
- input: true
- },
- {
- type: 'htmlelement',
- tag: 'div',
- content: `Enter custom javascript code.
${exampleHTML}`
- }
- ]
- },
- {
- type: 'panel',
- title: 'JSONLogic',
- collapsible: true,
- collapsed: true,
- key: `${property}-json`,
- components: [
- {
- type: 'htmlelement',
- tag: 'div',
- /* eslint-disable prefer-template */
- content: 'Execute custom logic using JSONLogic .
' +
- 'Full Lodash support is provided using an "_" before each operation, such as {"_sum": {var: "data.a"}}
' +
- exampleJSON
- /* eslint-enable prefer-template */
- },
- {
- type: 'textarea',
- key: propertyJSON,
- rows: 5,
- editor: 'ace',
- hideLabel: true,
- as: 'json',
- input: true
- }
- ]
- }
- ];
-
- if (excludeJSONLogic) {
- components.splice(2, 1);
- }
-
- return {
- type: 'panel',
- title: title,
- theme: 'default',
- collapsible: true,
- collapsed: true,
- key: `${property}Panel`,
- weight: weight,
- components
- };
- }
-};
-
-export default EditFormUtils;
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/utils.spec.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/utils.spec.js
deleted file mode 100644
index 2ae526fd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/editForm/utils.spec.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { expect } from 'chai';
-import _ from 'lodash';
-import utils from './utils';
-
-describe('Edit Form Utils', function() {
- describe('unifyComponents', () => {
- it('should merge all objects with the same key', () => {
- const components = [
- { key: 'a', label: 1, input: true },
- { key: 'a', one: 1, two: 2 },
- { key: 'b', one: 1, two: 2 }
- ];
-
- expect(_.unionWith(components, utils.unifyComponents)).to.deep.equal([
- { key: 'a', label: 1, input: true, one: 1, two: 2 },
- { key: 'b', one: 1, two: 2 }
- ]);
- });
-
- it('should not merge objects with "skipMerge" flag', () => {
- const components = [
- { key: 'a', label: 1 },
- { key: 'a', label: 2, skipMerge: true },
- { key: 'b', one: 1, two: 2 },
- { key: 'b', one: 1 },
- { key: 'b', one: 1, ok: true }
- ];
-
- expect(_.unionWith(components, utils.unifyComponents)).to.deep.equal([
- { key: 'a', label: 1 },
- { key: 'a', label: 2, skipMerge: true },
- { key: 'b', one: 1, two: 2, ok: true },
- ]);
- });
-
- it('should override with "override" flag', () => {
- const components = [
- { key: 'a', label: 1, ok: true },
- { key: 'a', label: 2, overrideEditForm: true }
- ];
-
- expect(_.unionWith(components, utils.unifyComponents)).to.deep.equal([
- { key: 'a', label: 2, ok: true, overrideEditForm: true }
- ]);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp1.js
deleted file mode 100644
index d2031b1b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp1.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- 'tags': [],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': 0,
- 'minLength': 0,
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'firstName',
- 'label': 'First Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp2.js
deleted file mode 100644
index dc0c5d3f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp2.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- 'tags': [],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': 0,
- 'minLength': 0,
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': true,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'names',
- 'label': 'Names',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp3.js
deleted file mode 100644
index 904cd35f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp3.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export default {
- label: 'Text Field',
- tableView: true,
- modalEdit: true,
- multiple: true,
- validate: {
- multiple: true
- },
- key: 'textField',
- type: 'textfield',
- input: true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp4.js
deleted file mode 100644
index b53b5bf0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp4.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export default {
- _id: '611389eae1215a4dadc1099d',
- label: 'Text Field',
- tableView: true,
- modalEdit: true,
- validate: {
- required: true
- },
- key: 'textField',
- type: 'textfield',
- input: true,
- title: 'FIO-3631',
- display: 'form',
- name: 'fio3631',
- path: 'fio3631',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp5.js
deleted file mode 100644
index 68806c95..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/component/fixtures/comp5.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export default {
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Text Field',
- description: " ",
- tooltip: " {
- if (this.isValueChanged() && !this.component.disabled) {
- this.showDialog();
- }
- else {
- this.closeModalHandler(event);
- }
- };
- this.closeModalListener = this.closeModalHandler.bind(this);
- this.saveModalListener = this.saveModalValueHandler.bind(this);
- this.closeDialogListener = this.closeDialog.bind(this);
- this.saveDialogListener = this.saveDialog.bind(this);
- this.loadRefs();
- }
-
- setValue(value) {
- if (this.dataLoaded && this.currentValue === value) {
- return;
- }
-
- this.currentValue = fastCloneDeep(value);
- this.dataLoaded = true;
- this.updateView();
- }
-
- setOpenModalElement(template) {
- if (this.component?.visible) {
- this.openModalTemplate = template;
- this.component.setContent(this.refs.openModalWrapper, template);
- this.loadRefs();
- this.setEventListeners();
- if (this.isOpened) {
- this.refs.modalWrapper.classList.add('formio-dialog-disabled-animation');
- this.openModal();
- }
- }
- }
-
- get templateRefs() {
- return {
- modalOverlay: 'single',
- modalContents: 'single',
- modalClose: 'single',
- openModalWrapper: 'single',
- openModal: 'single',
- modalSave: 'single',
- modalWrapper: 'single',
- };
- }
-
- loadRefs() {
- this.component.loadRefs(this.element, this.templateRefs);
- }
-
- removeEventListeners() {
- this.component.removeEventListener(this.refs.openModal, 'click', this.openModalListener);
- this.component.removeEventListener(this.refs.modalOverlay, 'click', this.refs.modalSave ? this.showDialogListener : this.saveModalListener);
- this.component.removeEventListener(this.refs.modalClose, 'click', this.showDialogListener);
- this.component.removeEventListener(this.refs.modalSave, 'click', this.saveModalListener);
- }
-
- setEventListeners() {
- this.removeEventListeners();
- this.component.addEventListener(this.refs.openModal, 'click', this.openModalListener);
- this.component.addEventListener(this.refs.modalOverlay, 'click', this.refs.modalSave ? this.showDialogListener : this.saveModalListener);
- this.component.addEventListener(this.refs.modalClose, 'click', this.showDialogListener);
- this.component.addEventListener(this.refs.modalSave, 'click', this.saveModalListener);
- }
-
- isValueChanged() {
- let componentValue = this.component.getValue();
- let currentValue = this.currentValue;
-
- //excluding metadata comparison for components that have it in dataValue (for ex. nested forms)
- if (componentValue && componentValue.data && componentValue.metadata) {
- componentValue = this.component.getValue().data;
- currentValue = this.currentValue.data;
- }
-
- return !_.isEqual(fastCloneDeep(componentValue), currentValue);
- }
-
- setOpenEventListener() {
- this.component.removeEventListener(this.refs.openModal, 'click', this.openModalListener);
- this.component.loadRefs(this.refs.openModalWrapper ?? this.element, {
- 'openModal': 'single',
- });
- this.component.addEventListener(this.refs.openModal, 'click', this.openModalListener);
- }
-
- openModalHandler(event) {
- event.preventDefault();
- this.openModal();
- }
-
- positionOverElement() {
- // Position the modal just over the element on the page.
- const elementOffset = this.element.getBoundingClientRect().top;
- const modalHeight = this.refs.modalContents.getBoundingClientRect().height;
- let modalTop = elementOffset - modalHeight - 10;
- modalTop = modalTop > 0 ? modalTop : 10;
- this.refs.modalWrapper.style.paddingTop = `${modalTop}px`;
- }
-
- openModal() {
- this.isOpened = true;
- this.refs.modalWrapper.classList.remove('component-rendering-hidden');
- if (this.component.component.type === 'signature') {
- // Position signature modals just above the signature button.
- this.positionOverElement();
- }
- }
-
- updateView() {
- const template = _.isEqual(this.currentValue, this.component.defaultValue)
- ? this.openModalTemplate
- : this.component.getModalPreviewTemplate();
- this.component.setContent(this.refs.openModalWrapper, template);
- this.setOpenEventListener();
- }
-
- closeModal() {
- this.refs.modalWrapper.classList.remove('formio-dialog-disabled-animation');
- this.refs.modalWrapper.classList.add('component-rendering-hidden');
- this.isOpened = false;
- this.updateView();
- }
-
- closeModalHandler(event) {
- event.preventDefault();
- if (!this.component.disabled) {
- this.component.setValue(_.cloneDeep(this.currentValue), { resetValue: true });
- }
- this.closeModal();
- }
-
- showDialog() {
- this.dialogElement = this.component.ce('div');
- const dialogContent = `
- ${this.component.t('Do you want to clear changes?')}
-
- ${this.component.t('Cancel')}
- ${this.component.t('Yes, delete it')}
-
- `;
-
- this.dialogElement.innerHTML = dialogContent;
- this.dialogElement.refs = {};
- this.component.loadRefs.call(this.dialogElement, this.dialogElement, {
- dialogHeader: 'single',
- dialogCancelButton: 'single',
- dialogYesButton: 'single',
- });
-
- this.dialog = this.component.createModal(this.dialogElement);
- this.component.addEventListener(this.dialogElement.refs.dialogYesButton, 'click', this.saveDialogListener);
- this.component.addEventListener(this.dialogElement.refs.dialogCancelButton, 'click', this.closeDialogListener);
- }
-
- closeDialog(event) {
- event.preventDefault();
- this.dialog.close();
- this.component.removeEventListener(this.dialogElement.refs.dialogYesButton, 'click', this.saveDialogListener);
- this.component.removeEventListener(this.dialogElement.refs.dialogCancelButton, 'click', this.closeDialogListener);
- }
-
- saveDialog(event) {
- this.closeDialog(event);
- this.closeModalHandler(event);
- }
-
- saveModalValueHandler(event) {
- event.preventDefault();
- this.currentValue = fastCloneDeep(this.component.dataValue ?? this.component.getValue());
- this.closeModal();
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/field/Field.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/field/Field.js
deleted file mode 100644
index 5bc4a52e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/field/Field.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import Component from '../component/Component';
-
-export default class Field extends Component {
- render(element) {
- if (this.noField) {
- return super.render(element);
- }
- else if (this.isAdvancedLabel || this.options.condensedMode) {
- return super.render(this.renderTemplate('field', {
- ...this.getLabelInfo(this.options.condensedMode),
- labelMarkup: this.renderTemplate('label'),
- element: element
- }, 'align'));
- }
- else {
- return super.render(this.renderTemplate('field', {
- labelMarkup: this.renderTemplate('label'),
- element: element,
- }));
- }
- }
-
- // Saves current caret position to restore it after the component is redrawn
- saveCaretPosition(element, index) {
- if (this.root?.focusedComponent?.path === this.path) {
- try {
- this.root.currentSelection = { selection: [element.selectionStart, element.selectionEnd], index };
- }
- catch (e) {
- if (!(e instanceof DOMException)) {
- console.debug(e);
- }
- }
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/input/Input.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/input/Input.js
deleted file mode 100644
index ba386a3c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/input/Input.js
+++ /dev/null
@@ -1,324 +0,0 @@
-import Multivalue from '../multivalue/Multivalue';
-import { convertStringToHTMLElement } from '../../../utils/utils';
-import Widgets from '../../../widgets';
-import NativePromise from 'native-promise-only';
-import _ from 'lodash';
-
-export default class Input extends Multivalue {
- constructor(component, options, data) {
- super(component, options, data);
- this.triggerUpdateValueAt = _.debounce(this.updateValueAt.bind(this), 100);
- }
-
- static schema(...extend) {
- return Multivalue.schema({
- widget: {
- type: 'input'
- }
- }, ...extend);
- }
-
- get inputInfo() {
- const attr = {
- name: this.options.name,
- type: this.component.inputType || 'text',
- class: 'form-control',
- lang: this.options.language
- };
-
- if (this.options.attachMode === 'builder' || this.options.building || _.get(this.root, 'form.settings.disableAutocomplete')) {
- attr.autocomplete = this.autocompleteDisableAttrName;
- }
-
- if (this.component.inputMode) {
- attr.inputmode = this.component.inputMode;
- }
-
- if (this.component.placeholder) {
- attr.placeholder = this.getFormattedAttribute(this.component.placeholder);
- }
-
- if (this.component.tabindex) {
- attr.tabindex = this.component.tabindex;
- }
-
- if (this.disabled) {
- attr.disabled = 'disabled';
- }
-
- if (this.component.autocomplete) {
- attr.autocomplete = this.component.autocomplete;
- }
-
- _.defaults(attr, this.component.attributes);
-
- return {
- id: this.key,
- type: 'input',
- changeEvent: 'input',
- content: '',
- attr
- };
- }
-
- get autocompleteDisableAttrName() {
- return 'off';
- }
-
- get maskOptions() {
- return _.map(this.component.inputMasks, mask => {
- return {
- label: mask.label,
- value: mask.label
- };
- });
- }
-
- get isMultipleMasksField() {
- return this.component.allowMultipleMasks && !!this.component.inputMasks && !!this.component.inputMasks.length;
- }
-
- getMaskByName(maskName) {
- const inputMask = _.find(this.component.inputMasks, (inputMask) => {
- return inputMask.label === maskName;
- });
- return inputMask ? inputMask.mask : undefined;
- }
-
- setInputMask(input, inputMask) {
- const mask = inputMask || this.component.displayMask || this.component.inputMask;
- return super.setInputMask(input, mask, !this.component.placeholder);
- }
-
- getMaskOptions() {
- return this.component.inputMasks
- .map(mask => ({
- label: mask.label,
- value: mask.label,
- }));
- }
-
- getWordCount(value) {
- return !value ? 0 : value.trim().split(/\s+/).length;
- }
-
- get remainingWords() {
- const maxWords = _.parseInt(_.get(this.component, 'validate.maxWords'), 10);
- const wordCount = this.getWordCount(this.dataValue);
- return maxWords - wordCount;
- }
-
- get prefix() {
- return this.component.prefix;
- }
-
- get suffix() {
- if (this.component.widget && this.component.widget.type === 'calendar') {
- const calendarIcon = this.renderTemplate('icon', {
- ref: 'icon',
- // After font-awesome would be updated to v5.x, "clock-o" should be replaced with "clock"
- className: this.iconClass(this.component.enableDate || this.component.widget.enableDate ? 'calendar' : 'clock-o'),
- styles: '',
- content: ''
- }).trim();
- if (this.component.prefix !== calendarIcon) {
- // converting string to HTML markup to render correctly DateTime component in portal.form.io
- return convertStringToHTMLElement(calendarIcon, '[ref="icon"]');
- }
- }
- return this.component.suffix;
- }
-
- renderElement(value, index) {
- // Double quotes cause the input value to close so replace them with html quote char.
- if (value && typeof value === 'string') {
- value = value.replace(/"/g, '"');
- }
- const info = this.inputInfo;
- info.attr = info.attr || {};
- info.attr.value = this.getValueAsString(this.formatValue(this.parseValue(value)))
- .replace(/"/g, '"');
-
- const valueMask = this.component.inputMask;
- const displayMask = this.component.displayMask;
- const hasDifferentDisplayAndSaveFormats = valueMask && displayMask && valueMask !== displayMask;
-
- if (this.isMultipleMasksField) {
- info.attr.class += ' formio-multiple-mask-input';
- }
-
- return this.isMultipleMasksField
- ? this.renderTemplate('multipleMasksInput', {
- input: info,
- value,
- index,
- selectOptions: this.getMaskOptions() || [],
- }, this.isHtmlRenderMode() ? 'html' : null)
- : this.renderTemplate('input', {
- prefix: this.prefix,
- suffix: this.suffix,
- input: info,
- value: this.formatValue(this.parseValue(value)),
- hasValueMaskInput: hasDifferentDisplayAndSaveFormats,
- index
- }, this.isHtmlRenderMode() ? 'html' : null);
- }
-
- setCounter(type, element, count, max) {
- if (max) {
- const remaining = max - count;
- if (remaining > 0) {
- this.removeClass(element, 'text-danger');
- }
- else {
- this.addClass(element, 'text-danger');
- }
- this.setContent(element, this.t(`{{ remaining }} ${type} remaining.`, {
- remaining: remaining
- }));
- }
- else {
- this.setContent(element, this.t(`{{ count }} ${type}`, {
- count: count
- }));
- }
- }
-
- updateValueAt(value, flags, index) {
- flags = flags || {};
- if (_.get(this.component, 'showWordCount', false)) {
- if (this.refs.wordcount && this.refs.wordcount[index]) {
- const maxWords = _.parseInt(_.get(this.component, 'validate.maxWords', 0), 10);
- this.setCounter(this.t('words'), this.refs.wordcount[index], this.getWordCount(value), maxWords);
- }
- }
- if (_.get(this.component, 'showCharCount', false)) {
- if (this.refs.charcount && this.refs.charcount[index]) {
- const maxChars = _.parseInt(_.get(this.component, 'validate.maxLength', 0), 10);
- this.setCounter(this.t('characters'), this.refs.charcount[index], value.length, maxChars);
- }
- }
- }
-
- getValueAt(index) {
- const input = this.performInputMapping(this.refs.input[index]);
- if (input && input.widget) {
- return input.widget.getValue();
- }
- return input ? input.value : undefined;
- }
-
- updateValue(value, flags, index) {
- flags = flags || {};
- const changed = super.updateValue(value, flags);
- this.triggerUpdateValueAt(this.dataValue, flags, index);
- return changed;
- }
-
- parseValue(value) {
- return value;
- }
-
- formatValue(value) {
- return value;
- }
-
- attach(element) {
- this.loadRefs(element, {
- charcount: 'multiple',
- wordcount: 'multiple',
- prefix: 'multiple',
- suffix: 'multiple'
- });
- return super.attach(element);
- }
-
- getWidget(index) {
- index = index || 0;
- if (this.refs.input && this.refs.input[index]) {
- return this.refs.input[index].widget;
- }
- return null;
- }
-
- attachElement(element, index) {
- super.attachElement(element, index);
- if (element.widget) {
- element.widget.destroy();
- }
- // Attach the widget.
- let promise = NativePromise.resolve();
- element.widget = this.createWidget(index);
- if (element.widget) {
- promise = element.widget.attach(element);
- if (this.refs.prefix && this.refs.prefix[index]) {
- element.widget.addPrefix(this.refs.prefix[index]);
- }
- if (this.refs.suffix && this.refs.suffix[index]) {
- element.widget.addSuffix(this.refs.suffix[index]);
- }
- }
-
- // Add focus and blur events.
- this.addFocusBlurEvents(element);
-
- if (this.options.submitOnEnter) {
- this.addEventListener(element, 'keypress', (event) => {
- const key = event.keyCode || event.which;
- if (key === 13) {
- event.preventDefault();
- event.stopPropagation();
- this.emit('submitButton');
- }
- });
- }
- return promise;
- }
-
- /**
- * Creates an instance of a widget for this component.
- *
- * @return {null}
- */
- createWidget(index) {
- // Return null if no widget is found.
- if (!this.component.widget) {
- return null;
- }
-
- // Get the widget settings.
- const settings = (typeof this.component.widget === 'string') ? {
- type: this.component.widget
- } : this.component.widget;
-
- if (this.root?.shadowRoot) {
- settings.shadowRoot = this.root?.shadowRoot;
- }
-
- // Make sure we have a widget.
- if (!Widgets.hasOwnProperty(settings.type)) {
- return null;
- }
-
- // Create the widget.
- const widget = new Widgets[settings.type](settings, this.component, this, index);
- widget.on('update', () => this.updateValue(this.getValue(), {
- modified: true
- }, index), true);
- widget.on('redraw', () => this.redraw(), true);
- return widget;
- }
-
- detach() {
- super.detach();
- if (this.refs && this.refs.input) {
- for (let i = 0; i <= this.refs.input.length; i++) {
- const widget = this.getWidget(i);
- if (widget) {
- widget.destroy();
- }
- }
- }
- this.refs.input = [];
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/ListComponent.form.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/ListComponent.form.js
deleted file mode 100644
index e0cca99f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/ListComponent.form.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import Components from '../../Components';
-import ListEditData from './editForm/ListComponent.edit.data';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'data',
- components: ListEditData
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/ListComponent.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/ListComponent.js
deleted file mode 100644
index a63df1f4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/ListComponent.js
+++ /dev/null
@@ -1,275 +0,0 @@
-import Field from '../field/Field';
-import { GlobalFormio as Formio } from '../../../Formio';
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-import { getItemTemplateKeys } from '../../../utils/utils';
-
-export default class ListComponent extends Field {
- static schema(...extend) {
- return Field.schema({
- dataSrc: 'values',
- authenticate: false,
- ignoreCache: false,
- template: '{{ item.label }} ',
- validate: {
- onlyAvailableItems: false
- },
- }, ...extend);
- }
-
- get isSelectURL() {
- return this.component.dataSrc === 'url';
- }
-
- get selectData() {
- const selectData = _.get(this.root, 'submission.metadata.selectData', {});
- return _.get(selectData, this.path);
- }
-
- get shouldLoad() {
- if (this.loadingError) {
- return false;
- }
- // Live forms should always load.
- if (!this.options.readOnly) {
- return true;
- }
-
- // If there are template keys, then we need to see if we have the data.
- if (this.templateKeys && this.templateKeys.length) {
- // See if we already have the data we need.
- const dataValue = this.dataValue;
- const selectData = this.selectData;
- return this.templateKeys.reduce((shouldLoad, key) => {
- const hasValue = _.has(dataValue, key) ||
- (_.isArray(selectData) ? selectData.every((data) => _.has(data, key)) : _.has(selectData, key));
- return shouldLoad || !hasValue;
- }, false);
- }
-
- // Return that we should load.
- return true;
- }
-
- getTemplateKeys() {
- const template = this.component.template;
- this.templateKeys = this.options.readOnly && template
- ? getItemTemplateKeys(template)
- : [];
- }
-
- get requestHeaders() {
- // Create the headers object.
- const headers = new Formio.Headers();
- // Add custom headers to the url.
- if (this.component.data && this.component.data.headers) {
- try {
- _.each(this.component.data.headers, (header) => {
- if (header.key) {
- headers.set(header.key, this.interpolate(header.value));
- }
- });
- }
- catch (err) {
- console.warn(err.message);
- }
- }
-
- return headers;
- }
-
- // Must be implemented in child classes.
- setItems() {}
-
- updateCustomItems() {}
-
- loadItems() {}
-
- getOptionTemplate(data, value, index) {
- if (!this.component.template) {
- return data.label;
- }
- const options = {
- noeval: true,
- data: {}
- };
- const template = this.sanitize(
- this.component.template
- ? this.interpolate(this.component.template, { item: data }, options)
- : data.label,
- this.shouldSanitizeValue,
- );
- const templateValue = this.component.reference && value?._id ? value._id.toString() : value;
- if (templateValue && !_.isObject(templateValue) && options.data.item) {
- // If the value is not an object, then we need to save the template data off for when it is selected.
- this.templateData[templateValue] = options.data.item;
- }
- if (_.isNumber(index)) {
- this.templateData[index] = options.data.item;
- }
- return template;
- }
-
- itemTemplate(data, value, index) {
- if (_.isEmpty(data)) {
- return '';
- }
-
- const template = this.sanitize(this.getOptionTemplate(data, value, index), this.shouldSanitizeValue);
- if (template) {
- const label = template.replace(/<\/?[^>]+(>|$)/g, '');
- const hasTranslator = this.i18next?.translator;
- if (!label || (hasTranslator && !this.t(label, { _userInput: true }))) return;
- return hasTranslator ? template.replace(label, this.t(label, { _userInput: true })) : label;
- }
- else {
- return this.sanitize(JSON.stringify(data), this.shouldSanitizeValue);
- }
- }
-
- handleLoadingError(err) {
- this.loading = false;
- if (err.networkError) {
- this.networkError = true;
- }
- this.itemsLoadedResolve();
- this.emit('componentError', {
- component: this.component,
- message: err.toString(),
- });
- console.warn(`Unable to load resources for ${this.key}`);
- }
-
- /* eslint-disable max-statements */
- updateItems(searchInput, forceUpdate) {
- if (!this.component.data) {
- console.warn(`Select component ${this.key} does not have data configuration.`);
- this.itemsLoadedResolve();
- return;
- }
-
- // Only load the data if it is visible.
- if (!this.visible) {
- this.itemsLoadedResolve();
- return;
- }
-
- switch (this.component.dataSrc) {
- case 'values':
- this.setItems(this.component.data.values);
- break;
- case 'json':
- this.setItems(this.component.data.json);
- break;
- case 'custom':
- this.updateCustomItems(forceUpdate);
- break;
- case 'resource': {
- // If there is no resource, or we are lazyLoading, wait until active.
- if (!this.component.data.resource || (!forceUpdate && !this.active)) {
- this.itemsLoadedResolve();
- return;
- }
-
- let resourceUrl = this.options.formio ? this.options.formio.formsUrl : `${Formio.getProjectUrl()}/form`;
- resourceUrl += (`/${this.component.data.resource}/submission`);
-
- if (forceUpdate || this.additionalResourcesAvailable || !this.serverCount) {
- try {
- this.loadItems(resourceUrl, searchInput, this.requestHeaders);
- }
- catch (err) {
- console.warn(`Unable to load resources for ${this.key}`);
- }
- }
- else {
- this.setItems(this.downloadedResources);
- }
- break;
- }
- case 'url': {
- if (!forceUpdate && !this.active && !this.calculatedValue && this.component.type === 'select') {
- // If we are lazyLoading, wait until activated.
- this.itemsLoadedResolve();
- return;
- }
- let { url } = this.component.data;
- let method;
- let body;
- if (url.startsWith('/')) {
- // if URL starts with '/project', we should use base URL to avoid issues with URL formed like //project//...
- const baseUrl = url.startsWith('/project') ? Formio.getBaseUrl() : Formio.getProjectUrl() || Formio.getBaseUrl();
- url = baseUrl + url;
- }
-
- if (!this.component.data.method) {
- method = 'GET';
- }
- else {
- method = this.component.data.method;
- if (method.toUpperCase() === 'POST') {
- body = this.component.data.body;
- }
- else {
- body = null;
- }
- }
-
- const options = this.component.authenticate ? {} : { noToken: true };
- this.loadItems(url, searchInput, this.requestHeaders, options, method, body);
- break;
- }
- case 'indexeddb': {
- if (typeof window === 'undefined') {
- return;
- }
-
- if (!window.indexedDB) {
- window.alert("Your browser doesn't support current version of indexedDB");
- }
-
- if (this.component.indexeddb && this.component.indexeddb.database && this.component.indexeddb.table) {
- const request = window.indexedDB.open(this.component.indexeddb.database);
-
- request.onupgradeneeded = (event) => {
- if (this.component.customOptions) {
- const db = event.target.result;
- const objectStore = db.createObjectStore(this.component.indexeddb.table, { keyPath: 'myKey', autoIncrement: true });
- objectStore.transaction.oncomplete = () => {
- const transaction = db.transaction(this.component.indexeddb.table, 'readwrite');
- this.component.customOptions.forEach((item) => {
- transaction.objectStore(this.component.indexeddb.table).put(item);
- });
- };
- }
- };
-
- request.onerror = () => {
- window.alert(request.errorCode);
- };
-
- request.onsuccess = (event) => {
- const db = event.target.result;
- const transaction = db.transaction(this.component.indexeddb.table, 'readwrite');
- const objectStore = transaction.objectStore(this.component.indexeddb.table);
- new NativePromise((resolve) => {
- const responseItems = [];
- objectStore.getAll().onsuccess = (event) => {
- event.target.result.forEach((item) => {
- responseItems.push(item);
- });
- resolve(responseItems);
- };
- }).then((items) => {
- if (!_.isEmpty(this.component.indexeddb.filter)) {
- items = _.filter(items, this.component.indexeddb.filter);
- }
- this.setItems(items);
- });
- };
- }
- }
- }
- }
- /* eslint-enable max-statements */
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/editForm/ListComponent.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/editForm/ListComponent.edit.data.js
deleted file mode 100644
index d74bb7a4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/list/editForm/ListComponent.edit.data.js
+++ /dev/null
@@ -1,117 +0,0 @@
-export default [
- {
- type: 'select',
- input: true,
- weight: 0,
- tooltip: 'The source to use for the select data. Values lets you provide your own values and labels. JSON lets you provide raw JSON data. URL lets you provide a URL to retrieve the JSON data from.',
- key: 'dataSrc',
- defaultValue: 'values',
- label: 'Data Source Type',
- dataSrc: 'values',
- },
- {
- type: 'textfield',
- input: true,
- key: 'data.url',
- weight: 10,
- label: 'Data Source URL',
- placeholder: 'Data Source URL',
- tooltip: 'A URL that returns a JSON array to use as the data source.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'url'] },
- },
- },
- {
- type: 'datagrid',
- input: true,
- label: 'Request Headers',
- key: 'data.headers',
- tooltip: 'Set any headers that should be sent along with the request to the url. This is useful for authentication.',
- weight: 11,
- components: [
- {
- label: 'Key',
- key: 'key',
- input: true,
- type: 'textfield',
- },
- {
- label: 'Value',
- key: 'value',
- input: true,
- type: 'textfield',
- },
- ],
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'url'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- label: 'Value Property',
- key: 'valueProperty',
- skipMerge: true,
- clearOnHide: false,
- weight: 13,
- description: "The selected item's property to save.",
- tooltip: 'The property of each item in the data source to use as the select value. If not specified, the item itself will be used.',
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'json',
- 'url',
- 'custom'
- ],
- ],
- },
- },
- },
- {
- type: 'textarea',
- input: true,
- key: 'template',
- label: 'Item Template',
- editor: 'ace',
- as: 'html',
- rows: 3,
- weight: 18,
- tooltip: 'The HTML template for the result data items.',
- allowCalculateOverride: true,
- calculateValue:(context) => {
- if (!context.data.template) {
- if (context.instance && context.instance._currentForm.options.editComponent) {
- return context.instance._currentForm.options.editComponent.template;
- }
- }
- return context.data.template;
- },
- },
- {
- type: 'checkbox',
- input: true,
- weight: 26,
- key: 'authenticate',
- label: 'Formio Authenticate',
- tooltip: 'Check this if you would like to use Formio Authentication with the request.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'url'] },
- },
- },
- {
- type: 'checkbox',
- input: true,
- weight: 29,
- key: 'ignoreCache',
- label: 'Disables Storing Request Result in the Cache',
- tooltip: 'Check it if you don\'t want the requests and its results to be stored in the cache. By default, it is stored and if the Select tries to make the request to the same URL with the same paremetrs, the cached data will be returned. It allows to increase performance, but if the remote source\'s data is changing quite often and you always need to keep it up-to-date, uncheck this option.',
- conditional: {
- json: { 'or': [
- { '===': [{ var: 'data.dataSrc' }, 'url'] },
- { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- ] },
- },
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/multivalue/Multivalue.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/multivalue/Multivalue.js
deleted file mode 100644
index 826ba905..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/multivalue/Multivalue.js
+++ /dev/null
@@ -1,299 +0,0 @@
-import Field from '../field/Field';
-import NativePromise from 'native-promise-only';
-import _ from 'lodash';
-
-export default class Multivalue extends Field {
- get dataValue() {
- const parent = super.dataValue;
-
- if (!parent && this.component.multiple) {
- return [];
- }
- return parent;
- }
-
- set dataValue(value) {
- super.dataValue = value;
- }
-
- get defaultValue() {
- let value = super.defaultValue;
-
- if (this.component.multiple) {
- if (_.isArray(value)) {
- value = !value.length ? [super.emptyValue] : value;
- }
- else {
- value = [value];
- }
- }
-
- return value;
- }
-
- get addAnother() {
- return this.t(this.component.addAnother || 'Add Another');
- }
-
- useWrapper() {
- return this.component.hasOwnProperty('multiple') && this.component.multiple;
- }
-
- render() {
- // If single value field.
- if (!this.useWrapper()) {
- return super.render(
- `
- ${this.renderElement(
- this.component.type !== 'hidden' ? this.dataValue : ''
- )}
-
`
- );
- }
-
- // Make sure dataValue is in the correct array format.
- let dataValue = this.dataValue;
- if (!Array.isArray(dataValue)) {
- dataValue = dataValue ? [dataValue] : [];
- }
-
- // If multiple value field.
- return super.render(this.renderTemplate('multiValueTable', {
- rows: dataValue.map(this.renderRow.bind(this)).join(''),
- disabled: this.disabled,
- addAnother: this.addAnother,
- }));
- }
-
- renderElement() {
- return '';
- }
-
- renderRow(value, index) {
- return this.renderTemplate('multiValueRow', {
- index,
- disabled: this.disabled,
- element: `${this.renderElement(value, index)}`,
- });
- }
-
- attach(dom) {
- const superAttach = super.attach(dom);
- this.loadRefs(dom, {
- addButton: 'multiple',
- input: 'multiple',
- removeRow: 'multiple',
- mask: 'multiple',
- select: 'multiple',
- });
-
- const promises = [];
-
- this.refs.input.forEach((element, index) => {
- promises.push(this.attachElement.call(this, element, index));
- });
-
- if (!this.component.multiple) {
- return NativePromise.all(promises);
- }
-
- this.refs.removeRow.forEach((removeButton, index) => {
- this.addEventListener(removeButton, 'click', (event) => {
- event.preventDefault();
- this.removeValue(index);
- });
- });
-
- // If single value field.
- this.refs.addButton.forEach((addButton) => {
- this.addEventListener(addButton, 'click', (event) => {
- event.preventDefault();
- this.addValue();
- });
- });
- return superAttach.then(() => {
- return NativePromise.all(promises);
- });
- }
-
- detach() {
- if (this.refs.input && this.refs.input.length) {
- this.refs.input.forEach((input) => {
- if (input.mask) {
- input.mask.destroy();
- }
- if (input.widget) {
- input.widget.destroy();
- }
- });
- }
- if (this.refs.mask && this.refs.mask.length) {
- this.refs.mask.forEach((input) => {
- if (input.mask) {
- input.mask.destroy();
- }
- });
- }
- super.detach();
- }
-
- /**
- * Attach inputs to the element.
- *
- * @param element
- * @param index
- */
- attachElement(element, index) {
- this.addEventListener(element, this.inputInfo.changeEvent, () => {
- // Delay update slightly to give input mask a chance to run.
- const textCase = _.get(this.component, 'case', 'mixed');
-
- if (textCase !== 'mixed') {
- const {
- selectionStart,
- selectionEnd,
- } = element;
-
- if (textCase === 'uppercase' && element.value) {
- element.value = element.value.toUpperCase();
- }
- if (textCase === 'lowercase' && element.value) {
- element.value = element.value.toLowerCase();
- }
-
- if (element.selectionStart && element.selectionEnd) {
- element.selectionStart = selectionStart;
- element.selectionEnd = selectionEnd;
- }
- }
-
- try {
- this.saveCaretPosition(element, index);
- }
- catch (err) {
- console.warn('An error occurred while trying to save caret position', err);
- }
-
- // If a mask is present, delay the update to allow mask to update first.
- if (element.mask) {
- setTimeout(() => {
- return this.updateValue(null, {
- modified: (this.component.type !== 'hidden')
- }, index);
- }, 1);
- }
- else {
- return this.updateValue(null, {
- modified: (this.component.type !== 'hidden')
- }, index);
- }
- });
-
- if (!this.attachMultiMask(index)) {
- const applyMask = () => {
- this.setInputMask(element);
-
- const valueMask = this.component.inputMask;
- const displayMask = this.component.displayMask;
-
- if (valueMask && displayMask && displayMask !== valueMask && this.refs.valueMaskInput) {
- this.setInputMask(this.refs.valueMaskInput, valueMask);
- }
- };
-
- if (this.inputInfo.changeEvent === 'blur') {
- this.addEventListener(element, this.inputInfo.changeEvent, () => {
- applyMask();
- this.dataValue = this.refs.input[0].value;
- let submitBtnDisabled = document.querySelector('[name="data[submit]"]')?.disabled;
- submitBtnDisabled = true;
-
- if (this.checkComponentValidity()) {
- this.updateComponentValue(this.refs.input[0].value);
- submitBtnDisabled = false;
- }
- });
- }
- else {
- applyMask();
- }
- }
- }
-
- onSelectMaskHandler(event) {
- this.updateMask(event.target.maskInput, this.getMaskPattern(event.target.value));
- }
-
- getMaskPattern(maskName) {
- if (!this.multiMasks) {
- this.multiMasks = {};
- }
- if (this.multiMasks[maskName]) {
- return this.multiMasks[maskName];
- }
- const mask = this.component.inputMasks.find(inputMask => inputMask.label === maskName);
- this.multiMasks[maskName] = mask ? mask.mask : this.component.inputMasks[0].mask;
- return this.multiMasks[maskName];
- }
-
- attachMultiMask(index) {
- if (!(this.isMultipleMasksField && this.component.inputMasks.length && this.refs.input.length)) {
- return false;
- }
-
- const maskSelect = this.refs.select[index];
- maskSelect.onchange = this.onSelectMaskHandler.bind(this);
- maskSelect.maskInput = this.refs.mask[index];
- this.setInputMask(maskSelect.maskInput, this.component.inputMasks[0].mask);
- return true;
- }
-
- updateMask(input, mask) {
- if (!mask) {
- return;
- }
- this.setInputMask(input, mask, !this.component.placeholder);
- this.updateValue();
- }
-
- /**
- * Adds a new empty value to the data array.
- */
- addNewValue(value) {
- if (value === undefined) {
- value = this.component.defaultValue ?
- this.component.defaultValue : this.emptyValue;
- // If default is an empty aray, default back to empty value.
- if (Array.isArray(value) && value.length === 0) {
- value = this.emptyValue;
- }
- }
- let dataValue = this.dataValue || [];
- if (!Array.isArray(dataValue)) {
- dataValue = [dataValue];
- }
-
- if (Array.isArray(value)) {
- dataValue = dataValue.concat(value);
- }
- else {
- dataValue.push(value);
- }
- this.dataValue = dataValue;
- }
-
- /**
- * Adds a new empty value to the data array, and add a new row to contain it.
- */
- addValue() {
- this.addNewValue();
- this.redraw();
- this.checkConditions();
- if (!this.isEmpty(this.dataValue)) {
- this.restoreValue();
- }
- if (this.root) {
- this.root.onChange();
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.form.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.form.js
deleted file mode 100644
index 5795262c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.form.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import Components from '../../Components';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'data',
- ignore: true
- },
- {
- key: 'validation',
- ignore: true
- }
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.js
deleted file mode 100644
index a70e7771..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.js
+++ /dev/null
@@ -1,794 +0,0 @@
-'use strict';
-import _ from 'lodash';
-import Field from '../field/Field';
-import Components from '../../Components';
-import NativePromise from 'native-promise-only';
-import { getArrayFromComponentPath, getStringFromComponentPath, getRandomComponentId } from '../../../utils/utils';
-
-export default class NestedComponent extends Field {
- static schema(...extend) {
- return Field.schema({
- tree: false,
- lazyLoad: false,
- }, ...extend);
- }
-
- constructor(component, options, data) {
- super(component, options, data);
- this.type = 'components';
- this._collapsed = !!this.component.collapsed;
- }
-
- get defaultSchema() {
- return NestedComponent.schema();
- }
-
- get schema() {
- const schema = super.schema;
- const components = _.uniqBy(this.getComponents(), 'component.key');
- schema.components = _.map(components, 'schema');
- return schema;
- }
-
- get collapsed() {
- return this._collapsed;
- }
-
- collapse(value) {
- const promise = this.redraw();
- if (!value) {
- this.checkValidity(this.data, !this.pristine, null, this.pristine);
- }
- return promise;
- }
-
- set collapsed(value) {
- this._collapsed = value;
- this.collapse(value);
- }
-
- set visible(value) {
- // DO NOT CALL super here. There is an issue where clearOnHide was getting triggered with
- // subcomponents because the "parentVisible" flag was set to false when it should really be
- // set to true.
- const visibilityChanged = this._visible !== value;
- this._visible = value;
- const isVisible = this.visible;
- const forceShow = this.shouldForceShow();
- const forceHide = this.shouldForceHide();
- this.components.forEach(component => {
- // Set the parent visibility first since we may have nested components within nested components
- // and they need to be able to determine their visibility based on the parent visibility.
- component.parentVisible = isVisible;
-
- const conditionallyVisible = component.conditionallyVisible();
- if (forceShow || conditionallyVisible) {
- component.visible = true;
- }
- else if (forceHide || !isVisible || !conditionallyVisible) {
- component.visible = false;
- }
- // If hiding a nested component, clear all errors below.
- if (!component.visible) {
- component.error = '';
- }
- });
- if (visibilityChanged) {
- this.clearOnHide();
- this.redraw();
- }
- }
-
- get visible() {
- return super.visible;
- }
-
- set parentVisible(value) {
- super.parentVisible = value;
- this.components.forEach(component => component.parentVisible = this.visible);
- }
-
- get parentVisible() {
- return super.parentVisible;
- }
-
- get disabled() {
- return super.disabled;
- }
-
- set disabled(disabled) {
- super.disabled = disabled;
- this.components.forEach((component) => component.parentDisabled = disabled);
- }
-
- set parentDisabled(value) {
- super.parentDisabled = value;
- this.components.forEach(component => {
- component.parentDisabled = this.disabled;
- });
- }
-
- get parentDisabled() {
- return super.parentDisabled;
- }
-
- get ready() {
- return NativePromise.all(this.getComponents().map(component => component.ready));
- }
-
- get currentForm() {
- return super.currentForm;
- }
-
- set currentForm(instance) {
- super.currentForm = instance;
- this.getComponents().forEach(component => {
- component.currentForm = instance;
- });
- }
-
- get rowIndex() {
- return this._rowIndex;
- }
-
- set rowIndex(value) {
- this._rowIndex = value;
- this.eachComponent((component) => {
- component.rowIndex = value;
- });
- }
-
- componentContext() {
- return this._data;
- }
-
- get data() {
- return this._data;
- }
-
- set data(value) {
- this._data = value;
- this.eachComponent((component) => {
- component.data = this.componentContext(component);
- });
- }
-
- getComponents() {
- return this.components || [];
- }
-
- /**
- * Perform a deep iteration over every component, including those
- * within other container based components.
- *
- * @param {function} fn - Called for every component.
- */
- everyComponent(fn, options) {
- const components = this.getComponents();
- _.each(components, (component, index) => {
- if (fn(component, components, index) === false) {
- return false;
- }
-
- if (typeof component.everyComponent === 'function') {
- if (component.everyComponent(fn, options) === false) {
- return false;
- }
- }
- });
- }
-
- hasComponent(component) {
- let result = false;
-
- this.everyComponent((comp) => {
- if (comp === component) {
- result = true;
- return false;
- }
- });
-
- return result;
- }
-
- flattenComponents() {
- const result = {};
-
- this.everyComponent((component) => {
- result[component.component.flattenAs || component.key] = component;
- });
-
- return result;
- }
-
- /**
- * Perform an iteration over each component within this container component.
- *
- * @param {function} fn - Called for each component
- */
- eachComponent(fn) {
- _.each(this.getComponents(), (component, index) => {
- if (fn(component, index) === false) {
- return false;
- }
- });
- }
-
- /**
- * Returns a component provided a key. This performs a deep search within the
- * component tree.
- *
- * @param {string} key - The key of the component to retrieve.
- * @param {function} fn - Called with the component once found.
- * @return {Object} - The component that is located.
- */
- getComponent(path, fn, originalPath) {
- originalPath = originalPath || getStringFromComponentPath(path);
- path = getArrayFromComponentPath(path);
- const pathStr = originalPath;
- const newPath = _.clone(path);
- let key = newPath.shift();
- const remainingPath = newPath;
- let comp = null;
- let possibleComp = null;
-
- if (_.isNumber(key)) {
- key = remainingPath.shift();
- }
-
- if (!_.isString(key)) {
- return comp;
- }
-
- this.everyComponent((component, components) => {
- const matchPath = component.hasInput && component.path ? pathStr.includes(component.path) : true;
- if (component.component.key === key) {
- possibleComp = component;
- if (matchPath) {
- comp = component;
- if (remainingPath.length > 0 && 'getComponent' in component) {
- comp = component.getComponent(remainingPath, fn, originalPath);
- }
- else if (fn) {
- fn(component, components);
- }
- return false;
- }
- }
- });
-
- if (!comp) {
- comp = possibleComp;
- }
-
- return comp;
- }
-
- /**
- * Return a component provided the Id of the component.
- *
- * @param {string} id - The Id of the component.
- * @param {function} fn - Called with the component once it is retrieved.
- * @return {Object} - The component retrieved.
- */
- getComponentById(id, fn) {
- let comp = null;
- this.everyComponent((component, components) => {
- if (component.id === id) {
- comp = component;
- if (fn) {
- fn(component, components);
- }
- return false;
- }
- });
- return comp;
- }
-
- /**
- * Return a path of component's value.
- *
- * @param {Object} component - The component instance.
- * @return {string} - The component's value path.
- */
- calculateComponentPath(component) {
- let path = '';
- if (component.component.key) {
- let thisPath = this;
- while (thisPath && !thisPath.allowData && thisPath.parent) {
- thisPath = thisPath.parent;
- }
- const rowIndex = component.row ? `[${Number.parseInt(component.row)}]` : '';
- path = thisPath.path ? `${thisPath.path}${rowIndex}.` : '';
- path += component._parentPath && component.component.shouldIncludeSubFormPath ? component._parentPath : '';
- path += component.component.key;
- return path;
- }
- }
-
- /**
- * Create a new component and add it to the components array.
- *
- * @param component
- * @param data
- */
- createComponent(component, options, data, before, replacedComp) {
- if (!component) {
- return;
- }
- options = options || this.options;
- data = data || this.data;
- options.parent = this;
- options.parentVisible = this.visible;
- options.root = options?.root || this.root || this;
- options.localRoot = this.localRoot;
- options.skipInit = true;
- if (!(options.display === 'pdf' && this.builderMode)) {
- component.id = getRandomComponentId();
- }
- if (!this.isInputComponent && this.component.shouldIncludeSubFormPath) {
- component.shouldIncludeSubFormPath = true;
- }
- const comp = Components.create(component, options, data, true);
-
- const path = this.calculateComponentPath(comp);
- if (path) {
- comp.path = path;
- }
- comp.init();
- if (component.internal) {
- return comp;
- }
-
- if (before) {
- const index = _.findIndex(this.components, { id: before.id });
- if (index !== -1) {
- this.components.splice(index, 0, comp);
- }
- else {
- this.components.push(comp);
- }
- }
- else if (replacedComp) {
- const index = _.findIndex(this.components, { id: replacedComp.id });
- if (index !== -1) {
- this.components[index] = comp;
- }
- else {
- this.components.push(comp);
- }
- }
- else {
- this.components.push(comp);
- }
- return comp;
- }
-
- getContainer() {
- return this.element;
- }
-
- get componentComponents() {
- return this.component.components || [];
- }
-
- get nestedKey() {
- return `nested-${this.key}`;
- }
-
- get templateName() {
- return 'container';
- }
-
- init() {
- this.components = this.components || [];
- this.addComponents();
- return super.init();
- }
-
- /**
- *
- * @param element
- * @param data
- */
- addComponents(data, options) {
- data = data || this.data;
- options = options || this.options;
- if (options.components) {
- this.components = options.components;
- }
- else {
- const components = this.hook('addComponents', this.componentComponents, this) || [];
- components.forEach((component) => this.addComponent(component, data));
- }
- }
-
- /**
- * Add a new component to the components array.
- *
- * @param {Object} component - The component JSON schema to add.
- * @param {Object} data - The submission data object to house the data for this component.
- * @param {HTMLElement} before - A DOM element to insert this element before.
- * @return {Component} - The created component instance.
- */
- addComponent(component, data, before, noAdd) {
- data = data || this.data;
- if (this.options.parentPath) {
- component.shouldIncludeSubFormPath = true;
- }
- component = this.hook('addComponent', component, data, before, noAdd);
- const comp = this.createComponent(component, this.options, data, before ? before : null);
- if (noAdd) {
- return comp;
- }
- return comp;
- }
-
- beforeFocus() {
- if (this.parent && 'beforeFocus' in this.parent) {
- this.parent.beforeFocus(this);
- }
- }
-
- render(children) {
- // If already rendering, don't re-render.
- return super.render(children || this.renderTemplate(this.templateName, {
- children: !this.visible ? '' : this.renderComponents(),
- nestedKey: this.nestedKey,
- collapsed: this.options.pdf ? false : this.collapsed,
- }));
- }
-
- renderComponents(components) {
- components = components || this.getComponents();
- const children = components.map(component => component.render());
- return this.renderTemplate('components', {
- children,
- components,
- });
- }
-
- attach(element) {
- const superPromise = super.attach(element);
-
- this.loadRefs(element, {
- header: 'single',
- collapsed: this.collapsed,
- [this.nestedKey]: 'single',
- });
-
- let childPromise = NativePromise.resolve();
- if (this.refs[this.nestedKey]) {
- childPromise = this.attachComponents(this.refs[this.nestedKey]);
- }
-
- if (!this.visible) {
- this.attachComponentsLogic();
- }
-
- if (this.component.collapsible && this.refs.header) {
- this.addEventListener(this.refs.header, 'click', () => {
- this.collapsed = !this.collapsed;
- });
- this.addEventListener(this.refs.header, 'keydown', (e) => {
- if (e.keyCode === 13 || e.keyCode === 32) {
- e.preventDefault();
- this.collapsed = !this.collapsed;
- }
- });
- }
-
- return NativePromise.all([
- superPromise,
- childPromise,
- ]);
- }
-
- attachComponentsLogic(components) {
- components = components || this.components;
-
- _.each(components, (comp) => {
- comp.attachLogic();
-
- if (_.isFunction(comp.attachComponentsLogic)) {
- comp.attachComponentsLogic();
- }
- });
- }
-
- attachComponents(element, components, container) {
- components = components || this.components;
- container = container || this.component.components;
-
- element = this.hook('attachComponents', element, components, container, this);
- if (!element) {
- // Return a non-resolving promise.
- return (new NativePromise(() => {}));
- }
-
- let index = 0;
- const promises = [];
- Array.prototype.slice.call(element.children).forEach(child => {
- if (!child.getAttribute('data-noattach') && components[index]) {
- promises.push(components[index].attach(child));
- index++;
- }
- });
- return NativePromise.all(promises);
- }
-
- /**
- * Remove a component from the components array.
- *
- * @param {Component} component - The component to remove from the components.
- * @param {Array} components - An array of components to remove this component from.
- */
- removeComponent(component, components) {
- components = components || this.components;
- component.destroy();
- _.remove(components, { id: component.id });
- }
-
- /**
- * Removes a component provided the API key of that component.
- *
- * @param {string} key - The API key of the component to remove.
- * @param {function} fn - Called once the component is removed.
- * @return {null}
- */
- removeComponentByKey(key, fn) {
- const comp = this.getComponent(key, (component, components) => {
- this.removeComponent(component, components);
- if (fn) {
- fn(component, components);
- }
- });
- if (!comp) {
- if (fn) {
- fn(null);
- }
- return null;
- }
- }
-
- /**
- * Removes a component provided the Id of the component.
- *
- * @param {string} id - The Id of the component to remove.
- * @param {function} fn - Called when the component is removed.
- * @return {null}
- */
- removeComponentById(id, fn) {
- const comp = this.getComponentById(id, (component, components) => {
- this.removeComponent(component, components);
- if (fn) {
- fn(component, components);
- }
- });
- if (!comp) {
- if (fn) {
- fn(null);
- }
- return null;
- }
- }
-
- updateValue(value, flags = {}) {
- return this.components.reduce((changed, comp) => {
- return comp.updateValue(null, flags) || changed;
- }, super.updateValue(value, flags));
- }
-
- shouldSkipValidation(data, dirty, row) {
- // Nested components with no input should not be validated.
- if (!this.component.input) {
- return true;
- }
- else {
- return super.shouldSkipValidation(data, dirty, row);
- }
- }
-
- checkData(data, flags, row, components) {
- if (this.builderMode) {
- return true;
- }
- data = data || this.rootValue;
- flags = flags || {};
- row = row || this.data;
- components = components && _.isArray(components) ? components : this.getComponents();
- const isValid = components.reduce((valid, comp) => {
- return comp.checkData(data, flags, row) && valid;
- }, super.checkData(data, flags, row));
-
- this.checkModal(isValid, this.isDirty);
- return isValid;
- }
-
- checkConditions(data, flags, row) {
- // check conditions of parent component first, because it may influence on visibility of it's children
- const check = super.checkConditions(data, flags, row);
- //row data of parent component not always corresponds to row of nested components, use comp.data as row data for children instead
- this.getComponents().forEach(comp => comp.checkConditions(data, flags, comp.data));
- return check;
- }
-
- clearOnHide(show) {
- super.clearOnHide(show);
- if (this.component.clearOnHide) {
- if (this.allowData && !this.hasValue() && !(this.options.server && !this.visible)) {
- this.dataValue = this.defaultValue;
- }
- if (this.hasValue()) {
- this.restoreComponentsContext();
- }
- }
- this.getComponents().forEach(component => component.clearOnHide(show));
- }
-
- restoreComponentsContext() {
- this.getComponents().forEach((component) => component.data = this.dataValue);
- }
-
- /**
- * Allow components to hook into the next page trigger to perform their own logic.
- *
- * @return {*}
- */
- beforePage(next) {
- return NativePromise.all(this.getComponents().map((comp) => comp.beforePage(next)));
- }
-
- /**
- * Allow components to hook into the submission to provide their own async data.
- *
- * @return {*}
- */
- beforeSubmit() {
- return NativePromise.all(this.getComponents().map((comp) => comp.beforeSubmit()));
- }
-
- calculateValue(data, flags, row) {
- // Do not iterate into children and calculateValues if this nested component is conditionally hidden.
- if (!this.conditionallyVisible()) {
- return false;
- }
- return this.getComponents().reduce(
- (changed, comp) => comp.calculateValue(data, flags, row) || changed,
- super.calculateValue(data, flags, row)
- );
- }
-
- isLastPage() {
- return this.pages.length - 1 === this.page;
- }
-
- isValid(data, dirty) {
- return this.getComponents().reduce(
- (valid, comp) => comp.isValid(data, dirty) && valid,
- super.isValid(data, dirty)
- );
- }
-
- checkChildComponentsValidity(data, dirty, row, silentCheck, isParentValid) {
- return this.getComponents().reduce(
- (check, comp) => comp.checkValidity(data, dirty, row, silentCheck) && check,
- isParentValid
- );
- }
-
- checkValidity(data, dirty, row, silentCheck) {
- if (!this.checkCondition(row, data)) {
- this.setCustomValidity('');
- return true;
- }
-
- const isValid = this.checkChildComponentsValidity(data, dirty, row, silentCheck, super.checkValidity(data, dirty, row, silentCheck));
- this.checkModal(isValid, dirty);
- return isValid;
- }
-
- checkAsyncValidity(data, dirty, row, silentCheck) {
- return this.ready.then(() => {
- const promises = [super.checkAsyncValidity(data, dirty, row, silentCheck)];
- this.eachComponent((component) => promises.push(component.checkAsyncValidity(data, dirty, row, silentCheck)));
- return NativePromise.all(promises).then((results) => results.reduce((valid, result) => (valid && result), true));
- });
- }
-
- setPristine(pristine) {
- super.setPristine(pristine);
- this.getComponents().forEach((comp) => comp.setPristine(pristine));
- }
-
- get isPristine() {
- return this.pristine && this.getComponents().every((c) => c.isPristine);
- }
-
- get isDirty() {
- return this.dirty && this.getComponents().every((c) => c.isDirty);
- }
-
- detach() {
- this.components.forEach(component => {
- component.detach();
- });
- super.detach();
- }
-
- clear() {
- this.components.forEach(component => {
- component.clear();
- });
- super.clear();
- }
-
- destroy() {
- this.destroyComponents();
- super.destroy();
- }
-
- destroyComponents() {
- const components = this.getComponents().slice();
- components.forEach((comp) => this.removeComponent(comp, this.components));
- this.components = [];
- }
-
- get errors() {
- const thisErrors = this.error ? [this.error] : [];
- return this.getComponents()
- .reduce((errors, comp) => errors.concat(comp.errors || []), thisErrors)
- .filter(err => err.level !== 'hidden');
- }
-
- getValue() {
- return this.data;
- }
-
- resetValue() {
- super.resetValue();
- this.getComponents().forEach((comp) => comp.resetValue());
- this.setPristine(true);
- }
-
- get dataReady() {
- return NativePromise.all(this.getComponents().map((component) => component.dataReady));
- }
-
- setNestedValue(component, value, flags = {}) {
- component._data = this.componentContext(component);
- if (component.type === 'button') {
- return false;
- }
- if (component.type === 'components') {
- if (component.tree && component.hasValue(value)) {
- return component.setValue(_.get(value, component.key), flags);
- }
- return component.setValue(value, flags);
- }
- else if (value && component.hasValue(value)) {
- return component.setValue(_.get(value, component.key), flags);
- }
- else if ((!this.rootPristine || component.visible) && component.shouldAddDefaultValue) {
- flags.noValidate = !flags.dirty;
- flags.resetValue = true;
- return component.setValue(component.defaultValue, flags);
- }
- }
-
- setValue(value, flags = {}) {
- if (!value) {
- return false;
- }
- if (value.submitAsDraft && !value.submit) {
- flags.noValidate = true;
- }
- return this.getComponents().reduce((changed, component) => {
- return this.setNestedValue(component, value, flags, changed) || changed;
- }, false);
- }
-
- get lazyLoad() {
- return this.component.lazyLoad ?? false;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.unit.js
deleted file mode 100644
index 883ae2e5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/NestedComponent.unit.js
+++ /dev/null
@@ -1,331 +0,0 @@
-'use strict';
-import NestedComponent from './NestedComponent';
-import Harness from '../../../../test/harness';
-import assert from 'power-assert';
-import each from 'lodash/each';
-import { expect } from 'chai';
-import { comp1, comp2, comp3 } from './fixtures';
-import { nestedForm } from '../../../../test/fixtures';
-import _map from 'lodash/map';
-import Webform from '../../../Webform';
-
-let component = null;
-describe('NestedComponent class', () => {
- it('Should create a new NestedComponent class', () => {
- return Harness.testCreate(NestedComponent, {
- // key: 'nested',
- components: [
- {
- type: 'textfield',
- key: 'firstName',
- input: true
- },
- {
- type: 'textfield',
- key: 'lastName',
- input: true
- }
- ]
- }).then((_component) => {
- component = _component;
- Harness.testElements(component, 'input[name="data[firstName]"]', 1);
- Harness.testElements(component, 'input[name="data[lastName]"]', 1);
- });
- });
-
- it('Should be able to add new components', (done) => {
- component.addComponent({
- type: 'email',
- key: 'email',
- input: true
- });
- component.redraw();
- Harness.testElements(component, 'input[name="data[email]"]', 1);
- done();
- });
-
- it('Should be able to set data within the components.', (done) => {
- const value = {
- firstName: 'Joe',
- lastName: 'Smith',
- email: 'joe@example.com'
- };
- component.setValue(value);
- assert.deepEqual(component.getValue(), value);
- each(component.components, (component) => {
- assert.equal(component.getValue(), value[component.key]);
- });
- done();
- });
-
- it('Should create nested visibility elements.', () => {
- return Harness.testCreate(NestedComponent, {
- components: [
- {
- type: 'checkbox',
- key: 'showPanel',
- label: 'Show Panel',
- input: true
- },
- {
- type: 'panel',
- key: 'parent',
- title: 'Parent Panel',
- conditional: {
- json: { var: 'data.showPanel' }
- },
- components: [
- {
- type: 'checkbox',
- key: 'showChild',
- label: 'Child 1',
- input: true,
- conditional: {
- json: { var: 'data.showChild' }
- }
- },
- {
- type: 'checkbox',
- key: 'forceParent',
- label: 'Child 2',
- input: true,
- conditional: {
- json: { var: 'data.forceParent' },
- }
- }
- ]
- }
- ]
- }).then((comp) => {
- // Make sure we built the components tree.
- assert.equal(comp.components.length, 2);
- assert.equal(comp.components[1].components.length, 2, 'two');
- const data = {
- showPanel: true,
- showChild: false,
- forceParent: false
- };
-
- comp.setValue(data);
- comp.checkConditions(data);
- assert.equal(comp.components[1]._visible, true);
- assert.equal(comp.components[1].components[0]._visible, false);
- assert.equal(comp.components[1].components[1]._visible, false);
-
- data.showChild = true;
- comp.setValue(data);
- comp.checkConditions(data);
- assert.equal(comp.components[1]._visible, true);
- assert.equal(comp.components[1].components[0]._visible, true);
- assert.equal(comp.components[1].components[1]._visible, false);
-
- data.showPanel = false;
- comp.setValue(data);
- comp.checkConditions(data);
- assert.equal(comp.components[1]._visible, false);
- assert.equal(comp.components[1].components[0]._visible, true);
- assert.equal(comp.components[1].components[1]._visible, false);
-
- // overrideParent is depricated.
- data.forceParent = true;
- comp.setValue(data);
- comp.checkConditions(data);
- assert.equal(comp.components[1]._visible, false);
- assert.equal(comp.components[1].components[0]._visible, true);
- assert.equal(comp.components[1].components[1]._visible, true);
- });
- });
-
- describe('set/get visible', () => {
- it('should set/get visible flag on instance and child components', done => {
- Harness.testCreate(NestedComponent, comp1)
- .then(nested => {
- expect(nested.visible).to.be.true;
- nested.components.forEach(cmp => {
- expect(cmp.parentVisible).to.be.true;
- });
-
- nested.visible = false;
-
- expect(nested.visible).to.be.false;
-
- nested.components.forEach(cmp => {
- expect(cmp.parentVisible).to.be.false;
- });
-
- nested.visible = true;
-
- nested.components.forEach(cmp => {
- expect(cmp.parentVisible).to.be.true;
- });
-
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('set/get parentVisible', () => {
- it('should set/get parentVisible flag on instance and child components', done => {
- Harness.testCreate(NestedComponent, comp1)
- .then(nested => {
- expect(nested.parentVisible).to.be.true;
-
- nested.components.forEach(cmp => {
- expect(cmp.parentVisible).to.be.true;
- });
-
- nested.parentVisible = false;
-
- expect(nested.parentVisible).to.be.false;
-
- nested.components.forEach(cmp => {
- expect(cmp.parentVisible).to.be.false;
- });
-
- nested.parentVisible = true;
-
- expect(nested.parentVisible).to.be.true;
-
- nested.components.forEach(cmp => {
- expect(cmp.parentVisible).to.be.true;
- });
-
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('get schema', () => {
- it('components array shouldn\'t have duplicates', done => {
- Harness.testCreate(NestedComponent, comp1)
- .then(nested => {
- const child = nested.components[0];
- nested.components = [...nested.components, child, child, child];
- expect(nested.components).to.have.lengthOf(5);
- expect(nested.schema.components).to.be.lengthOf(2);
- expect(_map(nested.schema.components, 'key')).to.deep.equal(['firstName', 'lastName']);
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('calculateComponentPath', () => {
- it('the first layer components', (done) => {
- Harness.testCreate(NestedComponent, comp1)
- .then((nested) => {
- assert(nested.components[0].path === 'firstName');
- assert(nested.components[1].path === 'lastName');
- done();
- })
- .catch(done);
- });
- it('inside data components', (done) => {
- Harness.testCreate(NestedComponent, comp2)
- .then((nested) => {
- assert(nested.components[0].path === 'dataGrid');
- const dataGrid = nested.components[0];
- dataGrid.setValue([{ textField: '' }, { textField: '' }]);
- setTimeout(() => {
- assert(dataGrid.components[0].path === 'dataGrid[0].textField');
- assert(dataGrid.components[1].path === 'dataGrid[1].textField');
- done();
- },250);
- })
- .catch(done);
- });
- it('inside nested forms', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(nestedForm)
- .then(() => {
- assert(form.components[0].path === 'form');
-
- const childForm = form.components[0].subForm;
- const textField = childForm.components[0];
- const dataGrid = childForm.components[1];
- const tabs = childForm.components[2];
-
- assert(textField.path === 'form.data.textField');
- assert(dataGrid.path === 'form.data.dataGrid');
- assert(dataGrid.components[0].path === 'form.data.dataGrid[0].textField');
- assert(tabs.path === 'form.data.tabs');
- assert(tabs.tabs[0][0].path === 'form.data.tabsTextfield');
- done();
- })
- .catch(done);
- });
- });
-
- describe('getComponent', () => {
- it('the first layer components', (done) => {
- Harness.testCreate(NestedComponent, comp1)
- .then((nested) => {
- const firstNameTextFieldByStringPath = nested.getComponent('firstName');
- const firstNameTextFieldByArrayPath = nested.getComponent(['firstName']);
- assert(firstNameTextFieldByStringPath.path === 'firstName');
- assert(firstNameTextFieldByArrayPath.path === 'firstName');
- done();
- })
- .catch(done);
- });
- it('inside data components', (done) => {
- Harness.testCreate(NestedComponent, comp2)
- .then((nested) => {
- assert(nested.components[0].path === 'dataGrid');
- const dataGrid = nested.components[0];
- dataGrid.setValue([{ textField: '' }, { textField: '' }]);
- setTimeout(() => {
- const dataGridFirstRowTextField= nested.getComponent('dataGrid[0].textField');
- const dataGridSecondRowTextField= nested.getComponent('dataGrid[1].textField');
-
- assert(dataGrid.components[0] === dataGridFirstRowTextField);
- assert(dataGrid.components[1] === dataGridSecondRowTextField);
- done();
- },250);
- })
- .catch(done);
- });
- it('inside nested forms', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(nestedForm)
- .then(() => {
- const childForm = form.components[0].subForm;
- const textField = form.getComponent('form.data.textField');
- const dataGrid = form.getComponent('form.data.dataGrid');
- const dataGridTextField = form.getComponent('form.data.dataGrid[0].textField');
-
- assert(textField === childForm.components[0]);
- assert(dataGrid === childForm.components[1]);
- assert(dataGridTextField === childForm.components[1].components[0]);
- done();
- })
- .catch(done);
- });
- });
-
- describe('render value as String', () => {
- it('Should render a Select\'s value template', (done) => {
- Harness.testCreate(NestedComponent, comp3)
- .then((nested) => {
- const editGrid = nested.components[0];
- editGrid.addRow();
- editGrid.editRows[0].components[0].setValue(2);
- setTimeout(() => {
- editGrid.saveRow(0);
- setTimeout(() => {
- assert.equal(editGrid.dataValue[0].select, 2);
- const rowContent = editGrid.element.querySelector('[ref="editgrid-editGrid-row"] .row .col-sm-2 span');
- assert(rowContent);
- assert.equal(rowContent.textContent, 'Banana');
- done();
- }, 250);
- }, 250);
- })
- .catch(done);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp1.js
deleted file mode 100644
index 0f86f4a7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp1.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default {
- components: [
- {
- type: 'textfield',
- key: 'firstName',
- input: true
- },
- {
- type: 'textfield',
- key: 'lastName',
- input: true
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp2.js
deleted file mode 100644
index 5b76be11..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp2.js
+++ /dev/null
@@ -1,225 +0,0 @@
-export default {
- components: [
- {
- label: 'Data Grid',
- reorder: false,
- addAnotherPosition: 'bottom',
- defaultOpen: false,
- layoutFixed: false,
- enableRowGroups: false,
- tableView: false,
- defaultValue: [
- {}
- ],
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true,
- custom: '',
- customPrivate: false,
- strictDateValidation: false,
- multiple: false,
- unique: false,
- minLength: '',
- maxLength: '',
- pattern: ''
- },
- key: 'textField',
- type: 'textfield',
- input: true,
- placeholder: '',
- prefix: '',
- customClass: '',
- suffix: '',
- multiple: false,
- defaultValue: null,
- 'protected': false,
- unique: false,
- persistent: true,
- hidden: false,
- clearOnHide: true,
- refreshOn: '',
- redrawOn: '',
- modalEdit: false,
- labelPosition: 'top',
- description: '',
- errorLabel: '',
- tooltip: '',
- hideLabel: false,
- tabindex: '',
- disabled: false,
- autofocus: false,
- dbIndex: false,
- customDefaultValue: '',
- calculateValue: '',
- calculateServer: false,
- widget: {
- type: 'input'
- },
- attributes: {},
- validateOn: 'change',
- conditional: {
- show: null,
- when: null,
- eq: ''
- },
- overlay: {
- style: '',
- left: '',
- top: '',
- width: '',
- height: ''
- },
- allowCalculateOverride: false,
- encrypted: false,
- showCharCount: false,
- showWordCount: false,
- properties: {},
- allowMultipleMasks: false,
- mask: false,
- inputType: 'text',
- inputFormat: 'plain',
- inputMask: '',
- spellcheck: true,
- id: 'emxxdbi'
- }
- ],
- placeholder: '',
- prefix: '',
- customClass: '',
- suffix: '',
- multiple: false,
- 'protected': false,
- unique: false,
- persistent: true,
- hidden: false,
- clearOnHide: true,
- refreshOn: '',
- redrawOn: '',
- modalEdit: false,
- labelPosition: 'top',
- description: '',
- errorLabel: '',
- tooltip: '',
- hideLabel: false,
- tabindex: '',
- disabled: false,
- autofocus: false,
- dbIndex: false,
- customDefaultValue: '',
- calculateValue: '',
- calculateServer: false,
- widget: null,
- attributes: {},
- validateOn: 'change',
- validate: {
- required: false,
- custom: '',
- customPrivate: false,
- strictDateValidation: false,
- multiple: false,
- unique: false
- },
- conditional: {
- show: null,
- when: null,
- eq: ''
- },
- overlay: {
- style: '',
- left: '',
- top: '',
- width: '',
- height: ''
- },
- allowCalculateOverride: false,
- encrypted: false,
- showCharCount: false,
- showWordCount: false,
- properties: {},
- allowMultipleMasks: false,
- tree: true,
- disableAddingRemovingRows: false,
- id: 'erygkn'
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- placeholder: '',
- prefix: '',
- customClass: '',
- suffix: '',
- multiple: false,
- defaultValue: null,
- 'protected': false,
- unique: false,
- persistent: false,
- hidden: false,
- clearOnHide: true,
- refreshOn: '',
- redrawOn: '',
- modalEdit: false,
- labelPosition: 'top',
- description: '',
- errorLabel: '',
- tooltip: '',
- hideLabel: false,
- tabindex: '',
- disabled: false,
- autofocus: false,
- dbIndex: false,
- customDefaultValue: '',
- calculateValue: '',
- calculateServer: false,
- widget: {
- type: 'input'
- },
- attributes: {},
- validateOn: 'change',
- validate: {
- required: false,
- custom: '',
- customPrivate: false,
- strictDateValidation: false,
- multiple: false,
- unique: false
- },
- conditional: {
- show: null,
- when: null,
- eq: ''
- },
- overlay: {
- style: '',
- left: '',
- top: '',
- width: '',
- height: ''
- },
- allowCalculateOverride: false,
- encrypted: false,
- showCharCount: false,
- showWordCount: false,
- properties: {},
- allowMultipleMasks: false,
- size: 'md',
- leftIcon: '',
- rightIcon: '',
- block: false,
- action: 'submit',
- disableOnInvalid: false,
- theme: 'primary',
- dataGridLabel: true,
- id: 'evn07ja'
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp3.js
deleted file mode 100644
index ea23bfff..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/comp3.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default {
- 'components': [{
- 'label': 'Edit Grid',
- 'tableView': false,
- 'rowDrafts': false,
- 'key': 'editGrid',
- 'type': 'editgrid',
- 'input': true,
- 'components': [
- {
- 'label': 'Select',
- 'widget': 'choicesjs',
- 'tableView': true,
- 'dataSrc': 'custom',
- 'data': {
- 'custom': "values = [\n {id: 1, name: 'Apple'},\n {id: 2, name: 'Banana'},\n {id: 3, name: 'Orange'},\n {id: 3, name: 'Pineapple'}\n];"
- },
- 'valueProperty': 'id',
- 'template': '{{ item.name }} ',
- 'selectThreshold': 0.3,
- 'key': 'select',
- 'type': 'select',
- 'input': true
- }
- ]
- }]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/index.js
deleted file mode 100644
index 6a792d0a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nested/fixtures/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as comp1 } from './comp1';
-export { default as comp2 } from './comp2';
-export { default as comp3 } from './comp3';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nestedarray/NestedArrayComponent.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nestedarray/NestedArrayComponent.js
deleted file mode 100644
index d718fd60..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nestedarray/NestedArrayComponent.js
+++ /dev/null
@@ -1,218 +0,0 @@
-'use strict';
-
-import _ from 'lodash';
-import { componentValueTypes } from '../../../utils/utils';
-
-import Component from '../component/Component';
-import NestedDataComponent from '../nesteddata/NestedDataComponent';
-
-export default class NestedArrayComponent extends NestedDataComponent {
- static schema(...extend) {
- return NestedDataComponent.schema({
- disableAddingRemovingRows: false
- }, ...extend);
- }
-
- static savedValueTypes() {
- return [componentValueTypes.array];
- }
-
- componentContext(component) {
- return this.iteratableRows[component.rowIndex].data;
- }
-
- get iteratableRows() {
- throw new Error('Getter #iteratableRows() is not implemented');
- }
-
- get rowIndex() {
- return super.rowIndex;
- }
-
- set rowIndex(value) {
- this._rowIndex = value;
- }
-
- init() {
- super.init();
- this.prevHasAddButton = this.hasAddButton();
- }
-
- checkAddButtonChanged() {
- const isAddButton = this.hasAddButton();
- if (isAddButton !== this.prevHasAddButton) {
- this.prevHasAddButton = isAddButton;
- this.redraw();
- }
- }
-
- checkData(data, flags, row) {
- data = data || this.rootValue;
- flags = flags || {};
- row = row || this.data;
- this.checkAddButtonChanged();
-
- return this.checkRows('checkData', data, flags, Component.prototype.checkData.call(this, data, flags, row));
- }
-
- checkRows(method, data, opts, defaultValue, silentCheck) {
- return this.iteratableRows.reduce(
- (valid, row, rowIndex) => {
- if (!opts?.rowIndex || opts?.rowIndex === rowIndex) {
- return this.checkRow(method, data, opts, row.data, row.components, silentCheck) && valid;
- }
- else {
- return valid;
- }
- },
- defaultValue,
- );
- }
-
- checkRow(method, data, opts, row, components, silentCheck) {
- if (opts?.isolateRow) {
- silentCheck = true;
- opts.noRefresh = true;
- }
-
- const valid = _.reduce(
- components,
- (valid, component) => component[method](data, opts, row, silentCheck) && valid,
- true,
- );
- if (opts?.noRefresh) {
- delete opts.noRefresh;
- }
- return valid;
- }
-
- hasAddButton() {
- const maxLength = _.get(this.component, 'validate.maxLength');
- const conditionalAddButton = _.get(this.component, 'conditionalAddButton');
-
- return !this.component.disableAddingRemovingRows &&
- !this.options.readOnly &&
- !this.disabled &&
- this.fullMode &&
- !this.options.preview &&
- (!maxLength || (this.iteratableRows.length < maxLength)) &&
- (!conditionalAddButton || this.evaluate(conditionalAddButton, {
- value: this.dataValue,
- }, 'show'));
- }
-
- getComponent(path, fn, originalPath) {
- path = Array.isArray(path) ? path : [path];
- let key = path.shift();
- const remainingPath = path;
- let result = [];
- let possibleComp = null;
- let comp = null;
- let rowIndex = null;
-
- if (_.isNumber(key)) {
- rowIndex = key;
- key = remainingPath.shift();
- }
- if (!_.isString(key)) {
- return result;
- }
-
- this.everyComponent((component, components) => {
- if (component.component.key === key) {
- possibleComp = component;
- if (remainingPath.length > 0 && 'getComponent' in component) {
- comp = component.getComponent(remainingPath, fn, originalPath);
- }
- else if (fn) {
- fn(component, components);
- }
- result = rowIndex !== null ? comp : result.concat(comp || possibleComp);
- }
- }, rowIndex);
- if ((!result || result.length === 0) && possibleComp) {
- result = rowIndex !== null ? possibleComp : [possibleComp];
- }
- return result;
- }
-
- everyComponent(fn, rowIndex, options) {
- if (_.isObject(rowIndex)) {
- options = rowIndex;
- rowIndex = null;
- }
-
- if (options?.email) {
- return;
- }
-
- const components = this.getComponents(rowIndex);
- _.each(components, (component, index) => {
- if (fn(component, components, index) === false) {
- return false;
- }
-
- if (typeof component.everyComponent === 'function') {
- if (component.everyComponent(fn, options) === false) {
- return false;
- }
- }
- });
- }
-
- getValueAsString(value, options) {
- if (options?.email) {
- let result = (`
-
-
-
- `);
-
- this.component.components?.forEach((component) => {
- const label = component.label || component.key;
- result += `${label} `;
- });
-
- result += (`
-
-
-
- `);
-
- this.iteratableRows.forEach(({ components }) => {
- result += '';
- _.each(components, (component) => {
- result += '';
- if (component.isInputComponent && component.visible && !component.skipInEmail) {
- result += component.getView(component.dataValue, options);
- }
- result += ' ';
- });
- result += ' ';
- });
-
- result += (`
-
-
- `);
-
- return result;
- }
-
- if (!value || !value.length) {
- return '';
- }
-
- return super.getValueAsString(value, options);
- }
-
- getComponents(rowIndex) {
- if (rowIndex !== undefined) {
- if (!this.iteratableRows[rowIndex]) {
- return [];
- }
- return this.iteratableRows[rowIndex].components;
- }
- return super.getComponents();
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nestedarray/NestedArrayComponent.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nestedarray/NestedArrayComponent.unit.js
deleted file mode 100644
index 5f252615..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nestedarray/NestedArrayComponent.unit.js
+++ /dev/null
@@ -1,28 +0,0 @@
-'use strict';
-import NestedArrayComponent from './NestedArrayComponent';
-import Harness from '../../../../test/harness';
-
-let component = null;
-describe('NestedArrayComponent class', () => {
- it('Should create a new NestedArrayComponent class', () => {
- return Harness.testCreate(NestedArrayComponent, {
- // key: 'nested',
- components: [
- {
- type: 'textfield',
- key: 'firstName',
- input: true
- },
- {
- type: 'textfield',
- key: 'lastName',
- input: true
- }
- ]
- }).then((_component) => {
- component = _component;
- Harness.testElements(component, 'input[name="data[firstName]"]', 1);
- Harness.testElements(component, 'input[name="data[lastName]"]', 1);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nesteddata/NestedDataComponent.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nesteddata/NestedDataComponent.js
deleted file mode 100644
index b88ab330..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nesteddata/NestedDataComponent.js
+++ /dev/null
@@ -1,155 +0,0 @@
-'use strict';
-import Component from '../component/Component';
-import NestedComponent from '../nested/NestedComponent';
-import _ from 'lodash';
-import { componentValueTypes, getComponentSavedTypes } from '../../../utils/utils';
-
-export default class NestedDataComponent extends NestedComponent {
- hasChanged(newValue, oldValue) {
- // If we do not have a value and are getting set to anything other than undefined or null, then we changed.
- if (
- newValue !== undefined &&
- newValue !== null &&
- !this.hasValue()
- ) {
- return true;
- }
- return !_.isEqual(newValue, oldValue);
- }
-
- static savedValueTypes(schema) {
- return getComponentSavedTypes(schema) || [componentValueTypes.object];
- }
-
- get allowData() {
- return true;
- }
-
- get emptyValue() {
- return {};
- }
-
- componentContext() {
- return this.dataValue;
- }
-
- getValueAsString(value, options) {
- if (options?.email) {
- let result = (`
-
-
- `);
-
- this.everyComponent((component) => {
- if (component.isInputComponent && component.visible && !component.skipInEmail) {
- result += (`
-
- ${component.label}
- ${component.getView(component.dataValue, options)}
-
- `);
- }
- }, {
- ...options,
- fromRoot: true,
- });
-
- result += (`
-
-
- `);
-
- return result;
- }
- if (_.isEmpty(value)) {
- return '';
- }
- if (options?.modalPreview) {
- delete options.modalPreview;
- return this.getDataValueAsTable(value, options);
- }
-
- return '[Complex Data]';
- }
-
- getDataValueAsTable(value, options) {
- let result = (`
-
- `);
-
- return result;
- }
-
- everyComponent(fn, options) {
- if (options?.email) {
- if (options.fromRoot) {
- delete options.fromRoot;
- }
- else {
- return;
- }
- }
-
- return super.everyComponent(fn, options);
- }
-
- /**
- * Get the value of this component.
- *
- * @returns {*}
- */
- getValue() {
- return this.dataValue;
- }
-
- updateValue(value, flags = {}) {
- // Intentionally skip over nested component updateValue method to keep
- // recursive update from occurring with sub components.
- return Component.prototype.updateValue.call(this, value, flags);
- }
-
- setValue(value, flags = {}) {
- let changed = false;
-
- const hasValue = this.hasValue();
- if (hasValue && _.isEmpty(this.dataValue)) {
- flags.noValidate = true;
- }
-
- if (!value || !_.isObject(value) || !hasValue) {
- changed = true;
- this.dataValue = this.defaultValue;
- }
-
- changed = super.setValue(value, flags) || changed;
-
- this.updateOnChange(flags, changed);
- return changed;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nesteddata/NestedDataComponent.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/_classes/nesteddata/NestedDataComponent.unit.js
deleted file mode 100644
index c0931c4d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/_classes/nesteddata/NestedDataComponent.unit.js
+++ /dev/null
@@ -1,28 +0,0 @@
-'use strict';
-import NestedDataComponent from './NestedDataComponent';
-import Harness from '../../../../test/harness';
-
-let component = null;
-describe('NestedDataComponent class', () => {
- it('Should create a new NestedDataComponent class', () => {
- return Harness.testCreate(NestedDataComponent, {
- // key: 'nested',
- components: [
- {
- type: 'textfield',
- key: 'firstName',
- input: true
- },
- {
- type: 'textfield',
- key: 'lastName',
- input: true
- }
- ]
- }).then((_component) => {
- component = _component;
- Harness.testElements(component, 'input[name="data[firstName]"]', 1);
- Harness.testElements(component, 'input[name="data[lastName]"]', 1);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/Address.form.js b/web-client/core/themes/italia/static/formio/css/src/components/address/Address.form.js
deleted file mode 100644
index aae69d7c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/Address.form.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import Components from '../Components';
-import AddressEditData from './editForm/Address.edit.data';
-import AddressEditDisplay from './editForm/Address.edit.display';
-import AddressEditProvider from './editForm/Address.edit.provider';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'data',
- components: AddressEditData,
- },
- {
- key: 'display',
- components: AddressEditDisplay,
- },
- {
- label: 'Provider',
- key: 'provider',
- weight: 15,
- components: AddressEditProvider,
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/Address.js b/web-client/core/themes/italia/static/formio/css/src/components/address/Address.js
deleted file mode 100644
index 215e2dd6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/Address.js
+++ /dev/null
@@ -1,664 +0,0 @@
-import autocompleter from 'autocompleter';
-import _ from 'lodash';
-
-import { GlobalFormio as Formio } from '../../Formio';
-import { GoogleAddressProvider } from '../../providers/address/GoogleAddressProvider';
-
-import Field from '../_classes/field/Field';
-import NestedComponent from '../_classes/nested/NestedComponent';
-import ContainerComponent from '../container/Container';
-import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-
-export const AddressComponentMode = {
- Autocomplete: 'autocomplete',
- Manual: 'manual',
-};
-
-const RemoveValueIconHiddenClass = 'address-autocomplete-remove-value-icon--hidden';
-const ChildConditional = 'show = _.get(instance, \'parent.manualMode\', false);';
-
-export default class AddressComponent extends ContainerComponent {
- static schema(...extend) {
- return ContainerComponent.schema({
- type: 'address',
- label: 'Address',
- key: 'address',
- switchToManualModeLabel: 'Can\'t find address? Switch to manual mode.',
- provider: '',
- providerOptions: {},
- manualModeViewString: '',
- hideLabel: false,
- disableClearIcon: false,
- enableManualMode: false,
- components: [
- {
- label: 'Address 1',
- tableView: false,
- key: 'address1',
- type: 'textfield',
- input: true,
- customConditional: ChildConditional,
- },
- {
- label: 'Address 2',
- tableView: false,
- key: 'address2',
- type: 'textfield',
- input: true,
- customConditional: ChildConditional,
- },
- {
- label: 'City',
- tableView: false,
- key: 'city',
- type: 'textfield',
- input: true,
- customConditional: ChildConditional,
- },
- {
- label: 'State',
- tableView: false,
- key: 'state',
- type: 'textfield',
- input: true,
- customConditional: ChildConditional,
- },
- {
- label: 'Country',
- tableView: false,
- key: 'country',
- type: 'textfield',
- input: true,
- customConditional: ChildConditional,
- },
- {
- label: 'Zip Code',
- tableView: false,
- key: 'zip',
- type: 'textfield',
- input: true,
- customConditional: ChildConditional,
- },
- ],
- }, ...extend);
- }
-
- static savedValueTypes(schema) {
- schema = schema || {};
-
- return getComponentSavedTypes(schema) || [componentValueTypes.object];
- }
-
- static get builderInfo() {
- return {
- title: 'Address',
- group: 'advanced',
- icon: 'home',
- documentation: '/userguide/form-building/advanced-components#address',
- weight: 35,
- schema: AddressComponent.schema(),
- };
- }
-
- mergeSchema(component = {}) {
- let { defaultSchema } = this;
-
- if (component.components) {
- defaultSchema = _.omit(defaultSchema, 'components');
- }
-
- return _.defaultsDeep(component , defaultSchema);
- }
-
- init() {
- this.components = this.components || [];
- if (this.builderMode || this.manualModeEnabled) {
- NestedComponent.prototype.addComponents.call(this, this.manualMode ? this.address : {});
- }
- Field.prototype.init.call(this);
-
- if (!this.builderMode) {
- if (this.component.provider) {
- const {
- provider,
- providerOptions,
- } = this.component;
- this.provider = this.initializeProvider(provider, providerOptions);
- }
- else if (this.component.map) {
- // Fallback to legacy version where Google Maps was the only provider.
- this.component.provider = GoogleAddressProvider.name;
- this.component.providerOptions = this.component.providerOptions || {};
-
- const {
- map,
- provider,
- providerOptions,
- } = this.component;
-
- const {
- key,
- region,
- } = map;
-
- if (key) {
- _.set(providerOptions, 'params.key', key);
- }
- if (region) {
- _.set(providerOptions, 'params.region', region);
- }
-
- this.provider = this.initializeProvider(provider, providerOptions);
- }
- }
- }
-
- initializeProvider(provider, options = {}) {
- const url = this.interpolate(options.url);
- const Provider = Formio.Providers.getProvider('address', provider);
- return new Provider({ ...options, url });
- }
-
- get emptyValue() {
- return this.manualModeEnabled
- ? {
- mode: AddressComponentMode.Autocomplete,
- address: {},
- }
- : {};
- }
-
- get mode() {
- if (!this.manualModeEnabled) {
- return AddressComponentMode.Autocomplete;
- }
-
- return this.dataValue?.mode ?? AddressComponentMode.Autocomplete;
- }
-
- set mode(value) {
- if (this.manualModeEnabled) {
- this.dataValue.mode = value;
- }
- }
-
- get autocompleteMode() {
- return this.mode === AddressComponentMode.Autocomplete;
- }
-
- get manualMode() {
- return this.mode === AddressComponentMode.Manual;
- }
-
- get manualModeEnabled() {
- return !this.isMultiple && Boolean(this.component.enableManualMode);
- }
-
- restoreComponentsContext() {
- this.getComponents().forEach((component) => {
- component.data = this.address;
- component.setValue(component.dataValue, {
- noUpdateEvent: true,
- });
- });
- }
-
- get isMultiple() {
- return Boolean(this.component.multiple);
- }
-
- get address() {
- if (this.isMultiple) {
- return _.isArray(this.dataValue) ? this.dataValue : [this.dataValue];
- }
- // Manual mode is not implementing for multiple value
- return (this.manualModeEnabled && this.dataValue) ? this.dataValue.address : this.dataValue;
- }
-
- set address(value) {
- if (this.manualModeEnabled && !this.isMultiple) {
- this.dataValue.address = value;
- }
- else {
- this.dataValue = value;
- }
- }
-
- get defaultValue() {
- let defaultValue = super.defaultValue;
-
- if (this.isMultiple) {
- defaultValue = _.isArray(defaultValue) ? defaultValue : [defaultValue];
- }
-
- return defaultValue;
- }
-
- get defaultSchema() {
- return AddressComponent.schema();
- }
-
- isValueInLegacyFormat(value) {
- return value && !value.mode;
- }
-
- normalizeValue(value) {
- return (this.manualModeEnabled && this.isValueInLegacyFormat(value))
- ? {
- mode: AddressComponentMode.Autocomplete,
- address: value,
- }
- : value;
- }
-
- setValue(value, flags = {}) {
- const changed = Field.prototype.setValue.call(this, value, flags);
-
- if (this.manualMode) {
- this.restoreComponentsContext();
- }
-
- if (changed || !_.isEmpty(value) && flags.fromSubmission) {
- this.redraw();
- }
-
- return changed;
- }
-
- static get modeSwitcherRef() {
- return 'modeSwitcher';
- }
-
- static get removeValueIconRef() {
- return 'removeValueIcon';
- }
-
- static get searchInputRef() {
- return 'searchInput';
- }
-
- static get addRowButtonRef() {
- return 'addButton';
- }
-
- static get removeRowButtonRef() {
- return 'removeRow';
- }
-
- get modeSwitcher() {
- return this.refs
- ? (this.refs[AddressComponent.modeSwitcherRef] || null)
- : null;
- }
-
- get removeValueIcon() {
- return this.refs
- ? (this.refs[AddressComponent.removeValueIconRef] || null)
- : null;
- }
-
- get searchInput() {
- return this.refs
- ? (this.refs[AddressComponent.searchInputRef] || null)
- : null;
- }
-
- get addRowButton() {
- return this.refs
- ? (this.refs[AddressComponent.addRowButtonRef] || null)
- : null;
- }
-
- get removeRowButton() {
- return this.refs
- ? (this.refs[AddressComponent.removeRowButtonRef] || null)
- : null;
- }
-
- get searchInputAttributes() {
- const attr = {
- name: this.options.name,
- type: 'text',
- class: 'form-control',
- lang: this.options.language,
- tabindex: this.component.tabindex || 0,
- };
-
- if (this.component.placeholder) {
- attr.placeholder = this.t(this.component.placeholder), { _userInput: true };
- }
-
- if (this.disabled) {
- attr.disabled = 'disabled';
- }
-
- _.defaults(attr, this.component.attributes);
-
- return attr;
- }
-
- get templateName() {
- return 'address';
- }
-
- get gridTemplateName() {
- return 'multiValueTable';
- }
-
- get rowTemplateName() {
- return 'multiValueRow';
- }
-
- get hasChildren() {
- return !this.isMultiple && (this.builderMode || this.manualModeEnabled);
- }
-
- get addAnother() {
- return this.t(this.component.addAnother || 'Add Another');
- }
-
- renderElement(value) {
- return this.renderTemplate(this.templateName, {
- children: this.hasChildren ? this.renderComponents() : '',
- nestedKey: this.nestedKey,
- inputAttributes: this.searchInputAttributes,
- ref: {
- modeSwitcher: AddressComponent.modeSwitcherRef,
- removeValueIcon: AddressComponent.removeValueIconRef,
- searchInput: AddressComponent.searchInputRef,
- },
- displayValue: this.getDisplayValue(value),
- mode: {
- autocomplete: this.autocompleteMode,
- manual: this.manualMode,
- },
- });
- }
-
- renderRow(value, index) {
- return this.renderTemplate(this.rowTemplateName, {
- index,
- disabled: this.disabled,
- element: `${this.renderElement(value, index)}`,
- });
- }
-
- renderGrid() {
- return this.renderTemplate(this.gridTemplateName, {
- rows: this.address.map(this.renderRow.bind(this)).join(''),
- disabled: this.disabled,
- addAnother: this.addAnother,
- });
- }
-
- render() {
- if (this.isMultiple) {
- return super.render(this.renderGrid());
- }
-
- return super.render(this.renderElement());
- }
-
- onSelectAddress(address, element, index) {
- if (this.isMultiple) {
- this.address[index] = address;
- this.address = [...this.address];
- }
- else {
- this.address = address;
- }
-
- this.triggerChange({
- modified: true,
- });
-
- if (element) {
- element.value = this.getDisplayValue(this.isMultiple ? this.address[index] : this.address);
- }
-
- this.updateRemoveIcon(index);
- }
-
- addRow() {
- this.address = this.address.concat(this.emptyValue);
- super.redraw();
- }
-
- attach(element) {
- const result = ((this.builderMode || this.manualMode) ? super.attach : Field.prototype.attach).call(this, element);
-
- if (!this.builderMode) {
- if (!this.provider && this.component.provider) {
- const {
- provider,
- providerOptions,
- } = this.component;
- this.provider = this.initializeProvider(provider, providerOptions);
- }
- }
-
- this.loadRefs(element, {
- [AddressComponent.addRowButtonRef]: 'single',
- [AddressComponent.modeSwitcherRef]: 'single',
- [AddressComponent.removeRowButtonRef]: 'multiple',
- [AddressComponent.removeValueIconRef]: 'multiple',
- [AddressComponent.searchInputRef]: 'multiple',
- });
-
- this.searchInput.forEach((element, index) => {
- if (!this.builderMode && element && this.provider) {
- if (this.component.provider === 'google') {
- this.provider.attachAutocomplete(element, index, this.onSelectAddress.bind(this));
- }
- else {
- autocompleter({
- input: element,
- debounceWaitMs: 300,
- fetch: (text, update) => {
- const query = text;
- this.provider.search(query).then(update);
- },
- render: (address) => {
- const div = this.ce('div');
- div.textContent = this.getDisplayValue(address);
- return div;
- },
- onSelect: (address) => {
- this.onSelectAddress(address, element, index);
- },
- });
- }
-
- this.addEventListener(element, 'blur', () => {
- if (!element) {
- return;
- }
-
- if (element.value) {
- element.value = this.getDisplayValue(this.isMultiple ? this.address[index] : this.address);
- }
- });
-
- this.addEventListener(element, 'keyup', () => {
- if (!element) {
- return;
- }
-
- if (!element.value) {
- this.clearAddress(element, index);
- }
- });
- }
- });
- if (this.addRowButton) {
- this.addEventListener(this.addRowButton, 'click', event => {
- event.preventDefault();
- this.addRow();
- });
- }
- this.removeRowButton.forEach((removeRowButton, index) => {
- this.addEventListener(removeRowButton, 'click', event => {
- event.preventDefault();
- this.removeValue(index);
- });
- });
-
- if (this.modeSwitcher) {
- this.addEventListener(this.modeSwitcher, 'change', () => {
- if (!this.modeSwitcher) {
- return;
- }
-
- this.dataValue = this.emptyValue;
- this.mode = this.modeSwitcher.checked
- ? AddressComponentMode.Manual
- : AddressComponentMode.Autocomplete;
-
- if (!this.builderMode) {
- if (this.manualMode) {
- this.restoreComponentsContext();
- }
-
- this.triggerChange({
- modified: true,
- });
- }
-
- this.redraw();
- });
- }
-
- if (!this.builderMode) {
- this.removeValueIcon.forEach((removeValueIcon, index) => {
- this.updateRemoveIcon(index);
-
- const removeValueHandler = () => {
- const searchInput = this.searchInput?.[index];
- this.clearAddress(searchInput, index);
-
- if (searchInput) {
- searchInput.focus();
- }
- };
-
- this.addEventListener(removeValueIcon, 'click', removeValueHandler);
- this.addEventListener(removeValueIcon, 'keydown', ({ key }) => {
- if (key === 'Enter') {
- removeValueHandler();
- }
- });
- });
-
- _.each(this.refs.searchInput || [], el => this.addFocusBlurEvents(el));
- }
-
- return result;
- }
-
- addChildComponent(component) {
- component.customConditional = ChildConditional;
- }
-
- redraw() {
- const modeSwitcherInFocus = (this.modeSwitcher && (document.activeElement === this.modeSwitcher));
-
- return super.redraw()
- .then((result) => {
- if (modeSwitcherInFocus && this.modeSwitcher) {
- this.modeSwitcher.focus();
- }
-
- return result;
- });
- }
-
- clearAddress(element, index) {
- if (!this.isEmpty()) {
- this.triggerChange();
- }
-
- if (this.address?.[index]) {
- this.address[index] = this.emptyValue;
- }
- else {
- this.address = this.emptyValue;
- }
- if (element) {
- element.value = '';
- }
- this.updateRemoveIcon(index);
- }
-
- getDisplayValue(value = this.address) {
- return (this.provider && !this.manualMode)
- ? this.provider.getDisplayValue(value)
- : '';
- }
-
- validateMultiple() {
- return this.isMultiple;
- }
-
- updateRemoveIcon(index) {
- const removeValueIcon = this.removeValueIcon?.[index];
- if (removeValueIcon) {
- const value = this.isMultiple ? this.address[index] : this.address;
- if (this.isEmpty(value) || this.disabled) {
- this.addClass(removeValueIcon, RemoveValueIconHiddenClass);
- }
- else {
- this.removeClass(removeValueIcon, RemoveValueIconHiddenClass);
- }
- }
- }
-
- getValueAsString(value, options) {
- if (!value) {
- return '';
- }
-
- const normalizedValue = this.normalizeValue(value);
-
- const {
- address,
- mode,
- } = (
- this.manualModeEnabled
- ? normalizedValue
- : {
- address: normalizedValue,
- mode: AddressComponentMode.Autocomplete,
- }
- );
- const valueInManualMode = (mode === AddressComponentMode.Manual);
-
- if (this.provider && !valueInManualMode) {
- return this.getDisplayValue(address);
- }
-
- if (valueInManualMode) {
- if (this.component.manualModeViewString) {
- return this.interpolate(this.component.manualModeViewString, {
- address,
- data: this.data,
- component: this.component,
- });
- }
-
- return this.getComponents()
- .filter((component) => component.hasValue(address))
- .map((component) => [component, _.get(address, component.key)])
- .filter(([component, componentValue]) => !component.isEmpty(componentValue))
- .map(([component, componentValue]) => component.getValueAsString(componentValue, options))
- .join(', ');
- }
-
- return super.getValueAsString(address, options);
- }
-
- focus() {
- if (this.searchInput && this.searchInput[0]) {
- this.searchInput[0].focus();
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/Address.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/address/Address.unit.js
deleted file mode 100644
index acc889f4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/Address.unit.js
+++ /dev/null
@@ -1,233 +0,0 @@
-import Harness from '../../../test/harness';
-import AddressComponent from './Address';
-import assert from 'power-assert';
-import Formio from './../../Formio';
-import _ from 'lodash';
-
-import {
- comp1,
- comp2,
- comp3,
- comp4,
-} from './fixtures';
-
-describe('Address Component', () => {
- it('Should build an address component', () => {
- return Harness.testCreate(AddressComponent, comp1);
- });
-
- it('Should set default value and clear it on "clear icon" click (openStreetMap provider)', (done) => {
- const form = _.cloneDeep(comp2);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const address = form.getComponent('address');
- assert.equal(!!address.provider, true);
- assert.equal(address.refs.searchInput[0].value, 'Dallas County, Texas, United States');
- const clearIcon = address.refs.removeValueIcon[0];
-
- const clickEvent = new Event('click');
- clearIcon.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(address.refs.searchInput[0].value, '');
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should disable "clear icon"', (done) => {
- const form = _.cloneDeep(comp2);
- const element = document.createElement('div');
- form.components[0].disableClearIcon = true;
-
- Formio.createForm(element, form).then(form => {
- const address = form.getComponent('address');
- assert.equal(!!address.provider, true);
- assert.equal(address.refs.removeValueIcon.length, 0);
-
- done();
- }).catch(done);
- });
-
- it('Test manual mode', (done) => {
- const form = _.cloneDeep(comp2);
- const element = document.createElement('div');
- form.components[0].disableClearIcon = true;
- form.components[0].enableManualMode = true;
- form.components[0].switchToManualModeLabel = 'Check it to switch to manual mode';
- Formio.createForm(element, form).then(form => {
- const address = form.getComponent('address');
- assert.equal(!!address.provider, true);
- assert.equal(address.mode, 'autocomplete');
- assert.equal(address.refs.modeSwitcher.checked, false, 'Manual mode should be turned off');
- assert.equal(address.refs.modeSwitcher.nextElementSibling.textContent, 'Check it to switch to manual mode', 'Should set custom label for manual mode checkbox');
-
- address.components.forEach(comp => {
- assert.equal(comp.visible, false, 'Manual mode components should be hidden');
- });
- address.refs.modeSwitcher.checked = true;
-
- const changeEvent = new Event('change');
- address.refs.modeSwitcher.dispatchEvent(changeEvent);
-
- setTimeout(() => {
- assert.equal(address.refs.modeSwitcher.checked, true, 'Manual mode should be turned on');
- assert.equal(address.mode, 'manual');
- const manualModeValue = {
- address1: 'test address1',
- address2: 'test address2',
- city: 'test city',
- country: 'test country',
- state: 'test state',
- zip: '1111111',
- };
-
- address.components.forEach(comp => {
- assert.equal(comp.visible, true, 'Manual mode components should be visible');
-
- const inputEvent = new Event('input');
- const input = comp.refs.input[0];
- input.value = manualModeValue[`${comp.component.key}`];
- input.dispatchEvent(inputEvent);
- });
-
- setTimeout(() => {
- assert.deepEqual(address.dataValue, { address: manualModeValue, mode: 'manual' }, 'Should set manual mode value');
-
- document.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should close modal window without showing dialog if value not changed', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const value = {
- 'address_components': [
- {
- 'long_name': 'Los Angeles',
- 'short_name': 'Los Angeles',
- types: ['locality', 'political'],
- },
- {
- 'long_name': 'Los Angeles County',
- 'short_name': 'Los Angeles County',
- types: ['administrative_area_level_2', 'political'],
- },
- {
- 'long_name': 'California',
- 'short_name': 'CA',
- types: ['administrative_area_level_1', 'political'],
- },
- {
- 'long_name': 'United States',
- 'short_name': 'US',
- types: ['country', 'political'],
- },
- ],
- 'formatted_address': 'Los Angeles, CA, USA',
- geometry: {
- location: { lat: 34.0522342, lng: -118.2436849 },
- viewport: {
- south: 33.70365193147634,
- west: -118.6681759484859,
- north: 34.33730608759191,
- east: -118.155289077463,
- },
- },
- 'place_id': 'ChIJE9on3F3HwoAR9AhGJW_fL-I',
- types: ['locality', 'political'],
- formattedPlace: 'Los Angeles, CA, USA',
- };
- const address = form.getComponent('address');
- const openModalButton = address.componentModal.refs.openModal;
- const clickEvent = new Event('click');
- openModalButton.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(address.componentModal.isOpened, true);
- address.dataValue = value;
- address.componentModal.closeModal();
- address.redraw();
-
- setTimeout(() => {
- address.componentModal.isOpened = true;
- openModalButton.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(address.componentModal.isOpened, true);
- assert.equal(!!address.dataValue, true);
- const modalOverlayButton = address.componentModal.refs.modalOverlay;
- modalOverlayButton.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!address.componentModal.isValueChanged(), false);
- assert.equal(!!address.componentModal.dialogElement, false);
- done();
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should correctly display component that has a conditional based on the Address component', (done) => {
- const value = {
- 'place_id': 298032694,
- licence: 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright',
- 'osm_type': 'relation',
- 'osm_id': 1180520,
- boundingbox: [
- 37.4148293,
- 37.907822,
- -93.191483,
- -92.845795
- ],
- lat: 37.6832712,
- lon: -93.0219376,
- 'display_name': 'Dallas County, Missouri, United States',
- class: 'boundary',
- type: 'administrative',
- importance: 0.6131235182618818,
- icon: 'https://nominatim.openstreetmap.org/ui/mapicons/poi_boundary_administrative.p.20.png',
- address: {
- county: 'Dallas County',
- state: 'Missouri',
- 'ISO3166-2-lvl4': 'US-MO',
- country: 'United States',
- 'country_code': 'us'
- }
- };
-
- const form = _.cloneDeep(comp4);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const address = form.getComponent('address');
- const textfield = form.getComponent('textField');
-
- setTimeout(() => {
- address.setValue(value);
-
- setTimeout(() => {
- assert.equal(textfield.visible, true);
- const clearIcon = address.refs.removeValueIcon[0];
- const clickEvent = new Event('click');
- clearIcon.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(textfield.visible, false);
- done();
- }, 300);
- }, 300);
- }, 300);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.data.js
deleted file mode 100644
index 5b84522e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.data.js
+++ /dev/null
@@ -1,23 +0,0 @@
-export default [
- {
- key: 'multiple',
- customConditional: ({ data }) => !data.enableManualMode,
- },
- {
- type: 'address',
- label: 'Default Value',
- key: 'defaultValue',
- weight: 5,
- placeholder: 'Default Value',
- tooltip: 'The Default Value will be the value for this field, before user interaction. Having a default value will override the placeholder text.',
- input: true,
- customDefaultValue: ({ instance }) => (
- instance.manualModeEnabled
- ? {
- mode: 'autocomplete',
- address: {},
- }
- : {}
- ),
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.display.js
deleted file mode 100644
index 1f390812..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.display.js
+++ /dev/null
@@ -1,42 +0,0 @@
-export default [
- {
- weight: 20,
- type: 'checkbox',
- input: true,
- key: 'enableManualMode',
- label: 'Enable Manual Mode',
- tooltip: 'Should Manual Mode be enabled for that component or not.',
- customConditional: ({ data }) => !data.multiple,
- },
- {
- weight: 30,
- type: 'textfield',
- input: true,
- key: 'switchToManualModeLabel',
- label: 'Switch To Manual Mode Label',
- placeholder: 'Switch To Manual Mode Label',
- tooltip: 'The label for the checkbox used to switch to manual mode.',
- validate: {
- required: true,
- },
- customConditional: ({ data }) => Boolean(data.enableManualMode),
- },
- {
- weight: 40,
- type: 'checkbox',
- input: true,
- key: 'disableClearIcon',
- label: 'Disable Clear Icon',
- tooltip: 'Clear Icon allows easily clear component\'s value.',
- },
- {
- type: 'textfield',
- label: 'Add Another Text',
- key: 'addAnother',
- tooltip: 'Set the text of the Add Another button.',
- placeholder: 'Add Another',
- weight: 410,
- input: true,
- customConditional: ({ data }) => data.multiple,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.provider.js b/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.provider.js
deleted file mode 100644
index 6b5f2fc2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/editForm/Address.edit.provider.js
+++ /dev/null
@@ -1,153 +0,0 @@
-import _ from 'lodash';
-
-import { GlobalFormio as Formio } from '../../../Formio';
-
-export default [
- {
- type: 'select',
- input: true,
- key: 'provider',
- label: 'Provider',
- placeholder: 'Select your address search provider',
- weight: 0,
- tooltip: 'Which address search service should be used.',
- valueProperty: 'value',
- dataSrc: 'custom',
- data: {
- custom() {
- return _.values(Formio.Providers.getProviders('address')).sort().map((provider) => ({
- label: provider.displayName,
- value: provider.name,
- }));
- },
- },
- validate: {
- required: true,
- },
- },
- {
- type: 'textfield',
- input: true,
- key: "providerOptions.params['subscription-key']",
- label: 'Subscription Key',
- placeholder: 'Enter Subscription Key',
- weight: 10,
- tooltip: 'Use your Azure Maps subscription key here.',
- validate: {
- required: true,
- },
- conditional: {
- json: { '===': [{ var: 'data.provider' }, 'azure'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'providerOptions.url',
- label: 'Url',
- placeholder: 'Enter Url',
- weight: 10,
- tooltip: 'Url to the service which should be used to search addresses for autocomplete.',
- validate: {
- required: true,
- },
- conditional: {
- json: { '===': [{ var: 'data.provider' }, 'custom'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'providerOptions.queryProperty',
- label: 'Query Property',
- defaultValue: 'query',
- placeholder: 'Enter Query Property',
- weight: 20,
- tooltip: 'Which query param should be used to pass as a search string. Default is `query`.',
- conditional: {
- json: { '===': [{ var: 'data.provider' }, 'custom'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'providerOptions.responseProperty',
- label: 'Response Property',
- placeholder: 'Enter Response Property',
- weight: 30,
- tooltip: 'The property within the response data, where iterable addresses reside. For example: results.',
- conditional: {
- json: { '===': [{ var: 'data.provider' }, 'custom'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'providerOptions.displayValueProperty',
- label: 'Display Value Property',
- placeholder: 'Display Value Property',
- weight: 40,
- tooltip: 'The property of each address in the response to use as the display value.',
- conditional: {
- json: { '===': [{ var: 'data.provider' }, 'custom'] },
- },
- },
- {
- type: 'textarea',
- input: true,
- key: 'providerOptions.params',
- label: 'Params',
- placeholder: '{ ... }',
- weight: 50,
- rows: 5,
- editor: 'ace',
- as: 'json',
- tooltip: 'Additional query params can be specified here in a way of JSON object.',
- conditional: {
- json: { '===': [{ var: 'data.provider' }, 'custom'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'providerOptions.params.key',
- label: 'API Key',
- placeholder: 'Enter API Key',
- weight: 10,
- tooltip: 'Use your Google API key here.',
- validate: {
- required: true,
- },
- conditional: {
- json: { '===': [{ var: 'data.provider' }, 'google'] },
- },
- },
- {
- type: 'textarea',
- input: true,
- key: 'providerOptions.params.autocompleteOptions',
- label: 'Provider options',
- placeholder: 'Enter provider options as JSON object',
- defaultValue:{},
- weight: 60,
- rows: 5,
- as: 'json',
- editor: 'ace',
- tooltip: 'Specify Google Maps Autocomplete options used for address searching as JSON object. Follow the link for available options',
- conditional: {
- json: { '===': [{ var: 'data.provider' }, 'google'] },
- },
- },
- {
- type: 'textarea',
- input: true,
- key: 'manualModeViewString',
- label: 'Manual Mode View String',
- placeholder: 'Enter Manual Mode View String',
- description: '"address" variable references component value, "data" - submission data and "component" - address component schema.',
- weight: 60,
- rows: 5,
- editor: 'ace',
- tooltip: 'Specify template which should be when quering view string for the component value entered in manual mode. This string is used in table view, CSV export and email rendering. When left blank combined value of all components joined with comma will be used.',
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp1.js
deleted file mode 100644
index 11fc37ad..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp1.js
+++ /dev/null
@@ -1,71 +0,0 @@
-export default {
- 'input': true,
- 'tableView': true,
- 'label': 'address',
- 'key': 'address',
- 'placeholder': '',
- 'multiple': false,
- 'protected': false,
- 'clearOnHide': true,
- 'unique': false,
- 'persistent': true,
- 'provider': 'nominatim',
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'required': false,
- },
- 'type': 'address',
- 'tags': [
-
- ],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': '',
- },
- 'components': [
- {
- label: 'Street',
- tableView: true,
- key: 'street',
- type: 'textfield',
- input: true,
- },
- {
- label: 'City',
- tableView: true,
- key: 'city',
- type: 'textfield',
- input: true,
- },
- {
- label: 'County',
- tableView: true,
- key: 'county',
- type: 'textfield',
- input: true,
- },
- {
- label: 'State',
- tableView: true,
- key: 'state',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Zip Code',
- tableView: true,
- key: 'zip',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Country',
- tableView: true,
- key: 'country',
- type: 'textfield',
- input: true,
- },
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp2.js
deleted file mode 100644
index f0d71a37..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp2.js
+++ /dev/null
@@ -1,101 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Address',
- tableView: false,
- provider: 'nominatim',
- key: 'address',
- type: 'address',
- providerOptions: {
- params: {
- autocompleteOptions: {}
- },
- url: 'undefined'
- },
- input: true,
- components: [
- {
- label: 'Address 1',
- tableView: false,
- key: 'address1',
- type: 'textfield',
- input: true,
- customConditional: "show = _.get(instance, 'parent.manualMode', false);"
- },
- {
- label: 'Address 2',
- tableView: false,
- key: 'address2',
- type: 'textfield',
- input: true,
- customConditional: "show = _.get(instance, 'parent.manualMode', false);"
- },
- {
- label: 'City',
- tableView: false,
- key: 'city',
- type: 'textfield',
- input: true,
- customConditional: "show = _.get(instance, 'parent.manualMode', false);"
- },
- {
- label: 'State',
- tableView: false,
- key: 'state',
- type: 'textfield',
- input: true,
- customConditional: "show = _.get(instance, 'parent.manualMode', false);"
- },
- {
- label: 'Country',
- tableView: false,
- key: 'country',
- type: 'textfield',
- input: true,
- customConditional: "show = _.get(instance, 'parent.manualMode', false);"
- },
- {
- label: 'Zip Code',
- tableView: false,
- key: 'zip',
- type: 'textfield',
- input: true,
- customConditional: "show = _.get(instance, 'parent.manualMode', false);"
- }
- ],
- defaultValue: {
- 'place_id': 256774876,
- licence: 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright',
- 'osm_type': 'relation',
- 'osm_id': 1837698,
- boundingbox: ['32.5453486', '32.9899027', '-97.0383833', '-96.5168819'],
- lat: '32.7620405',
- lon: '-96.7790069',
- 'display_name': 'Dallas County, Texas, United States',
- class: 'boundary',
- type: 'administrative',
- importance: 0.6662149661993487,
- icon: 'https://nominatim.openstreetmap.org/ui/mapicons//poi_boundary_administrative.p.20.png',
- address: {
- county: 'Dallas County',
- state: 'Texas',
- country: 'United States',
- 'country_code': 'us'
- }
- }
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'test11',
- display: 'form',
- name: 'test11',
- path: 'test11'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp3.js
deleted file mode 100644
index 579c0a0e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp3.js
+++ /dev/null
@@ -1,89 +0,0 @@
-export default {
- _id: '610cd91f1c0d42a708a148de',
- type: 'form',
- components: [
- {
- label: 'Address',
- tableView: false,
- modalEdit: true,
- provider: 'google',
- key: 'address',
- type: 'address',
- providerOptions: {
- params: {
- autocompleteOptions: {},
- key: 'AIzaSyBNL2e4MnmyPj9zN7SVAe428nCSLP1X144',
- },
- },
- input: true,
- components: [
- {
- label: 'Address 1',
- tableView: false,
- key: 'address1',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, "parent.manualMode", false);',
- },
- {
- label: 'Address 2',
- tableView: false,
- key: 'address2',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, "parent.manualMode", false);',
- },
- {
- label: 'City',
- tableView: false,
- key: 'city',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, "parent.manualMode", false);',
- },
- {
- label: 'State',
- tableView: false,
- key: 'state',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, "parent.manualMode", false);',
- },
- {
- label: 'Country',
- tableView: false,
- key: 'country',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, "parent.manualMode", false);',
- },
- {
- label: 'Zip Code',
- tableView: false,
- key: 'zip',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, "parent.manualMode", false);',
- },
- ],
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- title: 'FIO-3280',
- display: 'form',
- name: 'fio3280',
- path: 'fio3280',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp4.js
deleted file mode 100644
index 97a7d781..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/comp4.js
+++ /dev/null
@@ -1,97 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Address',
- tableView: false,
- provider: 'nominatim',
- key: 'address',
- type: 'address',
- providerOptions: {
- params: {
- autocompleteOptions: {},
- },
- },
- input: true,
- components: [
- {
- label: 'Address 1',
- tableView: false,
- key: 'address1',
- type: 'textfield',
- input: true,
- customConditional:
- "show = _.get(instance, 'parent.manualMode', false);",
- },
- {
- label: 'Address 2',
- tableView: false,
- key: 'address2',
- type: 'textfield',
- input: true,
- customConditional:
- "show = _.get(instance, 'parent.manualMode', false);",
- },
- {
- label: 'City',
- tableView: false,
- key: 'city',
- type: 'textfield',
- input: true,
- customConditional:
- "show = _.get(instance, 'parent.manualMode', false);",
- },
- {
- label: 'State',
- tableView: false,
- key: 'state',
- type: 'textfield',
- input: true,
- customConditional:
- "show = _.get(instance, 'parent.manualMode', false);",
- },
- {
- label: 'Country',
- tableView: false,
- key: 'country',
- type: 'textfield',
- input: true,
- customConditional:
- "show = _.get(instance, 'parent.manualMode', false);",
- },
- {
- label: 'Zip Code',
- tableView: false,
- key: 'zip',
- type: 'textfield',
- input: true,
- customConditional:
- "show = _.get(instance, 'parent.manualMode', false);",
- },
- ],
- },
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- conditional: {
- show: false,
- when: 'address',
- },
- type: 'textfield',
- input: true,
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- },
- ],
- title: 'testconditional',
- display: 'form',
- name: 'testconditional',
- path: 'testconditional',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/index.js
deleted file mode 100644
index 6664cb89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/values.js
deleted file mode 100644
index dee28be3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/address/fixtures/values.js
+++ /dev/null
@@ -1,17 +0,0 @@
-export default [
- {
- mode: 'autocomplete',
- address: {},
- },
- {
- mode: 'manual',
- address: {
- street: '',
- city: '',
- county: '',
- state: '',
- zip: '',
- country: '',
- },
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/alert/Alert.js b/web-client/core/themes/italia/static/formio/css/src/components/alert/Alert.js
deleted file mode 100644
index e41e4c37..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/alert/Alert.js
+++ /dev/null
@@ -1,203 +0,0 @@
-import _ from 'lodash';
-import { getStringFromComponentPath } from '../../utils/utils';
-
-export default class Alert {
- constructor(container, component) {
- this.container = container;
- this.alert = null;
- this.parentComponent = component;
- this.refs = {};
- this.loadRefs = this.parentComponent.loadRefs.bind(this);
- }
-
- get refsNames() {
- return {
- messageRef: 'multiple'
- };
- }
-
- get alertTypes() {
- return {
- error: 'danger',
- success: 'success',
- info: 'info',
- warning: 'warning'
- };
- }
-
- showErrors(errors = [], triggerEvent = false, options = {}) {
- errors = _.isArray(errors) ? errors : [errors];
-
- const messagesList = this.createMessagesList('error', errors);
- this.showAlert('error', messagesList, options);
-
- if (triggerEvent) {
- this.parentComponent.emit('error', errors);
- }
-
- return errors;
- }
-
- showMessage(message, type, options = {}) {
- let messageElement = message;
- if (messageElement instanceof HTMLElement) {
- messageElement.setAttribute('ref', 'messageRef');
- }
- else {
- messageElement = this.parentComponent.ce('p', {
- ref: 'messageRef'
- });
- }
- this.showAlert(type, messageElement, options);
- }
-
- createMessagesList(type, ...args) {
- switch (type) {
- case 'error':
- return this.createErrorList(...args);
- }
- }
-
- createErrorList(errors) {
- const p = this.parentComponent.ce('p');
- this.parentComponent.setContent(p, this.parentComponent.t('error'));
- const ul = this.parentComponent.ce('ul');
- const messagesList = document.createDocumentFragment();
-
- errors.forEach(err => this.appendErrorToList(err, ul));
-
- p.appendChild(ul);
- messagesList.appendChild(p);
- return messagesList;
- }
-
- showAlert(type, messagesList, options = {}) {
- const { customClasses, customEvents } = options;
- this.setAlert(type, messagesList, { customClasses });
- if (!this.alert) {
- return;
- }
- this.attach({ customEvents });
- this.parentComponent.prependTo(this.alert, this.container);
- }
-
- setAlert(type, messagesList, options = {}) {
- const alertType = this.alertTypes[type];
- if (this.alert) {
- this.clear();
- }
- if (messagesList) {
- const {
- id = `${type}-list-${this.parentComponent.id}`,
- customClasses = `alert alert-${alertType}`
- } = options;
- this.alert = this.parentComponent.ce('div', { id, class: customClasses });
- if (messagesList instanceof HTMLElement) {
- this.parentComponent.appendTo(messagesList, this.alert);
- }
- else {
- this.parentComponent.setContent(this.alert, messagesList);
- }
- }
- }
-
- attach(options) {
- let { customEvents = {} } = options;
- this.eventListenersKeys = [];
- this.loadRefs(this.alert, this.refsNames);
- const clickListeners = customEvents.click?.listeners || [];
- const keyPressListeners = customEvents.keypress?.listeners || [];
- customEvents = {
- ...customEvents,
- click: [
- ...clickListeners,
- (e) => {
- const key = e.currentTarget.dataset.componentKey;
- this.focusOnComponent(key);
- }
- ],
- keypress: [
- ...keyPressListeners,
- (e) => {
- const key = e.currentTarget.dataset.componentKey;
- this.focusOnComponent(key);
- }
- ]
- };
-
- if (this.refs.messageRef?.length) {
- this.refs.messageRef.forEach(el => {
- Object.entries(customEvents).forEach(([event, listeners]) => {
- listeners.forEach((listener) => this.parentComponent.addEventListener(el, event, listener));
- this.eventListenersKeys.push(event);
- });
- });
- }
- }
-
- clear() {
- try {
- if (this.refs.messageRef?.length) {
- this.refs.messageRef.forEach(el => {
- this.eventListenersKeys.forEach(event => this.parentComponent.removeEventListener(el, event));
- });
- }
- this.refs = {};
- this.parentComponent.removeChildFrom(this.alert, this.container);
- this.alert = null;
- }
- catch (err) {
- // ignore
- }
- }
-
- focusOnComponent(keyOrPath) {
- if (keyOrPath) {
- const path = this.parentComponent._parentPath ? keyOrPath.replace(this.parentComponent._parentPath, '') : keyOrPath;
- const component = this.parentComponent.root?.getComponent(path, null, keyOrPath);
- if (component && _.isFunction(component.focus)) {
- component.focus();
- }
- }
- }
-
- createMessage(type, element, message, index, err) {
- switch (type) {
- case 'error':
- return this.createErrorMessage(element, message, index, err);
- }
- }
-
- createErrorMessage(element, message, index, err) {
- const params = {
- style: 'cursor: pointer',
- ref: 'messageRef',
- tabIndex: 0,
- 'aria-label': `${message}. Click to navigate to the field with following error.`
- };
-
- const li = this.parentComponent.ce('li', params);
- this.parentComponent.setContent(li, message);
-
- const messageFromIndex = !_.isUndefined(index) && err?.messages?.[index];
- const keyOrPath = messageFromIndex?.path || err?.component?.key;
- if (keyOrPath) {
- const formattedKeyOrPath = getStringFromComponentPath(keyOrPath);
- li.dataset.componentKey = formattedKeyOrPath;
- }
-
- this.parentComponent.appendTo(li, element);
- }
-
- appendErrorToList(err, ul) {
- if (err?.messages?.length) {
- err.messages.forEach(({ message }, index) => {
- this.createMessage('error', ul, message, index, err);
- });
- }
- else if (err) {
- const message = _.isObject(err) ? err.message || '' : err;
- this.createMessage('error', ul, message);
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/builder.js b/web-client/core/themes/italia/static/formio/css/src/components/builder.js
deleted file mode 100644
index 3884eacd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/builder.js
+++ /dev/null
@@ -1,88 +0,0 @@
-import Components from '.';
-import AddressForm from './address/Address.form';
-import ButtonForm from './button/Button.form';
-import CheckboxForm from './checkbox/Checkbox.form';
-import ColumnsForm from './columns/Columns.form';
-import ComponentForm from './_classes/component/Component.form';
-import ContainerForm from './container/Container.form';
-import ContentForm from './content/Content.form';
-import CurrencyForm from './currency/Currency.form';
-import DataGridForm from './datagrid/DataGrid.form';
-import DataMapForm from './datamap/DataMap.form';
-import DateTimeForm from './datetime/DateTime.form';
-import DayForm from './day/Day.form';
-import EditGridForm from './editgrid/EditGrid.form';
-import EmailForm from './email/Email.form';
-import FieldsetForm from './fieldset/Fieldset.form';
-import FileForm from './file/File.form';
-import FormForm from './form/Form.form';
-import ListForm from './_classes/list/ListComponent.form';
-import HiddenForm from './hidden/Hidden.form';
-import HtmlElementForm from './html/HTML.form';
-import NestedForm from './_classes/nested/NestedComponent.form';
-import NumberForm from './number/Number.form';
-import PanelForm from './panel/Panel.form';
-import PasswordForm from './password/Password.form';
-import PhoneNumberForm from './phonenumber/PhoneNumber.form';
-import RadioForm from './radio/Radio.form';
-import ReCaptchaForm from './recaptcha/ReCaptcha.form';
-import ResourceForm from './resource/Resource.form';
-import SelectboxesForm from './selectboxes/SelectBoxes.form';
-import SelectForm from './select/Select.form';
-import SignatureForm from './signature/Signature.form';
-import SurveyForm from './survey/Survey.form';
-import TableForm from './table/Table.form';
-import TabsForm from './tabs/Tabs.form';
-import TagsForm from './tags/Tags.form';
-import TextAreaForm from './textarea/TextArea.form';
-import TextfieldForm from './textfield/TextField.form';
-import TimeForm from './time/Time.form';
-import TreeForm from './tree/Tree.form';
-import UnknownForm from './unknown/Unknown.form';
-import UrlForm from './url/Url.form';
-import WellForm from './well/Well.form';
-
-Components.address.editForm = AddressForm;
-Components.button.editForm = ButtonForm;
-Components.checkbox.editForm = CheckboxForm;
-Components.columns.editForm = ColumnsForm;
-Components.component.editForm = ComponentForm;
-Components.container.editForm = ContainerForm;
-Components.content.editForm = ContentForm;
-Components.currency.editForm = CurrencyForm;
-Components.datagrid.editForm = DataGridForm;
-Components.datamap.editForm = DataMapForm;
-Components.datetime.editForm = DateTimeForm;
-Components.day.editForm = DayForm;
-Components.editgrid.editForm = EditGridForm;
-Components.email.editForm = EmailForm;
-Components.fieldset.editForm = FieldsetForm;
-Components.file.editForm = FileForm;
-Components.form.editForm = FormForm;
-Components.list.editForm = ListForm;
-Components.hidden.editForm = HiddenForm;
-Components.htmlelement.editForm = HtmlElementForm;
-Components.nested.editForm = NestedForm;
-Components.number.editForm = NumberForm;
-Components.panel.editForm = PanelForm;
-Components.password.editForm = PasswordForm;
-Components.phoneNumber.editForm = PhoneNumberForm;
-Components.radio.editForm = RadioForm;
-Components.recaptcha.editForm = ReCaptchaForm;
-Components.resource.editForm = ResourceForm;
-Components.select.editForm = SelectForm;
-Components.selectboxes.editForm = SelectboxesForm;
-Components.signature.editForm = SignatureForm;
-Components.survey.editForm = SurveyForm;
-Components.table.editForm = TableForm;
-Components.tabs.editForm = TabsForm;
-Components.tags.editForm = TagsForm;
-Components.textarea.editForm = TextAreaForm;
-Components.textfield.editForm = TextfieldForm;
-Components.time.editForm = TimeForm;
-Components.tree.editForm = TreeForm;
-Components.unknown.editForm = UnknownForm;
-Components.url.editForm = UrlForm;
-Components.well.editForm = WellForm;
-
-export default Components;
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/Button.form.js b/web-client/core/themes/italia/static/formio/css/src/components/button/Button.form.js
deleted file mode 100644
index 1a7d2099..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/Button.form.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import Components from '../Components';
-import ButtonEditDisplay from './editForm/Button.edit.display';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: ButtonEditDisplay
- },
- {
- key: 'data',
- ignore: true,
- },
- {
- key: 'validation',
- ignore: true,
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/Button.js b/web-client/core/themes/italia/static/formio/css/src/components/button/Button.js
deleted file mode 100644
index 4a8a0101..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/Button.js
+++ /dev/null
@@ -1,520 +0,0 @@
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-import Field from '../_classes/field/Field';
-import Input from '../_classes/input/Input';
-import { componentValueTypes, eachComponent, getArrayFromComponentPath, getComponentSavedTypes } from '../../utils/utils';
-
-export default class ButtonComponent extends Field {
- static schema(...extend) {
- return Input.schema({
- type: 'button',
- label: 'Submit',
- key: 'submit',
- size: 'md',
- leftIcon: '',
- rightIcon: '',
- block: false,
- action: 'submit',
- persistent: false,
- disableOnInvalid: false,
- theme: 'primary',
- dataGridLabel: true
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Button',
- group: 'basic',
- icon: 'stop',
- documentation: '/userguide/form-building/form-components#button',
- weight: 110,
- schema: ButtonComponent.schema()
- };
- }
-
- static savedValueTypes(schema) {
- return getComponentSavedTypes(schema) || [componentValueTypes.boolean];
- }
-
- constructor(component, options, data) {
- super(component, options, data);
- this.filesUploading = [];
- }
-
- get defaultSchema() {
- return ButtonComponent.schema();
- }
-
- get inputInfo() {
- const info = super.elementInfo();
- info.type = 'button';
- info.attr.type = (['submit', 'saveState'].includes(this.component.action)) ? 'submit' : 'button';
- this.component.theme = this.component.theme || 'default';
- info.attr.class = `btn btn-${this.component.theme}`;
- if (this.component.size) {
- info.attr.class += ` btn-${this.component.size}`;
- }
- if (this.component.block) {
- info.attr.class += ' btn-block';
- }
- if (this.component.customClass) {
- info.attr.class += ` ${this.component.customClass}`;
- }
- info.content = this.t(this.component.label, { _userInput: true });
- return info;
- }
-
- get labelInfo() {
- return {
- hidden: true
- };
- }
-
- set loading(loading) {
- this.setLoading(this.refs.button, loading);
- }
-
- get skipInEmail() {
- return true;
- }
-
- // No label needed for buttons.
- createLabel() {}
-
- createInput(container) {
- this.refs.button = super.createInput(container);
- return this.refs.button;
- }
-
- get emptyValue() {
- return false;
- }
-
- getValue() {
- return this.dataValue;
- }
-
- get clicked() {
- return this.dataValue;
- }
-
- get defaultValue() {
- return false;
- }
-
- get className() {
- let className = super.className;
- className += ` ${this.transform('class', 'form-group')}`;
- return className;
- }
-
- get oauthConfig() {
- if (_.has(this, 'root.form.config.oauth') && this.component.oauthProvider) {
- return this.root.form.config.oauth[this.component.oauthProvider];
- }
- // Legacy oauth location.
- if (this.component.oauth) {
- return this.component.oauth;
- }
- return false;
- }
-
- render() {
- if (this.viewOnly || this.options.hideButtons) {
- this._visible = false;
- }
- return super.render(this.renderTemplate('button', {
- component: this.component,
- input: this.inputInfo,
- }));
- }
-
- attachButton() {
- this.addShortcut(this.refs.button);
- let onChange = null;
- let onError = null;
- if (this.component.action === 'submit') {
- this.on('submitButton', () => {
- this.disabled = true;
- }, true);
- this.on('cancelSubmit', () => {
- this.disabled = false;
- }, true);
- this.on('submitDone', (message) => {
- const resultMessage = _.isString(message) ? message : this.t('complete');
- this.loading = false;
- this.disabled = false;
- this.addClass(this.refs.button, 'btn-success submit-success');
- this.removeClass(this.refs.button, 'btn-danger submit-fail');
- this.addClass(this.refs.buttonMessageContainer, 'has-success');
- this.removeClass(this.refs.buttonMessageContainer, 'has-error');
- this.setContent(this.refs.buttonMessage, resultMessage);
- }, true);
- this.on('submitError', (message) => {
- const resultMessage = _.isString(message) ? this.t(message) : this.t(this.errorMessage('submitError'));
- this.loading = false;
- this.disabled = false;
- this.hasError = true;
- this.removeClass(this.refs.button, 'btn-success submit-success');
- this.addClass(this.refs.button, 'btn-danger submit-fail');
- this.removeClass(this.refs.buttonMessageContainer, 'has-success');
- this.addClass(this.refs.buttonMessageContainer, 'has-error');
- this.setContent(this.refs.buttonMessage, resultMessage);
- }, true);
-
- this.on('fileUploadingStart', (filePromise) => {
- this.filesUploading.push(filePromise);
- this.disabled = true;
- this.setDisabled(this.refs.button, this.disabled);
- }, true);
-
- this.on('fileUploadingEnd', (filePromise) => {
- const index = this.filesUploading.indexOf(filePromise);
- if (index !== -1) {
- this.filesUploading.splice(index, 1);
- }
- this.disabled = this.shouldDisabled ? true : false;
- this.setDisabled(this.refs.button, this.disabled);
- }, true);
-
- onChange = (value, isValid) => {
- this.removeClass(this.refs.button, 'btn-success submit-success');
- if (isValid) {
- this.removeClass(this.refs.button, 'btn-danger submit-fail');
- if (this.hasError) {
- this.hasError = false;
- this.setContent(this.refs.buttonMessage, '');
- this.removeClass(this.refs.buttonMessageContainer, 'has-success');
- this.removeClass(this.refs.buttonMessageContainer, 'has-error');
- }
- }
- };
- onError = () => {
- this.hasError = true;
- this.removeClass(this.refs.button, 'btn-success submit-success');
- this.addClass(this.refs.button, 'btn-danger submit-fail');
- this.removeClass(this.refs.buttonMessageContainer, 'has-success');
- this.addClass(this.refs.buttonMessageContainer, 'has-error');
- this.setContent(this.refs.buttonMessage, this.t(this.errorMessage('submitError')));
- };
- }
-
- if (this.component.action === 'url') {
- this.on('requestButton', () => {
- this.disabled = true;
- }, true);
- this.on('requestDone', () => {
- this.loading = false;
- this.disabled = false;
- }, true);
- }
-
- this.on('change', (value, flags) => {
- let isValid = value.isValid;
- const isSilent = flags && flags.silent;
- //check root validity only if disableOnInvalid is set and when it is not possible to make submission because of validation errors
- if (flags && flags.noValidate && (this.component.disableOnInvalid || this.hasError)) {
- isValid = flags.rootValidity || (this.root ? this.root.checkValidity(this.root.data, null, null, true) : true);
- flags.rootValidity = isValid;
- }
- this.isDisabledOnInvalid = this.component.disableOnInvalid && (isSilent || !isValid);
- this.disabled = this.shouldDisabled;
- this.setDisabled(this.refs.button, this.disabled);
-
- if (onChange) {
- onChange(value, isValid);
- }
- }, true);
-
- this.on('error', () => {
- this.loading = false;
- this.disabled = false;
- if (onError) {
- onError();
- }
- }, true);
-
- if (this.component.saveOnEnter) {
- this.root.addEventListener(this.root.element, 'keyup', (event) => {
- if (event.keyCode === 13) {
- this.onClick.call(this, event);
- }
- });
- }
- this.addEventListener(this.refs.button, 'click', this.onClick.bind(this));
- this.addEventListener(this.refs.buttonMessageContainer, 'click', () => {
- if (this.refs.buttonMessageContainer.classList.contains('has-error')) {
- if (this.root && this.root.alert) {
- this.scrollIntoView(this.root.alert);
- }
- }
- });
-
- this.disabled = this.shouldDisabled;
- this.setDisabled(this.refs.button, this.disabled);
-
- function getUrlParameter(name) {
- name = name.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
- const regex = new RegExp(`[\\?&]${name}=([^]*)`);
- const results = regex.exec(location.search);
- if (!results) {
- return results;
- }
- return decodeURIComponent(results[1].replace(/\+/g, ' '));
- }
-
- // If this is an OpenID Provider initiated login, perform the click event immediately
- if ((this.component.action === 'oauth') && this.oauthConfig && !this.oauthConfig.error) {
- const iss = getUrlParameter('iss');
- if (iss && (this.oauthConfig.authURI.indexOf(iss) === 0)) {
- this.openOauth(this.oauthConfig);
- }
- }
- }
-
- get shouldDisabled() {
- return super.shouldDisabled || !!this.filesUploading?.length || this.isDisabledOnInvalid;
- }
-
- attach(element) {
- this.loadRefs(element, {
- button: 'single',
- buttonMessageContainer: 'single',
- buttonMessage: 'single'
- });
-
- const superAttach = super.attach(element);
- this.attachButton();
- return superAttach;
- }
- /* eslint-enable max-statements */
-
- detach(element) {
- if (element && this.refs.button) {
- this.removeShortcut(this.refs.button);
- }
- super.detach();
- }
-
- onClick(event) {
- this.triggerReCaptcha();
- // Don't click if disabled or in builder mode.
- if (this.disabled || this.options.attachMode === 'builder') {
- return;
- }
- this.dataValue = true;
- if (this.component.action !== 'submit' && this.component.showValidations) {
- this.emit('checkValidity', this.data);
- }
- switch (this.component.action) {
- case 'saveState':
- case 'submit':
- event.preventDefault();
- event.stopPropagation();
- this.loading = true;
- this.emit('submitButton', {
- state: this.component.state || 'submitted',
- component: this.component,
- instance: this
- });
- break;
- case 'event':
- this.emit(this.interpolate(this.component.event), this.data);
- this.events.emit(this.interpolate(this.component.event), this.data);
- this.emit('customEvent', {
- type: this.interpolate(this.component.event),
- component: this.component,
- data: this.data,
- event: event
- });
- break;
- case 'custom': {
- // Get the FormioForm at the root of this component's tree
- const form = this.getRoot();
-
- const flattened = {};
- const components = {};
-
- eachComponent(form.components, (componentWrapper, path) => {
- const component = componentWrapper.component || componentWrapper;
- flattened[path] = component;
- components[component.key] = component;
- }, true);
-
- this.evaluate(this.component.custom, {
- form,
- flattened,
- components
- });
-
- this.triggerChange();
- break;
- }
- case 'url':
- this.loading = true;
- this.emit('requestButton', {
- component: this.component,
- instance: this
- });
- this.emit('requestUrl', {
- url: this.interpolate(this.component.url),
- headers: this.component.headers
- });
- break;
- case 'reset':
- this.emit('resetForm');
- break;
- case 'delete':
- this.emit('deleteSubmission');
- break;
- case 'oauth':
- if (this.root === this) {
- console.warn('You must add the OAuth button to a form for it to function properly');
- return;
- }
-
- // Display Alert if OAuth config is missing
- if (!this.oauthConfig) {
- this.root.setAlert('danger', 'OAuth not configured. You must configure oauth for your project before it will work.');
- break;
- }
-
- // Display Alert if oAuth has an error is missing
- if (this.oauthConfig.error) {
- this.root.setAlert('danger', `The Following Error Has Occured ${this.oauthConfig.error}`);
- break;
- }
-
- this.openOauth(this.oauthConfig);
-
- break;
- }
- }
-
- openOauth(settings) {
- if (!this.root.formio) {
- console.warn('You must attach a Form API url to your form in order to use OAuth buttons.');
- return;
- }
-
- /*eslint-disable camelcase */
- let params = {
- response_type: 'code',
- client_id: settings.clientId,
- redirect_uri: settings.redirectURI || window.location.origin || `${window.location.protocol}//${window.location.host}`,
- state: settings.state,
- scope: settings.scope
- };
- /*eslint-enable camelcase */
-
- // Needs for the correct redirection URI for the OpenID
- const originalRedirectUri = params.redirect_uri;
-
- // Make display optional.
- if (settings.display) {
- params.display = settings.display;
- }
-
- params = Object.keys(params).map(key => {
- return `${key}=${encodeURIComponent(params[key])}`;
- }).join('&');
-
- const separator = settings.authURI.indexOf('?') !== -1 ? '&' : '?';
- const url = `${settings.authURI}${separator}${params}`;
- const popup = window.open(url, settings.provider, 'width=1020,height=618');
-
- const interval = setInterval(() => {
- try {
- const popupHost = popup.location.host;
- const currentHost = window.location.host;
- if (popup && !popup.closed && popupHost === currentHost) {
- popup.close();
- const params = popup.location.search.substr(1).split('&').reduce((params, param) => {
- const split = param.split('=');
- params[split[0]] = split[1];
- return params;
- }, {});
- if (params.error) {
- alert(params.error_description || params.error);
- this.root.setAlert('danger', params.error_description || params.error);
- return;
- }
- // TODO: check for error response here
- if (settings.state !== params.state) {
- this.root.setAlert('danger', 'OAuth state does not match. Please try logging in again.');
- return;
- }
- // Depending on where the settings came from, submit to either the submission endpoint (old) or oauth endpoint (new).
- let requestPromise = NativePromise.resolve();
-
- if (_.has(this, 'root.form.config.oauth') && this.root.form.config.oauth[this.component.oauthProvider]) {
- params.provider = settings.provider;
- params.redirectURI = originalRedirectUri;
-
- // Needs for the exclude oAuth Actions that not related to this button
- params.triggeredBy = this.oauthComponentPath;
- requestPromise = this.root.formio.makeRequest('oauth', `${this.root.formio.projectUrl}/oauth2`, 'POST', params);
- }
- else {
- const submission = { data: {}, oauth: {} };
- submission.oauth[settings.provider] = params;
- submission.oauth[settings.provider].redirectURI = originalRedirectUri;
- if (settings.logoutURI) {
- this.root.formio.oauthLogoutURI(settings.logoutURI);
- }
-
- // Needs for the exclude oAuth Actions that not related to this button
- submission.oauth[settings.provider].triggeredBy = this.oauthComponentPath;
- requestPromise = this.root.formio.saveSubmission(submission);
- }
- requestPromise.then((result) => {
- this.root.onSubmit(result, true);
- })
- .catch((err) => {
- this.root.onSubmissionError(err);
- });
- }
- }
- catch (error) {
- if (error.name !== 'SecurityError' && (error.name !== 'Error' || error.message !== 'Permission denied')) {
- this.root.setAlert('danger', error.message || error);
- }
- }
- if (!popup || popup.closed || popup.closed === undefined) {
- clearInterval(interval);
- }
- }, 100);
- }
-
- get oauthComponentPath() {
- const pathArray = getArrayFromComponentPath(this.path);
- return _.chain(pathArray).filter(pathPart => !_.isNumber(pathPart)).join('.').value();
- }
-
- focus() {
- if (this.refs.button) {
- this.refs.button.focus();
- }
- }
-
- triggerReCaptcha() {
- if (!this.root) {
- return;
- }
-
- let recaptchaComponent;
-
- this.root.everyComponent((component)=> {
- if ( component.component.type === 'recaptcha' &&
- component.component.eventType === 'buttonClick' &&
- component.component.buttonKey === this.component.key) {
- recaptchaComponent = component;
- }
- });
-
- if (recaptchaComponent) {
- recaptchaComponent.verify(`${this.component.key}Click`);
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/Button.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/button/Button.unit.js
deleted file mode 100644
index c414866e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/Button.unit.js
+++ /dev/null
@@ -1,442 +0,0 @@
-import assert from 'power-assert';
-import _ from 'lodash';
-import Harness from '../../../test/harness';
-import ButtonComponent from './Button';
-import Formio from './../../Formio';
-import sinon from 'sinon';
-
-import {
- comp1,
- comp2,
- comp3
-} from './fixtures';
-import Webform from '../../Webform';
-import formWithResetValue from '../../../test/formtest/formWithResetValue';
-
-describe('Button Component', () => {
- it('Should build a button component', () => {
- return Harness.testCreate(ButtonComponent, comp1).then((component) => {
- const buttons = Harness.testElements(component, 'button[type="submit"]', 1);
- for (const button of buttons) {
- assert.equal(button.name, `data[${comp1.key}]`);
- assert.equal(button.innerHTML.trim(), comp1.label);
- }
- });
- });
-
- it('POST to URL button should pass URL and headers', (done) => {
- const formJson = {
- 'type': 'form',
- 'components': [{
- 'label': 'Some Field',
- 'type': 'textfield',
- 'input': true,
- 'key': 'someField'
- },
- {
- 'label': 'POST to URL',
- 'action': 'url',
- 'url': 'someUrl',
- 'headers': [{
- 'header': 'testHeader',
- 'value': 'testValue'
- }],
- 'type': 'button',
- 'input': true,
- 'key': 'postToUrl'
- }
- ]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson)
- .then(form => {
- const spy = sinon.spy(Formio, 'makeStaticRequest');
- form.getComponent('postToUrl').refs.button.click();
- const passedUrl = spy.firstCall.args[0];
- const passedHeaders = spy.firstCall.lastArg.headers;
- spy.restore();
- assert.deepEqual(passedHeaders, {
- 'testHeader': 'testValue'
- });
- assert.equal(passedUrl, 'someUrl');
- done();
- })
- .catch(done);
- });
-
- it('Test on error', (done) => {
- const element = document.createElement('div');
- Formio.createForm(element, {
- components: [{
- type: 'textfield',
- key: 'a',
- label: 'A',
- validate: {
- required: true
- }
- },
- {
- type: 'button',
- action: 'submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true
- }
- ]
- }).then(form => {
- form.on('change', () => {
- const button = form.getComponent('submit');
- assert(button.disabled, 'Button should be disabled');
- button.emit('submitError');
- setTimeout(() => {
- console.log('Text Content: ', button.refs.buttonMessage.innerHTML);
- assert.equal(button.refs.buttonMessage.textContent, 'Please check the form and correct all errors before submitting.');
- done();
- }, 100);
- });
- form.submission = {
- data: {}
- };
- }).catch(done);
- });
-
- it('POST to URL button should perform URL interpolation', (done) => {
- const formJson = {
- 'type': 'form',
- 'components': [{
- 'label': 'Some Field',
- 'type': 'textfield',
- 'input': true,
- 'key': 'someField'
- },
- {
- 'label': 'URL',
- 'type': 'textfield',
- 'input': true,
- 'key': 'url'
- },
- {
- 'label': 'POST to URL',
- 'action': 'url',
- 'url': '{{data.url}}/submission',
- 'type': 'button',
- 'input': true,
- 'key': 'postToUrl'
- }
- ]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson)
- .then(form => {
- form.submission = {
- data: {
- url: 'someUrl'
- }
- };
- return form.submissionReady
- .then(() => {
- const spy = sinon.spy(Formio, 'makeStaticRequest');
- form.getComponent('postToUrl').refs.button.click();
- const passedUrl = spy.firstCall.args[0];
- spy.restore();
- assert.equal(passedUrl, 'someUrl/submission');
- done();
- });
- })
- .catch(done);
- });
-
- it('POST to URL button should perform headers interpolation', (done) => {
- const formJson = {
- 'type': 'form',
- 'components': [{
- 'label': 'Some Field',
- 'type': 'textfield',
- 'input': true,
- 'key': 'someField'
- },
- {
- 'label': 'Header',
- 'type': 'textfield',
- 'input': true,
- 'key': 'header'
- },
- {
- 'label': 'POST to URL',
- 'action': 'url',
- 'url': 'someUrl',
- 'headers': [{
- 'header': 'testHeader',
- 'value': 'Value {{data.header}}'
- }],
- 'type': 'button',
- 'input': true,
- 'key': 'postToUrl'
- }
- ]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson)
- .then(form => {
- form.submission = {
- data: {
- someField: 'some value',
- header: 'some header'
- }
- };
- return form.submissionReady
- .then(() => {
- const spy = sinon.spy(Formio, 'makeStaticRequest');
- form.getComponent('postToUrl').refs.button.click();
- const passedHeaders = spy.firstCall.lastArg.headers;
- spy.restore();
- assert.deepEqual(passedHeaders, {
- 'testHeader': 'Value some header'
- });
- done();
- });
- })
- .catch(done);
- });
-
- it('Should not change color and show message if the error is silent', (done) => {
- const formJson = {
- 'type': 'form',
- 'components': [{
- 'label': 'Some Field',
- 'type': 'textfield',
- 'input': true,
- 'key': 'someField'
- },
- {
- 'label': 'Submit',
- 'action': 'submit',
- 'type': 'button',
- 'input': true,
- 'key': 'submit'
- }
- ]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson, {
- hooks: {
- beforeSubmit: function(submission, callback) {
- callback({
- message: 'Err',
- component: submission.component,
- silent: true,
- }, submission);
- }
- }
- })
- .then(form => {
- const button = form.getComponent('submit');
- button.emit('submitButton', {
- state: button.component.state || 'submitted',
- component: button.component,
- instance: button
- });
- setTimeout(() => {
- assert(!button.refs.button.className.includes('btn-danger submit-fail'));
- assert(!button.refs.button.className.includes('btn-success submit-success'));
- assert(!button.refs.buttonMessageContainer.className.includes('has-success'));
- assert(!button.refs.buttonMessageContainer.className.includes('has-error'));
- assert(button.refs.buttonMessage.innerHTML === '');
- done();
- }, 100);
- })
- .catch(done);
- });
-
- it('Should reset values of all the form\'s components and update properties dependent on values', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
-
- form.setForm(formWithResetValue).then(() => {
- const select = form.getComponent(['showPanel']);
-
- select.setValue('yes');
-
- setTimeout(() => {
- const panel = form.getComponent(['panel']);
- const textField = form.getComponent(['textField']);
- const textArea = form.getComponent(['textArea']);
-
- assert.equal(panel.visible, true, 'Panel should be visible');
- assert.equal(textField.visible, true, 'TextFiled should be visible');
- assert.equal(textArea.visible, true, 'TextArea should be visible');
-
- const resetButton = form.getComponent(['reset']);
- resetButton.emit('resetForm');
-
- setTimeout(() => {
- const panel = form.getComponent(['panel']);
- const textField = form.getComponent(['textField']);
- const textArea = form.getComponent(['textArea']);
-
- assert.equal(panel.visible, false, 'Panel should NOT be visible');
- assert.equal(textField.visible, false, 'TextFiled should NOT be visible');
- assert.equal(textArea.visible, false, 'TextArea should NOT be visible');
- done();
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-
- it('Should perform custom logic', (done) => {
- const element = document.createElement('div');
- const form = new Webform(element);
- const testForm = {
- components: [{
- type: 'number',
- key: 'number',
- label: 'Number'
- },
- {
- type: 'button',
- key: 'custom',
- label: 'Custom',
- action: 'custom',
- custom: 'data[\'number\'] = 5555'
- }
- ]
- };
-
- form.setForm(testForm)
- .then(() => {
- const button = form.getComponent('custom');
- const changeEventTriggered = sinon.spy(button, 'triggerChange');
- button.refs.button.click();
- assert(changeEventTriggered.calledOnce, 'Click on custom button should trigger change event');
- form.on('change', () => {
- const {
- data
- } = form.submission;
- assert.deepEqual(data, {
- number: 5555,
- custom: true
- });
- done();
- });
- })
- .catch((err) => done(err));
- });
-
- it('Should correctly set theme', (done) => {
- const form = _.cloneDeep(comp2);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(formObj => {
- const btns = formObj.components;
- const theme = ['warning', 'danger', 'success', 'info', 'secondary', 'primary'];
-
- _.each(btns, (btn, index) => {
- const btnClass = `btn-${theme[index]}`;
- const includeClass = btn.refs.button.classList.contains(btnClass);
- assert.equal(includeClass, true, `Should set ${theme[index]} theme for button`);
- });
-
- done();
- }).catch(done);
- });
-
- it('Should render block btn', (done) => {
- const form = _.cloneDeep(comp2);
- form.components = [{
- label: 'Submit',
- showValidations: false,
- block: true,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }];
-
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(formObj => {
- const btn = formObj.components[0];
- const btnClass = 'btn-block';
- const includeClass = btn.refs.button.classList.contains(btnClass);
-
- assert.equal(includeClass, true, 'Should set btn-block class for button');
-
- done();
- }).catch(done);
- });
-
- it('Test event, reset, post, save in state actions', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
-
- const originalMakeRequest = Formio.makeStaticRequest;
- Formio.makeStaticRequest = function(url, method, data) {
- assert.equal(url, 'https://test.com');
- assert.equal(method, 'POST');
- assert.deepEqual(data.data, {
- event: false,
- post: true,
- reset: false,
- saveInState: false
- });
-
- return new Promise(resolve => {
- resolve({
- ...data
- });
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const formio = new Formio('http://test.localhost/test', {});
-
- formio.makeRequest = (type, url, method, data) => {
- assert.equal(data.state, 'testState');
- assert.equal(method.toUpperCase(), 'POST');
-
- return new Promise(resolve => resolve({
- ...data
- }));
- };
-
- form.formio = formio;
-
- const click = (btnComp) => {
- const elem = btnComp.refs.button;
- const clickEvent = new Event('click');
- elem.dispatchEvent(clickEvent);
- };
-
- const saveInStateBtn = form.getComponent('saveInState');
- click(saveInStateBtn);
-
- setTimeout(() => {
- const eventBtn = form.getComponent('event');
- click(eventBtn);
-
- setTimeout(() => {
- const numberComp = form.getComponent('number');
- assert.equal(numberComp.dataValue, 2);
- assert.equal(numberComp.getValue(), 2);
-
- const resetBtn = form.getComponent('reset');
- click(resetBtn);
-
- setTimeout(() => {
- const numberComp = form.getComponent('number');
- assert.equal(numberComp.dataValue, null);
- assert.equal(numberComp.getValue(), null);
-
- const postBtn = form.getComponent('post');
- click(postBtn);
-
- setTimeout(() => {
- Formio.makeStaticRequest = originalMakeRequest;
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/editForm/Button.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/button/editForm/Button.edit.display.js
deleted file mode 100644
index 75d377d0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/editForm/Button.edit.display.js
+++ /dev/null
@@ -1,251 +0,0 @@
-import BuilderUtils from '../../../utils/builder';
-import _ from 'lodash';
-
-export default [
- {
- key: 'labelPosition',
- ignore: true,
- },
- {
- key: 'placeholder',
- ignore: true,
- },
- {
- key: 'hideLabel',
- customConditional(context) {
- return context.instance.options?.flags?.inDataGrid;
- },
- },
- {
- key: 'dataGridLabel',
- ignore: true,
- },
- {
- type: 'select',
- key: 'action',
- label: 'Action',
- input: true,
- dataSrc: 'values',
- weight: 110,
- tooltip: 'This is the action to be performed by this button.',
- data: {
- values: [
- { label: 'Submit', value: 'submit' },
- { label: 'Save in state', value: 'saveState' },
- { label: 'Event', value: 'event' },
- { label: 'Custom', value: 'custom' },
- { label: 'Reset', value: 'reset' },
- { label: 'OAuth', value: 'oauth' },
- { label: 'POST to URL', value: 'url' },
- ],
- },
- },
- {
- type: 'select',
- key: 'oauthProvider',
- label: 'OAuth Provider',
- input: true,
- dataSrc: 'values',
- weight: 111,
- tooltip: 'The oauth provider to use to log in (8.x server only).',
- data: {
- values: [
- { label: 'OpenID', value: 'openid' },
- { label: 'Github', value: 'github' },
- { label: 'Google', value: 'google' },
- ],
- },
- conditional: {
- json: { '===': [{ var: 'data.action' }, 'oauth'] },
- },
- },
- {
- type: 'textfield',
- label: 'Save in state',
- key: 'state',
- weight: 112,
- tooltip: 'The state you wish to save the submission under when this button is pressed. Example "draft" would save the submission in Draft Mode.',
- placeholder: 'submitted',
- input: true,
- conditional: {
- json: { '===': [{ var: 'data.action' }, 'saveState'] },
- },
- },
- {
- type: 'checkbox',
- input: true,
- inputType: 'checkbox',
- key: 'saveOnEnter',
- label: 'Save On Enter',
- weight: 113,
- tooltip: 'Use the Enter key to submit form.',
- conditional: {
- json: { '===': [{ var: 'data.action' }, 'submit'] },
- },
- },
- {
- type: 'checkbox',
- input: true,
- inputType: 'checkbox',
- key: 'showValidations',
- label: 'Show Validations',
- weight: 115,
- tooltip: 'When the button is pressed, show any validation errors on the form.',
- conditional: {
- json: { '!==': [{ var: 'data.action' }, 'submit'] },
- },
- },
- {
- type: 'textfield',
- label: 'Button Event',
- key: 'event',
- input: true,
- weight: 120,
- tooltip: 'The event to fire when the button is clicked.',
- conditional: {
- json: { '===': [{ var: 'data.action' }, 'event'] },
- },
- },
- {
- type: 'textfield',
- inputType: 'url',
- key: 'url',
- input: true,
- weight: 120,
- label: 'Button URL',
- tooltip: 'The URL where the submission will be sent.',
- placeholder: 'https://example.form.io',
- conditional: {
- json: { '===': [{ var: 'data.action' }, 'url'] },
- },
- },
- {
- type: 'datagrid',
- key: 'headers',
- input: true,
- weight: 130,
- label: 'Headers',
- addAnother: 'Add Header',
- tooltip: 'Headers Properties and Values for your request',
- components: [
- {
- key: 'header',
- label: 'Header',
- input: true,
- type: 'textfield',
- },
- {
- key: 'value',
- label: 'Value',
- input: true,
- type: 'textfield',
- }
- ],
- conditional: {
- json: { '===': [{ var: 'data.action' }, 'url'] },
- },
- },
- {
- type: 'textarea',
- key: 'custom',
- label: 'Button Custom Logic',
- tooltip: 'The custom logic to evaluate when the button is clicked.',
- rows: 5,
- editor: 'ace',
- input: true,
- weight: 120,
- placeholder: "data['mykey'] = data['anotherKey'];",
- conditional: {
- json: { '===': [{ var: 'data.action' }, 'custom'] },
- },
- },
- {
- type: 'select',
- key: 'theme',
- label: 'Theme',
- input: true,
- tooltip: 'The color theme of this button.',
- dataSrc: 'values',
- weight: 140,
- data: {
- values: [
- { label: 'Primary', value: 'primary' },
- { label: 'Secondary', value: 'secondary' },
- { label: 'Info', value: 'info' },
- { label: 'Success', value: 'success' },
- { label: 'Danger', value: 'danger' },
- { label: 'Warning', value: 'warning' },
- ],
- },
- },
- {
- type: 'select',
- key: 'size',
- label: 'Size',
- input: true,
- tooltip: 'The size of this button.',
- dataSrc: 'values',
- weight: 150,
- data: {
- values: [
- { label: 'Small', value: 'sm' },
- { label: 'Medium', value: 'md' },
- { label: 'Large', value: 'lg' },
- ],
- },
- },
- {
- type: 'textfield',
- key: 'leftIcon',
- label: 'Left Icon',
- input: true,
- placeholder: 'Enter icon classes',
- tooltip: "This is the full icon class string to show the icon. Example: 'fa fa-plus'",
- weight: 160,
- },
- {
- type: 'textfield',
- key: 'rightIcon',
- label: 'Right Icon',
- input: true,
- placeholder: 'Enter icon classes',
- tooltip: "This is the full icon class string to show the icon. Example: 'fa fa-plus'",
- weight: 170,
- },
- {
- type: 'select',
- input: true,
- weight: 180,
- label: 'Shortcut',
- key: 'shortcut',
- tooltip: 'Shortcut for this component.',
- dataSrc: 'custom',
- valueProperty: 'value',
- customDefaultValue: () => '',
- template: '{{ item.label }}',
- data: {
- custom(context) {
- return BuilderUtils.getAvailableShortcuts(
- _.get(context, 'instance.options.editForm', {}),
- _.get(context, 'instance.options.editComponent', {})
- );
- },
- },
- },
- {
- type: 'checkbox',
- key: 'block',
- label: 'Block Button',
- input: true,
- weight: 155,
- tooltip: 'This control should span the full width of the bounding container.',
- },
- {
- type: 'checkbox',
- key: 'disableOnInvalid',
- label: 'Disable on Form Invalid',
- tooltip: 'This will disable this field if the form is invalid.',
- input: true,
- weight: 620,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp1.js
deleted file mode 100644
index c4de6a9f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp1.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default {
- 'type': 'button',
- 'theme': 'primary',
- 'disableOnInvalid': false,
- 'action': 'submit',
- 'block': false,
- 'rightIcon': '',
- 'leftIcon': '',
- 'size': 'md',
- 'key': 'submit',
- 'tableView': false,
- 'label': 'Submit',
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp2.js
deleted file mode 100644
index f5f69f71..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp2.js
+++ /dev/null
@@ -1,55 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Submit',
- showValidations: false,
- theme: 'warning',
- tableView: false,
- key: 'submit5',
- type: 'button',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- theme: 'danger',
- tableView: false,
- key: 'submit4',
- type: 'button',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- theme: 'success',
- tableView: false,
- key: 'submit3',
- type: 'button',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- theme: 'info',
- tableView: false,
- key: 'submit2',
- type: 'button',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- theme: 'secondary',
- tableView: false,
- key: 'submit1',
- type: 'button',
- input: true
- },
- { label: 'Submit', showValidations: false, tableView: false, key: 'submit', type: 'button', input: true }
- ],
- title: 'test checkbox',
- display: 'form',
- name: 'testCheckbox',
- path: 'testcheckbox',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp3.js
deleted file mode 100644
index 6079c364..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/comp3.js
+++ /dev/null
@@ -1,82 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'number',
- logic: [
- {
- name: 'show two',
- trigger: {
- type: 'event',
- event: 'showTwo'
- },
- actions: [
- {
- name: 'simple action',
- type: 'value',
- value: 'value = 2;'
- }
- ]
- }
- ],
- type: 'number',
- input: true
- },
- {
- label: 'Save in state',
- action: 'saveState',
- showValidations: false,
- tableView: false,
- key: 'saveInState',
- type: 'button',
- state: 'testState',
- input: true
- },
- {
- label: 'Event',
- action: 'event',
- showValidations: false,
- tableView: false,
- key: 'event',
- type: 'button',
- event: 'showTwo',
- input: true
- },
- {
- label: 'Reset',
- action: 'reset',
- showValidations: false,
- tableView: false,
- key: 'reset',
- type: 'button',
- input: true
- },
- {
- label: 'Post',
- action: 'url',
- showValidations: false,
- tableView: false,
- key: 'post',
- type: 'button',
- url: 'https://test.com',
- headers: [
- {
- header: '',
- value: ''
- }
- ],
- input: true
- }
- ],
- title: 'test',
- display: 'form',
- name: 'test',
- path: 'test'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/index.js
deleted file mode 100644
index bb8fc410..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/values.js
deleted file mode 100644
index e59550a1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/button/fixtures/values.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- true,
- false,
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.form.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.form.js
deleted file mode 100644
index 2eca29b2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.form.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import Components from '../Components';
-import CheckboxEditData from './editForm/Checkbox.edit.data';
-import CheckboxEditDisplay from './editForm/Checkbox.edit.display';
-import CheckboxEditValidation from './editForm/Checkbox.edit.validation';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'data',
- components: CheckboxEditData
- },
- {
- key: 'display',
- components: CheckboxEditDisplay
- },
- {
- key: 'validation',
- components: CheckboxEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.js
deleted file mode 100644
index 2704352e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.js
+++ /dev/null
@@ -1,255 +0,0 @@
-import _ from 'lodash';
-import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-import Field from '../_classes/field/Field';
-
-export default class CheckBoxComponent extends Field {
- static schema(...extend) {
- return Field.schema({
- type: 'checkbox',
- inputType: 'checkbox',
- label: 'Checkbox',
- key: 'checkbox',
- dataGridLabel: true,
- labelPosition: 'right',
- value: '',
- name: ''
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Checkbox',
- group: 'basic',
- icon: 'check-square',
- documentation: '/userguide/form-building/form-components#check-box',
- weight: 50,
- schema: CheckBoxComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return CheckBoxComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: ['isEqual'],
- valueComponent() {
- return {
- valueType: 'boolean',
- data: {
- values: [
- { label: 'Checked', value: 'true' },
- { label: 'Not Checked', value: 'false' },
- ]
- },
- type: 'select'
- };
- }
- };
- }
-
- static savedValueTypes(schema) {
- schema = schema || {};
- const types = getComponentSavedTypes(schema);
-
- if (_.isArray(types)) {
- return types;
- }
-
- if (schema.inputType === 'radio') {
- return [componentValueTypes.string];
- }
-
- return [componentValueTypes.boolean];
- }
-
- get defaultSchema() {
- return CheckBoxComponent.schema();
- }
-
- get defaultValue() {
- const { name } = this.component;
- const defaultValue = super.defaultValue;
-
- return name ? (this.component[name] || this.emptyValue) : (defaultValue || this.component.defaultValue || false).toString() === 'true';
- }
-
- get labelClass() {
- let className = '';
- if (this.isInputComponent
- && !this.options.inputsOnly
- && this.component.validate
- && this.component.validate.required) {
- className += ' field-required';
- }
- return `${className}`;
- }
-
- get hasSetValue() {
- return this.hasValue();
- }
-
- get inputInfo() {
- const info = super.elementInfo();
- info.type = 'input';
- info.changeEvent = 'click';
- info.attr.type = this.component.inputType || 'checkbox';
- info.attr.class = 'form-check-input';
- if (this.component.name) {
- info.attr.name = `data[${this.component.name}]`;
- }
- info.attr.value = this.component.value ? this.component.value : 0;
- info.label = this.t(this.component.label, { _userInput: true });
- info.labelClass = this.labelClass;
- return info;
- }
-
- get labelInfo() {
- return {
- hidden: true
- };
- }
-
- render() {
- return super.render(this.renderTemplate('checkbox', {
- input: this.inputInfo,
- checked: this.checked,
- tooltip: this.interpolate(this.t(this.component.tooltip) || '', { _userInput: true }).replace(/(?:\r\n|\r|\n)/g, ' ')
- }));
- }
-
- attach(element) {
- this.loadRefs(element, { input: 'multiple' });
- this.input = this.refs.input[0];
- if (this.refs.input) {
- this.addEventListener(this.input, this.inputInfo.changeEvent, () => this.updateValue(null, {
- modified: true
- }));
- this.addShortcut(this.input);
- }
- return super.attach(element);
- }
-
- detach(element) {
- if (element && this.input) {
- this.removeShortcut(this.input);
- }
- super.detach();
- }
-
- get emptyValue() {
- return this.component.inputType === 'radio' ? null : false;
- }
-
- isEmpty(value = this.dataValue) {
- return super.isEmpty(value) || value === false;
- }
-
- get key() {
- return this.component.name ? this.component.name : super.key;
- }
-
- getValueAt(index) {
- if (this.component.name) {
- return this.refs.input[index].checked ? this.component.value : '';
- }
- return !!this.refs.input[index].checked;
- }
-
- getValue() {
- const value = super.getValue();
- if (this.component.name) {
- return value ? this.setCheckedState(value) : this.setCheckedState(this.dataValue);
- }
- else {
- return (value === '') ? this.dataValue : !!value;
- }
- }
-
- get checked() {
- if (this.component.name) {
- return (this.dataValue === this.component.value);
- }
- return !!this.dataValue;
- }
-
- setCheckedState(value) {
- if (!this.input) {
- return;
- }
- if (this.component.name) {
- this.input.value = (value === this.component.value) ? this.component.value : 0;
- this.input.checked = (value === this.component.value) ? 1 : 0;
- }
- else if (value === 'on') {
- this.input.value = 1;
- this.input.checked = 1;
- }
- else if (value === 'off') {
- this.input.value = 0;
- this.input.checked = 0;
- }
- else if (value) {
- this.input.value = 1;
- this.input.checked = 1;
- }
- else {
- this.input.value = 0;
- this.input.checked = 0;
- }
- if (this.input.checked) {
- this.input.setAttribute('checked', true);
- }
- else {
- this.input.removeAttribute('checked');
- }
- return value;
- }
-
- setValue(value, flags = {}) {
- if (
- this.setCheckedState(value) !== undefined ||
- (!this.input && value !== undefined && (this.visible || this.conditionallyVisible() || !this.component.clearOnHide))
- ) {
- const changed = this.updateValue(value, flags);
- if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {
- this.redraw();
- }
- return changed;
- }
- return false;
- }
-
- getValueAsString(value) {
- const { name: componentName, value: componentValue } = this.component;
- const hasValue = componentName ? _.isEqual(value, componentValue) : value;
-
- return this.t(hasValue ? 'Yes' : 'No');
- }
-
- updateValue(value, flags) {
- // If this is a radio and is alredy checked, uncheck it.
- if (this.component.name && flags.modified && (this.dataValue === this.component.value)) {
- this.input.checked = 0;
- this.input.value = 0;
- this.dataValue = '';
- this.updateOnChange(flags, true);
- }
-
- const changed = super.updateValue(value, flags);
-
- // Update attributes of the input element
- if (changed && this.input) {
- if (this.input.checked) {
- this.input.setAttribute('checked', 'true');
- }
- else {
- this.input.removeAttribute('checked');
- }
- }
-
- return changed;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.unit.js
deleted file mode 100644
index 248c4a0c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/Checkbox.unit.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import assert from 'power-assert';
-import _ from 'lodash';
-
-import Harness from '../../../test/harness';
-import Formio from '../../Formio';
-import CheckBoxComponent from './Checkbox';
-
-import {
- comp1,
- customDefaultComponent,
- comp2,
- comp3,
- comp4
-} from './fixtures';
-
-describe('Checkbox Component', () => {
- it('Should build a checkbox component', () => {
- return Harness.testCreate(CheckBoxComponent, comp1).then((component) => {
- const inputs = Harness.testElements(component, 'input[type="checkbox"]', 1);
- for (let i=0; i < inputs.length; i++) {
- assert(inputs[i].getAttribute('class').indexOf('form-check-input') !== -1, 'No form-check-input class');
- assert.equal(inputs[i].name, `data[${comp1.key}]`);
- }
- Harness.testElements(component, 'span', 1);
- });
- });
-
- it('Span should have correct text label', () => {
- return Harness.testCreate(CheckBoxComponent, comp1).then((component) => {
- const checkboxes = component.element.querySelectorAll('input[ref="input"]');
- assert.equal(checkboxes.length, 1);
- const componentClass = checkboxes[0].getAttribute('class');
- assert(componentClass.indexOf('form-check-input') !== -1, 'No form-check-input class.');
- const labels = component.element.querySelectorAll('label');
- assert.equal(labels.length, 1);
- assert(labels[0].getAttribute('class').indexOf('form-check-label') !== -1, 'No form-check-label class');
- const spans = labels[0].querySelectorAll('span');
- assert.equal(spans.length, 1);
- assert.equal(spans[0].innerHTML, 'Check me');
- });
- });
-
- it('Should be able to set and get data', () => {
- return Harness.testCreate(CheckBoxComponent, comp1).then((component) => {
- Harness.testSetGet(component, 1);
- Harness.testSetGet(component, 0);
- });
- });
-
- it('Should be able to set custom default value', () => {
- return Harness.testCreate(CheckBoxComponent, customDefaultComponent).then((component) => {
- assert.equal(component.dataValue, true);
- });
- });
-
- it('Should be able to unselect a checkbox component with the radio input type', () => {
- return Harness.testCreate(CheckBoxComponent, comp2).then((component) => {
- const input = Harness.testElements(component, 'input[type="radio"]', 1)[0];
- Harness.clickElement(component, input);
- assert.equal(input.checked, true);
- Harness.clickElement(component, input);
- assert.equal(input.checked, false);
- });
- });
-
- it('Should render red asterisk for preview template of the modal required checkbox ', (done) => {
- Harness.testCreate(CheckBoxComponent, comp3).then((component) => {
- const label = component.element.querySelector('.control-label');
- assert(label.className.includes('field-required'));
- done();
- }).catch(done);
- });
-
- it('Should hide component with conditional logic when checkbox component with the radio input type is unchecked', (done) => {
- const form = _.cloneDeep(comp4);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const radioCheckbox = form.getComponent('p1');
- const contentComp = form.getComponent('p1Content');
- assert.equal(contentComp.visible, false);
- const radio = Harness.testElements(radioCheckbox, 'input[type="radio"]', 1)[0];
- Harness.clickElement(radioCheckbox, radio);
- setTimeout(() => {
- assert.equal(contentComp.visible, true);
- Harness.clickElement(radioCheckbox, radio);
- setTimeout(() => {
- assert.equal(contentComp.visible, false);
- done();
- }, 300);
- }, 300);
- }).catch((err) => done(err));
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.data.js
deleted file mode 100644
index 37a32a08..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.data.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.display.js
deleted file mode 100644
index 82ecf53a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.display.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import BuilderUtils from '../../../utils/builder';
-import _ from 'lodash';
-
-export default [
- {
- key: 'labelPosition',
- ignore: true,
- },
- {
- key: 'placeholder',
- ignore: true,
- },
- {
- type: 'select',
- input: true,
- weight: 350,
- label: 'Shortcut',
- key: 'shortcut',
- tooltip: 'Shortcut for this component.',
- dataSrc: 'custom',
- valueProperty: 'value',
- customDefaultValue: () => '',
- template: '{{ item.label }}',
- data: {
- custom(context) {
- return BuilderUtils.getAvailableShortcuts(
- _.get(context, 'instance.options.editForm', {}),
- _.get(context, 'instance.options.editComponent', {})
- );
- },
- },
- },
- {
- type: 'select',
- input: true,
- key: 'inputType',
- label: 'Input Type',
- tooltip: 'This is the input type used for this checkbox.',
- dataSrc: 'values',
- weight: 410,
- data: {
- values: [
- { label: 'Checkbox', value: 'checkbox' },
- { label: 'Radio', value: 'radio' },
- ],
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'name',
- label: 'Radio Key',
- tooltip: 'The key used to trigger the radio button toggle.',
- weight: 420,
- conditional: {
- json: { '===': [{ var: 'data.inputType' }, 'radio'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- label: 'Radio Value',
- key: 'value',
- tooltip: 'The value used with this radio button.',
- weight: 430,
- conditional: {
- json: { '===': [{ var: 'data.inputType' }, 'radio'] },
- },
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.validation.js
deleted file mode 100644
index 5e1241b5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/editForm/Checkbox.edit.validation.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default [
- {
- key: 'validateOn',
- ignore: true
- },
- {
- key: 'unique',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp1.js
deleted file mode 100644
index 596bd8e0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp1.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'checkbox',
- 'validate': {
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'defaultValue': false,
- 'key': 'checkme',
- 'dataGridLabel': true,
- 'label': 'Check me',
- 'hideLabel': false,
- 'tableView': true,
- 'inputType': 'checkbox',
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp2.js
deleted file mode 100644
index ad10fc4f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp2.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default {
- label: 'Checkbox - Radio',
- inputType: 'radio',
- tableView: false,
- defaultValue: false,
- key: 'checkboxRadio',
- type: 'checkbox',
- name: 'radio',
- value: 'true',
- input: true,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp3.js
deleted file mode 100644
index 9fc0e289..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp3.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default {
- label: 'Checkbox',
- fancyButton: false,
- promptOnDeselect: false,
- tableView: false,
- modalEdit: true,
- validate: {
- required: true
- },
- key: 'checkbox',
- type: 'checkbox',
- input: true,
- defaultValue: false
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp4.js
deleted file mode 100644
index 8b1dc8e8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/comp4.js
+++ /dev/null
@@ -1,37 +0,0 @@
-export default {
- title: '6009test',
- name: '6009Test',
- path: '6009test',
- type: 'form',
- display: 'form',
- components:[
- {
- label: 'P1',
- inputType:'radio',
- tableView:false,
- key: 'p1',
- type:'checkbox',
- name:'priorities',
- value:'p1',
- input:true
- },
- {
- html:'Content 1
',
- label:'P1 Content',
- refreshOnChange:false,
- key:'p1Content',
- type:'content',
- input:false,
- tableView:false,
- customConditional:'show = data.priorities == "p1"'
- },
- {
- type:'button',
- label:'Submit',
- key:'submit',
- disableOnInvalid:true,
- input:true,
- tableView:false
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/customDefaultComponent.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/customDefaultComponent.js
deleted file mode 100644
index fd0dc2bf..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/customDefaultComponent.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'customDefaultValue': 'value = true;',
- 'type': 'checkbox',
- 'validate': {
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'defaultValue': false,
- 'key': 'checkme',
- 'dataGridLabel': true,
- 'label': 'Check me',
- 'hideLabel': false,
- 'tableView': true,
- 'inputType': 'checkbox',
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/index.js
deleted file mode 100644
index 505a3d5f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export comp1 from './comp1';
-export customDefaultComponent from './customDefaultComponent';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/values.js
deleted file mode 100644
index e34ef929..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/checkbox/fixtures/values.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default [
- true,
- false,
-];
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.form.js b/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.form.js
deleted file mode 100644
index 76bac20a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.form.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import nestedComponentForm from '../_classes/nested/NestedComponent.form';
-
-import ColumnsEditDisplay from './editForm/Columns.edit.display';
-
-export default function(...extend) {
- return nestedComponentForm([
- {
- key: 'display',
- components: ColumnsEditDisplay
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.js b/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.js
deleted file mode 100644
index 009b9977..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.js
+++ /dev/null
@@ -1,180 +0,0 @@
-import _ from 'lodash';
-import NestedComponent from '../_classes/nested/NestedComponent';
-
-export default class ColumnsComponent extends NestedComponent {
- static schema(...extend) {
- return NestedComponent.schema({
- label: 'Columns',
- key: 'columns',
- type: 'columns',
- columns: [
- { components: [], width: 6, offset: 0, push: 0, pull: 0, size: 'md' },
- { components: [], width: 6, offset: 0, push: 0, pull: 0, size: 'md' }
- ],
- clearOnHide: false,
- input: false,
- tableView: false,
- persistent: false,
- autoAdjust: false
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Columns',
- icon: 'columns',
- group: 'layout',
- documentation: '/userguide/form-building/layout-components#columns',
- showPreview: false,
- weight: 10,
- schema: ColumnsComponent.schema()
- };
- }
-
- static savedValueTypes() {
- return [];
- }
-
- constructor(component, options, data) {
- super(component, options, data);
- this.rows = [];
- }
-
- get schema() {
- const schema = _.omit(super.schema, ['components']);
- schema.columns?.map((column, colIndex) => {
- column.components.map((comp, compIndex) => {
- const clonedComp = _.clone(comp);
- clonedComp.internal = true;
- const component = this.createComponent(clonedComp);
- delete component.component.internal;
- schema.columns[colIndex].components[compIndex] = component.schema;
- });
- });
- return schema;
- }
-
- get defaultSchema() {
- return ColumnsComponent.schema();
- }
-
- get className() {
- return `row ${super.className}`;
- }
-
- get columnKey() {
- return `column-${this.id}`;
- }
-
- init() {
- super.init();
- this.columns = [];
- _.each(this.component.columns, (column, index) => {
- this.columns[index] = [];
- if (!column.size) {
- column.size = 'md';
- }
- column.currentWidth = this.options.condensedMode ? this.gridSize : column.width || 0;
- // Ensure there is a components array.
- if (!Array.isArray(column.components)) {
- column.components = [];
- }
- _.each(column.components, (comp) => {
- const component = this.createComponent(comp);
- component.column = index;
- this.columns[index].push(component);
- });
- });
- if (this.component.autoAdjust && this.options.display !== 'pdf') {
- this.justify();
- }
- this.rows = this.groupByRow();
- }
-
- labelIsHidden() {
- return true;
- }
-
- render() {
- return super.render(this.renderTemplate('columns', {
- columnKey: this.columnKey,
- columnComponents: this.columns.map(column => this.renderComponents(column))
- }));
- }
-
- justifyColumn(items, index) {
- const toAdjust = _.every(items, item => !item.visible);
- const column = this.component.columns[index];
- const width = (toAdjust && items.length) ? 0 : column.width;
- const shouldRedraw = !_.isEqual(width, column.currentWidth);
-
- column.currentWidth = width;
-
- return shouldRedraw;
- }
-
- justify() {
- return this.columns.reduce((redraw, items, index) => this.justifyColumn(items, index) || redraw, false);
- }
-
- attach(element) {
- this.loadRefs(element, { [this.columnKey]: 'multiple' });
- const superAttach = super.attach(element);
- if (this.refs[this.columnKey]) {
- this.refs[this.columnKey].forEach((column, index) =>
- this.attachComponents(column, this.columns[index], this.component.columns[index].components)
- );
- }
- return superAttach;
- }
-
- get gridSize() {
- return 12;
- }
-
- /**
- * Group columns in rows.
- * @return {Array.}
- */
- groupByRow() {
- const initVal = { stack: [], rows: [] };
- const width = x => x.component.width;
- const result = _.reduce(this.components, (acc, next) => {
- const stack = [...acc.stack, next];
- if (_.sumBy(stack, width) <= this.gridSize) {
- acc.stack = stack;
- return acc;
- }
- else {
- acc.rows = [...acc.rows, acc.stack];
- acc.stack = [next];
- return acc;
- }
- }, initVal);
-
- return _.concat(result.rows, [result.stack]);
- }
-
- checkData(data, flags, row, components) {
- const isValid = super.checkData(data, flags, row, components);
-
- if (this.component.autoAdjust && this.options.display !== 'pdf') {
- const redraw = this.justify();
-
- if (redraw) {
- this.redraw();
- }
- }
-
- return isValid;
- }
-
- detach(all) {
- super.detach(all);
- }
-
- destroy() {
- super.destroy();
- this.columns = [];
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.unit.js
deleted file mode 100644
index 6cc1d29e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/columns/Columns.unit.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import Harness from '../../../test/harness';
-import ColumnsComponent from './Columns';
-import assert from 'power-assert';
-import {
- comp1,
- comp2,
- comp3
-} from './fixtures';
-
-describe('Columns Component', () => {
- it('Should build a columns component', () => {
- return Harness.testCreate(ColumnsComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 2);
- });
- });
- it('Should be auto-adjusting when auto adjust is set to true', done => {
- Harness.testCreate(ColumnsComponent, comp2)
- .then((component) => {
- const columns = component.component.columns;
- assert.equal(columns.every(col => col.currentWidth === 2), true);
- const oddIndexes = [0, 2, 4]; // 0 column has 2 textfields
- oddIndexes.forEach(i => columns[i].components[0].hidden = true); // we're setting hidden for odd columns
- // initially all components aren't hidden and have default width = 2
- component.rebuild(); // rebuild component to check conditions
-
- oddIndexes.forEach(i => {
- if (i === 0) {
- assert.equal(columns[i].currentWidth, 2, `column[${i}] should have width = 2`); // it has at least a component as visible
- }
- else {
- assert.equal(columns[i].currentWidth, 0, `column[${i}] should have width = 0`); // columns which has no visible components should have currentWidth as 0
- }
- });
-
- oddIndexes.forEach(i => columns[i].components[0].hidden = false); // we're setting visible for odd columns again
- component.rebuild(); // rebuild component to check conditions
- assert.equal(columns.every(col => col.currentWidth === 2), true, 'all columns should have width = 2'); // ensure we have initial width
- })
- .then(done)
- .catch(done);
- });
-
- it('Should clear fields in modal window after confirming to clear data in dialog window', (done) => {
- Harness.testCreate(ColumnsComponent, comp3).then((component) => {
- const hiddenModalWindow = component.element.querySelector('.component-rendering-hidden');
- assert.equal(!!hiddenModalWindow, true);
-
- const clickEvent = new Event('click');
- const openModalElement = component.refs.openModal;
- //open modal edit window
- openModalElement.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!component.element.querySelector('.component-rendering-hidden'), false);
-
- const inputEvent = new Event('input');
- const columnsInputField = component.element.querySelector('[name="data[textField]"]');
-
- columnsInputField.value = 'alexy@form.io';
- columnsInputField.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(component.element.querySelector('[name="data[textField]"]').value, 'alexy@form.io');
-
- const clickEvent = new Event('click');
- const modalOverlay = component.refs.modalOverlay;
- //click outside modal edit window
- modalOverlay.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!component.componentModal.dialog, true);
-
- const clickEvent = new Event('click');
- const btnForCleaningValues = document.querySelector('[ref="dialogYesButton"]');
- //click on 'yes, delete it' button inside alert window
- btnForCleaningValues.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const clickEvent = new Event('click');
- const openModalElement = component.refs.openModal;
- //open edit modal window again
- openModalElement.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(component.element.querySelector('[name="data[textField]"]').value, '');
- done();
- }, 100);
- }, 100);
- }, 100);
- }, 100);
- }, 100);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/columns/editForm/Columns.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/columns/editForm/Columns.edit.display.js
deleted file mode 100644
index 9d7178ba..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/columns/editForm/Columns.edit.display.js
+++ /dev/null
@@ -1,80 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- key: 'disabled',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
- {
- weight: 150,
- type: 'datagrid',
- input: true,
- key: 'columns',
- label: 'Column Properties',
- addAnother: 'Add Column',
- tooltip: 'The size and width settings for each column. One row is equal to 12. (e.g., a row with two columns spanning the entire page should be 6 and 6)',
- reorder: true,
- components: [
- {
- type: 'hidden',
- key: 'components',
- defaultValue: []
- },
- {
- type: 'select',
- key: 'size',
- defaultValue: 'md',
- label: 'Size',
- data: {
- values: [
- { label: 'xs', value: 'xs' },
- { label: 'sm', value: 'sm' },
- { label: 'md', value: 'md' },
- { label: 'lg', value: 'lg' },
- { label: 'xl', value: 'xl' },
- ],
- },
- },
- {
- type: 'number',
- key: 'width',
- defaultValue: 6,
- label: 'Width'
- }
- ]
- },
- {
- weight: 160,
- type: 'checkbox',
- label: 'Auto adjust columns',
- tooltip: 'Will automatically adjust columns based on if nested components are hidden.',
- key: 'autoAdjust',
- input: true
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp1.js
deleted file mode 100644
index 8d7c10bd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp1.js
+++ /dev/null
@@ -1,89 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'columns',
- 'columns': [
- {
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'firstName',
- 'label': 'First Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ]
- },
- {
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'lastName',
- 'label': 'Last Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ]
- }
- ],
- 'key': 'columns1',
- 'input': false
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp2.js
deleted file mode 100644
index c1fa1fb9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp2.js
+++ /dev/null
@@ -1,125 +0,0 @@
-export default {
- label: 'Columns',
- columns: [
- // First Column
- {
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField1',
- type: 'textfield',
- input: true
- },
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField2',
- type: 'textfield',
- input: true
- },
- ],
- width: 2,
- offset: 0,
- push: 0,
- pull: 0,
- size: 'md',
- currentWidth: 2,
- },
- // Second Column with hidden components
- {
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField3',
- type: 'textfield',
- input: true
- },
- ],
- width: 2,
- offset: 0,
- push: 0,
- pull: 0,
- size: 'md',
- currentWidth: 2,
- },
- // Third Column
- {
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField4',
- type: 'textfield',
- input: true
- },
- ],
- size: 'md',
- width: 2,
- offset: 0,
- push: 0,
- pull: 0,
- currentWidth: 2,
- },
- // Fourth Column
- {
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField5',
- type: 'textfield',
- input: true
- },
- ],
- size: 'md',
- width: 2,
- offset: 0,
- push: 0,
- pull: 0,
- currentWidth: 2,
- },
- // Fifth Column
- {
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField6',
- type: 'textfield',
- input: true
- },
- ],
- size: 'md',
- width: 2,
- offset: 0,
- push: 0,
- pull: 0,
- currentWidth: 2,
- },
- // Sixth Column
- {
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField7',
- type: 'textfield',
- input: true
- },
- ],
- size: 'md',
- width: 2,
- offset: 0,
- push: 0,
- pull: 0,
- currentWidth: 2,
- },
- ],
- autoAdjust: true,
- key: 'columns1',
- type: 'columns',
- input: false,
- tableView: false,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp3.js
deleted file mode 100644
index 5ad3d7f4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/comp3.js
+++ /dev/null
@@ -1,51 +0,0 @@
-export default {
- label: 'Columns',
- columns: [
- {
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- hideOnChildrenHidden: false,
- },
- ],
- width: 6,
- offset: 0,
- push: 0,
- pull: 0,
- size: 'md',
- currentWidth: 6,
- },
- {
- components: [
- {
- label: 'Number',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- key: 'number',
- type: 'number',
- input: true,
- hideOnChildrenHidden: false,
- },
- ],
- width: 6,
- offset: 0,
- push: 0,
- pull: 0,
- size: 'md',
- currentWidth: 6,
- },
- ],
- modalEdit: true,
- key: 'columns',
- type: 'columns',
- input: false,
- tableView: false,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/index.js
deleted file mode 100644
index bb8fc410..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/columns/fixtures/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/Container.form.js b/web-client/core/themes/italia/static/formio/css/src/components/container/Container.form.js
deleted file mode 100644
index 75755ed0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/Container.form.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Components from '../Components';
-import ContainerEditDisplay from './editForm/Container.edit.display';
-import ContainerEditData from './editForm/Container.edit.data';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: ContainerEditDisplay
- },
- {
- key: 'data',
- components: ContainerEditData
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/Container.js b/web-client/core/themes/italia/static/formio/css/src/components/container/Container.js
deleted file mode 100644
index 3c49b2e3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/Container.js
+++ /dev/null
@@ -1,91 +0,0 @@
-import _ from 'lodash';
-import { componentValueTypes, getComponentSavedTypes, getFocusableElements } from '../../utils/utils';
-
-import Component from '../_classes/component/Component';
-import Field from '../_classes/field/Field';
-import NestedDataComponent from '../_classes/nesteddata/NestedDataComponent';
-
-export default class ContainerComponent extends NestedDataComponent {
- static schema(...extend) {
- return NestedDataComponent.schema({
- label: 'Container',
- type: 'container',
- key: 'container',
- clearOnHide: true,
- input: true,
- tree: true,
- hideLabel: true,
- components: []
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Container',
- icon: 'folder-open',
- group: 'data',
- documentation: '/userguide/form-building/data-components#container',
- showPreview: false,
- weight: 10,
- schema: ContainerComponent.schema()
- };
- }
-
- constructor(...args) {
- super(...args);
- this.type = 'container';
- }
-
- static savedValueTypes(schema) {
- return getComponentSavedTypes(schema) || [componentValueTypes.object];
- }
-
- addComponents(data, options) {
- return super.addComponents(this.dataValue, options);
- }
-
- get defaultSchema() {
- return ContainerComponent.schema();
- }
-
- get emptyValue() {
- return {};
- }
-
- get templateName() {
- return 'container';
- }
-
- componentContext() {
- return this.dataValue;
- }
-
- checkData(data, flags, row, components) {
- data = data || this.rootValue;
- flags = flags || {};
- row = row || this.data;
- components = components && _.isArray(components) ? components : this.getComponents();
-
- return components.reduce((valid, comp) => {
- return comp.checkData(data, flags, this.dataValue) && valid;
- }, Component.prototype.checkData.call(this, data, flags, row));
- }
-
- checkChildComponentsValidity(data, dirty, row, silentCheck, isParentValid) {
- return super.checkChildComponentsValidity(data, dirty, this.dataValue, silentCheck, isParentValid);
- }
-
- focus() {
- const focusableElements = getFocusableElements(this.element);
- if (focusableElements && focusableElements[0]) {
- focusableElements[0].focus();
- }
- }
-
- checkConditions(data, flags, row) {
- // check conditions of parent component first, because it may influence on visibility of it's children
- const check = Field.prototype.checkConditions.call(this, data, flags, row);
- this.getComponents().forEach(comp => comp.checkConditions(data, flags, this.dataValue));
- return check;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/Container.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/container/Container.unit.js
deleted file mode 100644
index fe96056b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/Container.unit.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import assert from 'power-assert';
-import _ from 'lodash';
-import Harness from '../../../test/harness';
-import ContainerComponent from './Container';
-
-import {
- comp1,
- comp2,
- comp3,
- comp4,
-} from './fixtures';
-
-import Formio from '../../Formio';
-
-describe('Container Component', () => {
- it('Should build a container component', () => {
- return Harness.testCreate(ContainerComponent, comp1).then((component) => {
- const inputs = Harness.testElements(component, 'input[type="text"]', 2);
- for (let i=0; i < inputs.length; i++) {
- assert.equal(inputs[i].name, `data[${comp1.key}][${comp1.components[i].key}]`);
- }
- });
- });
-
- it('Should be able to set and get data', () => {
- return Harness.testCreate(ContainerComponent, comp1).then((component) => {
- const inputs = Harness.testElements(component, 'input[type="text"]', 2);
- Harness.testSetGet(component, {
- firstName: 'Joe',
- lastName: 'Smith'
- });
- assert.equal(inputs[0].value, 'Joe');
- assert.equal(inputs[1].value, 'Smith');
- });
- });
-
- it('Should set the dataValue, but after it sets the value of its nested components', () => {
- return Harness.testCreate(ContainerComponent, comp2).then((component) => {
- const editGrid = component.getComponent('children');
- const setValue = editGrid.setValue;
- editGrid.setValue = function(...args) {
- const changed = setValue.call(editGrid, ...args);
- assert(changed, 'The edit grid must have changed');
- return changed;
- };
- component.setValue({
- children: [
- {
- name: 'Joe'
- },
- {
- name: 'Sally'
- }
- ]
- });
- });
- });
-
- it('Should render form with a submission in a draft-state without validation errors', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.submission = {
- data: {
- 'container': {
- 'textField': 'a',
- }
- }
- };
-
- setTimeout(() => {
- const textField = form.getComponent(['textField']);
- const container = form.getComponent(['container']);
- assert.equal(textField.errors.length, 0);
- assert.equal(container.errors.length, 0);
- done();
- }, 100);
- }).catch(done);
- });
-
- it('Should not set the default value when clearOnHide during the server-side validation', (done) => {
- const form = _.cloneDeep(comp4);
- const element = document.createElement('div');
-
- Formio.createForm(element, form, { server: true, noDefaults: true }).then(form => {
- form.setValue({ data: { checkbox: false } }, {
- sanitize: true,
- }, true);
-
- form.checkConditions();
- form.clearOnHide();
-
- setTimeout(() => {
- assert.deepEqual(form._data, { checkbox: false }, 'Should not add Container\'s key');
- done();
- }, 200);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/editForm/Container.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/container/editForm/Container.edit.data.js
deleted file mode 100644
index 9aa6fd8d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/editForm/Container.edit.data.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true
- },
- {
- key: 'allowCalculateOverride',
- ignore: true
- },
- {
- key: 'defaultValue',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/editForm/Container.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/container/editForm/Container.edit.display.js
deleted file mode 100644
index e3656fe2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/editForm/Container.edit.display.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default [
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp1.js
deleted file mode 100644
index a3997245..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp1.js
+++ /dev/null
@@ -1,84 +0,0 @@
-export default {
- 'input': true,
- 'tree': true,
- 'components': [
- {
- 'input': true,
- 'tableView': true,
- 'inputType': 'text',
- 'inputMask': '',
- 'label': 'First Name',
- 'key': 'firstName',
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'multiple': false,
- 'defaultValue': '',
- 'protected': false,
- 'unique': false,
- 'persistent': true,
- 'validate': {
- 'required': false,
- 'minLength': '',
- 'maxLength': '',
- 'pattern': '',
- 'custom': '',
- 'customPrivate': false
- },
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'type': 'textfield',
- 'tags': [
-
- ]
- },
- {
- 'input': true,
- 'tableView': true,
- 'inputType': 'text',
- 'inputMask': '',
- 'label': 'Last Name',
- 'key': 'lastName',
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'multiple': false,
- 'defaultValue': '',
- 'protected': false,
- 'unique': false,
- 'persistent': true,
- 'validate': {
- 'required': false,
- 'minLength': '',
- 'maxLength': '',
- 'pattern': '',
- 'custom': '',
- 'customPrivate': false
- },
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'type': 'textfield',
- 'tags': [
-
- ]
- }
- ],
- 'tableView': true,
- 'label': 'User',
- 'key': 'user',
- 'protected': false,
- 'persistent': true,
- 'type': 'container',
- 'tags': [],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp2.js
deleted file mode 100644
index 211478a0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp2.js
+++ /dev/null
@@ -1,32 +0,0 @@
-export default {
- 'input': true,
- 'tree': true,
- 'components': [
- {
- type: 'editgrid',
- label: 'Edit Grid',
- key: 'children',
- input: true,
- components: [
- {
- type: 'textfield',
- key: 'name',
- label: 'Name',
- input: true
- }
- ]
- }
- ],
- 'tableView': true,
- 'label': 'User',
- 'key': 'user',
- 'protected': false,
- 'persistent': true,
- 'type': 'container',
- 'tags': [],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp3.js
deleted file mode 100644
index f97cb502..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp3.js
+++ /dev/null
@@ -1,55 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: { required: true, minLength: 2 },
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Container',
- tableView: false,
- validate: { required: true },
- key: 'container',
- type: 'container',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: { required: true, minLength: 2 },
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- ],
- },
- {
- label: 'Submit as Draft',
- action: 'saveState',
- showValidations: false,
- theme: 'secondary',
- tableView: false,
- key: 'submitAsDraft',
- type: 'button',
- state: 'draft',
- input: true,
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- saveOnEnter: false,
- },
- ],
- display: 'form',
- name: 'fio37151',
- path: 'fio37151',
- project: '6103a71934405111ce3f64fa',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp4.js
deleted file mode 100644
index c48b94e3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/comp4.js
+++ /dev/null
@@ -1,43 +0,0 @@
-export default {
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Checkbox',
- tableView: false,
- key: 'checkbox',
- type: 'checkbox',
- input: true,
- },
- {
- label: 'Container',
- tableView: false,
- key: 'container',
- conditional: {
- show: true,
- when: 'checkbox',
- eq: 'true',
- },
- type: 'container',
- input: true,
- components: [
- {
- label: 'Text Field',
- applyMaskOn: 'change',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- ],
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/index.js
deleted file mode 100644
index 6664cb89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/container/fixtures/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/content/Content.form.js b/web-client/core/themes/italia/static/formio/css/src/components/content/Content.form.js
deleted file mode 100644
index b81c82cd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/content/Content.form.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import Components from '../Components';
-import ContentEditDisplay from './editForm/Content.edit.display';
-import ContentEditLogic from './editForm/Content.edit.logic';
-
-export default function(...extend) {
- const editForm = Components.baseEditForm([
- {
- key: 'display',
- components: ContentEditDisplay,
- },
- {
- key: 'data',
- ignore: true,
- },
- {
- key: 'validation',
- ignore: true,
- },
- {
- key: 'logic',
- components: ContentEditLogic,
- },
- ], ...extend);
- // Add content as full width above the settings.
- editForm.components = [{
- weight: 0,
- type: 'textarea',
- editor: 'ckeditor',
- label: 'Content',
- hideLabel: true,
- input: true,
- key: 'html',
- as: 'html',
- rows: 3,
- tooltip: 'The HTML template for the result data items.',
- }].concat(editForm.components);
- return editForm;
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/content/Content.js b/web-client/core/themes/italia/static/formio/css/src/components/content/Content.js
deleted file mode 100644
index a9156b48..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/content/Content.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import Component from '../_classes/component/Component';
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-
-export default class ContentComponent extends Component {
- static schema(...extend) {
- return Component.schema({
- label: 'Content',
- type: 'content',
- key: 'content',
- input: false,
- html: ''
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Content',
- group: 'layout',
- icon: 'html5',
- preview: false,
- documentation: '/userguide/form-building/layout-components#content',
- weight: 5,
- schema: ContentComponent.schema()
- };
- }
-
- static savedValueTypes() {
- return [];
- }
-
- get defaultSchema() {
- return ContentComponent.schema();
- }
-
- get content() {
- if (this.builderMode) {
- return this.component.html || 'Content';
- }
- const submission = _.get(this.root, 'submission', {});
- return this.component.html ? this.interpolate(this.component.html, {
- metadata: submission.metadata || {},
- submission: submission,
- data: this.rootValue,
- row: this.data
- }) : '';
- }
-
- render() {
- return super.render(this.renderTemplate('html', {
- tag: 'div',
- attrs: [],
- content: this.content,
- }));
- }
-
- get dataReady() {
- return this.root?.submissionReady || NativePromise.resolve();
- }
-
- attach(element) {
- this.loadRefs(element, { html: 'single' });
- this.dataReady.then(() => {
- if (this.refs.html) {
- this.setContent(this.refs.html, this.content);
- }
- });
- if (this.component.refreshOnChange) {
- this.on('change', () => {
- if (this.refs.html) {
- this.setContent(this.refs.html, this.content);
- }
- }, true);
- }
- return super.attach(element);
- }
-
- get emptyValue() {
- return '';
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/content/Content.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/content/Content.unit.js
deleted file mode 100644
index 646d21f7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/content/Content.unit.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import assert from 'power-assert';
-
-import Harness from '../../../test/harness';
-import ContentComponent from './Content';
-import Formio from '../../Formio';
-
-import {
- comp1
-} from './fixtures';
-
-describe('Content Component', () => {
- it('Should build a content component', () => {
- return Harness.testCreate(ContentComponent, comp1).then((component) => {
- const html = component.element.querySelector('[ref="html"]');
- assert.equal(html.innerHTML.trim(), comp1.html.trim());
- });
- });
-
- it('Should update after submission set', (done) => {
- const formJson = {
- components: [{
- html: '{{submission.data.textField}}
',
- label: 'Content',
- refreshOnChange: false,
- key: 'content',
- type: 'content',
- }, {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- },]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson)
- .then(form => {
- form.submission = {
- data: {
- textField: 'textField'
- }
- };
- const content = form.getComponent('content');
- form.dataReady.then(() => {
- assert.equal(content.refs.html.innerHTML, 'textField
');
- done();
- });
- })
- .catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/content/editForm/Content.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/content/editForm/Content.edit.display.js
deleted file mode 100644
index 9cc26a81..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/content/editForm/Content.edit.display.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'hideLabel',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'disabled',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
- {
- weight: 700,
- type: 'checkbox',
- label: 'Refresh On Change',
- tooltip: 'Rerender the field whenever a value on the form changes.',
- key: 'refreshOnChange',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/content/editForm/Content.edit.logic.js b/web-client/core/themes/italia/static/formio/css/src/components/content/editForm/Content.edit.logic.js
deleted file mode 100644
index b9534cfa..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/content/editForm/Content.edit.logic.js
+++ /dev/null
@@ -1,98 +0,0 @@
-export default [
- {
- key: 'logic',
- components: [
- {
- key: 'actions',
- components: [
- {
- key: 'actionPanel',
- components: [
- {
- data: {
- json: [
- {
- label: 'Hidden',
- value: 'hidden',
- type: 'boolean',
- },
- {
- label: 'Required',
- value: 'validate.required',
- type: 'boolean',
- },
- {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean',
- },
- {
- label: 'Label',
- value: 'label',
- type: 'string',
- },
- {
- label: 'Title',
- value: 'title',
- type: 'string',
- },
- {
- label: 'Tooltip',
- value: 'tooltip',
- type: 'string',
- },
- {
- label: 'Description',
- value: 'description',
- type: 'string',
- },
- {
- label: 'Placeholder',
- value: 'placeholder',
- type: 'string',
- },
- {
- label: 'CSS Class',
- value: 'className',
- type: 'string',
- },
- {
- label: 'Container Custom Class',
- value: 'customClass',
- type: 'string',
- },
- {
- label: 'Content',
- value: 'html',
- type: 'string',
- component: 'content',
- },
- ],
- },
- key: 'property',
- },
- {
- type: 'textarea',
- editor: 'ace',
- rows: 10,
- as: 'html',
- label: 'Content',
- tooltip: 'The content of this HTML element.',
- defaultValue: 'Content
',
- key: 'content',
- weight: 30,
- input: true,
- customConditional(context) {
- return (context.row.type === 'property' &&
- context.row.hasOwnProperty('property') &&
- context.row.property.type === 'string' &&
- context.row.property.component === 'content');
- },
- },
- ],
- },
- ],
- },
- ],
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/content/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/content/fixtures/comp1.js
deleted file mode 100644
index 0d6665b4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/content/fixtures/comp1.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'content',
- 'html': 'This is a test \n',
- 'input': false,
- 'key': 'content1'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/content/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/content/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/content/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.form.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.form.js
deleted file mode 100644
index 2bfc648a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.form.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import baseEditForm from '../textfield/TextField.form';
-import CurrencyEditDisplay from './editForm/Currency.edit.display';
-import CurrencyEditData from './editForm/Currency.edit.data';
-export default function(...extend) {
- return baseEditForm([
- {
- key: 'display',
- components: CurrencyEditDisplay
- },
- {
- key: 'data',
- components: CurrencyEditData
- },
- {
- key: 'validation',
- components: [
- {
- key: 'validate.minLength',
- ignore: true,
- },
- {
- key: 'validate.maxLength',
- ignore: true,
- },
- {
- key: 'validate.minWords',
- ignore: true,
- },
- {
- key: 'validate.maxWords',
- ignore: true,
- },
- {
- key: 'validate.pattern',
- ignore: true,
- },
- ]
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.js
deleted file mode 100644
index 0356ca2b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.js
+++ /dev/null
@@ -1,199 +0,0 @@
-import { createNumberMask } from '@formio/text-mask-addons';
-import { maskInput } from '@formio/vanilla-text-mask';
-import _ from 'lodash';
-import { getCurrencyAffixes } from '../../utils/utils';
-import NumberComponent from '../number/Number';
-
-export default class CurrencyComponent extends NumberComponent {
- static schema(...extend) {
- return NumberComponent.schema({
- type: 'currency',
- label: 'Currency',
- key: 'currency'
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Currency',
- group: 'advanced',
- icon: 'usd',
- documentation: '/userguide/form-building/advanced-components#currency',
- weight: 70,
- schema: CurrencyComponent.schema()
- };
- }
-
- constructor(component, options, data) {
- // Currency should default to have a delimiter unless otherwise specified.
- if (component && !component.hasOwnProperty('delimiter')) {
- component.delimiter = true;
- }
- super(component, options, data);
- }
-
- /**
- * Creates the number mask for currency numbers.
- *
- * @return {*}
- */
- createNumberMask() {
- const decimalLimit = _.get(this.component, 'decimalLimit', 2);
- const affixes = getCurrencyAffixes({
- currency: this.component.currency,
- decimalLimit: decimalLimit,
- decimalSeparator: this.decimalSeparator,
- lang: this.options.language
- });
- this.currencyPrefix = this.options.prefix || affixes.prefix;
- this.currencySuffix = this.options.suffix || affixes.suffix;
- return createNumberMask({
- prefix: this.currencyPrefix,
- suffix: this.currencySuffix,
- thousandsSeparatorSymbol: _.get(this.component, 'thousandsSeparator', this.delimiter),
- decimalSymbol: _.get(this.component, 'decimalSymbol', this.decimalSeparator),
- decimalLimit: decimalLimit,
- allowNegative: _.get(this.component, 'allowNegative', true),
- allowDecimal: this.isDecimalAllowed(),
- });
- }
-
- isDecimalAllowed() {
- return _.get(this.component, 'allowDecimal', true);
- }
-
- setInputMask(input) {
- const affixes = getCurrencyAffixes({
- currency: this.component.currency,
- decimalSeparator: this.decimalSeparator,
- lang: this.options.language,
- });
- let numberPattern = `${affixes.prefix}[0-9`;
- numberPattern += this.decimalSeparator || '';
- numberPattern += this.delimiter || '';
- numberPattern += ']*';
- input.setAttribute('pattern', numberPattern);
- input.mask = maskInput({
- inputElement: input,
- mask: this.numberMask || '',
- pipe: (conformedValue) => {
- if (conformedValue === '$0._') {
- // Delay to allow mask to update first.
- setTimeout(() => {
- const caretPosition = input.value.length - 1;
- input.setSelectionRange(caretPosition, caretPosition);
- });
- }
- return conformedValue;
- },
- shadowRoot: this.root ? this.root.shadowRoot : null
- });
- }
-
- get defaultSchema() {
- return CurrencyComponent.schema();
- }
-
- parseNumber(value) {
- return super.parseNumber(this.stripPrefixSuffix(value));
- }
-
- parseValue(value) {
- return super.parseValue(this.stripPrefixSuffix(value));
- }
-
- addZerosAndFormatValue(value) {
- if (!value && value !== 0) return;
-
- const decimalLimit = _.get(this.component, 'decimalLimit', 2);
-
- let integerPart;
- let decimalPart = '';
- let decimalPartNumbers = [];
- const negativeValueSymbol = '-';
- const hasPrefix = this.currencyPrefix ? value.includes(this.currencyPrefix) : false;
- const hasSuffix = this.currencySuffix ? value.includes(this.currencySuffix) : false;
- const isNegative = value.includes(negativeValueSymbol) || false;
-
- value = this.stripPrefixSuffix(isNegative ? value.replace(negativeValueSymbol,'') : value);
-
- if (value.includes(this.decimalSeparator)) {
- [integerPart, decimalPart] = value.split(this.decimalSeparator);
- decimalPartNumbers =[...decimalPart.split('')] ;
- }
- else {
- integerPart = value;
- }
-
- if (decimalPart.length < decimalLimit) {
- while (decimalPartNumbers.length < decimalLimit) {
- decimalPartNumbers.push('0');
- }
- }
-
- const formattedValue = `${isNegative ? negativeValueSymbol:''}${hasPrefix ? this.currencyPrefix : ''}${integerPart}${this.decimalSeparator}${decimalPartNumbers.join('')}${hasSuffix ? this.currencySuffix : ''}`;
-
- return super.formatValue(formattedValue);
- }
-
- getValueAsString(value, options) {
- const stringValue = super.getValueAsString(value, options);
-
- // eslint-disable-next-line eqeqeq
- if (value || value == '0') {
- if (Array.isArray(value)) {
- return value.map((val) => this.addZerosAndFormatValue(super.getValueAsString(val, options))).join(', ');
- }
- return this.addZerosAndFormatValue(stringValue);
- }
-
- return stringValue;
- }
-
- formatValue(value) {
- if (value || value === '0') {
- return this.addZerosAndFormatValue(value);
- }
-
- return super.formatValue(value);
- }
-
- stripPrefixSuffix(value) {
- if (typeof value === 'string') {
- try {
- const hasPrefix = this.currencyPrefix ? value.includes(this.currencyPrefix) : false;
- const hasSuffix = this.currencySuffix ? value.includes(this.currencySuffix) : false;
- const hasDelimiter = value.includes(this.delimiter);
- const hasDecimalSeparator = value.includes(this.decimalSeparator);
-
- if (this.currencyPrefix) {
- value = value.replace(this.currencyPrefix, '');
- }
- if (this.currencySuffix) {
- value = value.replace(this.currencySuffix, '');
- }
- //when we enter $ in the field using dashboard, it contains '_' that is NaN
- if ((hasPrefix || hasSuffix) && !hasDelimiter && !hasDecimalSeparator && (Number.isNaN(+value) || !value)) {
- value ='0';
- }
- }
- catch (err) {
- // If value doesn't have a replace method, continue on as before.
- }
- }
- return value;
- }
-
- addFocusBlurEvents(element) {
- super.addFocusBlurEvents(element);
-
- this.addEventListener(element, 'focus', () => {
- if (element.defaultValue === element.value) {
- element.setSelectionRange(0, element.defaultValue.length);
- }
- });
- this.addEventListener(element, 'blur', () => {
- element.value = this.getValueAsString(this.addZerosAndFormatValue(this.parseValue(element.value)));
- });
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.unit.js
deleted file mode 100644
index 4ddec25f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/Currency.unit.js
+++ /dev/null
@@ -1,329 +0,0 @@
-import Harness from '../../../test/harness';
-import CurrencyComponent from './Currency';
-import assert from 'power-assert';
-import {
- comp1,
- comp2,
- comp3,
- comp4,
-} from './fixtures';
-
-describe('Currency Component', () => {
- before(done => {
- // Need to polyfill some Intl.locale support, since node doesn't include it in standard builds
- require('../../../test/numberFormatPolyfill');
-
- done();
- });
-
- it('Should build a currency component', () => {
- return Harness.testCreate(CurrencyComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 1);
- });
- });
-
- it('Should place a caret between the period and the underline.', (done) => {
- Harness.testCreate(CurrencyComponent, comp3, { language: 'en-US' })
- .then((component) => {
- const inputEvent = new Event('input');
- const currencyElement = component.element.querySelector('[name="data[currency]"]');
-
- currencyElement.value = 42;
- currencyElement.dispatchEvent(inputEvent);
- assert.equal(currencyElement.value, '$42');
-
- currencyElement.value = '.';
- currencyElement.dispatchEvent(inputEvent);
- setTimeout(() => {
- assert.equal(currencyElement.selectionStart, 3);
- done();
- }, 200);
- });
- });
-
- it('Should format value on blur for USA locale', (done) => {
- Harness.testCreate(CurrencyComponent, comp1, { language: 'en-US' }).then((component) => {
- component.root = {
- onChange: ()=>{},
- triggerChange: ()=>{},
- };
-
- const blurEvent = new Event('blur');
- const inputEvent = new Event('input');
- const valueElement = component.element.querySelector('[name="data[money]"]');
-
- valueElement.value = 22222222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '$22,222,222.00');
-
- valueElement.value = 22222222.2;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '$22,222,222.20');
-
- valueElement.value = 22222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '$22,222.00');
-
- valueElement.value = 222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '$222.00');
-
- valueElement.value = 2;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '$2.00');
-
- done();
- });
- });
-
- it('Should format value on blur for French locale', (done) => {
- Harness.testCreate(CurrencyComponent, comp1, { language: 'fr' }).then((component) => {
- component.root = {
- onChange: ()=>{},
- triggerChange: ()=>{},
- };
-
- const blurEvent = new Event('blur');
- const inputEvent = new Event('input');
- const valueElement = component.element.querySelector('[name="data[money]"]');
-
- valueElement.value = 22222222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '22 222 222,00 $US');
-
- valueElement.value = '22222222,2';
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '22 222 222,20 $US');
-
- valueElement.value = 22222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '22 222,00 $US');
-
- valueElement.value = 222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '222,00 $US');
-
- valueElement.value = 2;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '2,00 $US');
-
- done();
- });
- });
-
- it('Should not change entered value on blur if multiple value is set', (done) => {
- Harness.testCreate(CurrencyComponent, comp2).then((component) => {
- component.root = {
- onChange: ()=>{},
- triggerChange: ()=>{},
- };
- const blurEvent = new Event('blur');
- const clickEvent = new Event('click');
- const addBtn = component.refs.addButton[0];
-
- addBtn.dispatchEvent(clickEvent);
-
- const firstValueElement = component.element.querySelectorAll('[name="data[currency]"]')[0];
- const secondValueElement = component.element.querySelectorAll('[name="data[currency]"]')[1];
-
- component.setValue([111,222]);
-
- firstValueElement.dispatchEvent(blurEvent);
- secondValueElement.dispatchEvent(blurEvent);
-
- assert.equal(component.dataValue[0], component.getValue()[0]);
- assert.equal(component.dataValue[1], component.getValue()[1]);
- done();
- });
- });
-
- it('Should format currency submissions for table view for French locale', () => {
- return Harness.testCreate(CurrencyComponent, comp1, { language: 'fr' }).then((component) => {
- const value1 = component.getValueAsString(1);
- const value2 = component.getValueAsString(1.1);
- const value3 = component.getValueAsString(1.11);
- const value4 = component.getValueAsString(1111);
- const value5 = component.getValueAsString(1111111);
- const value6 = component.getValueAsString(-11111);
-
- assert.equal(value1, '1,00 $US');
- assert.equal(value2, '1,10 $US');
- assert.equal(value3, '1,11 $US');
- assert.equal(value4, '1 111,00 $US');
- assert.equal(value5, '1 111 111,00 $US');
- assert.equal(value6, '-11 111,00 $US');
- });
- });
-
- it('Should format currency sumbissions for table view for USA locale', () => {
- return Harness.testCreate(CurrencyComponent, comp1, { language: 'en-US' }).then((component) => {
- const value1 = component.getValueAsString(1);
- const value2 = component.getValueAsString(1.1);
- const value3 = component.getValueAsString(1.11);
- const value4 = component.getValueAsString(1111);
- const value5 = component.getValueAsString(1111111);
- const value6 = component.getValueAsString(-11111);
-
- assert.equal(value1, '$1.00');
- assert.equal(value2, '$1.10');
- assert.equal(value3, '$1.11');
- assert.equal(value4, '$1,111.00');
- assert.equal(value5, '$1,111,111.00');
- assert.equal(value6, '-$11,111.00');
- });
- });
-
- it('Should add trailing zeros', () => {
- return Harness.testCreate(CurrencyComponent, comp1, { language: 'en-US' }).then((component) => {
- assert.equal(component.addZerosAndFormatValue(null),);
- assert.equal(component.addZerosAndFormatValue('3'), '3.00');
- assert.equal(component.addZerosAndFormatValue('3.1'), '3.10');
- assert.equal(component.addZerosAndFormatValue('-3'), '-3.00');
- assert.equal(component.addZerosAndFormatValue('$3'), '$3.00');
- assert.equal(component.addZerosAndFormatValue('-$3'), '-$3.00');
- assert.equal(component.addZerosAndFormatValue('$3.3'), '$3.30');
- assert.equal(component.addZerosAndFormatValue('$3.33'), '$3.33');
- });
- });
-
- it('Should set values with trailing zeros', () => {
- return Harness.testCreate(CurrencyComponent, comp1, { language: 'en-US' }).then((component) => {
- assert.equal(component.formatValue(null), null);
- assert.equal(component.formatValue('0'), '0.00');
- assert.equal(component.formatValue('3'), '3.00');
- assert.equal(component.formatValue('3.3'), '3.30');
- assert.equal(component.formatValue('3.33'), '3.33');
- });
- });
-
- it('Should format currency for USA locale', () => {
- /* eslint-disable max-statements */
- return Harness.testCreate(CurrencyComponent, comp1, { language: 'en-US' }).then((component) => {
- Harness.testSetInput(component, null, null, '');
- Harness.testSetInput(component, undefined, null, '');
- Harness.testSetInput(component, {}, null, '');
- Harness.testSetInput(component, [], null, '');
- Harness.testSetInput(component, [''], null, '');
- Harness.testSetInput(component, ['1'], 1, '$1.00');
- Harness.testSetInput(component, ['$1.00'], 1, '$1.00');
- Harness.testSetInput(component, 0, 0, '$0.00');
- Harness.testSetInput(component, 1.00, 1, '$1.00');
- Harness.testSetInput(component, -1.00, -1, '-$1.00');
- Harness.testSetInput(component, 1, 1, '$1.00');
- Harness.testSetInput(component, -1, -1, '-$1.00');
- Harness.testSetInput(component, 1000, 1000, '$1,000.00');
- Harness.testSetInput(component, -1000, -1000, '-$1,000.00');
- Harness.testSetInput(component, 1000.01, 1000.01, '$1,000.01');
- Harness.testSetInput(component, -1000.01, -1000.01, '-$1,000.01');
- Harness.testSetInput(component, 1234567890.12, 1234567890.12, '$1,234,567,890.12');
- Harness.testSetInput(component, -1234567890.12, -1234567890.12, '-$1,234,567,890.12');
- Harness.testSetInput(component, 123456789.123456789, 123456789.12, '$123,456,789.12');
- Harness.testSetInput(component, -123456789.123456789, -123456789.12, '-$123,456,789.12');
- Harness.testSetInput(component, '0', 0, '$0.00');
- Harness.testSetInput(component, '1.00', 1, '$1.00');
- Harness.testSetInput(component, '-1.00', -1, '-$1.00');
- Harness.testSetInput(component, '1', 1, '$1.00');
- Harness.testSetInput(component, '-1', -1, '-$1.00');
- Harness.testSetInput(component, '1000', 1000, '$1,000.00');
- Harness.testSetInput(component, '-1000', -1000, '-$1,000.00');
- Harness.testSetInput(component, '1000.01', 1000.01, '$1,000.01');
- Harness.testSetInput(component, '-1000.01', -1000.01, '-$1,000.01');
- Harness.testSetInput(component, '1234567890.12', 1234567890.12, '$1,234,567,890.12');
- Harness.testSetInput(component, '-1234567890.12', -1234567890.12, '-$1,234,567,890.12');
- Harness.testSetInput(component, '123456789.123456789', 123456789.12, '$123,456,789.12');
- Harness.testSetInput(component, '-123456789.123456789', -123456789.12, '-$123,456,789.12');
- Harness.testSetInput(component, '$0', 0, '$0.00');
- Harness.testSetInput(component, '$_', 0, '$0.00');
- Harness.testSetInput(component, '-$_', 0, '$0.00');
- Harness.testSetInput(component, '$1.00', 1, '$1.00');
- Harness.testSetInput(component, '-$1.00', -1, '-$1.00');
- Harness.testSetInput(component, '$1', 1, '$1.00');
- Harness.testSetInput(component, '-$1', -1, '-$1.00');
- Harness.testSetInput(component, '$1000', 1000, '$1,000.00');
- Harness.testSetInput(component, '-$1000', -1000, '-$1,000.00');
- Harness.testSetInput(component, '$1000.01', 1000.01, '$1,000.01');
- Harness.testSetInput(component, '-$1000.01', -1000.01, '-$1,000.01');
- Harness.testSetInput(component, '$1234567890.12', 1234567890.12, '$1,234,567,890.12');
- Harness.testSetInput(component, '-$1234567890.12', -1234567890.12, '-$1,234,567,890.12');
- Harness.testSetInput(component, '$123456789.123456789', 123456789.12, '$123,456,789.12');
- Harness.testSetInput(component, '-$123456789.123456789', -123456789.12, '-$123,456,789.12');
- });
- /* eslint-enable max-statements */
- });
-
- it('Should format currency for British locale', () => {
- return Harness.testCreate(CurrencyComponent, comp1, { language: 'en-GB' }).then((component) => {
- Harness.testSetInput(component, null, null, '');
- Harness.testSetInput(component, 0, 0, 'US$0.00');
- Harness.testSetInput(component, 1.00, 1, 'US$1.00');
- Harness.testSetInput(component, -1.00, -1, '-US$1.00');
- Harness.testSetInput(component, 1, 1, 'US$1.00');
- Harness.testSetInput(component, -1, -1, '-US$1.00');
- Harness.testSetInput(component, 1000, 1000, 'US$1,000.00');
- Harness.testSetInput(component, -1000, -1000, '-US$1,000.00');
- Harness.testSetInput(component, 1000.01, 1000.01, 'US$1,000.01');
- Harness.testSetInput(component, -1000.01, -1000.01, '-US$1,000.01');
- Harness.testSetInput(component, 1234567890.12, 1234567890.12, 'US$1,234,567,890.12');
- Harness.testSetInput(component, -1234567890.12, -1234567890.12, '-US$1,234,567,890.12');
- Harness.testSetInput(component, 123456789.123456789, 123456789.12, 'US$123,456,789.12');
- Harness.testSetInput(component, -123456789.123456789, -123456789.12, '-US$123,456,789.12');
- });
- });
-
- it('Should format currency for French locale', () => {
- return Harness.testCreate(CurrencyComponent, comp1, { language: 'fr' }).then((component) => {
- // The spaces in these tests are a weird unicode space so be careful duplicating the tests.
- Harness.testSetInput(component, null, null, '');
- Harness.testSetInput(component, 0, 0, '0,00 $US');
- Harness.testSetInput(component, 1.00, 1, '1,00 $US');
- Harness.testSetInput(component, -1.00, -1, '-1,00 $US');
- Harness.testSetInput(component, 1, 1, '1,00 $US');
- Harness.testSetInput(component, -1, -1, '-1,00 $US');
- Harness.testSetInput(component, 1000, 1000, '1 000,00 $US');
- Harness.testSetInput(component, -1000, -1000, '-1 000,00 $US');
- Harness.testSetInput(component, 1000.01, 1000.01, '1 000,01 $US');
- Harness.testSetInput(component, -1000.01, -1000.01, '-1 000,01 $US');
- Harness.testSetInput(component, 1234567890.12, 1234567890.12, '1 234 567 890,12 $US');
- Harness.testSetInput(component, -1234567890.12, -1234567890.12, '-1 234 567 890,12 $US');
- Harness.testSetInput(component, 1234567890.123456789, 1234567890.12, '1 234 567 890,12 $US');
- Harness.testSetInput(component, -1234567890.123456789, -1234567890.12, '-1 234 567 890,12 $US');
- });
- });
-
- it('Should format currency for German locale', () => {
- return Harness.testCreate(CurrencyComponent, comp1, { language: 'de' }).then((component) => {
- Harness.testSetInput(component, null, null, '');
- Harness.testSetInput(component, 0, 0, '0,00 $');
- Harness.testSetInput(component, 1.00, 1.00, '1,00 $');
- Harness.testSetInput(component, -1.00, -1.00, '-1,00 $');
- Harness.testSetInput(component, 1, 1, '1,00 $');
- Harness.testSetInput(component, -1, -1, '-1,00 $');
- Harness.testSetInput(component, 1000, 1000, '1.000,00 $');
- Harness.testSetInput(component, -1000, -1000, '-1.000,00 $');
- Harness.testSetInput(component, 1000.01, 1000.01, '1.000,01 $');
- Harness.testSetInput(component, -1000.01, -1000.01, '-1.000,01 $');
- Harness.testSetInput(component, 1234567890.12, 1234567890.12, '1.234.567.890,12 $');
- Harness.testSetInput(component, -1234567890.12, -1234567890.12, '-1.234.567.890,12 $');
- Harness.testSetInput(component, 1234567890.123456789, 1234567890.12, '1.234.567.890,12 $');
- Harness.testSetInput(component, -1234567890.123456789, -1234567890.12, '-1.234.567.890,12 $');
- });
- });
-
- it('Should return value as string properly for multiple values', (done) => {
- Harness.testCreate(CurrencyComponent, comp4).then((component) => {
- component.refs.input = null;
- assert.equal(component.getValueAsString([100, 200, 300, 500]), '$100.00, $200.00, $300.00, $500.00');
- done();
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/editForm/Currency.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/editForm/Currency.edit.data.js
deleted file mode 100644
index a155bb0b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/editForm/Currency.edit.data.js
+++ /dev/null
@@ -1,186 +0,0 @@
-export default [
- {
- type: 'select',
- input: true,
- weight: 50,
- key: 'currency',
- label: 'Currency',
- tooltip: 'The currency to use in currency formatting. Possible values are (ISO-4217) currency codes.',
- defaultValue: 'USD',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'US Dollar (USD)', value: 'USD' },
- { label: 'Euro (EUR)', value: 'EUR' },
- { label: 'Pound Sterling (GBP)', value: 'GBP' },
- { label: 'Australian Dollar (AUD)', value: 'AUD' },
- { label: 'Afghani (AFN)', value: 'AFN' },
- { label: 'Lek (ALL)', value: 'ALL' },
- { label: 'Algerian Dinar (DZD)', value: 'DZD' },
- { label: 'Kwanza (AOA)', value: 'AOA' },
- { label: 'East Caribbean Dollar (XCD)', value: 'XCD' },
- { label: 'Argentine Peso (ARS)', value: 'ARS' },
- { label: 'Armenian Dram (AMD)', value: 'AMD' },
- { label: 'Aruban Florin (AWG)', value: 'AWG' },
- { label: 'Azerbaijan Manat (AZN)', value: 'AZN' },
- { label: 'Bahamian Dollar (BSD)', value: 'BSD' },
- { label: 'Bahraini Dinar (BHD)', value: 'BHD' },
- { label: 'Taka (BDT)', value: 'BDT' },
- { label: 'Barbados Dollar (BBD)', value: 'BBD' },
- { label: 'Belarusian Ruble (BYN)', value: 'BYN' },
- { label: 'Belize Dollar (BZD)', value: 'BZD' },
- { label: 'CFA Franc BCEAO (XOF)', value: 'XOF' },
- { label: 'Bermudian Dollar (BMD)', value: 'BMD' },
- { label: 'Indian Rupee (INR)', value: 'INR' },
- { label: 'Ngultrum (BTN)', value: 'BTN' },
- { label: 'Boliviano (BOB)', value: 'BOB' },
- { label: 'Mvdol (BOV)', value: 'BOV' },
- { label: 'Convertible Mark (BAM)', value: 'BAM' },
- { label: 'Pula (BWP)', value: 'BWP' },
- { label: 'Norwegian Krone (NOK)', value: 'NOK' },
- { label: 'Brazilian Real (BRL)', value: 'BRL' },
- { label: 'Brunei Dollar (BND)', value: 'BND' },
- { label: 'Bulgarian Lev (BGN)', value: 'BGN' },
- { label: 'Burundi Franc (BIF)', value: 'BIF' },
- { label: 'Cabo Verde Escudo (CVE)', value: 'CVE' },
- { label: 'Riel (KHR)', value: 'KHR' },
- { label: 'CFA Franc BEAC (XAF)', value: 'XAF' },
- { label: 'Canadian Dollar (CAD)', value: 'CAD' },
- { label: 'Cayman Islands Dollar (KYD)', value: 'KYD' },
- { label: 'Chilean Peso (CLP)', value: 'CLP' },
- { label: 'Unidad de Fomento (CLF)', value: 'CLF' },
- { label: 'Yuan Renminbi (CNY)', value: 'CNY' },
- { label: 'Colombian Peso (COP)', value: 'COP' },
- { label: 'Unidad de Valor Real (COU)', value: 'COU' },
- { label: 'Comorian Franc (KMF)', value: 'KMF' },
- { label: 'Congolese Franc (CDF)', value: 'CDF' },
- { label: 'New Zealand Dollar (NZD)', value: 'NZD' },
- { label: 'Costa Rican Colon (CRC)', value: 'CRC' },
- { label: 'Kuna (HRK)', value: 'HRK' },
- { label: 'Cuban Peso (CUP)', value: 'CUP' },
- { label: 'Peso Convertible (CUC)', value: 'CUC' },
- { label: 'Netherlands Antillean Guilder (ANG)', value: 'ANG' },
- { label: 'Czech Koruna (CZK)', value: 'CZK' },
- { label: 'Danish Krone (DKK)', value: 'DKK' },
- { label: 'Djibouti Franc (DJF)', value: 'DJF' },
- { label: 'Dominican Peso (DOP)', value: 'DOP' },
- { label: 'Egyptian Pound (EGP)', value: 'EGP' },
- { label: 'El Salvador Colon (SVC)', value: 'SVC' },
- { label: 'Nakfa (ERN)', value: 'ERN' },
- { label: 'Ethiopian Birr (ETB)', value: 'ETB' },
- { label: 'Falkland Islands Pound (FKP)', value: 'FKP' },
- { label: 'Fiji Dollar (FJD)', value: 'FJD' },
- { label: 'CFP Franc (XPF)', value: 'XPF' },
- { label: 'Dalasi (GMD)', value: 'GMD' },
- { label: 'Lari (GEL)', value: 'GEL' },
- { label: 'Ghana Cedi (GHS)', value: 'GHS' },
- { label: 'Gibraltar Pound (GIP)', value: 'GIP' },
- { label: 'Quetzal (GTQ)', value: 'GTQ' },
- { label: 'Guinean Franc (GNF)', value: 'GNF' },
- { label: 'Guyana Dollar (GYD)', value: 'GYD' },
- { label: 'Gourde (HTG)', value: 'HTG' },
- { label: 'Lempira (HNL)', value: 'HNL' },
- { label: 'Hong Kong Dollar (HKD)', value: 'HKD' },
- { label: 'Forint (HUF)', value: 'HUF' },
- { label: 'Iceland Krona (ISK)', value: 'ISK' },
- { label: 'Indian Rupee (INR)', value: 'INR' },
- { label: 'Rupiah (IDR)', value: 'IDR' },
- { label: 'SDR (Special Drawing Right) (XDR)', value: 'XDR' },
- { label: 'Iranian Rial (IRR)', value: 'IRR' },
- { label: 'Iraqi Dinar (IQD)', value: 'IQD' },
- { label: 'New Israeli Sheqel (ILS)', value: 'ILS' },
- { label: 'Jamaican Dollar (JMD)', value: 'JMD' },
- { label: 'Yen (JPY)', value: 'JPY' },
- { label: 'Jordanian Dinar (JOD)', value: 'JOD' },
- { label: 'Tenge (KZT)', value: 'KZT' },
- { label: 'Kenyan Shilling (KES)', value: 'KES' },
- { label: 'North Korean Won (KPW)', value: 'KPW' },
- { label: 'Won (KRW)', value: 'KRW' },
- { label: 'Kuwaiti Dinar (KWD)', value: 'KWD' },
- { label: 'Som (KGS)', value: 'KGS' },
- { label: 'Lao Kip (LAK)', value: 'LAK' },
- { label: 'Lebanese Pound (LBP)', value: 'LBP' },
- { label: 'Loti (LSL)', value: 'LSL' },
- { label: 'Rand (ZAR)', value: 'ZAR' },
- { label: 'Liberian Dollar (LRD)', value: 'LRD' },
- { label: 'Libyan Dinar (LYD)', value: 'LYD' },
- { label: 'Swiss Franc (CHF)', value: 'CHF' },
- { label: 'Pataca (MOP)', value: 'MOP' },
- { label: 'Denar (MKD)', value: 'MKD' },
- { label: 'Malagasy Ariary (MGA)', value: 'MGA' },
- { label: 'Malawi Kwacha (MWK)', value: 'MWK' },
- { label: 'Malaysian Ringgit (MYR)', value: 'MYR' },
- { label: 'Rufiyaa (MVR)', value: 'MVR' },
- { label: 'Ouguiya (MRU)', value: 'MRU' },
- { label: 'Mauritius Rupee (MUR)', value: 'MUR' },
- { label: 'ADB Unit of Account (XUA)', value: 'XUA' },
- { label: 'Mexican Peso (MXN)', value: 'MXN' },
- { label: 'Mexican Unidad de Inversion (UDI) (MXV)', value: 'MXV' },
- { label: 'Moldovan Leu (MDL)', value: 'MDL' },
- { label: 'Tugrik (MNT)', value: 'MNT' },
- { label: 'Moroccan Dirham (MAD)', value: 'MAD' },
- { label: 'Mozambique Metical (MZN)', value: 'MZN' },
- { label: 'Kyat (MMK)', value: 'MMK' },
- { label: 'Namibia Dollar (NAD)', value: 'NAD' },
- { label: 'Nepalese Rupee (NPR)', value: 'NPR' },
- { label: 'Cordoba Oro (NIO)', value: 'NIO' },
- { label: 'Naira (NGN)', value: 'NGN' },
- { label: 'Rial Omani (OMR)', value: 'OMR' },
- { label: 'Pakistan Rupee (PKR)', value: 'PKR' },
- { label: 'Balboa (PAB)', value: 'PAB' },
- { label: 'Kina (PGK)', value: 'PGK' },
- { label: 'Guarani (PYG)', value: 'PYG' },
- { label: 'Sol (PEN)', value: 'PEN' },
- { label: 'Philippine Peso (PHP)', value: 'PHP' },
- { label: 'Zloty (PLN)', value: 'PLN' },
- { label: 'Qatari Rial (QAR)', value: 'QAR' },
- { label: 'Romanian Leu (RON)', value: 'RON' },
- { label: 'Russian Ruble (RUB)', value: 'RUB' },
- { label: 'Rwanda Franc (RWF)', value: 'RWF' },
- { label: 'Saint Helena Pound (SHP)', value: 'SHP' },
- { label: 'Tala (WST)', value: 'WST' },
- { label: 'Dobra (STN)', value: 'STN' },
- { label: 'Saudi Riyal (SAR)', value: 'SAR' },
- { label: 'Serbian Dinar (RSD)', value: 'RSD' },
- { label: 'Seychelles Rupee (SCR)', value: 'SCR' },
- { label: 'Leone (SLL)', value: 'SLL' },
- { label: 'Singapore Dollar (SGD)', value: 'SGD' },
- { label: 'Sucre (XSU)', value: 'XSU' },
- { label: 'Solomon Islands Dollar (SBD)', value: 'SBD' },
- { label: 'Somali Shilling (SOS)', value: 'SOS' },
- { label: 'South Sudanese Pound (SSP)', value: 'SSP' },
- { label: 'Sri Lanka Rupee (LKR)', value: 'LKR' },
- { label: 'Sudanese Pound (SDG)', value: 'SDG' },
- { label: 'Surinam Dollar (SRD)', value: 'SRD' },
- { label: 'Lilangeni (SZL)', value: 'SZL' },
- { label: 'Swedish Krona (SEK)', value: 'SEK' },
- { label: 'WIR Euro (CHE)', value: 'CHE' },
- { label: 'WIR Franc (CHW)', value: 'CHW' },
- { label: 'Syrian Pound (SYP)', value: 'SYP' },
- { label: 'New Taiwan Dollar (TWD)', value: 'TWD' },
- { label: 'Somoni (TJS)', value: 'TJS' },
- { label: 'Tanzanian Shilling (TZS)', value: 'TZS' },
- { label: 'Baht (THB)', value: 'THB' },
- { label: 'Pa’anga (TOP)', value: 'TOP' },
- { label: 'Trinidad and Tobago Dollar (TTD)', value: 'TTD' },
- { label: 'Tunisian Dinar (TND)', value: 'TND' },
- { label: 'Turkish Lira (TRY)', value: 'TRY' },
- { label: 'Turkmenistan New Manat (TMT)', value: 'TMT' },
- { label: 'Uganda Shilling (UGX)', value: 'UGX' },
- { label: 'Hryvnia (UAH)', value: 'UAH' },
- { label: 'UAE Dirham (AED)', value: 'AED' },
- { label: 'US Dollar (Next day) (USN)', value: 'USN' },
- { label: 'Peso Uruguayo (UYU)', value: 'UYU' },
- { label: 'Uruguay Peso en Unidades Indexadas (UYI)', value: 'UYI' },
- { label: 'Unidad Previsional (UYW)', value: 'UYW' },
- { label: 'Uzbekistan Sum (UZS)', value: 'UZS' },
- { label: 'Vatu (VUV)', value: 'VUV' },
- { label: 'Bolívar Soberano (VES)', value: 'VES' },
- { label: 'Dong (VND)', value: 'VND' },
- { label: 'Yemeni Rial (YER)', value: 'YER' },
- { label: 'Zambian Kwacha (ZMW)', value: 'ZMW' },
- { label: 'Zimbabwe Dollar (ZWL),', value: 'ZWL' }
- ]
- }
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/editForm/Currency.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/editForm/Currency.edit.display.js
deleted file mode 100644
index f5fce37c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/editForm/Currency.edit.display.js
+++ /dev/null
@@ -1,34 +0,0 @@
-export default [
- {
- key: 'inputMask',
- ignore: true
- },
- {
- key: 'allowMultipleMasks',
- ignore: true
- },
- {
- key: 'showWordCount',
- ignore: true
- },
- {
- key: 'showCharCount',
- ignore: true
- },
- {
- type: 'textfield',
- input: true,
- weight: 310,
- key: 'prefix',
- label: 'prefix',
- tooltip: 'Specify the prefix symbol after the component (e.g.: USD, EUR)'
- },
- {
- type: 'textfield',
- input: true,
- weight: 320,
- key: 'suffix',
- label: 'suffix',
- tooltip: 'Specify the suffix symbol after the component (e.g.: USD, EUR).'
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp1.js
deleted file mode 100644
index f94ca6d3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp1.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- 'input': true,
- 'tableView': true,
- 'inputType': 'text',
- 'inputMask': '',
- 'label': 'Money',
- 'key': 'money',
- 'placeholder': '',
- 'prefix': '$',
- 'suffix': 'USD',
- 'defaultValue': '',
- 'protected': false,
- 'persistent': true,
- 'clearOnHide': true,
- 'validate': {
- 'required': false,
- 'multiple': '',
- 'custom': ''
- },
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'type': 'currency',
- 'requireDecimal': true,
- 'delimiter': true,
- 'tags': [
-
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp2.js
deleted file mode 100644
index 0254f68e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp2.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default {
- 'label': 'Currency',
- 'mask': false,
- 'spellcheck': true,
- 'tableView': false,
- 'multiple': true,
- 'currency': 'USD',
- 'inputFormat': 'plain',
- 'calculateServer': false,
- 'validate': {
- 'multiple': true
- },
- 'key': 'currency',
- 'type': 'currency',
- 'input': true,
- 'delimiter': true,
- 'defaultValue': [null]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp3.js
deleted file mode 100644
index 8a380d89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp3.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export default {
- 'label': 'Currency',
- 'mask': false,
- 'spellcheck': true,
- 'tableView': false,
- 'currency': 'USD',
- 'inputFormat': 'plain',
- 'key': 'currency',
- 'type': 'currency',
- 'input': true,
- 'delimiter': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp4.js
deleted file mode 100644
index 44f7245c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/comp4.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default {
- label: 'Currency',
- mask: false,
- spellcheck: true,
- tableView: false,
- modalEdit: true,
- multiple: true,
- currency: 'USD',
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- key: 'currency',
- type: 'currency',
- input: true,
- delimiter: true,
- defaultValue: [
- null
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/index.js
deleted file mode 100644
index 6664cb89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/values.js
deleted file mode 100644
index f284c117..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/currency/fixtures/values.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- 1.00,
- 2.31,
- 1000.00,
- 123456.78,
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.form.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.form.js
deleted file mode 100644
index 6e721867..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.form.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import Components from '../Components';
-import DataGridEditData from './editForm/DataGrid.edit.data';
-import DataGridEditDisplay from './editForm/DataGrid.edit.display';
-import DataGridEditValidation from './editForm/DataGrid.edit.validation';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: DataGridEditDisplay
- },
- {
- key: 'data',
- components: DataGridEditData
- },
- {
- key: 'validation',
- components: DataGridEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.js
deleted file mode 100644
index ae21e5f8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.js
+++ /dev/null
@@ -1,784 +0,0 @@
-import _ from 'lodash';
-import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
-import { fastCloneDeep, getFocusableElements } from '../../utils/utils';
-
-let dragula;
-if (typeof window !== 'undefined') {
- // Import from "dist" because it would require and "global" would not be defined in Angular apps.
- dragula = require('dragula/dist/dragula');
-}
-
-export default class DataGridComponent extends NestedArrayComponent {
- static schema(...extend) {
- return NestedArrayComponent.schema({
- label: 'Data Grid',
- key: 'dataGrid',
- type: 'datagrid',
- clearOnHide: true,
- input: true,
- tree: true,
- components: []
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Data Grid',
- icon: 'th',
- group: 'data',
- documentation: '/userguide/form-building/data-components#data-grid',
- showPreview: false,
- weight: 30,
- schema: DataGridComponent.schema()
- };
- }
-
- constructor(...args) {
- super(...args);
- this.type = 'datagrid';
- this.tabIndex = 0;
- }
-
- init() {
- this.components = this.components || [];
-
- // Add new values based on minLength.
- this.rows = [];
- this.columns = [...this.component.components];
-
- if (this.initRows || !_.isEqual(this.dataValue, this.emptyValue)) {
- this.createRows(true);
- }
-
- this.visibleColumns = {};
- this.prevHasAddButton = this.hasAddButton();
- this.checkColumns();
- }
-
- get dataValue() {
- const dataValue = super.dataValue;
- if (!dataValue || !Array.isArray(dataValue)) {
- return this.emptyValue;
- }
- return dataValue;
- }
-
- set dataValue(value) {
- super.dataValue = value;
- }
-
- get defaultSchema() {
- return DataGridComponent.schema();
- }
-
- get initEmpty() {
- return this.component.initEmpty || this.component.noFirstRow;
- }
-
- get initRows() {
- return this.builderMode || this.path === 'defaultValue' || !this.initEmpty;
- }
-
- get emptyValue() {
- return this.initEmpty ? [] : [{}];
- }
-
- get addAnotherPosition() {
- return _.get(this.component, 'addAnotherPosition', 'bottom');
- }
-
- get minLength() {
- if (this.hasRowGroups()) {
- return _.sum(this.getGroupSizes());
- }
- else {
- return _.get(this.component, 'validate.minLength', 0);
- }
- }
-
- get defaultValue() {
- const isBuilderMode = this.builderMode;
- const isEmptyInit = this.initEmpty;
- // Ensure we have one and only one row in builder mode.
- if (isBuilderMode || (isEmptyInit && !this.dataValue.length)) {
- return isEmptyInit && !isBuilderMode ? [] : [{}];
- }
-
- const value = super.defaultValue;
- let defaultValue;
-
- if (Array.isArray(value)) {
- defaultValue = value;
- }
- else if (value && (typeof value === 'object')) {
- defaultValue = [value];
- }
- else {
- defaultValue = this.emptyValue;
- }
-
- for (let dIndex = defaultValue.length; dIndex < this.minLength; dIndex++) {
- defaultValue.push({});
- }
-
- return defaultValue;
- }
-
- set disabled(disabled) {
- super.disabled = disabled;
- _.each(this.refs[`${this.datagridKey}-addRow`], (button) => {
- button.disabled = disabled;
- });
- _.each(this.refs[`${this.datagridKey}-removeRow`], (button) => {
- button.disabled = disabled;
- });
- }
-
- get disabled() {
- return super.disabled;
- }
-
- get datagridKey() {
- return `datagrid-${this.key}`;
- }
-
- get allowReorder() {
- return !this.options.readOnly && _.get(this.component, 'reorder', false);
- }
-
- get iteratableRows() {
- return this.rows.map((row, index) => ({
- components: row,
- data: this.dataValue[index],
- }));
- }
-
- isEmpty(value = this.dataValue) {
- const isEmpty = super.isEmpty(value);
-
- if (this.components?.length) {
- return this.components.reduce((isEmpty, component) => {
- return isEmpty && component.isEmpty();
- }, true);
- }
-
- return isEmpty;
- }
-
- /**
- * Split rows into chunks.
- * @param {Number[]} groups - array of numbers where each item is size of group
- * @param {Array} rows - rows collection
- * @return {Array}
- */
- getRowChunks(groups, rows) {
- const [, chunks] = groups.reduce(
- ([startIndex, acc], size) => {
- const endIndex = startIndex + size;
- return [endIndex, [...acc, [startIndex, endIndex]]];
- }, [0, []]
- );
- return chunks.map(range => _.slice(rows, ...range));
- }
-
- /**
- * Create groups object.
- * Each key in object represents index of first row in group.
- * @return {Object}
- */
- getGroups() {
- const groups = _.get(this.component, 'rowGroups', []);
- const sizes = _.map(groups, 'numberOfRows').slice(0, -1);
- const indexes = sizes.reduce((groupIndexes, size) => {
- const last = groupIndexes[groupIndexes.length - 1];
- return groupIndexes.concat(last + size);
- }, [0]);
-
- return groups.reduce(
- (gidxs, group, idx) => {
- return {
- ...gidxs,
- [indexes[idx]]: group
- };
- },
- {}
- );
- }
-
- /**
- * Retrun group sizes.
- * @return {Number[]}
- */
- getGroupSizes() {
- return _.map(_.get(this.component, 'rowGroups', []), 'numberOfRows');
- }
-
- hasRowGroups() {
- return _.get(this, 'component.enableRowGroups', false) && !this.builderMode;
- }
-
- totalRowsNumber(groups) {
- return _.sum(_.map(groups, 'numberOfRows'));
- }
-
- setStaticValue(n) {
- this.dataValue = _.range(n).map(() => ({}));
- }
-
- hasExtraColumn() {
- return (this.hasRemoveButtons() || this.canAddColumn);
- }
-
- hasRemoveButtons() {
- return !this.builderMode && !this.component.disableAddingRemovingRows &&
- !this.options.readOnly &&
- !this.disabled &&
- this.fullMode &&
- (this.dataValue.length > _.get(this.component, 'validate.minLength', 0));
- }
-
- hasTopSubmit() {
- return this.hasAddButton() && ['top', 'both'].includes(this.addAnotherPosition);
- }
-
- hasBottomSubmit() {
- return this.hasAddButton() && ['bottom', 'both'].includes(this.addAnotherPosition);
- }
-
- get canAddColumn() {
- return this.builderMode;
- }
-
- render() {
- const columns = this.getColumns();
- let columnExtra = 0;
- const hasRemoveButtons = this.hasRemoveButtons();
- if (this.component.reorder) {
- columnExtra++;
- }
- if (hasRemoveButtons) {
- columnExtra++;
- }
- if (this.canAddColumn) {
- columnExtra++;
- }
- const colWidth = Math.floor(12 / (columns.length + columnExtra));
- return super.render(this.renderTemplate('datagrid', {
- rows: this.getRows(),
- columns: columns,
- groups: this.hasRowGroups() ? this.getGroups() : [],
- visibleColumns: this.visibleColumns,
- hasToggle: _.get(this, 'component.groupToggle', false),
- hasHeader: this.hasHeader(),
- hasExtraColumn: this.hasExtraColumn(),
- hasAddButton: this.hasAddButton(),
- hasRemoveButtons,
- hasTopSubmit: this.hasTopSubmit(),
- hasBottomSubmit: this.hasBottomSubmit(),
- hasGroups: this.hasRowGroups(),
- numColumns: columns.length + (this.hasExtraColumn() ? 1 : 0),
- datagridKey: this.datagridKey,
- allowReorder: this.allowReorder,
- builder: this.builderMode,
- canAddColumn: this.canAddColumn,
- tabIndex: this.tabIndex,
- placeholder: this.renderTemplate('builderPlaceholder', {
- position: this.componentComponents.length,
- }),
- colWidth: colWidth.toString()
- }));
- }
-
- getRows() {
- return this.rows.map(row => {
- const components = {};
- _.each(row, (col, key) => {
- components[key] = col.render();
- });
- return components;
- });
- }
-
- getColumns() {
- return this.columns.filter((comp) => {
- return (!this.visibleColumns.hasOwnProperty(comp.key) || this.visibleColumns[comp.key]);
- });
- }
-
- hasHeader() {
- return this.component.components.reduce((hasHeader, col) => {
- // If any of the components has a title and it isn't hidden, display the header.
- return hasHeader || ((col.label || col.title) && !col.hideLabel);
- }, false);
- }
-
- loadRefs(element, refs) {
- super.loadRefs(element, refs);
-
- if (refs['messageContainer'] === 'single') {
- const container = _.last(element.querySelectorAll('[ref=messageContainer]'));
- this.refs['messageContainer'] = container || this.refs['messageContainer'];
- }
- }
-
- attach(element) {
- this.loadRefs(element, {
- [`${this.datagridKey}-row`]: 'multiple',
- [`${this.datagridKey}-tbody`]: 'single',
- [`${this.datagridKey}-addRow`]: 'multiple',
- [`${this.datagridKey}-removeRow`]: 'multiple',
- [`${this.datagridKey}-group-header`]: 'multiple',
- [this.datagridKey]: 'multiple',
- 'messageContainer': 'single'
- });
-
- if (this.allowReorder) {
- this.refs[`${this.datagridKey}-row`].forEach((row, index) => {
- row.dragInfo = { index };
- });
-
- if (dragula) {
- this.dragula = dragula([this.refs[`${this.datagridKey}-tbody`]], {
- moves: (_draggedElement, _oldParent, clickedElement) => {
- const clickedElementKey = clickedElement.getAttribute('data-key');
- const oldParentKey = _oldParent.getAttribute('data-key');
-
- //Check if the clicked button belongs to that container, if false, it belongs to the nested container
- if (oldParentKey === clickedElementKey) {
- return clickedElement.classList.contains('formio-drag-button');
- }
- }
- }).on('drop', this.onReorder.bind(this));
-
- this.dragula.on('cloned', (el, original) => {
- if (el && el.children && original && original.children) {
- _.each(original.children, (child, index) => {
- const styles = getComputedStyle(child, null);
-
- if (styles.cssText !== '') {
- el.children[index].style.cssText = styles.cssText;
- }
- else {
- const cssText = Object.values(styles).reduce(
- (css, propertyName) => {
- return `${css}${propertyName}:${styles.getPropertyValue(
- propertyName
- )};`;
- },
- ''
- );
-
- el.children[index].style.cssText = cssText;
- }
- });
- }
- });
- }
- }
-
- this.refs[`${this.datagridKey}-addRow`].forEach((addButton) => {
- this.addEventListener(addButton, 'click', this.addRow.bind(this));
- });
-
- this.refs[`${this.datagridKey}-removeRow`].forEach((removeButton, index) => {
- this.addEventListener(removeButton, 'click', this.removeRow.bind(this, index));
- });
-
- if (this.hasRowGroups()) {
- this.refs.chunks = this.getRowChunks(this.getGroupSizes(), this.refs[`${this.datagridKey}-row`]);
- this.refs[`${this.datagridKey}-group-header`].forEach((header, index) => {
- this.addEventListener(header, 'click', () => this.toggleGroup(header, index));
- });
- }
-
- const columns = this.getColumns();
- const rowLength = columns.length;
- this.rows.forEach((row, rowIndex) => {
- let columnIndex = 0;
- columns.forEach((col) => {
- this.attachComponents(
- this.refs[this.datagridKey][(rowIndex * rowLength) + columnIndex],
- [this.rows[rowIndex][col.key]],
- this.getComponentsContainer(),
- );
- columnIndex++;
- });
- });
- return super.attach(element);
- }
-
- getComponentsContainer() {
- return this.component.components;
- }
-
- onReorder(element, _target, _source, sibling) {
- if (!element.dragInfo || (sibling && !sibling.dragInfo)) {
- console.warn('There is no Drag Info available for either dragged or sibling element');
- return;
- }
-
- const oldPosition = element.dragInfo.index;
- //should drop at next sibling position; no next sibling means drop to last position
- const newPosition = sibling ? sibling.dragInfo.index : this.dataValue.length;
- const movedBelow = newPosition > oldPosition;
- const dataValue = fastCloneDeep(this.dataValue);
- const draggedRowData = dataValue[oldPosition];
-
- //insert element at new position
- dataValue.splice(newPosition, 0, draggedRowData);
- //remove element from old position (if was moved above, after insertion it's at +1 index)
- dataValue.splice(movedBelow ? oldPosition : oldPosition + 1, 1);
-
- //need to re-build rows to re-calculate indexes and other indexed fields for component instance (like rows for ex.)
- this.setValue(dataValue, { isReordered: true });
- this.rebuild();
- }
-
- focusOnNewRowElement(row) {
- Object.keys(row).find((key) => {
- const element = row[key].element;
- if (element) {
- const focusableElements = getFocusableElements(element);
- if (focusableElements && focusableElements[0]) {
- focusableElements[0].focus();
- return true;
- }
- }
- return false;
- });
- }
-
- addRow() {
- const index = this.rows.length;
-
- // Handle length mismatch between rows and dataValue
- if (this.dataValue.length === index) {
- this.dataValue.push({});
- }
-
- let row;
- const dataValue = this.dataValue;
- const defaultValue = this.defaultValue;
-
- if (this.initEmpty && defaultValue[index]) {
- row = defaultValue[index];
- dataValue[index] = row;
- }
- else {
- row = dataValue[index];
- }
-
- this.rows[index] = this.createRowComponents(row, index);
- this.emit('dataGridAddRow', {
- component: this.component,
- row
- });
- this.checkConditions();
- this.triggerChange();
- this.redraw().then(() => {
- this.focusOnNewRowElement(this.rows[index]);
- });
- }
-
- updateComponentsRowIndex(components, rowIndex) {
- components.forEach((component, colIndex) => {
- if (component.options?.name) {
- const newName = `[${this.key}][${rowIndex}]`;
- component.options.name = component.options.name.replace(`[${this.key}][${component.rowIndex}]`, newName);
- }
- component.rowIndex = rowIndex;
- component.row = `${rowIndex}-${colIndex}`;
- component.path = this.calculateComponentPath(component);
- });
- }
-
- updateRowsComponents(rowIndex) {
- this.rows.slice(rowIndex).forEach((row, index) => {
- this.updateComponentsRowIndex(Object.values(row), rowIndex + index);
- });
- }
-
- removeRow(index) {
- const makeEmpty = index === 0 && this.rows.length === 1;
- const flags = { isReordered: !makeEmpty, resetValue: makeEmpty };
- this.splice(index, flags);
- this.emit('dataGridDeleteRow', { index });
- const [row] = this.rows.splice(index, 1);
- this.removeRowComponents(row);
- this.updateRowsComponents(index);
- this.setValue(this.dataValue, flags);
- this.redraw();
- }
-
- removeRowComponents(row) {
- _.each(row, (component) => this.removeComponent(component));
- }
-
- getRowValues() {
- return this.dataValue;
- }
-
- setRowComponentsData(rowIndex, rowData) {
- _.each(this.rows[rowIndex], (component) => {
- component.data = rowData;
- });
- }
-
- createRows(init, rebuild) {
- let added = false;
- const rowValues = this.getRowValues();
- // Create any missing rows.
- rowValues.forEach((row, index) => {
- if (!rebuild && this.rows[index]) {
- this.setRowComponentsData(index, row);
- }
- else {
- if (this.rows[index]) {
- this.removeRowComponents(this.rows[index]);
- }
- this.rows[index] = this.createRowComponents(row, index);
- added = true;
- }
- });
- // Delete any extra rows.
- const removedRows = this.rows.splice(rowValues.length);
- const removed = !!removedRows.length;
- // Delete components of extra rows (to make sure that this.components contain only components of exisiting rows)
- if (removed) {
- removedRows.forEach(row => this.removeRowComponents(row));
- }
-
- if (!init && (added || removed)) {
- this.redraw();
- }
- return added;
- }
-
- createRowComponents(row, rowIndex) {
- const components = {};
- this.tabIndex = 0;
- this.component.components.map((col, colIndex) => {
- const options = _.clone(this.options);
- options.name += `[${rowIndex}]`;
- options.row = `${rowIndex}-${colIndex}`;
-
- let columnComponent;
-
- if (this.builderMode) {
- col.id = col.id + rowIndex;
- columnComponent = col;
- }
- else {
- columnComponent = { ...col, id: (col.id + rowIndex) };
- }
-
- const component = this.createComponent(columnComponent, options, row);
- component.parentDisabled = !!this.disabled;
- component.rowIndex = rowIndex;
- component.inDataGrid = true;
- if (
- columnComponent.tabindex &&
- parseInt(columnComponent.tabindex) > this.tabIndex
- ) {
- this.tabIndex = parseInt(columnComponent.tabindex);
- }
- components[col.key] = component;
- });
- return components;
- }
-
- /**
- * Checks the validity of this datagrid.
- *
- * @param data
- * @param dirty
- * @return {*}
- */
- checkValidity(data, dirty, row, silentCheck) {
- data = data || this.rootValue;
- row = row || this.data;
-
- if (!this.checkCondition(row, data)) {
- this.setCustomValidity('');
- return true;
- }
-
- if (!this.checkComponentValidity(data, dirty, row, { silentCheck })) {
- return false;
- }
-
- const isValid = this.checkRows('checkValidity', data, dirty, true, silentCheck);
-
- this.checkModal(isValid, dirty);
-
- return isValid;
- }
-
- checkColumns(data, flags = {}) {
- data = data || this.rootValue;
- let show = false;
-
- if (!this.rows || !this.rows.length) {
- return { rebuild: false, show: false };
- }
-
- if (this.builderMode) {
- return { rebuild: false, show: true };
- }
-
- const visibility = {};
-
- let logicRebuild = false;
-
- const dataValue = this.dataValue;
- this.rows.forEach((row, rowIndex) => {
- _.each(row, (col, key) => {
- if (col && (typeof col.checkConditions === 'function')) {
- const firstRowCheck = visibility[key] === undefined;
- visibility[key] = !!visibility[key] ||
- (col.checkConditions(data, flags, dataValue[rowIndex]) && col.type !== 'hidden');
-
- if (col.component.logic && firstRowCheck) {
- const compIndex = _.findIndex(this.columns, ['key', key]);
- if (!_.isEqual(this.columns[compIndex], col.component)) {
- logicRebuild = true;
- this.columns[compIndex] = col.component;
- }
- }
- }
- });
- });
- const rebuild = !_.isEqual(visibility, this.visibleColumns) || logicRebuild;
- _.each(visibility, (col) => {
- show |= col;
- });
-
- this.visibleColumns = visibility;
- return { rebuild, show };
- }
-
- checkComponentConditions(data, flags, row) {
- const isVisible = this.visible;
- // If table isn't visible, don't bother calculating columns.
- if (!super.checkComponentConditions(data, flags, row)) {
- return false;
- }
-
- const { rebuild, show } = this.checkColumns(data, flags);
- // Check if a rebuild is needed or the visibility changes.
- if (rebuild || !isVisible) {
- this.createRows(false, rebuild);
- }
-
- // Return if this table should show.
- return show;
- }
-
- setValue(value, flags = {}) {
- if (!value) {
- this.dataValue = this.defaultValue;
- this.createRows();
- return false;
- }
- if (!Array.isArray(value)) {
- if (typeof value === 'object') {
- value = [value];
- }
- else {
- this.createRows();
- value = [{}];
- }
- }
-
- // Make sure we always have at least one row.
- // NOTE: Removing this will break "Public Configurations" in portal. ;)
- if (value && !value.length && !this.initEmpty) {
- value.push({});
- }
- const isSettingSubmission = flags.fromSubmission && !_.isEqual(value, this.emptyValue);
- const changed = this.hasChanged(value, this.dataValue);
-
- this.dataValue = value;
-
- if (this.initRows || isSettingSubmission) {
- if (!this.createRows() && changed) {
- this.redraw();
- }
- }
-
- if (this.componentModal && isSettingSubmission) {
- this.componentModal.setValue(value);
- }
-
- this.rows.forEach((row, rowIndex) => {
- if (value.length <= rowIndex) {
- return;
- }
- _.each(row, (col) => {
- col.rowIndex = rowIndex;
- this.setNestedValue(col, value[rowIndex], flags);
- });
- });
-
- this.updateOnChange(flags, changed);
- return changed;
- }
-
- restoreComponentsContext() {
- this.rows.forEach((row, index) => _.forIn(row, (component) => component.data = this.dataValue[index]));
- }
-
- getComponent(path, fn) {
- path = Array.isArray(path) ? path : [path];
- const [key, ...remainingPath] = path;
- let result = [];
- if (_.isNumber(key) && remainingPath.length) {
- const compKey = remainingPath.pop();
- result = this.rows[key][compKey];
- // If the component is inside a Layout Component, try to find it among all the row's components
- if (!result) {
- Object.entries(this.rows[key]).forEach(([, comp]) => {
- if ('getComponent' in comp) {
- const possibleResult = comp.getComponent([compKey], fn);
- if (possibleResult) {
- result = possibleResult;
- }
- }
- });
- }
- if (result && _.isFunction(fn)) {
- fn(result, this.getComponents());
- }
- if (remainingPath.length && 'getComponent' in result) {
- return result.getComponent(remainingPath, fn);
- }
- return result;
- }
- if (!_.isString(key)) {
- return result;
- }
-
- this.everyComponent((component, components) => {
- if (component.component.key === key) {
- let comp = component;
- if (remainingPath.length > 0 && 'getComponent' in component) {
- comp = component.getComponent(remainingPath, fn);
- }
- else if (fn) {
- fn(component, components);
- }
-
- result = result.concat(comp);
- }
- });
-
- return result.length > 0 ? result : null;
- }
-
- toggleGroup(element, index) {
- element.classList.toggle('collapsed');
- _.each(this.refs.chunks[index], row => {
- row.classList.toggle('hidden');
- });
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.unit.js
deleted file mode 100644
index 254055a5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/DataGrid.unit.js
+++ /dev/null
@@ -1,568 +0,0 @@
-import _ from 'lodash';
-import assert from 'power-assert';
-import { expect } from 'chai';
-import sinon from 'sinon';
-import Harness from '../../../test/harness';
-import DataGridComponent from './DataGrid';
-import Formio from '../../Formio';
-
-import {
- comp1,
- comp2,
- comp3,
- comp4,
- comp5,
- comp6,
- comp7,
- comp8,
- withDefValue,
- withRowGroupsAndDefValue,
- modalWithRequiredFields,
- withConditionalFieldsAndValidations,
- withLogic,
- withCollapsibleRowGroups,
- withAllowCalculateOverride
-} from './fixtures';
-
-describe('DataGrid Component', () => {
- it('Test modal edit confirmation dialog', (done) => {
- Harness.testCreate(DataGridComponent, comp5).then((component) => {
- component.componentModal.openModal();
- const fakeEvent = {
- preventDefault: () => {}
- };
- component.componentModal.showDialogListener(fakeEvent);
- assert.equal(component.componentModal.isOpened, false, 'Should be closed without confirmation dialog since value was not changed');
- setTimeout(() => {
- component.componentModal.openModal();
- Harness.setInputValue(component, 'data[dataGrid][0][textField]', 'My Text');
- setTimeout(() => {
- component.componentModal.showDialogListener(fakeEvent);
- assert.equal(component.componentModal.isValueChanged(), true, 'Should return true since value was modified');
- assert.equal(component.componentModal.isOpened, true, 'Should stay opened and wait until user confirm closing without changes saving');
- assert(component.componentModal.dialog, 'Should open confirmation dialog');
- component.componentModal.closeDialog(fakeEvent);
- component.destroy();
- done();
- }, 100);
- }, 100);
- }).catch(done);
- });
-
- it(`Should show alert message in modal edit, when clicking on modal overlay and value was changed,
- and clear values when pushing 'yes, delete it' in alert container`, (done) => {
- Harness.testCreate(DataGridComponent, comp4).then((component) => {
- const hiddenModalWindow = component.element.querySelector('.component-rendering-hidden');
- assert.equal(!!hiddenModalWindow, true);
-
- const clickEvent = new Event('click');
- const openModalElement = component.refs.openModal;
- //open modal edit window
- openModalElement.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!component.element.querySelector('.component-rendering-hidden'), false);
-
- const inputEvent = new Event('input');
- const dataGridInputField = component.element.querySelector('[name="data[dataGrid][0][number]"]');
-
- dataGridInputField.value = 55555;
- //input value in dataGrid field inside modal edit window
- dataGridInputField.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(component.element.querySelector('[name="data[dataGrid][0][number]"]').value, '55555');
-
- const clickEvent = new Event('click');
- const modalOverlay = component.refs.modalOverlay;
- //click outside modal edit window
- modalOverlay.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!component.componentModal.dialog, true);
-
- const clickEvent = new Event('click');
- const btnForCleaningValues = document.querySelector('[ref="dialogYesButton"]');
- //click on 'yes, delete it' button inside alert window
- btnForCleaningValues.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const clickEvent = new Event('click');
- const openModalElement = component.refs.openModal;
- //open edit modal window again
- openModalElement.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal( component.element.querySelector('[name="data[dataGrid][0][number]"]').value, '');
- done();
- }, 350);
- }, 300);
- }, 250);
- }, 200);
- }, 150);
- });
- });
-
- it('Should build a data grid component', () => {
- return Harness.testCreate(DataGridComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 3);
- });
- });
-
- it('Should build a data grid component with formio-component-datagrid class property', done => {
- Harness.testCreate(DataGridComponent, comp6).then((component) => {
- const element = component.element.component.components[0].element;
- setTimeout(() => {
- assert.deepEqual(element.className.includes('formio-component-datagrid'), true);
- done();
- }, 200);
- }, done)
- .catch(done);
- });
-
- it('Should not skip validation on input nested components', done => {
- Harness.testCreate(DataGridComponent, comp1)
- .then(cmp => {
- expect(cmp.shouldSkipValidation()).to.be.false;
- done();
- }, done)
- .catch(done);
- });
-
- it('Should get and set values within the grid.', () => {
- return Harness.testCreate(DataGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- make: 'Jeep',
- model: 'Wrangler',
- year: 1997
- },
- {
- make: 'Chevy',
- model: 'Tahoe',
- year: 2014
- }
- ]);
- });
- });
-
- it('Should be able to add another row.', () => {
- return Harness.testCreate(DataGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- make: 'Jeep',
- model: 'Wrangler',
- year: 1997
- }
- ]);
- component.addRow();
- assert.deepEqual(component.getValue(), [
- {
- make: 'Jeep',
- model: 'Wrangler',
- year: 1997
- },
- {
- make: '',
- model: '',
- }
- ]);
- });
- });
-
- it('Should allow provide default value', function(done) {
- try {
- Harness.testCreate(DataGridComponent, withDefValue)
- .then((datagrid) => {
- expect(datagrid.getValue()).to.deep.equal([
- { name: 'Alex', age: 1 },
- { name: 'Bob', age: 2 },
- { name: 'Conny', age: 3 }
- ]);
- done();
- }, done)
- .catch(done);
- }
- catch (err) {
- done(err);
- }
- });
-
- it('Should allow provide default value in row-groups model', function(done) {
- try {
- Harness.testCreate(DataGridComponent, withRowGroupsAndDefValue)
- .then((datagrid) => {
- expect(datagrid.getValue()).to.deep.equal([
- { name: 'Alex', age: 1 },
- { name: 'Bob', age: 2 },
- { name: 'Conny', age: 3 },
- { name: '' },
- { name: '' }
- ]);
- done();
- }, done)
- .catch(done);
- }
- catch (err) {
- done(err);
- }
- });
-
- it('Should not cause setValue loops when logic within hidden component is set', function(done) {
- Formio.createForm(document.createElement('div'), withLogic)
- .then((form) => {
- const datagrid = form.getComponent('dataGrid');
- const spyFunc = sinon.spy(datagrid, 'checkComponentConditions');
- const textField = form.getComponent('escalationId');
- const select = form.getComponent('teamName');
-
- textField.component.hidden = true;
- select.setValue('preRiskAnalysis', { modified: true });
-
- setTimeout(() => {
- expect(spyFunc.callCount).to.be.lessThan(4);
- done();
- }, 1500);
- });
- });
-
- it('Should collapse group rows on group header click', (done) => {
- Formio.createForm(document.createElement('div'), withCollapsibleRowGroups)
- .then((form) => {
- const groupHeadersRefName= 'datagrid-dataGrid-group-header';
- const datagrid = form.getComponent('dataGrid');
- assert.equal(datagrid.refs[groupHeadersRefName][0]?.classList?.contains('collapsed'), false);
- assert.equal(datagrid.refs.chunks[0][0].classList?.contains('hidden'), false);
- assert.equal(datagrid.refs.chunks[0][1].classList?.contains('hidden'), false);
-
- const clickEvent = new Event('click');
- datagrid.refs[groupHeadersRefName][0].dispatchEvent(clickEvent);
- setTimeout(() => {
- const collapedGroupRows = datagrid.refs.chunks[0] || [];
- assert.equal(datagrid.refs[groupHeadersRefName][0]?.classList?.contains('collapsed'), true);
- assert.equal(collapedGroupRows[0]?.classList?.contains('hidden'), true);
- assert.equal(collapedGroupRows[1]?.classList?.contains('hidden'), true);
- done();
- }, 300);
- });
- });
-
- describe('get minLength', () => {
- it('should return minimal number of required rows', () => {
- const EIDV = 'Invalid default value';
- const EDFC = 'Differ from configured value';
- const EDFG = 'Differ from number of rows in groups';
- const base = { type: 'datagrid', key: 'testkey' };
- let schema = _.cloneDeep(base);
- let datagrid = new DataGridComponent(schema, {});
-
- expect(datagrid.minLength, EIDV).to.equal(0);
-
- schema = Object.assign(_.cloneDeep(base), { validate: { minLength: 5 } });
- datagrid = new DataGridComponent(schema, {});
- expect(datagrid.minLength, EDFC).to.equal(5);
-
- schema = Object.assign(_.cloneDeep(base), {
- enableRowGroups: true,
- rowGroups: [
- { label: 'H1', numberOfRows: 1 },
- { label: 'B2', numberOfRows: 3 },
- { label: 'C3', numberOfRows: 3 },
- { label: 'M4', numberOfRows: 2 }
- ]
- });
- datagrid = new DataGridComponent(schema, {});
- expect(datagrid.minLength, EDFG).to.equal(9);
-
- schema = Object.assign(_.cloneDeep(base), {
- validate: { minLength: 5 },
- enableRowGroups: true,
- rowGroups: [
- { label: 'H1', numberOfRows: 1 },
- { label: 'B2', numberOfRows: 3 },
- { label: 'C3', numberOfRows: 3 },
- { label: 'M4', numberOfRows: 2 }
- ]
- });
- datagrid = new DataGridComponent(schema, {});
- if (datagrid.minLength === 5) {
- expect.fail('Number of row should take precedence over config');
- }
- else {
- expect(datagrid.minLength, EDFG).to.equal(9);
- }
- });
- });
-
- describe('getGroupSizes', () => {
- it('should return array of numbers representing group sizes', () => {
- const { getGroupSizes } = DataGridComponent.prototype;
- let self = { component: {} };
-
- expect(getGroupSizes.call(self)).to.deep.equal([]);
-
- self = { component: {
- rowGroups: [{ numberOfRows: 1 }]
- } };
-
- expect(getGroupSizes.call(self)).to.deep.equal([1]);
-
- self = { component: {
- rowGroups: [{ numberOfRows: 1 }, { numberOfRows: 2 }]
- } };
-
- expect(getGroupSizes.call(self)).to.deep.equal([1, 2]);
-
- self = { component: {
- rowGroups: [{ numberOfRows: 1 }, { numberOfRows: 3 }, { numberOfRows: 10 }]
- } };
-
- expect(getGroupSizes.call(self)).to.deep.equal([1, 3, 10]);
- });
- });
-
- it('Test "components" property and their context', (done) => {
- const testComponentsData = (components, expectedData) => {
- components.forEach((comp) => assert.deepEqual(
- comp.data,
- expectedData,
- 'Data of components inside DataGrid should be equal to row\'s data'
- ));
- };
-
- Formio.createForm(document.createElement('div'), withConditionalFieldsAndValidations)
- .then((form) => {
- const rootText = form.getComponent(['text']);
- rootText.setValue('Match', { modified: true });
-
- setTimeout(() => {
- const emptyRowData = {
- rootTest: '',
- rowTest: ''
- };
- const dataGrid = form.getComponent(['dataGrid']);
-
- assert.equal(dataGrid.components.length, 6, 'DataGrid.components should contain 6 components');
- testComponentsData(dataGrid.components, emptyRowData);
-
- const showTextFieldInsideDataGridRadio = form.getComponent(['radio']);
- showTextFieldInsideDataGridRadio.setValue('show', { modified: true });
-
- setTimeout(() => {
- const rowData1 = { ...emptyRowData, radio1: '' };
- const dataGridRowRadio = form.getComponent(['dataGrid', 0, 'radio1']);
-
- assert.equal(dataGrid.components.length, 6, 'DataGrid.components should contain 6 components');
- testComponentsData(dataGrid.components, rowData1);
- assert.equal(dataGridRowRadio.visible, true, 'Radio inside DataGrid should become visible');
-
- dataGridRowRadio.setValue('dgShow', { modified: true });
-
- setTimeout(() => {
- const rowData2 = {
- ...emptyRowData,
- radio1: 'dgShow',
- rowShowShowTextfieldWhenDataGridRadioHasShowValue: ''
- };
- const dataGridRowConditionalField = form.getComponent(['dataGrid', 0, 'rowShowShowTextfieldWhenDataGridRadioHasShowValue']);
-
- assert.equal(dataGrid.components.length, 6, 'DataGrid.components should contain 6 components');
- testComponentsData(dataGrid.components, rowData2);
- assert.equal(dataGridRowConditionalField.visible, true, 'Conditional field inside DataGrid should become visible');
-
- const rootTest = form.getComponent(['dataGrid', 0, 'rootTest']);
- const rowTest = form.getComponent(['dataGrid', 0, 'rowTest']);
-
- rootTest.setValue('Match', { modified: true });
- rowTest.setValue('Match', { modified: true });
-
- setTimeout(() => {
- const rowData3 = {
- ...rowData2,
- rowTest: 'Match',
- rootTest: 'Match'
- };
-
- assert.equal(dataGrid.components.length, 6, 'DataGrid.components should contain 6 components');
- testComponentsData(dataGrid.components, rowData3);
-
- form.checkAsyncValidity(null, true).then((valid) => {
- assert(valid, 'Form should be valid');
- done();
- }).catch(done);
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- })
- .catch(done);
- });
-});
-
-describe('DataGrid Panels', () => {
- it('Should build a data grid component', () => {
- return Harness.testCreate(DataGridComponent, comp2);
- });
-
- it('Should be able to set the values of one panel in the DataGrid.', () => {
- return Harness.testCreate(DataGridComponent, comp2).then((component) => {
- Harness.testSetGet(component, [
- {
- firstName: 'Joe',
- lastName: 'Smith'
- }
- ]);
-
- // Now add a new row.
- component.addRow();
- assert.deepEqual(component.getValue(), [
- {
- firstName: 'Joe',
- lastName: 'Smith'
- },
- {
- firstName: '',
- lastName: ''
- }
- ]);
- });
- });
-
- // Comp 7 Test
- it('Should have unique IDs inside data grid', () => {
- return Harness.testCreate(DataGridComponent, comp7).then((component) => {
- component.addRow();
- const idArr = [];
- component.components.forEach((row, i) => {
- idArr[i] = row.element.component.components[0].id;
- });
- assert.equal(idArr[0] !== idArr[1], true);
- });
- });
-
- it('Should hide label in header for Button component when hideLabel is true.', () => {
- const formElement = document.createElement('div');
- return Formio.createForm(formElement, {
- display: 'form',
- components: [comp8]
- })
- .then(() => {
- assert.equal(formElement.getElementsByTagName('th')[0].textContent.trim(), '', 'Should hide a label');
- assert.equal(formElement.getElementsByTagName('th')[1].textContent.trim(), 'Text Field', 'Should show a label');
- });
- });
-});
-
-describe('DataGrid disabling', () => {
- it('Child components should be disabled', () => {
- return Harness.testCreate(DataGridComponent, comp3).then((component) => {
- assert.equal(component.components.reduce((acc, child) => acc && child.parentDisabled, true), true);
- });
- });
-});
-
-describe('DataGrid modal', () => {
- it('Should be highlighted in red when invalid', (done) => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, {
- display: 'form',
- components: [modalWithRequiredFields]
- })
- .then((form) => {
- const data = {
- dataGrid: [
- {
- textField: '',
- textArea: ''
- }
- ]
- };
-
- form.checkValidity(data, true, data);
-
- setTimeout(() => {
- Harness.testModalWrapperErrorClasses(form);
-
- const validData = {
- dataGrid: [
- {
- textField: 'Some text',
- textArea: 'Mre text'
- }
- ]
- };
-
- form.setSubmission({ data: validData });
-
- setTimeout(() => {
- Harness.testModalWrapperErrorClasses(form, false);
- done();
- }, 200);
- }, 200);
- })
- .catch(done);
- });
-});
-
-describe('DataGrid calculated values', () => {
- it('Should allow override calculated value', (done) => {
- Formio.createForm(document.createElement('div'), withAllowCalculateOverride)
- .then((form) => {
- const select = form.getComponent('select');
- const dataGrid = form.getComponent('dataGrid');
-
- assert.deepEqual(dataGrid.getValue(),
- [{
- firstName: 'initial 1',
- lastName: 'initial 2'
- },
- {
- firstName: 'initial 1b',
- lastName: 'initial 2b'
- }]
- );
-
- select.setValue('a', { modified: true });
- setTimeout(() => {
- assert.deepEqual(dataGrid.getValue(),
- [{
- firstName: 'A f 1',
- lastName: 'A l 1'
- }]
- );
-
- select.setValue('b', { modified: true });
- setTimeout(() => {
- assert.deepEqual(dataGrid.getValue(),
- [{
- firstName: 'B f 1',
- lastName: 'B l 1'
- },
- {
- firstName: 'B f 2',
- lastName: 'B l 2'
- }]
- );
-
- const firstName = form.getComponent(['dataGrid', 0, 'firstName']);
- firstName.setValue('first name', { modified: true });
- select.setValue('c', { modified: true });
- setTimeout(() => {
- assert.deepEqual(dataGrid.getValue(),
- [{
- firstName: 'first name',
- lastName: 'B l 1'
- },
- {
- firstName: 'B f 2',
- lastName: 'B l 2'
- }]
- );
- done();
- }, 300);
- }, 300);
- }, 300);
- })
- .catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.data.js
deleted file mode 100644
index 37a32a08..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.data.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.display.js
deleted file mode 100644
index 394ea506..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.display.js
+++ /dev/null
@@ -1,147 +0,0 @@
-export default [
- {
- key: 'placeholder',
- ignore: true
- },
- {
- type: 'checkbox',
- label: 'Disable Adding / Removing Rows',
- key: 'disableAddingRemovingRows',
- tooltip: 'Check if you want to hide Add Another button and Remove Row button',
- weight: 405,
- input: true,
- clearOnHide: false,
- customConditional(context) {
- return !context.data.enableRowGroups;
- },
- calculateValue(context) {
- return context.data.enableRowGroups ? true : context.data.disableAddingRemovingRows;
- },
- },
- {
- weight: 406,
- type: 'textarea',
- input: true,
- key: 'conditionalAddButton',
- label: 'Conditional Add Button',
- placeholder: 'show = ...',
- tooltip: 'Specify condition when Add Button should be displayed.',
- editor: 'ace',
- as: 'javascript',
- wysiwyg: {
- minLines: 3,
- },
- },
- {
- type: 'checkbox',
- label: 'Allow Reorder',
- key: 'reorder',
- weight: 407,
- input: true,
- },
- {
- type: 'textfield',
- label: 'Add Another Text',
- key: 'addAnother',
- tooltip: 'Set the text of the Add Another button.',
- placeholder: 'Add Another',
- weight: 410,
- input: true,
- customConditional(context) {
- return !context.data.disableAddingRemovingRows;
- }
- },
- {
- type: 'select',
- label: 'Add Another Position',
- key: 'addAnotherPosition',
- dataSrc: 'values',
- tooltip: 'Position for Add Another button with respect to Data Grid Array.',
- defaultValue: 'bottom',
- input: true,
- data: {
- values: [
- { label: 'Top', value: 'top' },
- { label: 'Bottom', value: 'bottom' },
- { label: 'Both', value: 'both' }
- ]
- },
- weight: 411,
- customConditional(context) {
- return !context.data.disableAddingRemovingRows;
- }
- },
- {
- type: 'checkbox',
- label: 'Equal column width',
- key: 'layoutFixed',
- weight: 430,
- input: true,
- },
- {
- key: 'enableRowGroups',
- type: 'checkbox',
- label: 'Enable Row Groups',
- weight: 440,
- input: true
- },
- {
- label: 'Groups',
- disableAddingRemovingRows: false,
- defaultOpen: false,
- addAnother: '',
- addAnotherPosition: 'bottom',
- mask: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'datagrid',
- input: true,
- key: 'rowGroups',
- reorder: true,
- components: [
- {
- label: 'Label',
- allowMultipleMasks: false,
- showWordCount: false,
- showCharCount: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'textfield',
- input: true,
- key: 'label',
- widget: {
- type: ''
- },
- row: '0-0'
- },
- {
- label: 'Number of Rows',
- mask: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'number',
- input: true,
- key: 'numberOfRows',
- row: '0-1'
- }
- ],
- weight: 441,
- conditional: { json: { var: 'data.enableRowGroups' } }
- },
- {
- label: 'Hide Group on Header Click',
- type: 'checkbox',
- input: true,
- key: 'groupToggle',
- weight: 442,
- conditional: { json: { var: 'data.enableRowGroups' } }
- },
- {
- label: 'Initialize Empty',
- type: 'checkbox',
- input: true,
- key: 'initEmpty',
- tooltip: 'The DataGrid will have no visible rows when initialized.',
- weight: 450
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.validation.js
deleted file mode 100644
index 03e45c63..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/editForm/DataGrid.edit.validation.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export default [
- {
- ignore: true,
- key: 'unique',
- },
- {
- weight: 110,
- key: 'validate.minLength',
- label: 'Minimum Length',
- placeholder: 'Minimum Length',
- type: 'textfield',
- tooltip: 'The minimum length requirement this field must meet.',
- input: true
- },
- {
- weight: 120,
- key: 'validate.maxLength',
- label: 'Maximum Length',
- placeholder: 'Maximum Length',
- type: 'textfield',
- tooltip: 'The maximum length requirement this field must meet.',
- input: true
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-modal-with-required-fields.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-modal-with-required-fields.js
deleted file mode 100644
index 0d2efe24..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-modal-with-required-fields.js
+++ /dev/null
@@ -1,40 +0,0 @@
-export default {
- label: 'Data Grid',
- reorder: false,
- addAnotherPosition: 'bottom',
- defaultOpen: false,
- layoutFixed: false,
- enableRowGroups: false,
- initEmpty: false,
- tableView: false,
- modalEdit: true,
- defaultValue: [
- {}
- ],
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true
- },
- key: 'textField',
- type: 'textfield',
- input: true
- },
- {
- label: 'Text Area',
- autoExpand: false,
- tableView: true,
- validate: {
- required: true
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-on-blur-validation.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-on-blur-validation.js
deleted file mode 100644
index e69de29b..00000000
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-row-groups-with-def-value.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-row-groups-with-def-value.js
deleted file mode 100644
index cdc43bd6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-row-groups-with-def-value.js
+++ /dev/null
@@ -1,79 +0,0 @@
-export default {
- 'label': 'Data Grid',
- 'disableAddingRemovingRows': true,
- 'defaultOpen': false,
- 'layoutFixed': false,
- 'enableRowGroups': true,
- 'mask': false,
- 'tableView': true,
- 'alwaysEnabled': false,
- 'type': 'datagrid',
- 'input': true,
- 'key': 'dataGrid',
- 'components': [
- {
- 'label': 'Name',
- 'allowMultipleMasks': false,
- 'showWordCount': false,
- 'showCharCount': false,
- 'tableView': true,
- 'alwaysEnabled': false,
- 'type': 'textfield',
- 'input': true,
- 'key': 'name',
- 'widget': {
- 'type': ''
- },
- 'row': '0-0'
- },
- {
- 'label': 'Age',
- 'mask': false,
- 'tableView': true,
- 'alwaysEnabled': false,
- 'type': 'number',
- 'input': true,
- 'key': 'age',
- 'row': '0-1'
- }
- ],
- 'encrypted': false,
- 'defaultValue': [
- {
- 'name': 'Alex',
- 'age': 1
- },
- {
- 'name': 'Bob',
- 'age': 2
- },
- {
- 'name': 'Conny',
- 'age': 3
- }
- ],
- 'validate': {
- 'customMessage': '',
- 'json': ''
- },
- 'conditional': {
- 'show': '',
- 'when': '',
- 'json': ''
- },
- 'rowGroups': [
- {
- 'label': 'Header',
- 'numberOfRows': 1
- },
- {
- 'label': 'Body',
- 'numberOfRows': 3
- },
- {
- 'label': 'Footer',
- 'numberOfRows': 1
- }
- ],
- 'groupToggle': false
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-allow-calculate-override.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-allow-calculate-override.js
deleted file mode 100644
index 55a3e367..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-allow-calculate-override.js
+++ /dev/null
@@ -1,66 +0,0 @@
-export default {
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- data: {
- values: [
- {
- label: 'a',
- value: 'a'
- },
- {
- label: 'b',
- value: 'b'
- },
- {
- label: 'c',
- value: 'c'
- }
- ]
- },
- key: 'select',
- type: 'select',
- input: true
- },
- {
- label: 'Data Grid',
- reorder: false,
- addAnotherPosition: 'bottom',
- layoutFixed: false,
- enableRowGroups: false,
- initEmpty: false,
- tableView: false,
- defaultValue: [
- {
- firstName: '',
- lastName: ''
- }
- ],
- calculateValue: "var temp = [\n {'firstName': 'initial 1','lastName': 'initial 2'},\n {'firstName': 'initial 1b','lastName': 'initial 2b'},\n ];\n if(data.select === 'a')\n {\n temp = [{'firstName': 'A f 1','lastName': 'A l 1'}];\n } else if(data.select === 'b') { \n temp = [{'firstName': 'B f 1','lastName': 'B l 1'} \n ,{'firstName': 'B f 2','lastName': 'B l 2'}];\n } else if(data.select === 'c') { \n temp = [{'firstName': 'C f 1','lastName': 'C l 1'}];\n }\n value = temp;",
- allowCalculateOverride: true,
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- components: [
- {
- label: 'First Name',
- tableView: true,
- key: 'firstName',
- type: 'textfield',
- input: true
- },
- {
- label: 'Last Name',
- tableView: true,
- key: 'lastName',
- type: 'textfield',
- input: true
- }
- ]
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-collapsible-groups.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-collapsible-groups.js
deleted file mode 100644
index 82b711a3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-collapsible-groups.js
+++ /dev/null
@@ -1,73 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Data Grid',
- disableAddingRemovingRows: true,
- reorder: false,
- addAnotherPosition: 'bottom',
- layoutFixed: false,
- enableRowGroups: true,
- initEmpty: false,
- tableView: false,
- defaultValue: [
- {
- textField: '',
- number: '',
- },
- ],
- key: 'dataGrid',
- type: 'datagrid',
- rowGroups: [
- {
- label: 'group1',
- numberOfRows: 2,
- },
- {
- label: 'group2',
- numberOfRows: 3,
- },
- ],
- groupToggle: true,
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Number',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- key: 'number',
- type: 'number',
- input: true,
- },
- ],
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- _vid: 0,
- title: 'test',
- display: 'form',
- name: 'test',
- path: 'test',
- project: '6152d9c4daa2ef2742d17c07',
- created: '2022-12-19T10:14:02.292Z',
- modified: '2022-12-19T13:19:37.649Z',
- machineName: 'njwzrqvnlksevej:test',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-conditional-components-and-validations.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-conditional-components-and-validations.js
deleted file mode 100644
index 94ed00ed..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-conditional-components-and-validations.js
+++ /dev/null
@@ -1,176 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- title: 'Page 1',
- label: 'Page 1',
- type: 'panel',
- key: 'page1',
- components: [
- {
- label: 'HTML',
- attrs: [
- {
- attr: '',
- value: ''
- }
- ],
- content: "Various Tests on Calculations, Conditionals, and Custom Validations: \n(the following rules apply to both the DataGrid and EditGrid) \nRoot Text: \n - 1st Textfield in DG and EG should match the 'Root Text' field data\n - 2nd Textfield in DG and EG ('Row') should match the data from the 1st Textfield in the DG and EG\nRoot Radio: \n - When show is clicked, Radio should display in DG and EG\nGrid Radio: \n - When show is clicked for the Grid Radio, the 'Row Show' textfield should display in the DG and EG\nRoot Calculated Text: \n - Data entered in this textfield should display and populate grid calculated field\n - Textfield next to above should calculate based on grid calculated field",
- refreshOnChange: false,
- key: 'html',
- type: 'htmlelement',
- tableView: false,
- input: false,
- alwaysEnabled: false
- },
- {
- label: 'Root Text',
- alwaysEnabled: false,
- tableView: true,
- key: 'text',
- type: 'textfield',
- input: true
- },
- {
- label: 'Root - Radio',
- optionsLabelPosition: 'right',
- inline: false,
- alwaysEnabled: false,
- tableView: false,
- values: [
- {
- label: 'Show',
- value: 'show',
- shortcut: ''
- },
- {
- label: 'Hide',
- value: 'hide',
- shortcut: ''
- }
- ],
- validate: {
- required: true
- },
- key: 'radio',
- type: 'radio',
- input: true
- },
- {
- label: 'Root - Text Calculate',
- alwaysEnabled: false,
- tableView: true,
- key: 'textCal',
- type: 'textfield',
- input: true
- },
- {
- label: 'Data Grid',
- reorder: false,
- addAnotherPosition: 'bottom',
- defaultOpen: false,
- layoutFixed: false,
- enableRowGroups: false,
- alwaysEnabled: false,
- tableView: false,
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- components: [
- {
- label: 'Textfield - DG',
- tableView: true,
- validate: {
- custom: 'valid = (input === data.text) ? true : `data must match root textfield: ${input}, ${data.text}`;'
- },
- key: 'rootTest',
- type: 'textfield',
- alwaysEnabled: false,
- input: true
- },
- {
- label: 'Row Test - DG',
- tableView: true,
- validate: {
- custom: 'valid = (input == row.rootTest) ? true : `must equal textfield in dg: ${input}, ${row.rootTest}`;'
- },
- key: 'rowTest',
- type: 'textfield',
- alwaysEnabled: false,
- input: true
- },
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: false,
- tableView: false,
- values: [
- {
- label: 'DG Show',
- value: 'dgShow',
- shortcut: ''
- },
- {
- label: 'DG Hide',
- value: 'dgHide',
- shortcut: ''
- }
- ],
- validate: {
- required: true
- },
- key: 'radio1',
- customConditional: "show = (data.radio === 'show');",
- type: 'radio',
- alwaysEnabled: false,
- input: true
- },
- {
- label: "Row Show - Show textfield when data grid radio has 'show' value",
- alwaysEnabled: false,
- tableView: true,
- key: 'rowShowShowTextfieldWhenDataGridRadioHasShowValue',
- customConditional: "show = (row.radio1 === 'dgShow');",
- type: 'textfield',
- input: true,
- radio1: null
- },
- {
- label: "DG Calculated - Value should populate from 'root calculated text' field",
- tableView: true,
- calculateValue: 'value = data.textCal;',
- allowCalculateOverride: true,
- key: 'calculateTextDg',
- customConditional: 'show = (data.textCal);',
- type: 'textfield',
- alwaysEnabled: false,
- input: true
- },
- {
- label: 'Textfield - Data should populate from Datagrid calculate field',
- alwaysEnabled: false,
- tableView: true,
- calculateValue: 'value = row.calculateTextDg;',
- key: 'textfieldDataShouldPopulateFromDatagridCalculateField',
- customConditional: 'show = (data.textCal);',
- type: 'textfield',
- input: true
- }
- ],
- path: 'dataGrid'
- }
- ],
- input: false,
- tableView: false
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- display: 'form'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-def-value.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-def-value.js
deleted file mode 100644
index f5a386b8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-def-value.js
+++ /dev/null
@@ -1,67 +0,0 @@
-export default {
- 'label': 'Data Grid',
- 'disableAddingRemovingRows': false,
- 'addAnother': '',
- 'addAnotherPosition': 'bottom',
- 'removePlacement': 'col',
- 'defaultOpen': false,
- 'layoutFixed': false,
- 'enableRowGroups': false,
- 'mask': false,
- 'tableView': true,
- 'alwaysEnabled': false,
- 'type': 'datagrid',
- 'input': true,
- 'key': 'dataGrid',
- 'components': [
- {
- 'label': 'Name',
- 'allowMultipleMasks': false,
- 'showWordCount': false,
- 'showCharCount': false,
- 'tableView': true,
- 'alwaysEnabled': false,
- 'type': 'textfield',
- 'input': true,
- 'key': 'name',
- 'widget': {
- 'type': ''
- },
- 'row': '0-0'
- },
- {
- 'label': 'Age',
- 'mask': false,
- 'tableView': true,
- 'alwaysEnabled': false,
- 'type': 'number',
- 'input': true,
- 'key': 'age',
- 'row': '0-1'
- }
- ],
- 'encrypted': false,
- 'defaultValue': [
- {
- 'name': 'Alex',
- 'age': 1
- },
- {
- 'name': 'Bob',
- 'age': 2
- },
- {
- 'name': 'Conny',
- 'age': 3
- }
- ],
- 'validate': {
- 'customMessage': '',
- 'json': ''
- },
- 'conditional': {
- 'show': '',
- 'when': '',
- 'json': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-logic.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-logic.js
deleted file mode 100644
index ed147dd2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp-with-logic.js
+++ /dev/null
@@ -1,179 +0,0 @@
-export default {
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Data Grid',
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- tableView: false,
- components: [
- {
- label: 'Team Name',
- widget: 'choicesjs',
- tableView: true,
- data: {
- values: [
- {
- label: 'Pre Risk Analysis',
- value: 'preRiskAnalysis',
- },
- {
- label: 'Docs',
- value: 'docs',
- },
- ],
- },
- key: 'teamName',
- type: 'select',
- input: true,
- },
- {
- label: 'Priority(For Pre-Risk Analysis, select priority as Urgent)',
- tableView: false,
- values: [
- {
- label: 'Normal',
- value: 'normal',
- shortcut: '',
- },
- {
- label: 'Urgent',
- value: 'urgent',
- shortcut: '',
- },
- ],
- key: 'actionadd3',
- type: 'radio',
- input: true,
- },
- {
- label: 'Follow-up Date(For Urgent)',
- format: 'dd-MMM-yyyy HH:mm',
- hidden: true,
- tableView: false,
- enableMinDateInput: false,
- datePicker: {
- disableWeekends: true,
- disableWeekdays: false,
- },
- enableMaxDateInput: false,
- timePicker: {
- showMeridian: false,
- },
- key: 'followUpDate',
- logic: [
- {
- name: 'logic',
- trigger: {
- type: 'javascript',
- javascript:
- 'return (row.teamName === "preRiskAnalysis" && row.actionadd3 === "urgent")',
- },
- actions: [
- {
- name: 'action',
- type: 'property',
- property: {
- label: 'Hidden',
- value: 'hidden',
- type: 'boolean',
- },
- state: false,
- },
- ],
- },
- ],
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'viewer',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: true,
- noCalendar: false,
- format: 'dd-MMM-yyyy HH:mm',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': true,
- minDate: null,
- disableWeekends: true,
- disableWeekdays: false,
- maxDate: null,
- },
- },
- {
- label: 'Escalation ID',
- hidden: false,
- clearOnHide: true,
- disabled: true,
- tableView: true,
- key: 'escalationId',
- logic: [
- {
- name: 'logic1',
- trigger: {
- type: 'simple',
- simple: {
- show: true,
- when: 'dataGrid.teamName',
- eq: 'preRiskAnalysis',
- },
- },
- actions: [
- {
- name: 'ation1',
- type: 'value',
- value: 'value="RUSH"',
- },
- ],
- },
- {
- name: 'logic2',
- trigger: {
- type: 'simple',
- simple: {
- show: true,
- when: 'dataGrid.teamName',
- eq: 'docs',
- },
- },
- actions: [
- {
- name: 'action2',
- type: 'value',
- value: 'value="4DDJ"',
- },
- ],
- },
- {
- name: 'On Hide',
- trigger: {
- type: 'event',
- event: 'hide'
- },
- actions: [
- {
- name: 'Hide Component',
- type: 'property',
- property: {
- label: 'Hidden',
- value: 'hidden',
- type: 'boolean'
- },
- state: true
- }
- ]
- }
- ],
- type: 'textfield',
- input: true,
- },
- ],
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp1.js
deleted file mode 100644
index 3da8080b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp1.js
+++ /dev/null
@@ -1,121 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'datagrid',
- 'persistent': true,
- 'protected': false,
- 'key': 'cars',
- 'label': 'Cars',
- 'tableView': true,
- 'components': [
- {
- 'tags': [
-
- ],
- 'hideLabel': true,
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'make',
- 'label': 'Make',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- },
- {
- 'tags': [
-
- ],
- 'hideLabel': true,
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'model',
- 'label': 'Model',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- },
- {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'hideLabel': true,
- 'type': 'number',
- 'validate': {
- 'custom': '',
- 'multiple': '',
- 'integer': '',
- 'step': 'any',
- 'max': '',
- 'min': '',
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'defaultValue': '',
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'year',
- 'label': 'Year',
- 'inputType': 'number',
- 'delimiter': true,
- 'tableView': true,
- 'input': true
- }
- ],
- 'tree': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp2.js
deleted file mode 100644
index d09f778b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp2.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default {
- label: 'Children',
- key: 'children',
- type: 'datagrid',
- input: true,
- components: [
- {
- type: 'panel',
- label: 'User Information',
- key: 'userinfo',
- components: [
- {
- label: 'First Name',
- key: 'firstName',
- type: 'textfield',
- input: true
- },
- {
- label: 'Last Name',
- key: 'lastName',
- type: 'textfield',
- input: true
- }
- ]
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp3.js
deleted file mode 100644
index 26be8cf3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp3.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export default {
- label: 'Datagrid',
- key: 'comp3',
- type: 'datagrid',
- input: true,
- disabled: true,
- components: [
- {
- label: 'First Name',
- key: 'firstName',
- type: 'textfield',
- input: true
- },
- {
- label: 'Second Name',
- key: 'secondName',
- type: 'textfield',
- input: true
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp4.js
deleted file mode 100644
index 0fc98468..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp4.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default {
- 'label': 'Data Grid',
- 'reorder': false,
- 'addAnotherPosition': 'bottom',
- 'defaultOpen': false,
- 'layoutFixed': false,
- 'enableRowGroups': false,
- 'tableView': false,
- 'modalEdit': true,
- 'defaultValue': [{}],
- 'key': 'dataGrid',
- 'type': 'datagrid',
- 'input': true,
- 'components': [{
- 'label': 'Number',
- 'mask': false,
- 'spellcheck': true,
- 'tableView': false,
- 'delimiter': false,
- 'requireDecimal': false,
- 'inputFormat': 'plain',
- 'key': 'number',
- 'type': 'number',
- 'input': true
- }]
- };
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp5.js
deleted file mode 100644
index fddfa2cd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp5.js
+++ /dev/null
@@ -1,75 +0,0 @@
-export default {
- label: 'Data Grid',
- reorder: false,
- addAnotherPosition: 'bottom',
- defaultOpen: false,
- layoutFixed: false,
- enableRowGroups: false,
- initEmpty: false,
- tableView: true,
- modalEdit: true,
- defaultValue: [
- {
- textField: '',
- radio1: '',
- email: ''
- }
- ],
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- },
- {
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: true,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'number',
- type: 'number',
- input: true
- },
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: false,
- tableView: true,
- values: [
- {
- label: 'Ra',
- value: 'ra',
- shortcut: ''
- },
- {
- label: 'Rb',
- value: 'rb',
- shortcut: ''
- },
- {
- label: 'Rc',
- value: 'rc',
- shortcut: ''
- }
- ],
- key: 'radio1',
- type: 'radio',
- input: true
- },
- {
- label: 'Email',
- tableView: true,
- key: 'email',
- type: 'email',
- input: true
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp6.js
deleted file mode 100644
index 0d52604b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp6.js
+++ /dev/null
@@ -1,300 +0,0 @@
-export default {
- _id: '634d14afcfc5b40fecb8fb12',
- title: '4824-5',
- name: '48245',
- path: '48245',
- type: 'form',
- display: 'form',
- tags: [],
- owner: '6080329e2c806a03c1e15aa4',
- components: [
- {
- label: 'Data Grid',
- reorder: false,
- addAnotherPosition: 'bottom',
- layoutFixed: false,
- enableRowGroups: false,
- initEmpty: false,
- tableView: false,
- defaultValue: [{}],
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Text Area',
- autoExpand: false,
- tableView: true,
- key: 'textArea',
- type: 'textarea',
- input: true,
- },
- {
- label: 'Number',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- key: 'number',
- type: 'number',
- input: true,
- },
- {
- label: 'Password',
- autocomplete: 'dzmitry@form.io',
- tableView: false,
- key: 'password',
- type: 'password',
- input: true,
- protected: true,
- },
- {
- label: 'Checkbox',
- tableView: false,
- key: 'checkbox',
- type: 'checkbox',
- input: true,
- },
- {
- label: 'Select Boxes',
- optionsLabelPosition: 'right',
- tableView: false,
- values: [
- { label: 'Pamela Raynor', value: 'pamelaRaynor', shortcut: '' },
- { label: 'Evert Dickinson', value: 'evertDickinson', shortcut: '' },
- { label: 'Paige Brekke', value: 'paigeBrekke', shortcut: '' },
- ],
- key: 'selectBoxes',
- type: 'selectboxes',
- input: true,
- inputType: 'checkbox',
- },
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- data: {
- values: [
- { label: 'Aliza Hessel', value: 'alizaHessel' },
- { label: 'Carlie Nikolaus', value: 'carlieNikolaus' },
- { label: 'Jettie Wolf', value: 'jettieWolf' },
- ],
- },
- key: 'select',
- type: 'select',
- input: true,
- },
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: false,
- tableView: false,
- values: [
- { label: 'Anabelle Spinka', value: 'anabelleSpinka', shortcut: '' },
- { label: 'Osvaldo Krajcik', value: 'osvaldoKrajcik', shortcut: '' },
- { label: 'Cierra Reichel', value: 'cierraReichel', shortcut: '' },
- ],
- key: 'radio',
- type: 'radio',
- input: true,
- },
- {
- label: 'Email',
- tableView: true,
- key: 'email',
- type: 'email',
- input: true,
- },
- { label: 'Url', tableView: true, key: 'url', type: 'url', input: true },
- {
- label: 'Phone Number',
- tableView: true,
- key: 'phoneNumber',
- type: 'phoneNumber',
- input: true,
- },
- {
- label: 'Tags',
- tableView: false,
- key: 'tags',
- type: 'tags',
- input: true,
- },
- {
- label: 'Address',
- tableView: true,
- provider: 'google',
- key: 'address',
- type: 'address',
- providerOptions: {
- params: {
- autocompleteOptions: {},
- key: 'AIzaSyBNL2e4MnmyPj9zN7SVAe428nCSLP1X144',
- },
- },
- input: true,
- components: [
- {
- label: 'Address 1',
- tableView: false,
- key: 'address1',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, \'parent.manualMode\', false);',
- },
- {
- label: 'Address 2',
- tableView: false,
- key: 'address2',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, \'parent.manualMode\', false);',
- },
- {
- label: 'City',
- tableView: false,
- key: 'city',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, \'parent.manualMode\', false);',
- },
- {
- label: 'State',
- tableView: false,
- key: 'state',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, \'parent.manualMode\', false);',
- },
- {
- label: 'Country',
- tableView: false,
- key: 'country',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, \'parent.manualMode\', false);',
- },
- {
- label: 'Zip Code',
- tableView: false,
- key: 'zip',
- type: 'textfield',
- input: true,
- customConditional:
- 'show = _.get(instance, \'parent.manualMode\', false);',
- },
- ],
- },
- {
- label: 'Date / Time',
- tableView: false,
- datePicker: { disableWeekends: false, disableWeekdays: false },
- enableMinDateInput: false,
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'viewer',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: true,
- noCalendar: false,
- format: 'yyyy-MM-dd hh:mm a',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null,
- },
- },
- {
- label: 'Day',
- hideInputLabels: false,
- inputsLabelPosition: 'top',
- useLocaleSettings: false,
- tableView: false,
- fields: {
- day: { hide: false },
- month: { hide: false },
- year: { hide: false },
- },
- key: 'day',
- type: 'day',
- input: true,
- defaultValue: '00/00/0000',
- },
- {
- label: 'Time',
- tableView: true,
- key: 'time',
- type: 'time',
- input: true,
- inputMask: '99:99',
- },
- {
- label: 'Currency',
- mask: false,
- spellcheck: true,
- tableView: false,
- currency: 'USD',
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- key: 'currency',
- type: 'currency',
- input: true,
- delimiter: true,
- },
- {
- label: 'Survey',
- tableView: false,
- questions: [
- { label: 'Ole Ferry', value: 'oleFerry', tooltip: '' },
- { label: 'Kariane Erdman', value: 'karianeErdman', tooltip: '' },
- ],
- values: [
- { label: 'Alexa Corwin', value: 'alexaCorwin', tooltip: '' },
- { label: 'Susie Schiller', value: 'susieSchiller', tooltip: '' },
- ],
- key: 'survey',
- type: 'survey',
- input: true,
- },
- ],
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- settings: { theme: 'Materia' },
- properties: {},
- project: '61029d3b4c9d4e24e774bb15',
- _vid: 0,
- created: '2022-10-17T08:39:11.941Z',
- modified: '2022-10-19T08:24:10.344Z',
- machineName: 'dev-pvbwkiwgifflcai:48245',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp7.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp7.js
deleted file mode 100644
index f8fa4559..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp7.js
+++ /dev/null
@@ -1,33 +0,0 @@
-export default {
- label: 'Data Grid',
- reorder: false,
- addAnotherPosition: 'bottom',
- layoutFixed: false,
- enableRowGroups: false,
- initEmpty: false,
- tableView: false,
- defaultValue: [
- {}
- ],
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- components: [
- {
- key: 'fieldSet',
- type: 'fieldset',
- label: 'Field Set',
- input: false,
- tableView: false,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- }
- ]
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp8.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp8.js
deleted file mode 100644
index 52d1dcd2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/comp8.js
+++ /dev/null
@@ -1,35 +0,0 @@
-export default {
- label: 'Data Grid',
- reorder: false,
- addAnotherPosition: 'bottom',
- layoutFixed: false,
- enableRowGroups: false,
- initEmpty: false,
- tableView: false,
- defaultValue: [
- {}
- ],
- key: 'dataGrid',
- type: 'datagrid',
- input: true,
- components: [
- {
- label: 'Submit',
- showValidations: false,
- hideLabel: true,
- tableView: false,
- key: 'submit',
- type: 'button',
- saveOnEnter: false,
- input: true
- },
- {
- label: 'Text Field',
- dataGridLabel: true,
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/index.js
deleted file mode 100644
index 9bbb9f41..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datagrid/fixtures/index.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
-export comp6 from './comp6';
-export comp7 from './comp7';
-export comp8 from './comp8';
-export withDefValue from './comp-with-def-value';
-export withRowGroupsAndDefValue from './comp-row-groups-with-def-value';
-export modalWithRequiredFields from './comp-modal-with-required-fields';
-export withConditionalFieldsAndValidations from './comp-with-conditional-components-and-validations';
-export withLogic from './comp-with-logic';
-export withCollapsibleRowGroups from './comp-with-collapsible-groups';
-export withAllowCalculateOverride from './comp-with-allow-calculate-override';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.form.js b/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.form.js
deleted file mode 100644
index 2967af76..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.form.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Components from '../Components';
-import DataMapEditData from './editForm/DataMap.edit.data';
-import DataMapEditDisplay from './editForm/DataMap.edit.display';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: DataMapEditDisplay
- },
- {
- key: 'data',
- components: DataMapEditData
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.js b/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.js
deleted file mode 100644
index 75d22b76..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.js
+++ /dev/null
@@ -1,338 +0,0 @@
-import Component from '../_classes/component/Component';
-import DataGridComponent from '../datagrid/DataGrid';
-import _ from 'lodash';
-import EventEmitter from 'eventemitter3';
-import { componentValueTypes, getComponentSavedTypes, uniqueKey } from '../../utils/utils';
-
-export default class DataMapComponent extends DataGridComponent {
- static schema(...extend) {
- return Component.schema({
- label: 'Data Map',
- key: 'dataMap',
- type: 'datamap',
- clearOnHide: true,
- addAnother: 'Add Another',
- disableAddingRemovingRows: false,
- keyBeforeValue: true,
- valueComponent: {
- type: 'textfield',
- key: 'value',
- label: 'Value',
- input: true
- },
- input: true,
- validate: {
- maxLength: 0,
- minLength: 0
- }
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Data Map',
- icon: 'th-list',
- group: 'data',
- documentation: '/userguide/form-building/data-components#data-map',
- showPreview: false,
- weight: 20,
- schema: DataMapComponent.schema()
- };
- }
-
- get schema() {
- const schema = super.schema;
- if (this.components && (this.components.length > 0)) {
- schema.valueComponent = this.components[this.components.length - 1].schema;
- }
- return _.omit(schema, 'components');
- }
-
- static savedValueTypes(schema) {
- return getComponentSavedTypes(schema) || [componentValueTypes.object];
- }
-
- constructor(component, options, data) {
- super(component, options, data);
- this.type = 'datamap';
- }
-
- init() {
- this.components = [];
- this.rows = [];
- this.createRows();
- this.visibleColumns = {
- key: true,
- [this.valueKey]: true
- };
- this.component.valueComponent.hideLabel = true;
- }
-
- get defaultSchema() {
- return DataMapComponent.schema();
- }
-
- get emptyValue() {
- return {};
- }
-
- get dataValue() {
- if (
- !this.key ||
- (!this.visible && this.component.clearOnHide)
- ) {
- return this.emptyValue;
- }
- if (!this.hasValue() && this.shouldAddDefaultValue) {
- this.dataValue = this.emptyValue;
- }
- return _.get(this.data, this.key);
- }
-
- set dataValue(value) {
- super.dataValue = value;
- }
-
- get defaultValue() {
- const value = super.defaultValue;
- if (Array.isArray(value)) {
- return value[0];
- }
- return this.emptyValue;
- }
-
- get keySchema() {
- return {
- type: 'textfield',
- input: true,
- hideLabel: true,
- label: this.component.keyLabel || 'Key',
- key: '__key',
- disableBuilderActions: true,
- };
- }
-
- get valueKey() {
- return this.component.valueComponent.key;
- }
-
- getRowValues() {
- const dataValue = this.dataValue;
- if (this.builderMode) {
- return [dataValue];
- }
- if (_.isEmpty(dataValue)) {
- return [];
- }
-
- return Object.keys(dataValue).map(() => dataValue);
- }
-
- getComponentsContainer() {
- if (this.builderMode) {
- return this.getComponents().map(comp => comp.component);
- }
-
- return super.getComponentsContainer();
- }
-
- get iteratableRows() {
- return this.rows.map((row) => {
- return Object.keys(row).map(key => ({
- components: row[key],
- data: row[key].dataValue,
- }));
- });
- }
-
- componentContext(component) {
- return this.iteratableRows[component.row].find(comp => comp.components.key === component.key).data;
- }
-
- hasHeader() {
- return true;
- }
-
- hasRemoveButtons() {
- return !this.component.disableAddingRemovingRows &&
- !this.options.readOnly &&
- !this.disabled &&
- this.fullMode;
- }
-
- getColumns() {
- const keySchema = Object.assign({}, this.keySchema);
- const valueSchema = Object.assign({}, this.component.valueComponent);
- keySchema.hideLabel = false;
- valueSchema.hideLabel = false;
- return this.component.keyBeforeValue ?
- [keySchema, valueSchema] :
- [valueSchema, keySchema];
- }
-
- getRowKey(rowIndex) {
- const keys = Object.keys(this.dataValue);
- if (!keys[rowIndex]) {
- keys[rowIndex] = uniqueKey(this.dataValue, this.defaultRowKey);
- }
- return keys[rowIndex];
- }
-
- get defaultRowKey() {
- return 'key';
- }
-
- setRowComponentsData(rowIndex, rowData) {
- _.each(this.rows[rowIndex], (component) => {
- if (component.key === '__key') {
- component.data = {
- '__key': Object.keys(rowData)[rowIndex],
- };
- }
- else {
- component.data = rowData;
- }
- });
- }
-
- getValueAsString(value, options) {
- if (options?.email && this.visible && !this.skipInEmail && _.isObject(value)) {
- let result = (`
-
-
- `);
-
- result = Object.keys(value).reduce((result, key) => {
- result += (`
-
- ${key}
- ${this.getView(value[key], options)}
-
- `);
- return result;
- }, result);
-
- result += (`
-
-
- `);
-
- return result;
- }
- if (_.isEmpty(value)) {
- return '';
- }
- if (options?.modalPreview) {
- delete options.modalPreview;
- return this.getDataValueAsTable(value, options);
- }
-
- return typeof value === 'object' ? '[Complex Data]' : value;
- }
-
- getDataValueAsTable(value, options) {
- let result = (`
-
-
- `);
-
- if (this.visible && _.isObject(value)) {
- Object.keys(value).forEach((key) => {
- result += (`
-
- ${key}
- ${this.getView(value[key], options)}
-
- `);
- });
- }
-
- result += (`
-
-
- `);
-
- return result;
- }
-
- createRowComponents(row, rowIndex) {
- // Use original value component API key in builder mode to be able to edit value component
- let key = this.builderMode ? this.valueKey : this.getRowKey(rowIndex);
-
- // Create a new event emitter since fields are isolated.
- const options = _.clone(this.options);
- options.events = new EventEmitter();
- options.name += `[${rowIndex}]`;
- options.row = `${rowIndex}`;
-
- const components = {};
- components['__key'] = this.createComponent(this.keySchema, options, { __key: this.builderMode ? this.defaultRowKey : key });
- components['__key'].on('componentChange', (event) => {
- const dataValue = this.dataValue;
- const newKey = uniqueKey(dataValue, event.value);
- dataValue[newKey] = dataValue[key];
- delete dataValue[key];
- const comp = components[this.valueKey];
- comp.component.key = newKey;
- comp.path = this.calculateComponentPath(comp);
- key = newKey;
- });
-
- const valueComponent = _.clone(this.component.valueComponent);
- valueComponent.key = key;
-
- const componentOptions = this.options;
- componentOptions.row = options.row;
- components[this.valueKey] = this.createComponent(valueComponent, componentOptions, this.dataValue);
- return components;
- }
-
- get canAddColumn() {
- return false;
- }
-
- addChildComponent(component) {
- this.component.valueComponent = component;
- }
-
- saveChildComponent(component) {
- // Update the Value Component, the Key Component is not allowed to edit
- if (component.key !== this.keySchema.key) {
- this.component.valueComponent = component;
- }
- }
-
- removeChildComponent() {
- const defaultSchema = DataMapComponent.schema();
- this.component.valueComponent = defaultSchema.valueComponent;
- }
-
- addRow() {
- const index = this.rows.length;
- this.rows[index] = this.createRowComponents(this.dataValue, index);
- this.redraw();
- this.triggerChange();
- }
-
- removeRow(index) {
- const keys = Object.keys(this.dataValue);
- if (keys[index]) {
- delete this.dataValue[keys[index]];
- }
- this.rows.splice(index, 1);
- this.redraw();
- this.triggerChange();
- }
-
- setValue(value, flags = {}) {
- const changed = this.hasChanged(value, this.dataValue);
- this.dataValue = value;
- this.createRows();
- this.updateOnChange(flags, changed);
- return changed;
- }
-
- checkColumns() {
- return { rebuild: false, show: true };
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.unit.js
deleted file mode 100644
index 599ce6d8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datamap/DataMap.unit.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import Harness from '../../../test/harness';
-import DataMapComponent from './DataMap';
-import { comp1 } from './fixtures';
-
-describe('DataMap Component', () => {
- it('Should build a data map component', () => {
- return Harness.testCreate(DataMapComponent, comp1);
- });
-
- it('Should get and set values within the datamap.', () => {
- return Harness.testCreate(DataMapComponent, comp1).then((component) => {
- Harness.testSetGet(component, {
- one: 'One',
- two: 'Two',
- three: 'Three'
- });
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datamap/editForm/DataMap.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/datamap/editForm/DataMap.edit.data.js
deleted file mode 100644
index 98c49f29..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datamap/editForm/DataMap.edit.data.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true,
- },
- {
- key: 'defaultValue',
- ignore: true,
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datamap/editForm/DataMap.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/datamap/editForm/DataMap.edit.display.js
deleted file mode 100644
index 2989507a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datamap/editForm/DataMap.edit.display.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export default [
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- type: 'textfield',
- label: 'Label for Key column',
- key: 'keyLabel',
- tooltip: 'Provide a label text for Key column (otherwise \'Key\' will be used)',
- weight: 404,
- input: true
- },
- {
- type: 'checkbox',
- label: 'Disable Adding / Removing Rows',
- key: 'disableAddingRemovingRows',
- tooltip: 'Check if you want to hide Add Another button and Remove Row button',
- weight: 405,
- input: true
- },
- {
- type: 'checkbox',
- label: 'Show key column before value',
- key: 'keyBeforeValue',
- tooltip: 'Check if you would like to show the Key before the Value column.',
- weight: 406,
- input: true
- },
- {
- type: 'textfield',
- label: 'Add Another Text',
- key: 'addAnother',
- tooltip: 'Set the text of the Add Another button.',
- placeholder: 'Add Another',
- weight: 410,
- input: true,
- customConditional(context) {
- return !context.data.disableAddingRemovingRows;
- }
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datamap/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/datamap/fixtures/comp1.js
deleted file mode 100644
index 77415b60..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datamap/fixtures/comp1.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default {
- type: 'datamap',
- key: 'properties',
- label: 'Properties',
- input: true,
- valueComponent: {
- type: 'textfield',
- key: 'value',
- label: 'Value',
- defaultValue: 'Value',
- input: true
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datamap/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/datamap/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datamap/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.form.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.form.js
deleted file mode 100644
index 5a616bd4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.form.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import Components from '../Components';
-import DateTimeEditData from './editForm/DateTime.edit.data';
-import DateTimeEditDate from './editForm/DateTime.edit.date';
-import DateTimeEditDisplay from './editForm/DateTime.edit.display';
-import DateTimeEditTime from './editForm/DateTime.edit.time';
-import DateTimeEditValidation from './editForm/DateTime.edit.validation';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: DateTimeEditDisplay
- },
- {
- label: 'Date',
- key: 'date',
- weight: 1,
- components: DateTimeEditDate
- },
- {
- label: 'Time',
- key: 'time',
- weight: 2,
- components: DateTimeEditTime
- },
- {
- key: 'data',
- components: DateTimeEditData
- },
- {
- key: 'validation',
- components: DateTimeEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.js
deleted file mode 100644
index e07a334c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.js
+++ /dev/null
@@ -1,210 +0,0 @@
-import _ from 'lodash';
-import moment from 'moment';
-import FormioUtils from '../../utils';
-import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-import Input from '../_classes/input/Input';
-
-export default class DateTimeComponent extends Input {
- static schema(...extend) {
- return Input.schema({
- type: 'datetime',
- label: 'Date / Time',
- key: 'dateTime',
- format: 'yyyy-MM-dd hh:mm a',
- useLocaleSettings: false,
- allowInput: true,
- enableDate: true,
- enableTime: true,
- defaultValue: '',
- defaultDate: '',
- displayInTimezone: 'viewer',
- timezone: '',
- datepickerMode: 'day',
- datePicker: {
- showWeeks: true,
- startingDay: 0,
- initDate: '',
- minMode: 'day',
- maxMode: 'year',
- yearRows: 4,
- yearColumns: 5,
- minDate: null,
- maxDate: null
- },
- timePicker: {
- hourStep: 1,
- minuteStep: 1,
- showMeridian: true,
- readonlyInput: false,
- mousewheel: true,
- arrowkeys: true
- },
- customOptions: {},
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Date / Time',
- group: 'advanced',
- icon: 'calendar',
- documentation: '/userguide/form-building/advanced-components#date-and-time',
- weight: 40,
- schema: DateTimeComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return DateTimeComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: ['isDateEqual', 'isNotDateEqual', 'isEmpty', 'isNotEmpty','dateLessThan', 'dateGreaterThan', 'dateLessThanOrEqual','dateGreaterThanOrEqual'],
- valueComponent(classComp) {
- return {
- ...classComp,
- type: 'datetime',
- };
- }
- };
- }
-
- static savedValueTypes(schema) {
- schema = schema || {};
-
- return getComponentSavedTypes(schema) || [componentValueTypes.date];
- }
-
- constructor(component, options, data) {
- super(component, options, data);
- const timezone = (this.component.timezone || this.options.timezone);
- const time24hr = !_.get(this.component, 'timePicker.showMeridian', true);
-
- // Change the format to map to the settings.
- if (!this.component.enableDate) {
- this.component.format = this.component.format.replace(/yyyy-MM-dd /g, '');
- }
- else if (this.component.enableDate && !/[yMd]/.test(this.component.format) && this.builderMode) {
- this.component.format = `yyyy-MM-dd ${this.component.format}`;
- }
-
- if (!this.component.enableTime) {
- this.component.format = this.component.format.replace(/ hh:mm a$/g, '');
- }
- else if (this.component.enableTime && !/[mhH]/.test(this.component.format) && this.builderMode) {
- this.component.format = `${this.component.format} hh:mm a`;
- }
- else if (time24hr) {
- this.component.format = this.component.format.replace(/hh:mm a$/g, 'HH:mm');
- }
- else {
- this.component.format = this.component.format.replace(/HH:mm$/g, 'hh:mm a');
- }
-
- let customOptions = this.component.customOptions || {};
-
- if (typeof customOptions === 'string') {
- try {
- customOptions = JSON.parse(customOptions);
- }
- catch (err) {
- console.warn(err.message);
- customOptions = {};
- }
- }
-
- /* eslint-disable camelcase */
- this.component.widget = {
- type: 'calendar',
- timezone,
- displayInTimezone: _.get(this.component, 'displayInTimezone', 'viewer'),
- locale: this.options.language,
- useLocaleSettings: _.get(this.component, 'useLocaleSettings', false),
- allowInput: _.get(this.component, 'allowInput', true),
- mode: 'single',
- enableTime: _.get(this.component, 'enableTime', true),
- noCalendar: !_.get(this.component, 'enableDate', true),
- format: this.component.format,
- hourIncrement: _.get(this.component, 'timePicker.hourStep', 1),
- minuteIncrement: _.get(this.component, 'timePicker.minuteStep', 5),
- time_24hr: time24hr,
- readOnly: this.options.readOnly,
- minDate: _.get(this.component, 'datePicker.minDate'),
- disabledDates: _.get(this.component, 'datePicker.disable'),
- disableWeekends: _.get(this.component, 'datePicker.disableWeekends'),
- disableWeekdays: _.get(this.component, 'datePicker.disableWeekdays'),
- disableFunction: _.get(this.component, 'datePicker.disableFunction'),
- maxDate: _.get(this.component, 'datePicker.maxDate'),
- ...customOptions,
- };
- /* eslint-enable camelcase */
-
- // Add the validators date.
- this.validators.push('date');
- }
-
- get defaultSchema() {
- return DateTimeComponent.schema();
- }
-
- get defaultValue() {
- let defaultValue = super.defaultValue;
- if (!defaultValue && this.component.defaultDate) {
- defaultValue = FormioUtils.getDateSetting(this.component.defaultDate);
- defaultValue = defaultValue ? defaultValue.toISOString() : '';
- }
- return defaultValue;
- }
-
- get emptyValue() {
- return '';
- }
-
- get momentFormat() {
- return FormioUtils.convertFormatToMoment(this.component.format);
- }
-
- isEmpty(value = this.dataValue) {
- if (value && (value.toString() === 'Invalid Date')) {
- return true;
- }
- return super.isEmpty(value);
- }
-
- formatValue(input) {
- const result = moment.utc(input).toISOString();
- return result === 'Invalid date' ? input : result;
- }
-
- isEqual(valueA, valueB = this.dataValue) {
- return (this.isEmpty(valueA) && this.isEmpty(valueB))
- || moment.utc(valueA).format(this.momentFormat) === moment.utc(valueB).format(this.momentFormat);
- }
-
- createWrapper() {
- return false;
- }
-
- checkValidity(data, dirty, rowData) {
- if (this.refs.input) {
- this.refs.input.forEach((input) => {
- if (input.widget && input.widget.enteredDate) {
- dirty = true;
- }
- });
- }
- return super.checkValidity(data, dirty, rowData);
- }
-
- getValueAsString(value) {
- let format = FormioUtils.convertFormatToMoment(this.component.format);
- format += format.match(/z$/) ? '' : ' z';
- const timezone = this.timezone;
- if (value && !this.attached && timezone) {
- return _.trim(FormioUtils.momentDate(value, format, timezone).format(format));
- }
- return (value ? _.trim(moment(value).format(format)) : value) || '';
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.unit.js
deleted file mode 100644
index 7bea9e88..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/DateTime.unit.js
+++ /dev/null
@@ -1,757 +0,0 @@
-import assert from 'power-assert';
-import Harness from '../../../test/harness';
-import DateTimeComponent from './DateTime';
-import Formio from './../../Formio';
-import _ from 'lodash';
-import 'flatpickr';
-import {
- comp1,
- comp2,
- comp3,
- comp5,
- comp6,
- comp7,
- comp8,
- // comp9,
- comp10,
- comp11,
- comp12
-} from './fixtures';
-
-describe('DateTime Component', () => {
- it('Should build a date time component', () => {
- return Harness.testCreate(DateTimeComponent, comp1).then((dateTime) => dateTime.destroy());
- });
-
- it('Test formatting', (done) => {
- Harness.testCreate(DateTimeComponent, comp2).then((dateTime) => {
- const value = '2020-09-22T00:00:00';
- const formattedValue = '2020-09-22';
- dateTime.setValue(value);
- setTimeout(() => {
- assert.equal(dateTime.getValueAsString(value), formattedValue, 'getValueAsString should return formatted value');
- dateTime.destroy();
- done();
- }, 250);
- }).catch(done);
- });
-
- it('Should format value', () => {
- comp2.format = 'yyyy-MM-dd hh:mm a';
- return Harness.testCreate(DateTimeComponent, comp2)
- .then((dateTime) => {
- assert.equal(dateTime.getValueAsString('2020-09-18T12:12:00'), '2020-09-18 12:12 PM');
- dateTime.destroy();
- });
- });
-
- it('Should not change manually entered value on blur when time is disabled', (done) => {
- const form = _.cloneDeep(comp11);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const blurEvent = new Event('blur');
-
- const value = '01-02-2021';
- const input = dateTime.element.querySelector('.input');
- input.value = value;
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(input.value, value);
- document.innerHTML = '';
- done();
- }, 600);
- }).catch(done);
- });
-
- it('Should allow manual input', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const blurEvent = new Event('blur');
-
- const value = '2021-04-13 7:00 PM';
- const expectedValueStart = '2021-04-13T19:00:00';
- const input = dateTime.element.querySelector('.input');
- input.value = value;
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(dateTime.getValue().startsWith(expectedValueStart), true);
- assert.equal(dateTime.dataValue.startsWith(expectedValueStart), true);
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should allow manual input for date with full month format (like MMMM)', (done) => {
- const form = _.cloneDeep(comp12);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const blurEvent = new Event('blur');
-
- const value = 'April 22';
- const expectedValue = 'April/22';
- const input = dateTime.element.querySelector('.input');
- input.value = value;
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(input.value, expectedValue);
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should not allow manual input', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].allowInput = false;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const blurEvent = new Event('blur');
-
- const value = '2021-04-13 7:00 PM';
- const input = dateTime.element.querySelector('.input');
- input.value = value;
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(dateTime.getValue(), '');
- assert.equal(dateTime.dataValue, '');
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should format date correctly', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- const formatsInitial = [
- {
- format: 'yyyy-dd-MM',
- inputValue:'2021-15-03 11:10 AM',
- setValue:'2021-03-15T00:00:00',
- expectedFormattedValue:'2021-15-03'
- },
- {
- format: 'yyyy-dd',
- inputValue:'2021-15-03 11:10 AM',
- setValue:'2021-03-15T00:00:00',
- expectedFormattedValue:'2021-15'
- },
- {
- format: 'yyyy',
- inputValue:'2021-15-03 11:10 AM',
- setValue:'2021-03-15T00:00:00',
- expectedFormattedValue:'2021'
- },
- {
- format: 'dd-MM-yyyy',
- inputValue:'15-03-2021 11:10 AM',
- setValue:'2021-03-15T00:00:00',
- expectedFormattedValue:'15-03-2021'
- },
- {
- format: 'MM-dd',
- inputValue:'03-15-2021 11:10 AM',
- setValue:'2021-03-15T00:00:00',
- expectedFormattedValue:'03-15'
- },
- {
- format: 'dd-MM',
- inputValue:'15-03-2021 11:10 AM',
- setValue:'2021-03-15T00:00:00',
- expectedFormattedValue:'15-03'
- },
- {
- format: 'MM-dd-yyyy',
- inputValue:'03-15-2021 11:10 AM',
- setValue:'2021-03-15T00:00:00',
- expectedFormattedValue:'03-15-2021'
- },
- {
- format: 'yyyy-MM-dd',
- inputValue:'2021-03-15 11:10 AM',
- setValue:'2021-03-15T00:00:00',
- expectedFormattedValue:'2021-03-15'
- },
- {
- format: 'dd-MM-yyyy hh:mm',
- inputValue:'15-03-2021 11:10 AM',
- setValue:'2021-03-15T11:10:00',
- expectedFormattedValue:'15-03-2021 11:10'
- },
- {
- format: 'yyyy-MM-dd a',
- inputValue:'2021-03-15 PM',
- setValue:'2021-03-15T12:00:00',
- expectedFormattedValue:'2021-03-15 PM'
- },
- {
- format: 'hh',
- inputValue:'11:10 AM',
- setValue:'2021-01-01T11:00:00',
- expectedFormattedValue:'11'
- },
- {
- format: 'hh:mm a',
- inputValue:'11:10 AM 34',
- setValue:'2021-01-01T11:10:00',
- expectedFormattedValue:'11:10 AM'
- },
- {
- format: 'mm',
- inputValue:'11:10 AM',
- setValue:'2021-01-01T00:11:00',
- expectedFormattedValue:'11'
- },
- ];
-
- const getAllFormats = function(formats) {
- const separators = ['.', '/'];
-
- const formatsWithDiffSeparators = separators.reduce((result, separator) => {
- const formatWithNewSeparator = formats
- .filter(format => {
- return format.format.split('-').length > 1;
- })
- .map(format => {
- return {
- ...format,
- format: format.format.split('-').join(separator),
- inputValue: format.inputValue.split('-').join(separator),
- expectedFormattedValue: format.expectedFormattedValue.split('-').join(separator),
- };
- });
-
- return [...result, ...formatWithNewSeparator];
- }, []);
-
- return [...formats, ...formatsWithDiffSeparators];
- };
-
- const formats = getAllFormats(formatsInitial);
- const formComponents = [];
-
- formats.forEach((format, index) => {
- const comp = _.cloneDeep(form.components[0]);
- comp.format = format.format;
- comp.widget.format = format.format;
- comp.key = comp.key + index;
- formComponents.push(comp);
- });
-
- form.components = formComponents;
-
- Formio.createForm(element, form).then(form => {
- form.components.forEach((comp, index) => {
- comp.setValue(formats[index].setValue);
- });
-
- setTimeout(() => {
- form.components.forEach((comp, index) => {
- const input = comp.element.querySelector('.input');
- assert.equal(input.value, formats[index].expectedFormattedValue, 'Should format date/time value after setting value');
-
- const blurEvent = new Event('blur');
- input.value = formats[index].inputValue;
- input.dispatchEvent(blurEvent);
- });
-
- setTimeout(() => {
- form.components.forEach((comp, index) => {
- const input = comp.element.querySelector('.input');
- assert.equal(input.value, formats[index].expectedFormattedValue, 'Should format date/time value after inputting value');
- });
-
- document.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }).catch(done);
- }).timeout(4000);
-
- it('Should disable weekends', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].datePicker.disableWeekends = true;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const calendar = dateTime.element.querySelector('.flatpickr-input').widget.calendar;
- assert.equal(calendar.config.disableWeekends, true);
-
- document.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should disable weekdays', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].datePicker.disableWeekdays = true;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const calendar = dateTime.element.querySelector('.flatpickr-input').widget.calendar;
- assert.equal(calendar.config.disableWeekdays, true);
-
- document.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should disable time', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].enableTime = false;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const calendar = dateTime.element.querySelector('.flatpickr-input').widget.calendar;
- assert.equal(calendar.config.enableTime, false);
- assert.equal(!!calendar.timeContainer, false);
-
- document.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should disable date', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].enableDate = false;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const calendar = dateTime.element.querySelector('.flatpickr-input').widget.calendar;
- assert.equal(!!calendar.daysContainer, false);
-
- document.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should enable time', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].enableTime = true;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const calendar = dateTime.element.querySelector('.flatpickr-input').widget.calendar;
- assert.equal(calendar.config.enableTime, true);
- assert.equal(!!calendar.timeContainer, true);
-
- document.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should enable date', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].enableDate = true;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const calendar = dateTime.element.querySelector('.flatpickr-input').widget.calendar;
- assert.equal(calendar.config.enableDate, true);
- assert.equal(!!calendar.daysContainer, true);
-
- document.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should not input the date that is disabled', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].datePicker.disable = '2021-04-15';
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const input = dateTime.element.querySelector('.input');
-
- const blurEvent = new Event('blur');
- input.value = '2021-04-15';
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- const input = dateTime.element.querySelector('.input');
- assert.equal(input.value, '');
- assert.equal(dateTime.dataValue, '');
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should not input the date that is in disabled range', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].datePicker.disable = '2021-04-15-2021-04-20';
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const input = dateTime.element.querySelector('.input');
-
- const blurEvent = new Event('blur');
- input.value = '2021-04-17';
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- const input = dateTime.element.querySelector('.input');
- assert.equal(input.value, '');
- assert.equal(dateTime.dataValue, '');
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should not allow inputting the date that meets condition of "custom disabled date"', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].datePicker.disableFunction = 'date.getDay() === 2';
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const input = dateTime.element.querySelector('.input');
-
- const blurEvent = new Event('blur');
- input.value = '2021-04-06';
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- const input = dateTime.element.querySelector('.input');
- assert.equal(input.value, '');
- assert.equal(dateTime.dataValue, '');
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should not allow inputting the date if it is out of min/max date range', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].datePicker.minDate = '2021-04-04T12:00:00';
- form.components[0].datePicker.maxDate = '2021-04-18T12:00:00';
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const input = dateTime.element.querySelector('.input');
-
- const blurEvent = new Event('blur');
- input.value = '2020-04-03';
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- const input = dateTime.element.querySelector('.input');
- assert.equal(input.value, '');
- assert.equal(dateTime.dataValue, '');
-
- const blurEvent = new Event('blur');
- input.value = '2022-04-13';
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- const input = dateTime.element.querySelector('.input');
- assert.equal(input.value, '');
- assert.equal(dateTime.dataValue, '');
-
- document.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should set hour and minutes step', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].timePicker = { hourStep:3, minuteStep:10 };
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const calendar = dateTime.element.querySelector('.flatpickr-input').widget.calendar;
- assert.equal(calendar.config.minuteIncrement, 10);
- assert.equal(calendar.config.hourIncrement, 3);
-
- document.innerHTML = '';
- done();
- }).catch(done);
- });
-
- it('Should allow inputting 24h time', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].timePicker = { showMeridian: false };
- form.components[0].widget['time_24hr'] = true;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const input = dateTime.element.querySelector('.input');
-
- const blurEvent = new Event('blur');
- input.value = '2020-04-03 22:11';
- input.dispatchEvent(blurEvent);
- setTimeout(() => {
- const input = dateTime.element.querySelector('.input');
- assert.equal(input.value, '2020-04-03 22:11');
- assert.equal(dateTime.dataValue.startsWith('2020-04-03T22:11:00'), true);
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should not set value if it does not meet minDate validation', (done) => {
- const form = _.cloneDeep(comp5);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- dateTime.setValue('2021-05-01T09:00:00');
-
- setTimeout(() => {
- const input = dateTime.element.querySelector('.input');
- assert.equal(input.value, '');
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should set value in readOnly mode even if it does not meet current minDate validation conditions', (done) => {
- const form = _.cloneDeep(comp5);
- const element = document.createElement('div');
-
- Formio.createForm(element, form, { readOnly: true }).then(form => {
- const dateTime = form.getComponent('dateTime');
- dateTime.setValue('2021-05-01T09:00:00');
-
- setTimeout(() => {
- const input = dateTime.element.querySelector('.input');
- assert.equal(input.value, '05/01/21');
-
- document.innerHTML = '';
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should save hours and minutes values on first change', (done) => {
- const form = _.cloneDeep(comp6);
- const element = document.createElement('div');
- form.components[0].enableDate = false;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const blurEvent = new Event('blur');
- const input = dateTime.element.querySelector('.input');
- input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- const calendar = dateTime.element.querySelector('.flatpickr-input').widget.calendar;
- calendar._input.value = '7:00 PM';
- const expectedValue = 'T19:00:00';
- calendar._input.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(dateTime.dataValue.includes(expectedValue), true);
-
- document.innerHTML = '';
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should provide correct value after submission', (done) => {
- const form = _.cloneDeep(comp7);
- const element = document.createElement('div');
- form.components[0].enableTime = false;
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- dateTime.setValue('2022-12-21');
-
- setTimeout(() => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(dateTime.dataValue, '2022-12-21');
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should not highlight the field when it is valid when multiple values and required validation are enabled', (done) => {
- const form = _.cloneDeep(comp8);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const input1 = dateTime.element.querySelectorAll('.input')[0];
-
- const blurEvent = new Event('blur');
- input1.value = '2020-04-03';
- input1.dispatchEvent(blurEvent);
-
- const addAnotherBtn = dateTime.refs.addButton[0];
- const clickEvent = new Event('click');
- addAnotherBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(dateTime.refs.input.length, 2);
-
- const inputs = dateTime.element.querySelectorAll('.input');
- assert.equal(inputs[0].classList.contains('is-invalid'), false);
- assert.equal(inputs[1].classList.contains('is-invalid'), true);
-
- inputs[1].value = '2020-05-05';
- inputs[1].dispatchEvent(blurEvent);
-
- setTimeout(() => {
- const input2 = dateTime.element.querySelectorAll('.input')[1];
- assert.equal(input2.classList.contains('is-invalid'), false);
-
- document.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should provide correct values with time after submission', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const dateTime = form.getComponent('dateTime');
- const textField = form.getComponent('textField');
-
- dateTime.setValue('2022-04-01T14:00:00.000');
- textField.setValue('2022-04-01T14:00:00.000');
-
- setTimeout(() => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const input1 = dateTime.element.querySelector('.input');
- const input2 = textField.element.querySelector('.input');
-
- assert.equal(input1.value, '2022-04-01 02:00 PM');
- assert.equal(input2.value, '2022-04-01 02:00 PM');
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should add date to format if enableDate is true', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].format = 'hh:mm a';
- form.components[0].enableDate = true;
- const element = document.createElement('div');
-
- Formio.createForm(element, form, { attachMode: 'builder' }).then(form => {
- const dateTime = form.getComponent('dateTime');
- assert.equal(dateTime.component.format, 'yyyy-MM-dd hh:mm a');
- done();
- }).catch(done);
- });
-
- it('Should add time to format if enableTime is true', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].format = 'yyyy-MM-dd';
- form.components[0].enableTime = true;
- const element = document.createElement('div');
-
- Formio.createForm(element, form, { attachMode: 'builder' }).then(form => {
- const dateTime = form.getComponent('dateTime');
- assert.equal(dateTime.component.format, 'yyyy-MM-dd hh:mm a');
- done();
- }).catch(done);
- });
-
- // it('Should provide correct date in selected timezone after submission', (done) => {
- // const form = _.cloneDeep(comp9);
- // const element = document.createElement('div');
-
- // Formio.createForm(element, form, { readOnly: true }).then(form => {
- // const dateTime = form.getComponent('dateTime');
- // const dateTime1 = form.getComponent('dateTime1');
-
- // dateTime.setValue('2022-04-01T00:00:00.000');
- // dateTime1.setValue('2022-04-01T00:00:00.000');
-
- // document.body.addEventListener('zonesLoaded', () => {
- // setTimeout(() => {
- // const input = dateTime.element.querySelector('.input');
- // const input1 = dateTime1.element.querySelector('.input');
-
- // assert.equal(input.value, '2022-03-31 CDT');
- // assert.equal(input1.value, '2022-04-01 KST');
- // done();
- // }, 100);
- // });
- // }).catch(done);
- // });
-
- // it('Test Shortcut Buttons', (done) => {
- // // eslint-disable-next-line no-debugger
- // debugger;
- // window.flatpickr = Flatpickr;
- // window.ShortcutButtonsPlugin = ShortcutButtonsPlugin;
- // const formElement = document.createElement('div');
- // const form = new Webform(formElement);
- // form.setForm({ display: 'form', type: 'form', components: [comp2] })
- // .then(() => {
- // const dateTime = form.components[0];
- // const buttonsWrappers = document.querySelectorAll('.shortcut-buttons-flatpickr-wrapper');
- // const shortcutButtons = buttonsWrappers[buttonsWrappers.length - 1].querySelectorAll('.shortcut-buttons-flatpickr-button');
-
- // assert.equal(shortcutButtons.length, 1);
-
- // const input = dateTime.refs.input[0];
- // Harness.clickElement(dateTime, shortcutButtons[0]);
-
- // setTimeout(() => {
- // input.widget.calendar.close();
- // setTimeout(() => {
- // assert.equal(form.data.date, '2020-10-10T00:00:00+00:00');
- // dateTime.destroy();
- // done();
- // }, 250);
- // }, 150);
- // }).catch(done);
- // });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.data.js
deleted file mode 100644
index aea049b1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.data.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export default [
- {
- type: 'textfield',
- input: true,
- key: 'defaultDate',
- label: 'Default Date',
- placeholder: 'moment()',
- tooltip: 'You can use Moment.js functions to set the default value to a specific date. For example: \n \n moment().subtract(10, \'days\')',
- weight: 6
- },{
- type: 'textarea',
- as: 'json',
- editor: 'ace',
- weight: 28,
- input: true,
- key: 'customOptions',
- label: 'Flatpickr options',
- tooltip: 'A raw JSON object to use as options for the Date / Time component (Flatpickr).',
- defaultValue: {},
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.date.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.date.js
deleted file mode 100644
index 2c465dd4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.date.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import Evaluator from '../../../utils/Evaluator';
-import EditFormUtils from '../../_classes/component/editForm/utils';
-
-export default [
- {
- type: 'checkbox',
- input: true,
- key: 'enableDate',
- label: 'Enable Date Input',
- weight: 0,
- tooltip: 'Enables date input for this field.'
- },
- {
- type: 'tags',
- input: true,
- key: 'datePicker.disable',
- label: 'Disable specific dates or dates by range',
- placeholder: '(yyyy-MM-dd) or (yyyy-MM-dd - yyyy-MM-dd)',
- tooltip: 'Add dates that you want to blacklist. For example: \n \n 2025-02-21',
- validate: {
- custom: 'if (_.isEmpty(input)) {\n return true;\n}\nconst dates = _.isArray(input) ?\ninput : input.split(component.delimeter);\nconst isValid = _.every(dates, (data) => \n !!data.match(/\\d{4}-\\d{2}-\\d{2}/g));\nvalid = isValid || \'Invalid date\';'
- },
- weight: 21
- },
- {
- type: 'panel',
- title: 'Custom Disabled Dates',
- collapsible: true,
- collapsed: true,
- style: { 'margin-bottom': '10px' },
- key: 'panel-disable-function',
- customConditional() {
- return !Evaluator.noeval || Evaluator.protectedEval;
- },
- components: [
- EditFormUtils.logicVariablesTable('date The date object. '),
- {
- type: 'textarea',
- input: true,
- editor: 'ace',
- key: 'datePicker.disableFunction',
- label: 'Disabling dates by a function',
- description: 'For more information check out the Docs ',
- weight: 22
- },
- {
- type: 'htmlelement',
- tag: 'div',
- content: 'Example ' +
- `// Disable all weekends date.getDay() === 0 || date.getDay() === 6
- `
- }
- ]
- },
- {
- type: 'checkbox',
- input: true,
- key: 'datePicker.disableWeekends',
- label: 'Disable weekends',
- tooltip: 'Check to disable weekends',
- weight: 23
- },
- {
- type: 'checkbox',
- input: true,
- key: 'datePicker.disableWeekdays',
- label: 'Disable weekdays',
- tooltip: 'Check to disable weekdays',
- weight: 23
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.display.js
deleted file mode 100644
index cb727ee8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.display.js
+++ /dev/null
@@ -1,98 +0,0 @@
-export default [
- {
- type: 'select',
- input: true,
- key: 'displayInTimezone',
- label: 'Display in Timezone',
- tooltip: 'This will display the captured date time in the select timezone.',
- weight: 30,
- defaultValue: 'viewer',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'of Viewer', value: 'viewer' },
- { label: 'of Submission', value: 'submission' },
- { label: 'of Location', value: 'location' },
- { label: 'UTC', value: 'utc' }
- ]
- }
- },
- {
- type: 'select',
- input: true,
- key: 'timezone',
- label: 'Select Timezone',
- tooltip: 'Select the timezone you wish to display this Date',
- weight: 31,
- lazyLoad: true,
- defaultValue: '',
- valueProperty: 'name',
- dataSrc: 'url',
- data: {
- url: '{{options.cdnUrl}}/timezones.json'
- },
- template: '{{ item.label }} ',
- conditional: {
- json: { '===': [{ var: 'data.displayInTimezone' }, 'location'] }
- }
- },
- {
- type: 'checkbox',
- input: true,
- key: 'useLocaleSettings',
- label: 'Use Locale Settings',
- tooltip: 'Use locale settings to display date and time.',
- weight: 51
- },
- {
- type: 'checkbox',
- input: true,
- key: 'allowInput',
- label: 'Allow Manual Input',
- tooltip: 'Check this if you would like to allow the user to manually enter in the date.',
- weight: 51
- },
- {
- type: 'textfield',
- input: true,
- key: 'format',
- label: 'Format',
- placeholder: 'Format',
- description: 'Use formats provided by DateParser Codes ',
- tooltip: 'The date format for displaying the datetime value.',
- weight: 52
- },
- {
- type: 'editgrid',
- input: true,
- key: 'shortcutButtons',
- label: 'Shortcut Buttons',
- description: 'You can specify few buttons which will be shown above the calendar. Use Label to specify the name of the button and onClick to specify which date/time will be set when user clicks the button. E.g, date = new Date()',
- templates: {
- header: '',
- row: '\n
\n {{ flattenedComponents.label.getView(row.label) }}\n
\n
\n {{ flattenedComponents.onClick.getView(row.onClick) }}\n
\n {% if (!instance.disabled) { %}\n
\n
\n \n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n \n {% } %}\n
\n
\n {% } %}\n
'
- },
- components: [
- {
- label: 'Label',
- key: 'label',
- type: 'textfield',
- input: true,
- validate: {
- required: true
- }
- },
- {
- label: 'onClick',
- key: 'onClick',
- type: 'textarea',
- editor: 'ace',
- input: true,
- validate: {
- required: true
- }
- }
- ],
- defaultValue: []
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.time.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.time.js
deleted file mode 100644
index bbd1b6ce..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.time.js
+++ /dev/null
@@ -1,34 +0,0 @@
-export default [
- {
- type: 'checkbox',
- input: true,
- key: 'enableTime',
- label: 'Enable Time Input',
- tooltip: 'Enables time input for this field.',
- weight: 0
- },
- {
- type: 'number',
- input: true,
- key: 'timePicker.hourStep',
- label: 'Hour Step Size',
- tooltip: 'The number of hours to increment/decrement in the time picker.',
- weight: 10
- },
- {
- type: 'number',
- input: true,
- key: 'timePicker.minuteStep',
- label: 'Minute Step Size',
- tooltip: 'The number of minutes to increment/decrement in the time picker.',
- weight: 20
- },
- {
- type: 'checkbox',
- input: true,
- key: 'timePicker.showMeridian',
- label: '12 Hour Time (AM/PM)',
- tooltip: 'Display time in 12 hour time with AM/PM.',
- weight: 30
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.validation.js
deleted file mode 100644
index 775f3a4a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/editForm/DateTime.edit.validation.js
+++ /dev/null
@@ -1,82 +0,0 @@
-export default [
- {
- type: 'checkbox',
- input: true,
- key: 'enableMinDateInput',
- label: 'Use Input to add moment.js for minDate',
- persistent: false,
- weight: 10,
- tooltip: 'Enables to use input for moment functions instead of calendar.'
- },
- {
- type: 'datetime',
- input: true,
- key: 'datePicker.minDate',
- label: 'Use calendar to set minDate',
- skipMerge: true,
- weight: 10,
- tooltip: 'Enables to use calendar to set date.',
- customConditional({ data, component }) {
- if (component.datePicker && component.datePicker.minDate && component.datePicker.minDate.indexOf('moment') !== -1) {
- return false;
- }
- return !data.enableMinDateInput;
- },
- },
- {
- type: 'textfield',
- input: true,
- enableTime: false,
- key: 'datePicker.minDate',
- skipMerge: true,
- label: 'Minimum Date',
- weight: 10,
- tooltip: 'The minimum date that can be picked. You can also use Moment.js functions. For example: \n \n moment().subtract(10, \'days\')',
- customConditional({ data, component }) {
- if (component.datePicker && component.datePicker.minDate && component.datePicker.minDate.indexOf('moment') !== -1) {
- return true;
- }
- return data.enableMinDateInput;
- },
- },
- {
- type: 'checkbox',
- input: true,
- key: 'enableMaxDateInput',
- label: 'Use Input to add moment.js for maxDate',
- persistent: false,
- weight: 20,
- tooltip: 'Enables to use input for moment functions instead of calendar.'
- },
- {
- type: 'datetime',
- input: true,
- key: 'datePicker.maxDate',
- skipMerge: true,
- label: 'Use calendar to set maxDate',
- weight: 20,
- tooltip: 'Enables to use calendar to set date.',
- customConditional({ data, component }) {
- if (component.datePicker && component.datePicker.maxDate && component.datePicker.maxDate.indexOf('moment') !== -1) {
- return false;
- }
- return !data.enableMaxDateInput;
- },
- },
- {
- type: 'textfield',
- input: true,
- enableTime: false,
- key: 'datePicker.maxDate',
- skipMerge: true,
- label: 'Maximum Date',
- tooltip: 'The maximum date that can be picked. You can also use Moment.js functions. For example: \n \n moment().add(10, \'days\')',
- weight: 20,
- customConditional({ data, component }) {
- if (component.datePicker && component.datePicker.maxDate && component.datePicker.maxDate.indexOf('moment') !== -1) {
- return true;
- }
- return data.enableMaxDateInput;
- },
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp1.js
deleted file mode 100644
index d46462af..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp1.js
+++ /dev/null
@@ -1,44 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'datetime',
- 'validate': {
- 'custom': '',
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'timePicker': {
- 'arrowkeys': true,
- 'mousewheel': true,
- 'readonlyInput': false,
- 'showMeridian': true,
- 'minuteStep': 1,
- 'hourStep': 1
- },
- 'datePicker': {
- 'datepickerMode': 'day',
- 'yearRange': '20',
- 'maxMode': 'year',
- 'minMode': 'day',
- 'initDate': '',
- 'startingDay': 0,
- 'showWeeks': true
- },
- 'datepickerMode': 'day',
- 'defaultDate': '',
- 'enableTime': true,
- 'enableDate': true,
- 'format': 'yyyy-MM-dd hh:mm a',
- 'placeholder': 'Enter the date',
- 'key': 'date',
- 'label': 'Date',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp10.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp10.js
deleted file mode 100644
index 6f4bb586..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp10.js
+++ /dev/null
@@ -1,84 +0,0 @@
-export default {
- _id: '62d5264f8673caaf3e7afc14',
- title: 'dateTime2',
- name: 'dateTime2',
- path: 'datetime2',
- type: 'form',
- display: 'form',
- tags: [],
- owner: '6137352490eb201aaff6e79f',
- components: [
- {
- label: 'Date / Time',
- tableView: true,
- datePicker: { disableWeekends: false, disableWeekdays: false },
- enableMinDateInput: false,
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'viewer',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: true,
- noCalendar: false,
- format: 'yyyy-MM-dd hh:mm a',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null,
- },
- },
- {
- label: 'Text Field',
- widget: {
- type: 'calendar',
- altInput: true,
- allowInput: true,
- clickOpens: true,
- enableDate: true,
- enableTime: true,
- mode: 'single',
- noCalendar: false,
- format: 'yyyy-MM-dd hh:mm a',
- dateFormat: 'yyyy-MM-ddTHH:mm:ssZ',
- useLocaleSettings: false,
- hourIncrement: 1,
- minuteIncrement: 5,
- 'time_24hr': false,
- saveAs: 'text',
- displayInTimezone: 'viewer',
- locale: 'en',
- },
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- settings: {},
- properties: {},
- project: '61555aa912cab1f874bb17fc',
- controller: '',
- revisions: '',
- submissionRevisions: '',
- '_vid': 0,
- created: '2022-07-18T09:22:23.287Z',
- modified: '2022-11-14T13:40:52.276Z',
- machineName: 'tmcogwpnxqfxgxy:dateTime2',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp11.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp11.js
deleted file mode 100644
index d296bd3f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp11.js
+++ /dev/null
@@ -1,53 +0,0 @@
-export default {
- title: '5628',
- name: '5628',
- path: '5628',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Date / Time',
- format: 'dd-MM-yyyy',
- tableView: false,
- datePicker: {
- disableWeekends: false,
- disableWeekdays: false,
- },
- enableTime: false,
- enableMinDateInput: false,
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'viewer',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: false,
- noCalendar: false,
- format: 'dd-MM-yyyy',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null,
- },
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- created: '2022-11-16T10:06:19.656Z',
- modified: '2022-11-16T13:25:55.044Z',
- machineName: 'aabvnyfwnstnovd:5628',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp12.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp12.js
deleted file mode 100644
index 21253216..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp12.js
+++ /dev/null
@@ -1,53 +0,0 @@
-export default {
- _id: '6374b809ef6e5f56bfa91978',
- title: 'hhhhhh',
- name: 'hhhhhh',
- path: 'hhhhhh',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Date / Time',
- format: 'MMMM/yy',
- tableView: true,
- datePicker: {
- disableWeekends: false,
- disableWeekdays: false,
- },
- enableMinDateInput: false,
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'viewer',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: true,
- noCalendar: false,
- format: 'MMMM/yy',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null,
- },
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- created: '2022-11-16T10:14:33.808Z',
- modified: '2022-11-18T10:18:51.790Z',
- machineName: 'aabvnyfwnstnovd:hhhhhh',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp2.js
deleted file mode 100644
index f94004be..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp2.js
+++ /dev/null
@@ -1,41 +0,0 @@
-export default {
- 'type': 'datetime',
- 'validate': {
- 'custom': '',
- 'required': false
- },
- 'shortcutButtons': [
- {
- 'label': 'Today',
- 'onClick': 'date = new Date(\'2020-10-10T00:00:00\');'
- }
- ],
- 'persistent': true,
- 'protected': false,
- 'timePicker': {
- 'arrowkeys': true,
- 'mousewheel': true,
- 'readonlyInput': false,
- 'showMeridian': true,
- 'minuteStep': 1,
- 'hourStep': 1
- },
- 'datePicker': {
- 'datepickerMode': 'day',
- 'yearRange': '20',
- 'maxMode': 'year',
- 'minMode': 'day',
- 'initDate': '',
- 'startingDay': 0,
- 'showWeeks': true
- },
- 'datepickerMode': 'day',
- 'defaultDate': '',
- 'enableTime': true,
- 'enableDate': true,
- 'format': 'yyyy-MM-dd',
- 'key': 'date',
- 'label': 'Date',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp3.js
deleted file mode 100644
index d16b4fb3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp3.js
+++ /dev/null
@@ -1,38 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Date / Time',
- tableView: false,
- enableMinDateInput: false,
- datePicker: { disableWeekends: false, disableWeekdays: false },
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'utc',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: true,
- noCalendar: false,
- format: 'yyyy-MM-dd hh:mm a',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null
- }
- },
- { label: 'Submit', showValidations: false, tableView: false, key: 'submit', type: 'button', input: true }
- ],
- title: 'test11',
- display: 'form',
- name: 'test11',
- path: 'test11',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp5.js
deleted file mode 100644
index 66afd877..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp5.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export default {
- _id: '60e41b43e27f1e926447370b',
- type: 'form',
- components: [
- {
- label: 'Date / Time',
- format: 'MM/dd/yyyyy',
- tableView: false,
- enableMinDateInput: true,
- datePicker: {
- minDate: "moment().startOf('month')",
- disableFunction: 'date.getDate() !== 1',
- disableWeekends: false,
- disableWeekdays: false
- },
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'viewer',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: true,
- noCalendar: false,
- format: 'MM/dd/yyyyy',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: "moment().startOf('month')",
- disableWeekends: false,
- disableWeekdays: false,
- disableFunction: 'date.getDate() !== 1',
- maxDate: null
- }
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: true, input: true, tableView: false }
- ],
- title: 'test',
- display: 'form',
- name: 'test',
- path: 'test',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp6.js
deleted file mode 100644
index 545a20bd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp6.js
+++ /dev/null
@@ -1,47 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Date / Time',
- format: 'hh:mm a',
- tableView: false,
- enableDate: false,
- enableMinDateInput: false,
- datePicker: { disableWeekends: false, disableWeekdays: false },
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'viewer',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: true,
- noCalendar: true,
- format: 'hh:mm a',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null,
- },
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- title: 'FIO-3743',
- display: 'form',
- name: 'fio3743',
- path: 'fio3743',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp7.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp7.js
deleted file mode 100644
index 7cca21c4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp7.js
+++ /dev/null
@@ -1,51 +0,0 @@
-export default {
- _id: '61c1e89cc6eafd71c3175f0d',
- title: 'Date Time',
- name: 'dateTime',
- path: 'datetime',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Date / Time',
- format: 'yyyy-MM-dd',
- tableView: true,
- datePicker: { disableWeekends: false, disableWeekdays: false },
- enableTime: false,
- enableMinDateInput: false,
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- input: true,
- widget: {
- type: 'calendar',
- displayInTimezone: 'viewer',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: false,
- noCalendar: false,
- format: 'yyyy-MM-dd',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null,
- },
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- settings: {},
- properties: {},
- project: '61c101d0792d8ffc9be99694',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp8.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp8.js
deleted file mode 100644
index 92e52a57..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp8.js
+++ /dev/null
@@ -1,50 +0,0 @@
-export default {
- 'title': 'test11',
- 'name': 'test11',
- 'path': 'test11',
- 'type': 'form',
- 'display': 'form',
- 'components': [{
- 'label': 'Date / Time',
- 'format': 'yyyy-MM-dd',
- 'tableView': false,
- 'enableMinDateInput': false,
- 'datePicker': {
- 'disableWeekends': false,
- 'disableWeekdays': false
- },
- 'enableMaxDateInput': false,
- 'multiple': true,
- 'validate': {
- 'required': true
- },
- 'key': 'dateTime',
- 'type': 'datetime',
- 'input': true,
- 'widget': {
- 'type': 'calendar',
- 'displayInTimezone': 'viewer',
- 'locale': 'en',
- 'useLocaleSettings': false,
- 'allowInput': true,
- 'mode': 'single',
- 'enableTime': true,
- 'noCalendar': false,
- 'format': 'yyyy-MM-dd',
- 'hourIncrement': 1,
- 'minuteIncrement': 1,
- 'time_24hr': false,
- 'minDate': null,
- 'disableWeekends': false,
- 'disableWeekdays': false,
- 'maxDate': null
- }
- }, {
- 'type': 'button',
- 'label': 'Submit',
- 'key': 'submit',
- 'disableOnInvalid': true,
- 'input': true,
- 'tableView': false
- }],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp9.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp9.js
deleted file mode 100644
index ab56c0cd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/comp9.js
+++ /dev/null
@@ -1,93 +0,0 @@
-export default {
- _id: '625e8bb06c97f942effd7b8b',
- title: 'Date Time',
- name: 'dateTime',
- path: 'datetime',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Date / Time',
- displayInTimezone: 'location',
- format: 'yyyy-MM-dd',
- tableView: false,
- datePicker: {
- disableWeekends: false,
- disableWeekdays: false
- },
- enableTime: false,
- enableMinDateInput: false,
- enableMaxDateInput: false,
- key: 'dateTime',
- type: 'datetime',
- timezone: 'America/Chicago',
- input: true,
- widget: {
- type: 'calendar',
- timezone: 'America/Chicago',
- displayInTimezone: 'location',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: false,
- noCalendar: false,
- format: 'yyyy-MM-dd',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null
- }
- },
- {
- label: 'Date / Time',
- displayInTimezone: 'location',
- format: 'yyyy-MM-dd',
- tableView: false,
- datePicker: {
- disableWeekends: false,
- disableWeekdays: false
- },
- enableTime: false,
- enableMinDateInput: false,
- enableMaxDateInput: false,
- key: 'dateTime1',
- type: 'datetime',
- timezone: 'Asia/Seoul',
- input: true,
- widget: {
- type: 'calendar',
- timezone: 'Asia/Seoul',
- displayInTimezone: 'location',
- locale: 'en',
- useLocaleSettings: false,
- allowInput: true,
- mode: 'single',
- enableTime: false,
- noCalendar: false,
- format: 'yyyy-MM-dd',
- hourIncrement: 1,
- minuteIncrement: 1,
- 'time_24hr': false,
- minDate: null,
- disableWeekends: false,
- disableWeekdays: false,
- maxDate: null
- }
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
- settings: {},
- properties: {},
- project: '61c101d0792d8ffc9be99694',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/index.js
deleted file mode 100644
index 715fb865..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp5 from './comp5';
-export comp6 from './comp6';
-export comp7 from './comp7';
-export comp8 from './comp8';
-export comp9 from './comp9';
-export comp10 from './comp10';
-export comp11 from './comp11';
-export comp12 from './comp12';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/values.js
deleted file mode 100644
index 5dd0c45f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/datetime/fixtures/values.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default [
- '2019-11-06T18:00:00.000',
- '2019-11-25T20:11:21.887',
-];
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/Day.form.js b/web-client/core/themes/italia/static/formio/css/src/components/day/Day.form.js
deleted file mode 100644
index 928696ad..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/Day.form.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import Components from '../Components';
-import DayEditData from './editForm/Day.edit.data';
-import DayEditDisplay from './editForm/Day.edit.display';
-import DayEditValidation from './editForm/Day.edit.validation';
-import DayEditDay from './editForm/Day.edit.day';
-import DayEditMonth from './editForm/Day.edit.month';
-import DayEditYear from './editForm/Day.edit.year';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: DayEditDisplay
- },
- {
- key: 'data',
- components: DayEditData,
- },
- {
- key: 'validation',
- components: DayEditValidation
- },
- {
- key: 'day',
- label: 'Day',
- weight: 3,
- components: DayEditDay
- },
- {
- key: 'month',
- label: 'Month',
- weight: 3,
- components: DayEditMonth
- },
- {
- key: 'year',
- label: 'Year',
- weight: 3,
- components: DayEditYear
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/Day.js b/web-client/core/themes/italia/static/formio/css/src/components/day/Day.js
deleted file mode 100644
index add4bb96..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/Day.js
+++ /dev/null
@@ -1,643 +0,0 @@
-import _ from 'lodash';
-import moment from 'moment';
-import Field from '../_classes/field/Field';
-import { boolValue, componentValueTypes, getComponentSavedTypes, getLocaleDateFormatInfo } from '../../utils/utils';
-
-export default class DayComponent extends Field {
- static schema(...extend) {
- return Field.schema({
- type: 'day',
- label: 'Day',
- key: 'day',
- fields: {
- day: {
- type: 'number',
- placeholder: '',
- required: false
- },
- month: {
- type: 'select',
- placeholder: '',
- required: false
- },
- year: {
- type: 'number',
- placeholder: '',
- required: false
- }
- },
- dayFirst: false
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Day',
- group: 'advanced',
- icon: 'calendar',
- documentation: '/userguide/form-building/advanced-components#day',
- weight: 50,
- schema: DayComponent.schema()
- };
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: ['isDateEqual', 'isNotDateEqual', 'isEmpty', 'isNotEmpty','dateLessThan', 'dateGreaterThan', 'dateLessThanOrEqual','dateGreaterThanOrEqual'],
- };
- }
-
- static savedValueTypes(schema) {
- schema = schema || {};
- return getComponentSavedTypes(schema) || [componentValueTypes.string];
- }
-
- constructor(component, options, data) {
- if (component.maxDate && component.maxDate.indexOf('moment(') === -1) {
- component.maxDate = moment(component.maxDate, 'YYYY-MM-DD').toISOString();
- }
- if (component.minDate && component.minDate.indexOf('moment(') === -1) {
- component.minDate = moment(component.minDate, 'YYYY-MM-DD').toISOString();
- }
- super(component, options, data);
- }
-
- static get serverConditionSettings() {
- return DayComponent.conditionOperatorsSettings;
- }
-
- /**
- * The empty value for day component.
- *
- * @return {'00/00/0000'}
- */
- get emptyValue() {
- return '00/00/0000';
- }
-
- get valueMask() {
- return /^\d{2}\/\d{2}\/\d{4}$/;
- }
-
- get dayRequired() {
- return this.showDay && _.get(this.component, 'fields.day.required', false);
- }
-
- get showDay() {
- return !_.get(this.component, 'fields.day.hide', false);
- }
-
- get monthRequired() {
- return this.showMonth && _.get(this.component, 'fields.month.required', false);
- }
-
- get showMonth() {
- return !_.get(this.component, 'fields.month.hide', false);
- }
-
- get yearRequired() {
- return this.showYear && _.get(this.component, 'fields.year.required', false);
- }
-
- get showYear() {
- return !_.get(this.component, 'fields.year.hide', false);
- }
-
- get defaultSchema() {
- return DayComponent.schema();
- }
-
- get shouldDisabled() {
- return super.shouldDisabled || this.parentDisabled;
- }
-
- get inputInfo() {
- const info = super.elementInfo();
- info.type = 'input';
- info.attr.type = 'hidden';
- info.changeEvent = 'input';
- return info;
- }
-
- inputDefinition(name) {
- let min, max;
- if (name === 'day') {
- min = 1;
- max = 31;
- }
- if (name === 'month') {
- min = 1;
- max = 12;
- }
- if (name === 'year') {
- min = _.get(this.component, 'fields.year.minYear', 1900) || 1900;
- max = _.get(this.component, 'fields.year.maxYear', 2030) || 1900;
- }
- return {
- type: 'input',
- ref: name,
- attr: {
- id: `${this.component.key}-${name}`,
- class: `form-control ${this.transform('class', `formio-day-component-${name}`)}`,
- type: this.component.fields[name].type === 'select' ? 'select' : 'number',
- placeholder: this.component.fields[name].placeholder,
- step: 1,
- min,
- max,
- }
- };
- }
-
- selectDefinition(name) {
- return {
- multiple: false,
- ref: name,
- widget: 'html5',
- attr: {
- id: `${this.component.key}-${name}`,
- class: 'form-control',
- name,
- lang: this.options.language
- }
- };
- }
-
- get days() {
- if (this._days) {
- return this._days;
- }
- this._days = [
- { value: '', label: _.get(this.component, 'fields.day.placeholder', '') }
- ];
- for (let x = 1; x <= 31; x++) {
- this._days.push({
- value: x,
- label: x.toString()
- });
- }
- return this._days;
- }
-
- get months() {
- if (this._months) {
- return this._months;
- }
- this._months = [
- {
- value: '',
- label: _.get(this.component, 'fields.month.placeholder') || (this.hideInputLabels ? this.t('Month') : '')
- },
- { value: 1, label: 'January' },
- { value: 2, label: 'February' },
- { value: 3, label: 'March' },
- { value: 4, label: 'April' },
- { value: 5, label: 'May' },
- { value: 6, label: 'June' },
- { value: 7, label: 'July' },
- { value: 8, label: 'August' },
- { value: 9, label: 'September' },
- { value: 10, label: 'October' },
- { value: 11, label: 'November' },
- { value: 12, label: 'December' }
- ];
- return this._months;
- }
-
- get years() {
- if (this._years) {
- return this._years;
- }
- this._years = [
- { value: '', label: _.get(this.component, 'fields.year.placeholder', '') }
- ];
- const minYears = _.get(this.component, 'fields.year.minYear', 1900) || 1900;
- const maxYears = _.get(this.component, 'fields.year.maxYear', 2030) || 2030;
- for (let x = minYears; x <= maxYears; x++) {
- this._years.push({
- value: x,
- label: x.toString()
- });
- }
- return this._years;
- }
-
- setErrorClasses(elements, dirty, hasError) {
- super.setErrorClasses(elements, dirty, hasError);
- super.setErrorClasses([this.refs.day, this.refs.month, this.refs.year], dirty, hasError);
- }
-
- removeInputError(elements) {
- super.removeInputError([this.refs.day, this.refs.month, this.refs.year]);
- super.removeInputError(elements);
- }
-
- init() {
- super.init();
- this.validators = this.validators.concat(['day', 'maxDate', 'minDate', 'minYear', 'maxYear']);
-
- const minYear = this.component.fields.year.minYear;
- const maxYear = this.component.fields.year.maxYear;
- this.component.maxYear = maxYear;
- this.component.minYear = minYear;
-
- const dateFormatInfo = getLocaleDateFormatInfo(this.options.language);
- this.dayFirst = this.component.useLocaleSettings
- ? dateFormatInfo.dayFirst
- : this.component.dayFirst;
- }
-
- render() {
- if (this.isHtmlRenderMode()) {
- return super.render(this.renderTemplate('input'));
- }
-
- return super.render(this.renderTemplate('day', {
- dayFirst: this.dayFirst,
- showDay: this.showDay,
- showMonth: this.showMonth,
- showYear: this.showYear,
- day: this.renderField('day'),
- month: this.renderField('month'),
- year: this.renderField('year'),
- }));
- }
-
- renderField(name) {
- if (this.component.fields[name].type === 'select') {
- return this.renderTemplate('select', {
- input: this.selectDefinition(name),
- selectOptions: this[`${name}s`].reduce((html, option) =>
- html + this.renderTemplate('selectOption', {
- option,
- selected: false,
- attrs: {}
- }), ''
- ),
- });
- }
- else {
- return this.renderTemplate('input', {
- prefix: this.prefix,
- suffix: this.suffix,
- input: this.inputDefinition(name)
- });
- }
- }
-
- attach(element) {
- this.loadRefs(element, { day: 'single', month: 'single', year: 'single', input: 'multiple' });
- const superAttach = super.attach(element);
-
- const updateValueAndSaveFocus = (element, name) => () => {
- try {
- this.saveCaretPosition(element, name);
- }
- catch (err) {
- console.warn('An error occurred while trying to save caret position', err);
- }
- this.updateValue(null, {
- modified: true,
- });
- };
-
- if (this.shouldDisabled) {
- this.setDisabled(this.refs.day, true);
- this.setDisabled(this.refs.month, true);
- this.setDisabled(this.refs.year, true);
- if (this.refs.input) {
- this.refs.input.forEach((input) => this.setDisabled(input, true));
- }
- }
- else {
- this.addEventListener(this.refs.day, 'input', updateValueAndSaveFocus(this.refs.day, 'day'));
- // TODO: Need to rework this to work with day select as well.
- // Change day max input when month changes.
- this.addEventListener(this.refs.month, 'input', () => {
- const maxDay = this.refs.year ? parseInt(
- new Date(this.refs.year.value, this.refs.month.value, 0).getDate(),
- 10
- )
- : '';
- const day = this.getFieldValue('day');
- if (!this.component.fields.day.hide && maxDay) {
- this.refs.day.max = maxDay;
- }
- if (maxDay && day > maxDay) {
- this.refs.day.value = this.refs.day.max;
- }
- updateValueAndSaveFocus(this.refs.month, 'month')();
- });
- this.addEventListener(this.refs.year, 'input', updateValueAndSaveFocus(this.refs.year, 'year'));
- this.addEventListener(this.refs.input, this.info.changeEvent, () => this.updateValue(null, {
- modified: true
- }));
- [this.refs.day, this.refs.month, this.refs.year].filter((element) => !!element).forEach((element) => {
- super.addFocusBlurEvents(element);
- });
- }
- this.setValue(this.dataValue);
- // Force the disabled state with getters and setters.
- this.disabled = this.shouldDisabled;
- return superAttach;
- }
-
- validateRequired(setting, value) {
- const { day, month, year } = this.parts;
- if (this.dayRequired && !day) {
- return false;
- }
-
- if (this.monthRequired && !month) {
- return false;
- }
-
- if (this.yearRequired && !year) {
- return false;
- }
-
- if (!boolValue(setting)) {
- return true;
- }
- return !this.isEmpty(value);
- }
-
- set disabled(disabled) {
- super.disabled = disabled;
- if (!this.refs.year || !this.refs.month || !this.refs.day) {
- return;
- }
- if (disabled) {
- this.refs.year.setAttribute('disabled', 'disabled');
- this.refs.month.setAttribute('disabled', 'disabled');
- this.refs.day.setAttribute('disabled', 'disabled');
- }
- else {
- this.refs.year.removeAttribute('disabled');
- this.refs.month.removeAttribute('disabled');
- this.refs.day.removeAttribute('disabled');
- }
- }
-
- normalizeValue(value) {
- if (!value || this.valueMask.test(value)) {
- return value;
- }
- const dateParts = [];
- const valueParts = value.split('/');
- const [DAY, MONTH, YEAR] = this.component.dayFirst ? [0, 1, 2] : [1, 0, 2];
- const defaultValue = this.component.defaultValue ? this.component.defaultValue.split('/') : '';
-
- const getNextPart = (shouldTake, defaultValue) =>
- dateParts.push(shouldTake ? valueParts.shift() : defaultValue);
-
- if (this.dayFirst) {
- getNextPart(this.showDay, defaultValue ? defaultValue[DAY] : '00');
- }
-
- getNextPart(this.showMonth, defaultValue ? defaultValue[MONTH] : '00');
-
- if (!this.dayFirst) {
- getNextPart(this.showDay, defaultValue ? defaultValue[DAY] : '00');
- }
-
- getNextPart(this.showYear, defaultValue ? defaultValue[YEAR] : '0000');
-
- return dateParts.join('/');
- }
-
- /**
- * Set the value at a specific index.
- *
- * @param index
- * @param value
- */
- setValueAt(index, value) {
- // temporary solution to avoid input reset
- // on invalid date.
- if (!value || value === 'Invalid date') {
- return null;
- }
- const parts = value.split('/');
- let day;
- if (this.component.dayFirst) {
- day = parts.shift();
- }
- const month = parts.shift();
- if (!this.component.dayFirst) {
- day = parts.shift();
- }
- const year = parts.shift();
-
- if (this.refs.day && this.showDay) {
- this.refs.day.value = day === '00' ? '' : parseInt(day, 10);
- }
- if (this.refs.month && this.showMonth) {
- this.refs.month.value = month === '00' ? '' : parseInt(month, 10);
- }
- if (this.refs.year && this.showYear) {
- this.refs.year.value = year === '0000' ? '' : parseInt(year, 10);
- }
- }
-
- getFieldValue(name) {
- const parts = this.dataValue ? this.dataValue.split('/') : [];
- let val = 0;
-
- switch (name) {
- case 'month':
- val = parts[this.dayFirst ? 1 : 0];
- break;
- case 'day':
- val = parts[this.dayFirst ? 0 : 1];
- break;
- case 'year':
- val = parts[2];
- break;
- }
-
- val = parseInt(val, 10);
- return (!_.isNaN(val) && _.isNumber(val)) ? val : 0;
- }
-
- get parts() {
- return {
- day: this.getFieldValue('day'),
- month: this.getFieldValue('month'),
- year: this.getFieldValue('year'),
- };
- }
-
- /**
- * Get the format for the value string.
- * @returns {string}
- */
- get format() {
- let format = '';
- if (this.component.dayFirst && this.showDay) {
- format += 'D/';
- }
- if (this.showMonth) {
- format += 'M/';
- }
- if (!this.component.dayFirst && this.showDay) {
- format += 'D/';
- }
- if (this.showYear) {
- format += 'YYYY';
- return format;
- }
- else {
- // Trim off the "/" from the end of the format string.
- return format.length ? format.substring(0, format.length - 1) : format;
- }
- }
-
- /**
- * Return the date for this component.
- *
- * @param value
- * @return {*}
- */
- getDate(value) {
- let defaults = [], day, month, year;
- // Map positions to identifiers to get default values for each part of day
- const [DAY, MONTH, YEAR] = this.component.dayFirst ? [0, 1, 2] : [1, 0, 2];
- const defaultValue = value || this.component.defaultValue;
- if (defaultValue) {
- defaults = defaultValue.split('/').map(x => parseInt(x, 10));
- }
-
- if (this.showDay && this.refs.day) {
- day = parseInt(this.refs.day.value, 10);
- }
- if (day === undefined || _.isNaN(day)) {
- day = defaults[DAY] && !_.isNaN(defaults[DAY]) ? defaults[DAY] : 0;
- }
-
- if (this.showMonth && this.refs.month) {
- // Months are 0 indexed.
- month = parseInt(this.refs.month.value, 10);
- }
- if (month === undefined || _.isNaN(month)) {
- month = defaults[MONTH] && !_.isNaN(defaults[MONTH]) ? defaults[MONTH] : 0;
- }
-
- if (this.showYear && this.refs.year) {
- year = parseInt(this.refs.year.value);
- }
- if (year === undefined || _.isNaN(year)) {
- year = defaults[YEAR] && !_.isNaN(defaults[YEAR]) ? defaults[YEAR] : 0;
- }
-
- let result;
- if (!day && !month && !year) {
- return null;
- }
-
- // add trailing zeros if the data is showed
- day = this.showDay ? day.toString().padStart(2, 0) : '';
- month = this.showMonth ? month.toString().padStart(2, 0) : '';
- year = this.showYear ? year.toString().padStart(4, 0) : '';
-
- if (this.component.dayFirst) {
- result = `${day}${this.showDay && this.showMonth || this.showDay && this.showYear ? '/' : ''}${month}${this.showMonth && this.showYear ? '/' : ''}${year}`;
- }
- else {
- result = `${month}${this.showDay && this.showMonth || this.showMonth && this.showYear ? '/' : ''}${day}${this.showDay && this.showYear ? '/' : ''}${year}`;
- }
-
- return result;
- }
-
- /**
- * Return the date object for this component.
- * @returns {Date}
- */
- get date() {
- return this.getDate();
- }
-
- /**
- * Return the raw value.
- *
- * @returns {Date}
- */
- get validationValue() {
- return this.dataValue;
- }
-
- getValue() {
- const result = super.getValue();
- return (!result) ? this.dataValue : result;
- }
-
- /**
- * Get the value at a specific index.
- *
- * @param index
- * @returns {*}
- */
- getValueAt(index) {
- const date = this.date || this.emptyValue;
- if (date) {
- this.refs.input[index].value = date;
- return this.refs.input[index].value;
- }
- else {
- this.refs.input[index].value = '';
- return null;
- }
- }
-
- /**
- * Get the input value of the date.
- *
- * @param value
- * @return {null}
- */
- getValueAsString(value) {
- return this.getDate(value) || '';
- }
-
- focus(field) {
- if (field && typeof field === 'string' && this.refs[field]) {
- this.refs[field].focus();
- }
- else if (this.dayFirst && this.showDay || !this.dayFirst && !this.showMonth && this.showDay) {
- this.refs.day?.focus();
- }
- else if (this.dayFirst && !this.showDay && this.showMonth || !this.dayFirst && this.showMonth) {
- this.refs.month?.focus();
- }
- else if (!this.showDay && !this.showDay && this.showYear) {
- this.refs.year?.focus();
- }
- }
-
- restoreCaretPosition() {
- if (this.root?.currentSelection) {
- const { selection, index } = this.root.currentSelection;
- if (this.refs[index]) {
- const input = this.refs[index];
- const isInputRangeSelectable = (i) => /text|search|password|tel|url/i.test(i?.type || '');
- if (isInputRangeSelectable(input)) {
- input.setSelectionRange(...selection);
- }
- }
- }
- }
-
- isPartialDay(value) {
- if (!value) {
- return false;
- }
- const [DAY, MONTH, YEAR] = this.component.dayFirst ? [0, 1, 2] : [1, 0, 2];
- const values = value.split('/');
- return (values[DAY] === '00' || values[MONTH] === '00' || values[YEAR] === '0000');
- }
-
- getValidationFormat() {
- return this.dayFirst ? 'DD-MM-YYYY' : 'MM-DD-YYYY';
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/Day.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/day/Day.unit.js
deleted file mode 100644
index e83bfcb8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/Day.unit.js
+++ /dev/null
@@ -1,271 +0,0 @@
-import Formio from '../../Formio';
-import assert from 'power-assert';
-
-import Harness from '../../../test/harness';
-import DayComponent from './Day';
-
-import {
- comp1,
- comp2,
- comp3,
- comp4,
- comp5,
- comp6,
-} from './fixtures';
-import PanelComponent from '../panel/Panel';
-
-describe('Day Component', () => {
- it('Should build a day component', () => {
- return Harness.testCreate(DayComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="number"]', 2);
- Harness.testElements(component, 'select', 1);
- });
- });
-
- it('Should change the max day when the month changes', (done) => {
- Harness.testCreate(DayComponent, comp1).then((component) => {
- Harness.testElements(component, 'option', 13);
- assert(!!component.refs.year, 'There should be a year');
- // Set the year to a non-leap year.
- component.refs.year.value = 2017;
- component.setSelectValue(component.refs.month, '1');
- component.refs.month.dispatchEvent(new Event('input'));
- assert.equal(component.refs.day.max, '31');
-
- component.setSelectValue(component.refs.month, '2');
- component.refs.month.dispatchEvent(new Event('input'));
- assert.equal(component.refs.day.max, '28');
-
- component.setSelectValue(component.refs.month, '3');
- component.refs.month.dispatchEvent(new Event('input'));
- assert.equal(component.refs.day.max, '31');
-
- component.setSelectValue(component.refs.month, '4');
- component.refs.month.dispatchEvent(new Event('input'));
- assert.equal(component.refs.day.max, '30');
-
- // Set to a leap year.
- component.refs.year.value = 2020;
- component.setSelectValue(component.refs.month, '1');
- component.refs.month.dispatchEvent(new Event('input'));
- assert.equal(component.refs.day.max, '31');
-
- component.setSelectValue(component.refs.month, '2');
- component.refs.month.dispatchEvent(new Event('input'));
- assert.equal(component.refs.day.max, '29');
-
- component.setSelectValue(component.refs.month, '3');
- component.refs.month.dispatchEvent(new Event('input'));
- assert.equal(component.refs.day.max, '31');
-
- component.setSelectValue(component.refs.month, '4');
- component.refs.month.dispatchEvent(new Event('input'));
- assert.equal(component.refs.day.max, '30');
-
- done();
- });
- });
-
- it('Should put the month select first', (done) => {
- Harness.testCreate(DayComponent, comp1).then((component) => {
- const inputs = Harness.testElements(component, '.form-control', 4);
- assert.equal(inputs[0].id, `${component.component.key}-month`);
- assert.equal(inputs[1].id, `${component.component.key}-day`);
- assert.equal(inputs[2].id, `${component.component.key}-year`);
- component.setValue('03/20/2017');
- assert.equal(component.getValue(), '03/20/2017');
- done();
- });
- });
-
- it('Should put the day select first on configuration', (done) => {
- comp1.dayFirst = true;
- Harness.testCreate(DayComponent, comp1).then((component) => {
- const inputs = Harness.testElements(component, '.form-control', 4);
- assert.equal(inputs[0].id, `${component.component.key}-day`);
- assert.equal(inputs[1].id, `${component.component.key}-month`);
- assert.equal(inputs[2].id, `${component.component.key}-year`);
- component.setValue('20/03/2017');
- assert.equal(component.getValue(), '20/03/2017');
- done();
- });
- });
-
- it('Should not allow invalid days', (done) => {
- comp1.dayFirst = false;
- Harness.testCreate(DayComponent, comp1).then((component) => {
- component.on('componentError', (err) => {
- assert.equal(err.message, 'Date is not a valid day.');
- assert.equal(err.component.key, 'date');
- done();
- });
-
- component.on('componentChange', () => {
- component.checkValidity();
- });
-
- component.setValue('3/40/2017');
- });
- });
-
- it('Should ignore invalid months and use zeros as default', (done) => {
- comp1.dayFirst = false;
-
- Harness.testCreate(DayComponent, comp1).then((component) => {
- component.setValue('15/20/2017');
- assert.equal(component.getValue(), '00/20/2017');
- done();
- });
- });
-
- it('Should keep day value when switching months', (done) => {
- Harness.testCreate(DayComponent, comp1).then((component) => {
- component.setValue('01/05/2018');
- assert.equal(component.getValue(), '01/05/2018');
- component.on('componentChange', () => {
- assert.equal(component.getValue(), '02/05/2018');
- done();
- });
- component.refs.month.value = 2;
- component.refs.month.dispatchEvent(new Event('input'));
- });
- });
-
- it('Should adjust day value when day is great then maxDay of month', (done) => {
- Harness.testCreate(DayComponent, comp1).then((component) => {
- component.setValue('01/31/2018');
- assert.equal(component.getValue(), '01/31/2018');
- component.on('componentChange', () => {
- assert.equal(component.getValue(), '02/28/2018');
- done();
- });
- component.refs.month.value = 2;
- component.refs.month.dispatchEvent(new Event('input'));
- });
- });
-
- it('Should validate required fields', (done) => {
- Harness.testCreate(DayComponent, comp2).then((component) => {
- component.pristine = false;
- const valid = () => component.checkValidity(component.data, true);
- const tests = {
- '12/18/2018': true,
- '12/00/0000': false,
- '00/18/0000': false,
- '00/00/2018': false,
- '01/05/2018': true,
- };
-
- for (const v in tests) {
- component.setValue(v);
- assert.equal(valid(), tests[v]);
- }
-
- done();
- });
- });
-
- it('Should properly validate min-max dates when dayFirst is checked', (done) => {
- Harness.testCreate(DayComponent, comp3).then((component) => {
- component.setValue('01/02/2020');
- assert(!component.checkValidity(component.data, true), 'Component should not be valid');
-
- component.setValue('04/01/2021');
- assert(!component.checkValidity(component.data, true), 'Component should not be valid');
-
- component.setValue('03/01/2021');
- assert(component.checkValidity(component.data, true), 'Component should be valid');
-
- component.setValue('01/03/2020');
- assert(component.checkValidity(component.data, true), 'Component should be valid');
- done();
- });
- });
-
- it('Should disable day component if parent component is disabled', (done) => {
- Harness.testCreate(PanelComponent, comp4).then((component) => {
- Harness.testElements(component, '[disabled]', 4);
- done();
- });
- });
-
- it('Should use the default day value if the day field is hidden', (done) => {
- comp1.dayFirst = false;
- comp1.defaultValue = '00/01/0000';
- comp1.fields.day.hide = true;
- Harness.testCreate(DayComponent, comp1).then((component) => {
- component.setValue('12/2023');
- assert.equal(component.data.date, '12/01/2023');
- done();
- });
- comp1.fields.day.hide = false;
- });
-
- it('Should use the default month value if the month field is hidden', (done) => {
- comp1.defaultValue = '03/00/0000';
- comp1.fields.month.hide = true;
- Harness.testCreate(DayComponent, comp1).then((component) => {
- component.setValue('12/2023');
- assert.equal(component.data.date, '03/12/2023');
- done();
- });
- comp1.fields.month.hide = false;
- });
-
- it('Should use the default year value if the year field is hidden', (done) => {
- comp1.defaultValue = '00/00/2023';
- comp1.fields.year.hide = true;
- Harness.testCreate(DayComponent, comp1).then((component) => {
- component.setValue('12/21');
- assert.equal(component.data.date, '12/21/2023');
- done();
- });
- comp1.fields.year.hide = false;
- });
- it('OnBlur validation should work properly with Day component', (done) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, comp5).then(form => {
- const dayComponent = form.components[0];
- dayComponent.setValue('03/12/2023');
-
- setTimeout(() => {
- dayComponent.refs.day.focus();
- dayComponent.refs.day.value = '';
- dayComponent.refs.day.dispatchEvent(new Event('input'));
-
- setTimeout(() => {
- assert(!dayComponent.error, 'Day should be valid while changing');
- dayComponent.refs.day.dispatchEvent(new Event('blur'));
-
- setTimeout(() => {
- assert(dayComponent.error, 'Should set error after Day component was blurred');
- done();
- }, 200);
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should restore focus after redraw', (done) => {
- const element = document.createElement('div');
- document.body.appendChild(element);
- Formio.createForm(element, comp6).then(form => {
- const textField = form.getComponent(['textField']);
- textField.setValue('test');
-
- setTimeout(() => {
- const day = form.getComponent(['day']);
- document.querySelector('select.form-control').focus();
- day.refs.month.value = 2;
- day.refs.month.dispatchEvent(new Event('input'));
-
- setTimeout(() => {
- console.log(global.document.activeElement, day.refs.month);
- assert(global.document.activeElement === day.refs.month, 'Should keep focus on the year select');
- done();
- }, 200);
- }, 500);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.data.js
deleted file mode 100644
index c58832a6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.data.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.day.js b/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.day.js
deleted file mode 100644
index 22525ef2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.day.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export default [
- {
- wieght: 200,
- type: 'select',
- datasrc: 'values',
- key: 'fields.day.type',
- label: 'Type',
- data: {
- values: [
- {
- label: 'Number',
- value: 'number'
- },
- {
- label: 'Select',
- value: 'select'
- },
- ]
- }
- },
- {
- weight: 210,
- type: 'textfield',
- input: true,
- key: 'fields.day.placeholder',
- label: 'Placeholder',
- placeholder: 'Day Placeholder',
- tooltip: 'The placeholder text that will appear when Day field is empty.'
- },
- {
- weight: 215,
- type: 'checkbox',
- label: 'Hidden',
- tooltip: 'Hide the Day part of the component.',
- key: 'fields.day.hide',
- input: true
- },
- {
- weight: 214,
- type: 'checkbox',
- label: 'Day First',
- tooltip: 'Display the Day field before the Month field.',
- key: 'dayFirst',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.display.js
deleted file mode 100644
index 6b4d10a6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.display.js
+++ /dev/null
@@ -1,44 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- weight: 15,
- type: 'checkbox',
- label: 'Hide Input Labels',
- tooltip: 'Hide the labels of component inputs. This allows you to show the labels in the form builder, but not when it is rendered.',
- key: 'hideInputLabels',
- input: true
- },
- {
- type: 'select',
- input: true,
- key: 'inputsLabelPosition',
- label: 'Inputs Label Position',
- tooltip: 'Position for the labels for inputs for this field.',
- weight: 40,
- defaultValue: 'top',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Top', value: 'top' },
- { label: 'Left', value: 'left' },
- { label: 'Right', value: 'right' },
- { label: 'Bottom', value: 'bottom' }
- ]
- }
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- weight: 213,
- type: 'checkbox',
- label: 'Use Locale Settings',
- tooltip: 'Use locale settings to display day.',
- key: 'useLocaleSettings',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.month.js b/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.month.js
deleted file mode 100644
index 5d8f609b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.month.js
+++ /dev/null
@@ -1,38 +0,0 @@
-export default [
- {
- wieght: 200,
- type: 'select',
- datasrc: 'values',
- key: 'fields.month.type',
- label: 'Type of input',
- data: {
- values: [
- {
- label: 'Number',
- value: 'number'
- },
- {
- label: 'Select',
- value: 'select'
- },
- ]
- }
- },
- {
- weight: 210,
- type: 'textfield',
- input: true,
- key: 'fields.month.placeholder',
- label: 'Placeholder',
- placeholder: 'Month Placeholder',
- tooltip: 'The placeholder text that will appear when Month field is empty.'
- },
- {
- weight: 215,
- type: 'checkbox',
- label: 'Hidden',
- tooltip: 'Hide the Month part of the component.',
- key: 'fields.month.hide',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.validation.js
deleted file mode 100644
index 81537a4b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.validation.js
+++ /dev/null
@@ -1,52 +0,0 @@
-export default [
- {
- key: 'validate.required',
- ignore: true
- },
- {
- key: 'validate.unique',
- ignore: true
- },
- {
- weight: 0,
- type: 'checkbox',
- label: 'Require Day',
- tooltip: 'A required field must be filled in before the form can be submitted.',
- key: 'fields.day.required',
- input: true
- },
- {
- weight: 10,
- type: 'checkbox',
- label: 'Require Month',
- tooltip: 'A required field must be filled in before the form can be submitted.',
- key: 'fields.month.required',
- input: true
- },
- {
- weight: 20,
- type: 'checkbox',
- label: 'Require Year',
- tooltip: 'A required field must be filled in before the form can be submitted.',
- key: 'fields.year.required',
- input: true
- },
- {
- weight: 40,
- type: 'textfield',
- label: 'Minimum Day',
- placeholder: 'yyyy-MM-dd',
- tooltip: 'A minimum date that can be set. You can also use Moment.js functions. For example: \n \n moment().subtract(10, \'days\')',
- key: 'minDate',
- input: true,
- },
- {
- weight: 30,
- type: 'textfield',
- label: 'Maximum Day',
- placeholder: 'yyyy-MM-dd',
- tooltip: 'A maximum day that can be set. You can also use Moment.js functions. For example: \n \n moment().add(10, \'days\')',
- key: 'maxDate',
- input: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.year.js b/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.year.js
deleted file mode 100644
index e3ca7ff5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/editForm/Day.edit.year.js
+++ /dev/null
@@ -1,56 +0,0 @@
-export default [
- {
- wieght: 200,
- type: 'select',
- datasrc: 'values',
- key: 'fields.year.type',
- label: 'Type of input',
- data: {
- values: [
- {
- label: 'Number',
- value: 'number'
- },
- {
- label: 'Select',
- value: 'select'
- },
- ]
- }
- },
- {
- weight: 203,
- type: 'number',
- input: true,
- key: 'fields.year.minYear',
- label: 'Minimum Year',
- placeholder: '1900',
- tooltip: 'The minimum year that can be entered.'
- },
- {
- weight: 204,
- type: 'number',
- input: true,
- key: 'fields.year.maxYear',
- label: 'Maximum Year',
- placeholder: '2030',
- tooltip: 'The maximum year that can be entered.'
- },
- {
- weight: 210,
- type: 'textfield',
- input: true,
- key: 'fields.year.placeholder',
- label: 'Placeholder',
- placeholder: 'Year Placeholder',
- tooltip: 'The placeholder text that will appear when Year field is empty.'
- },
- {
- weight: 215,
- type: 'checkbox',
- label: 'Hidden',
- tooltip: 'Hide the Year part of the component.',
- key: 'fields.year.hide',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp1.js
deleted file mode 100644
index aae75040..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp1.js
+++ /dev/null
@@ -1,39 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'day',
- 'validate': {
- 'custom': ''
- },
- 'clearOnHide': true,
- 'persistent': true,
- 'protected': false,
- 'dayFirst': false,
- 'fields': {
- 'year': {
- 'required': false,
- 'placeholder': '',
- 'type': 'number'
- },
- 'month': {
- 'required': false,
- 'placeholder': '',
- 'type': 'select'
- },
- 'day': {
- 'required': false,
- 'placeholder': '',
- 'type': 'number'
- }
- },
- 'key': 'date',
- 'label': 'Date',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp2.js
deleted file mode 100644
index c373bf84..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp2.js
+++ /dev/null
@@ -1,39 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'day',
- 'validate': {
- 'custom': ''
- },
- 'clearOnHide': true,
- 'persistent': true,
- 'protected': false,
- 'dayFirst': false,
- 'fields': {
- 'year': {
- 'required': true,
- 'placeholder': '',
- 'type': 'number'
- },
- 'month': {
- 'required': true,
- 'placeholder': '',
- 'type': 'select'
- },
- 'day': {
- 'required': true,
- 'placeholder': '',
- 'type': 'number'
- }
- },
- 'key': 'date',
- 'label': 'Date',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp3.js
deleted file mode 100644
index cf33b96e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp3.js
+++ /dev/null
@@ -1,41 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'day',
- 'validate': {
- 'custom': ''
- },
- 'minDate': '2020-03-01',
- 'maxDate': '2021-01-03',
- 'clearOnHide': true,
- 'persistent': true,
- 'protected': false,
- 'dayFirst': true,
- 'fields': {
- 'year': {
- 'required': false,
- 'placeholder': '',
- 'type': 'number'
- },
- 'month': {
- 'required': false,
- 'placeholder': '',
- 'type': 'select'
- },
- 'day': {
- 'required': false,
- 'placeholder': '',
- 'type': 'number'
- }
- },
- 'key': 'date',
- 'label': 'Date',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp4.js
deleted file mode 100644
index 4f26ac44..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp4.js
+++ /dev/null
@@ -1,58 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'panel',
- 'components': [
- {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'day',
- 'validate': {
- 'custom': ''
- },
- 'clearOnHide': true,
- 'persistent': true,
- 'protected': false,
- 'dayFirst': false,
- 'fields': {
- 'year': {
- 'required': false,
- 'placeholder': '',
- 'type': 'number'
- },
- 'month': {
- 'required': false,
- 'placeholder': '',
- 'type': 'select'
- },
- 'day': {
- 'required': false,
- 'placeholder': '',
- 'type': 'number'
- }
- },
- 'key': 'date',
- 'label': 'Date',
- 'tableView': true,
- 'input': true
- }
- ],
- 'nextPage': null,
- 'theme': 'default',
- 'title': 'User Information',
- 'input': false,
- 'disabled': true,
- 'key': 'panel1'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp5.js
deleted file mode 100644
index 882efc18..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp5.js
+++ /dev/null
@@ -1,30 +0,0 @@
-export default {
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Day',
- hideInputLabels: false,
- inputsLabelPosition: 'top',
- useLocaleSettings: false,
- tableView: false,
- fields: {
- day: {
- hide: false,
- required: true
- },
- month: {
- hide: false
- },
- year: {
- hide: false
- }
- },
- validateOn: 'blur',
- key: 'day',
- type: 'day',
- input: true,
- defaultValue: '00/00/0000'
- },
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp6.js
deleted file mode 100644
index 95bc3dd9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/comp6.js
+++ /dev/null
@@ -1,74 +0,0 @@
-export default {
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Text Field',
- applyMaskOn: 'change',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Day',
- hideInputLabels: false,
- inputsLabelPosition: 'top',
- useLocaleSettings: false,
- tableView: false,
- fields: {
- day: {
- hide: true,
- },
- month: {
- hide: false,
- },
- year: {
- hide: false,
- },
- },
- defaultValue: '00/00/0000',
- key: 'day',
- logic: [
- {
- name: 'Disable when Test is empty',
- trigger: {
- type: 'simple',
- simple: {
- show: true,
- conjunction: 'all',
- conditions: [
- {
- component: 'textField',
- operator: 'isEmpty',
- },
- ],
- },
- },
- actions: [
- {
- name: 'Disable',
- type: 'property',
- property: {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean',
- },
- state: true,
- },
- ],
- },
- ],
- type: 'day',
- input: true,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/index.js
deleted file mode 100644
index 00ed00ee..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import comp1 from './comp1';
-import comp2 from './comp2';
-import comp3 from './comp3';
-import comp4 from './comp4';
-import comp5 from './comp5';
-import comp6 from './comp6';
-export { comp1, comp2, comp3, comp4, comp5, comp6 };
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/values.js
deleted file mode 100644
index 1abf3fd8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/day/fixtures/values.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- '01/01/2001',
- '12/31/1999',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.form.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.form.js
deleted file mode 100644
index caa0e655..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.form.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import Components from '../Components';
-import EditGridEditData from './editForm/EditGrid.edit.data';
-import EditGridEditDisplay from './editForm/EditGrid.edit.display';
-import EditGridEditTemplates from './editForm/EditGrid.edit.templates';
-import EditGridEditValidation from './editForm/EditGrid.edit.validation';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- label: 'Templates',
- key: 'templates',
- weight: 5,
- components: EditGridEditTemplates
- },
- {
- key: 'display',
- components: EditGridEditDisplay,
- },
- {
- key: 'data',
- components: EditGridEditData,
- },
- {
- key: 'validation',
- components: EditGridEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.js
deleted file mode 100644
index 50e1d8f3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.js
+++ /dev/null
@@ -1,1382 +0,0 @@
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
-import Component from '../_classes/component/Component';
-import Alert from '../alert/Alert';
-import { fastCloneDeep, Evaluator, getArrayFromComponentPath, eachComponent } from '../../utils/utils';
-import templates from './templates';
-
-const EditRowState = {
- New: 'new',
- Editing: 'editing',
- Saved: 'saved',
- Viewing: 'viewing',
- Removed: 'removed',
- Draft: 'draft',
-};
-
-export default class EditGridComponent extends NestedArrayComponent {
- static schema(...extend) {
- return NestedArrayComponent.schema({
- type: 'editgrid',
- label: 'Edit Grid',
- key: 'editGrid',
- clearOnHide: true,
- input: true,
- tree: true,
- removeRow: 'Cancel',
- defaultOpen: false,
- openWhenEmpty: false,
- modal: false,
- components: [],
- inlineEdit: false,
- templates: {
- header: EditGridComponent.defaultHeaderTemplate,
- row: EditGridComponent.defaultRowTemplate,
- tableHeader: EditGridComponent.defaultTableHeaderTemplate,
- tableRow: EditGridComponent.defaultTableRowTemplate,
- footer: '',
- },
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Edit Grid',
- icon: 'tasks',
- group: 'data',
- documentation: '/userguide/form-building/data-components#edit-grid',
- showPreview: false,
- weight: 30,
- schema: EditGridComponent.schema(),
- };
- }
-
- static get defaultHeaderTemplate() {
- return `
- {% util.eachComponent(components, function(component) { %}
- {% if (displayValue(component)) { %}
-
{{ t(component.label) }}
- {% } %}
- {% }) %}
-
`;
- }
-
- static get defaultTableHeaderTemplate() {
- return `
-
- {% util.eachComponent(components, function(component) { %}
- {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}
- {{ component.label }}
- {% } %}
- {% }) %}
- {% if (!instance.options.readOnly && !instance.disabled) { %}
- Actions
- {% } %}
-
- `;
- }
-
- static get defaultRowTemplate() {
- return `
- {% util.eachComponent(components, function(component) { %}
- {% if (displayValue(component)) { %}
-
- {{ isVisibleInRow(component) ? getView(component, row[component.key]) : ''}}
-
- {% } %}
- {% }) %}
- {% if (!instance.options.readOnly && !instance.disabled) { %}
-
-
-
- {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}
-
- {% } %}
-
-
- {% } %}
-
`;
- }
-
- static get defaultTableRowTemplate() {
- return `
- {% util.eachComponent(components, function(component) { %}
- {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}
-
- {{ getView(component, row[component.key]) }}
-
- {% } %}
- {% }) %}
- {% if (!instance.options.readOnly && !instance.disabled) { %}
-
-
-
- {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}
-
- {% } %}
-
-
- {% } %}
- `;
- }
-
- get defaultDialogTemplate() {
- return `
- ${this.t('Do you want to clear data?')}
-
- ${this.t('Cancel')}
- ${this.t('Yes, delete it')}
-
- `;
- }
-
- get defaultRowTemplate() {
- return this.displayAsTable
- ? EditGridComponent.defaultTableRowTemplate
- : EditGridComponent.defaultRowTemplate;
- }
-
- get defaultHeaderTemplate() {
- return this.displayAsTable
- ? EditGridComponent.defaultTableHeaderTemplate
- : EditGridComponent.defaultHeaderTemplate;
- }
-
- get rowTemplate() {
- let rowTemplate;
- if (Evaluator.noeval) {
- rowTemplate = this.displayAsTable ?
- templates.tableRow
- : templates.row;
- }
- else {
- rowTemplate = this.displayAsTable ?
- _.get(this.component, 'templates.tableRow', this.defaultRowTemplate)
- : _.get(this.component, 'templates.row', this.defaultRowTemplate);
- }
-
- return rowTemplate;
- }
-
- get headerTemplate() {
- let headerTemplate;
- if (Evaluator.noeval) {
- headerTemplate = this.displayAsTable ?
- templates.tableHeader
- : templates.header;
- }
- else {
- headerTemplate = this.displayAsTable ?
- _.get(this.component, 'templates.tableHeader', this.defaultHeaderTemplate)
- : _.get(this.component, 'templates.header', this.defaultHeaderTemplate);
- }
-
- return headerTemplate;
- }
-
- /**
- * Returns true if the component has nested components which don't trigger changes on the root level
- */
- get hasScopedChildren() {
- return !this.inlineEditMode;
- }
-
- get defaultSchema() {
- return EditGridComponent.schema();
- }
-
- get emptyValue() {
- return [];
- }
-
- get editgridKey() {
- return `editgrid-${this.key}`;
- }
-
- get rowRef() {
- return `${this.editgridKey}-row`;
- }
-
- get rowElements() {
- return this.refs[this.rowRef];
- }
-
- get rowRefs() {
- return this.refs[`editgrid-${this.component.key}-row`];
- }
-
- get addRowRef() {
- return `${this.editgridKey}-addRow`;
- }
-
- get addRowElements() {
- return this.refs[this.addRowRef];
- }
-
- get saveRowRef() {
- return `${this.editgridKey}-saveRow`;
- }
-
- get saveRowElements() {
- return this.refs[this.saveRowRef];
- }
-
- get cancelRowRef() {
- return `${this.editgridKey}-cancelRow`;
- }
-
- get cancelRowElements() {
- return this.refs[this.cancelRowRef];
- }
-
- get inlineEditMode() {
- return this.component.inlineEdit;
- }
-
- get saveEditMode() {
- return !this.inlineEditMode;
- }
-
- get minLength() {
- return this.builderMode ? 0 : _.get(this.component, 'validate.minLength', 0);
- }
-
- get data() {
- return this._data;
- }
-
- get dataValue() {
- return super.dataValue || [];
- }
-
- set dataValue(value) {
- super.dataValue = value;
- }
-
- get displayAsTable() {
- return this.component.displayAsTable;
- }
-
- set data(value) {
- this._data = value;
-
- const data = this.dataValue;
-
- (this.editRows || []).forEach((row, index) => {
- if (!data[index] && row.state !== EditRowState.New) {
- data[index] = {};
- }
- const rowData = data[index] || {};
-
- row.data = rowData;
- row.components.forEach((component) => {
- component.data = rowData;
- });
- });
- }
-
- get iteratableRows() {
- return this.editRows;
- }
-
- get defaultValue() {
- const value = super.defaultValue;
- const defaultValue = Array.isArray(value) ? value : [];
-
- _.times(this.minLength - defaultValue.length, () => defaultValue.push({}));
-
- return defaultValue;
- }
-
- constructor(...args) {
- super(...args);
- this.type = 'editgrid';
- }
-
- hasRemoveButtons() {
- return !this.component.disableAddingRemovingRows &&
- !this.options.readOnly &&
- !this.disabled &&
- this.fullMode &&
- (this.dataValue.length > _.get(this.component, 'validate.minLength', 0));
- }
-
- init() {
- if (this.builderMode) {
- this.editRows = [];
- return super.init();
- }
- this.components = this.components || [];
- const dataValue = this.dataValue;
- const openWhenEmpty = !dataValue.length && this.component.openWhenEmpty;
- if (openWhenEmpty) {
- const dataObj = {};
- this.editRows = [];
- this.createRow(dataObj, 0);
- }
- else {
- this.editRows = dataValue.map((row, rowIndex) => ({
- components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),
- data: row,
- state: EditRowState.Saved,
- backup: null,
- error: null,
- rowIndex,
- }));
- }
- this.prevHasAddButton = this.hasAddButton();
-
- this.checkData();
-
- this.setVariableTypeComponents();
-
- if (this.variableTypeComponentsIndexes.length) {
- _.each(this.editRows || [], (editRow, rowIndex) => this.checkRowVariableTypeComponents(editRow, rowIndex));
- }
- }
-
- checkRowVariableTypeComponents(editRow, rowIndex) {
- const rowComponents = editRow.components;
-
- if (_.some(this.variableTypeComponentsIndexes, (compIndex) => {
- const variableTypeComp = rowComponents[compIndex];
- return variableTypeComp.type !== variableTypeComp.component.type;
- })) {
- editRow.components = this.createRowComponents(editRow.data, rowIndex, true);
- }
- }
-
- setVariableTypeComponents() {
- //set components which type is changing within a row (e.g.,by mergeComponentSchema action)
- this.variableTypeComponentsIndexes = [];
-
- _.each(this.component.components, (comp, index) => {
- if (comp.typeChangeEnabled) {
- this.variableTypeComponentsIndexes.push(index);
- }
- });
- }
-
- isOpen(editRow) {
- return [EditRowState.New, EditRowState.Editing, EditRowState.Viewing].includes(editRow.state);
- }
-
- isComponentVisibleInSomeRow(component) {
- const rows = this.editRows;
- const savedStates = [EditRowState.Saved, EditRowState.Editing, EditRowState.Draft];
- const savedRows = rows.filter(row => _.includes(savedStates, row.state));
-
- this.visibleInHeader = this.visibleInHeader || [];
-
- const changeVisibleInHeader = (component, isVisible) => {
- if (!isVisible) {
- _.remove(this.visibleInHeader, (key) => key === component.key);
- }
-
- if (isVisible && !_.includes(this.visibleInHeader, component.key)) {
- this.visibleInHeader.push(component.key);
- }
- };
-
- if (_.isEmpty(rows)) {
- const rowComponents = this.createRowComponents({}, 0);
- let checkComponent;
-
- eachComponent(rowComponents, (comp) => {
- if (comp.component.key === component.key) {
- checkComponent = comp;
- }
- comp.checkConditions();
- });
-
- const isVisible = checkComponent ? checkComponent.visible : true;
- [...this.components].forEach((comp) => this.removeComponent(comp, this.components));
-
- changeVisibleInHeader(component, isVisible);
-
- return isVisible;
- }
-
- const isOpenRowWhenEmpty = _.get(this.component, 'openWhenEmpty') && rows.length === 1 && rows[0].state === EditRowState.New;
-
- if (!_.isEmpty(rows) && _.isEmpty(savedRows) && !isOpenRowWhenEmpty) {
- return _.includes(this.visibleInHeader, component.key);
- }
-
- return _.some(isOpenRowWhenEmpty ? rows : savedRows, (row, index) => {
- const editingRow = row.state === EditRowState.Editing;
- let isVisible;
-
- if (!editingRow) {
- const flattenedComponents = this.flattenComponents(index);
- const instance = flattenedComponents[component.key];
- isVisible = instance ? instance.visible : true;
-
- changeVisibleInHeader(component, isVisible);
- }
- else {
- isVisible = _.includes(this.visibleInHeader, component.key);
- }
-
- return isVisible;
- });
- }
-
- render(children) {
- if (this.builderMode) {
- return super.render();
- }
-
- const dataValue = this.dataValue;
- const headerTemplate = this.headerTemplate;
- const t = this.t.bind(this);
- const templateName = this.displayAsTable ? 'editgridTable' : 'editgrid';
-
- return super.render(children || this.renderTemplate(templateName, {
- ref: {
- row: this.rowRef,
- addRow: this.addRowRef,
- saveRow: this.saveRowRef,
- cancelRow: this.cancelRowRef,
- },
- header: this.renderString(headerTemplate, {
- displayValue: (component) => this.displayComponentValue(component, true),
- components: this.component.components,
- value: dataValue,
- t
- }),
- footer: this.renderString(_.get(this.component, 'templates.footer'), {
- components: this.component.components,
- value: dataValue,
- t
- }),
- rows: this.editRows.map(this.renderRow.bind(this)),
- openRows: this.editRows.map((row) => this.isOpen(row)),
- errors: this.editRows.map((row) => row.error),
- hasAddButton: this.hasAddButton(),
- hasRemoveButtons: this.hasRemoveButtons(),
- }));
- }
-
- renderComponents(components) {
- components = components || this.getComponents();
- const children = components.map(component => component.render());
- const templateName = this.displayAsTable && this.prevHasAddButton ? 'tableComponents' : 'components';
-
- return this.renderTemplate(templateName, {
- children,
- components,
- });
- }
-
- attach(element) {
- if (this.builderMode) {
- return super.attach(element);
- }
-
- this.loadRefs(element, {
- [this.addRowRef]: 'multiple',
- [this.saveRowRef]: 'multiple',
- [this.cancelRowRef]: 'multiple',
- [this.rowRef]: 'multiple',
- });
- this.addRowElements.forEach((addButton) => {
- this.addEventListener(addButton, 'click', () => this.addRow());
- });
-
- let openRowCount = 0;
- this.rowElements.forEach((row, rowIndex) => {
- const editRow = this.editRows[rowIndex];
- if (editRow?.isRowSelected) {
- row.classList.add('selected');
- }
- if (this.isOpen(editRow)) {
- this.attachComponents(row, editRow.components);
- this.addEventListener(this.saveRowElements[openRowCount], 'click', () => this.saveRow(rowIndex, true));
- this.addEventListener(this.cancelRowElements[openRowCount], 'click', () => this.cancelRow(rowIndex));
- openRowCount++;
- }
- else {
- // Attach edit and remove button events.
- [
- {
- className: 'removeRow',
- event: 'click',
- action: () => this.removeRow(rowIndex, true),
- },
- {
- className: 'editRow',
- event: 'click',
- action: () => {
- this.editRow(rowIndex).then(() => {
- if (this.component.rowDrafts) {
- this.validateRow(editRow, false);
-
- const hasErrors = editRow.errors && !!editRow.errors.length;
- const shouldShowRowErrorsAlert = this.component.modal && hasErrors && this.root?.submitted;
-
- if (shouldShowRowErrorsAlert) {
- this.alert.showErrors(editRow.errors, false);
- editRow.alerts = true;
- }
- }
- });
- },
- },
- {
- className: 'row',
- event: 'click',
- action: () => {
- row.classList.toggle('selected');
- let eventName = 'editGridSelectRow';
- if (Array.from(row.classList).includes('selected')) {
- editRow.isRowSelected = true;
- }
- else {
- delete editRow.isRowSelected;
- eventName = 'editGridUnSelectRow';
- }
-
- this.emit(eventName, {
- component: this.component,
- data: this.dataValue[rowIndex]
- });
- },
- }
- ].forEach(({
- className,
- event,
- action,
- }) => {
- const elements = row.getElementsByClassName(className);
- Array.prototype.forEach.call(elements, (element) => {
- if (this.options.pdf && _.intersection(element.classList, ['editRow', 'removeRow']).length) {
- element.style.display = 'none';
- }
- else {
- this.addEventListener(element, event, action);
- }
- });
- });
- }
- });
-
- // Add open class to the element if any edit grid row is open
- if (openRowCount) {
- this.addClass(this.refs.component, `formio-component-${this.component.type}-row-open`);
- }
- else {
- this.removeClass(this.refs.component, `formio-component-${this.component.type}-row-open`);
- }
-
- const superAttach = super.attach(element);
- this.loadRefs(element, {
- messageContainer: 'single-scope',
- });
- return superAttach;
- }
-
- flattenRowDataValue(dataValue) {
- const flattened = {};
-
- Object.keys(dataValue).forEach((key) => {
- if (_.isObject(dataValue[key]) && !_.isNil(dataValue[key])) {
- Object.assign(flattened, this.flattenRowDataValue(dataValue[key]));
- }
- else {
- flattened[key] = dataValue[key];
- }
- });
-
- return flattened;
- }
-
- isComponentVisibleInRow(component, flattenedComponents) {
- const instance = flattenedComponents[component.key];
- return instance ? instance.visible : true;
- }
-
- displayComponentValue(component, header) {
- return !!((!component.hasOwnProperty('tableView') || component.tableView)
- && header ? this.isComponentVisibleInSomeRow(component) : _.includes(this.visibleInHeader, component.key));
- }
-
- renderRow(row, rowIndex) {
- const dataValue = this.dataValue;
- if (this.isOpen(row)) {
- return this.renderComponents(row.components);
- }
- else {
- const flattenedComponents = this.flattenComponents(rowIndex);
- const rowTemplate = this.rowTemplate;
-
- return this.renderString(
- rowTemplate,
- {
- row: dataValue[rowIndex] || {},
- data: this.data,
- rowIndex,
- components: this.component.components,
- flattenedComponents,
- displayValue: (component) => this.displayComponentValue(component),
- isVisibleInRow: (component) => this.isComponentVisibleInRow(component, flattenedComponents),
- getView: (component, data) => {
- const instance = flattenedComponents[component.key];
- const view = instance ? instance.getView(data || instance.dataValue) : '';
-
- // If there is an html tag in view, don't allow it to be injected in template
- const htmlTagRegExp = new RegExp('<(.*?)>');
- return typeof view === 'string' && view.length && !instance.component?.template && htmlTagRegExp.test(view) && instance.component?.inputFormat !== 'html'
- ? ` `
- : view;
- },
- state: this.editRows[rowIndex].state,
- t: this.t.bind(this)
- },
- );
- }
- }
-
- eachComponent(fn, rowIndex) {
- _.each(this.getComponents(rowIndex), (component, index) => {
- if (fn(component, index) === false) {
- return false;
- }
- });
- }
-
- restoreComponentsContext() {
- this.getComponents().forEach((component) => {
- const rowData = this.dataValue[component.rowIndex];
- const editRowData = this.editRows[component.rowIndex]?.data;
- component.data = rowData || editRowData;
- });
- }
-
- flattenComponents(rowIndex) {
- const result = {};
-
- this.everyComponent((component) => {
- result[component.component.flattenAs || component.key] = component;
- }, rowIndex);
-
- return result;
- }
-
- getComponents(rowIndex) {
- // Ensure editrows is set.
- this.editRows = this.editRows || [];
- return this.builderMode
- ? super.getComponents()
- : _.isNumber(rowIndex)
- ? (this.editRows[rowIndex]?.components || [])
- : this.editRows.reduce((result, row) => result.concat(row.components || []), []);
- }
-
- destroy(all = false) {
- this.calculatedValue = undefined;
- super.destroy(all);
- }
-
- destroyComponents(rowIndex = 0) {
- if (this.builderMode) {
- return super.destroyComponents();
- }
-
- const components = this.getComponents(rowIndex).slice();
- components.forEach((comp) => this.removeComponent(comp, this.components));
- }
-
- createRow(dataObj, rowIndex) {
- const editRow = {
- components: this.createRowComponents(dataObj, rowIndex),
- data: dataObj,
- state: EditRowState.New,
- backup: null,
- error: null,
- rowIndex,
- };
-
- this.editRows.push(editRow);
- if (this.inlineEditMode) {
- this.dataValue.push(dataObj);
- }
-
- return editRow;
- }
-
- addRow() {
- if (this.options.readOnly) {
- return;
- }
-
- const dataObj = {};
- const rowIndex = this.editRows.length;
- const editRow = this.createRow(dataObj, rowIndex);
-
- if (editRow.state === EditRowState.New) {
- this.emptyRow = fastCloneDeep(editRow.data);
- }
-
- if (this.inlineEditMode) {
- this.triggerChange();
- }
- this.emit('editGridAddRow', {
- component: this.component,
- row: editRow,
- });
- this.checkRow('checkData', null, {}, editRow.data, editRow.components);
- if (this.component.modal) {
- this.addRowModal(rowIndex);
- }
- else {
- this.redraw();
- }
- return editRow;
- }
-
- addRowModal(rowIndex) {
- const modalContent = this.ce('div');
- const editRow = this.editRows[rowIndex];
- editRow.willBeSaved = false;
- const { components } = editRow;
- modalContent.innerHTML = this.renderComponents(components);
-
- const dialog = this.component.modal ? this.createModal(modalContent, {}, () => this.showDialog(rowIndex)) : undefined;
- dialog.classList.add(`editgrid-row-modal-${this.id}`);
-
- editRow.dialog = dialog;
-
- if (this.alert) {
- this.alert.clear();
- this.alert = null;
- }
- this.alert = new Alert(dialog.refs.dialogContents, this);
-
- this.addEventListener(dialog, 'close', () => {
- if (!editRow.willBeSaved) {
- if (this.editRows[rowIndex] && this.editRows[rowIndex].state !== EditRowState.New) {
- this.editRows[rowIndex].components.forEach((comp) => {
- comp.setPristine(true);
- });
- }
- this.cancelRow(rowIndex);
- }
- if (this.alert) {
- this.alert.clear();
- this.alert = null;
- }
-
- // Remove references to dialog elements to prevent possible in some cases memory leaks
- delete editRow.confirmationDialog;
- delete editRow.dialog;
- });
-
- dialog.refs.dialogContents.appendChild(this.ce('button', {
- class: 'btn btn-primary',
- onClick: () => {
- // After an attempt to save, all the components inside the row should become not pristine
- if (!this.component.rowDrafts) {
- editRow.components.forEach((comp) => comp.setPristine(false));
- }
- if (this.validateRow(editRow, true) || this.component.rowDrafts) {
- editRow.willBeSaved = true;
- dialog.close();
- this.saveRow(rowIndex, true);
- }
- else {
- this.alert.showErrors(editRow.errors, false);
- editRow.alerts = true;
- }
- },
- }, this.component.saveRow || 'Save'));
-
- return this.attachComponents(modalContent, components);
- }
-
- showDialog(rowIndex) {
- const editRow = this.editRows[rowIndex];
- if (editRow.state === EditRowState.New ? _.isEqual(this.emptyRow, editRow.data) : _.isEqual(editRow.backup, editRow.data)) {
- return Promise.resolve();
- }
-
- const wrapper = this.ce('div', { ref: 'confirmationDialog' });
- const dialogContent = this.component.dialogTemplate || this.defaultDialogTemplate;
-
- wrapper.innerHTML = dialogContent;
- wrapper.refs = {};
- this.loadRefs.call(wrapper, wrapper, {
- dialogHeader: 'single',
- dialogCancelButton: 'single',
- dialogYesButton: 'single',
- });
-
- const dialog = this.createModal(wrapper);
- dialog.classList.add(`editgrid-row-modal-confirmation-${this.id}`);
-
- const close = (event) => {
- event.preventDefault();
- dialog.close();
- };
- let dialogResult;
-
- const promise = new NativePromise((resolve, reject) => {
- dialogResult = { resolve, reject };
- });
-
- this.addEventListener(wrapper.refs.dialogYesButton, 'click', (event) => {
- close(event);
- dialogResult.resolve();
- });
- this.addEventListener(wrapper.refs.dialogCancelButton, 'click', (event) => {
- close(event);
- dialogResult.reject();
- });
-
- editRow.confirmationDialog = dialog;
- return promise;
- }
-
- editRow(rowIndex) {
- const editRow = this.editRows[rowIndex];
- const isAlreadyEditing = editRow.state === EditRowState.Editing || editRow.state === EditRowState.New;
- if (!editRow || isAlreadyEditing) {
- return NativePromise.resolve();
- }
- editRow.prevState = editRow.state;
- editRow.state = this.options.readOnly ? EditRowState.Viewing : EditRowState.Editing;
-
- if (this.lazyLoad && (editRow.components.length === 0)) {
- editRow.components = this.createRowComponents(editRow.data, rowIndex);
- }
-
- const dataSnapshot = fastCloneDeep(editRow.data);
-
- if (this.inlineEditMode) {
- editRow.backup = dataSnapshot;
- }
- else {
- editRow.backup = fastCloneDeep(editRow.data);
- editRow.data = dataSnapshot;
- this.restoreRowContext(editRow);
- }
-
- if (this.component.modal) {
- return this.addRowModal(rowIndex);
- }
-
- return this.redraw();
- }
-
- clearErrors(rowIndex) {
- const editRow = this.editRows[rowIndex];
- if (editRow && Array.isArray(editRow.components)) {
- editRow.components.forEach((comp) => {
- comp.setPristine(true);
- comp.setCustomValidity('');
- });
- }
- }
-
- cancelRow(rowIndex) {
- if (this.options.readOnly) {
- return;
- }
-
- const editRow = this.editRows[rowIndex];
- switch (editRow.state) {
- case EditRowState.New: {
- editRow.state = EditRowState.Removed;
-
- this.clearErrors(rowIndex);
- this.destroyComponents(rowIndex);
- if (this.inlineEditMode) {
- this.splice(rowIndex);
- }
- this.editRows.splice(rowIndex, 1);
- this.openWhenEmpty();
- break;
- }
- case EditRowState.Editing: {
- editRow.state = editRow.prevState;
-
- if (this.inlineEditMode) {
- this.dataValue[rowIndex] = editRow.backup;
- }
- editRow.data = editRow.backup;
- editRow.backup = null;
- this.restoreRowContext(editRow);
- this.clearErrors(rowIndex);
- break;
- }
- }
-
- this.emit('editGridCancelRow', {
- instance: this,
- component: this.component,
- editRow,
- });
-
- this.checkValidity(null, true);
- this.redraw();
-
- if (this.component.rowDrafts) {
- this.checkValidity(this.data, false);
- }
- }
-
- saveRow(rowIndex, modified) {
- const editRow = this.editRows[rowIndex];
-
- if (this.options.readOnly) {
- return;
- }
-
- // After an attempt to save, all the components inside the row should become not pristine
- if (!this.component.rowDrafts) {
- editRow.components.forEach((comp) => comp.setPristine(false));
- }
-
- const isRowValid = this.validateRow(editRow, true);
-
- if (!this.component.rowDrafts) {
- if (!isRowValid) {
- return false;
- }
- }
-
- if (this.saveEditMode) {
- const dataValue = this.dataValue;
- if (this.root?.focusedComponent?.component.typeChangeEnabled) {
- this.root.focusedComponent = null;
- }
- switch (editRow.state) {
- case EditRowState.New: {
- const newIndex = dataValue.length;
- dataValue.push(editRow.data);
- editRow.components.forEach(component=>component.rowIndex = newIndex);
- if (rowIndex !== newIndex) {
- this.editRows.splice(rowIndex, 1);
- this.editRows.splice(newIndex, 0, editRow);
- }
- break;
- }
- case EditRowState.Editing: {
- dataValue[rowIndex] = editRow.data;
- break;
- }
- }
- }
-
- editRow.state = this.component.rowDrafts && !isRowValid ? EditRowState.Draft : EditRowState.Saved;
- editRow.backup = null;
-
- this.updateValue();
- this.emit('editGridSaveRow', {
- component: this.component,
- row: editRow.data,
- instance: this
- });
- this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });
- if (this.component.rowDrafts) {
- editRow.components.forEach(comp => comp.setPristine(this.pristine));
- }
- this.checkValidity(null, true);
- this.redraw();
-
- if (editRow.alerts) {
- editRow.alerts = false;
- }
-
- return true;
- }
-
- beforeFocus(component) {
- if ('beforeFocus' in this.parent) {
- this.parent.beforeFocus(this);
- }
- const relativePath = this.getRelativePath(component.path);
- const arrayPath = getArrayFromComponentPath(relativePath);
-
- const rowIndex = arrayPath[0];
- let rowToEditIndex = arrayPath[0];
-
- this.editRows.forEach((row, indexInArray) => {
- if (row.rowIndex === rowIndex) {
- rowToEditIndex = indexInArray;
- }
- });
-
- if (_.isNumber(rowToEditIndex)) {
- this.editRow(rowToEditIndex);
- }
- }
-
- updateComponentsRowIndex(components, rowIndex) {
- components.forEach((component, colIndex) => {
- component.rowIndex = rowIndex;
- component.row = `${rowIndex}-${colIndex}`;
- });
- }
-
- updateRowsComponents(rowIndex) {
- this.editRows.slice(rowIndex).forEach((row, index) => {
- this.updateComponentsRowIndex(row.components, rowIndex + index);
- });
- }
-
- baseRemoveRow(rowIndex) {
- const editRow = this.editRows[rowIndex];
-
- editRow.state = EditRowState.Removed;
- this.destroyComponents(rowIndex);
-
- return editRow;
- }
-
- removeRow(rowIndex, modified) {
- if (this.options.readOnly) {
- return;
- }
-
- this.clearErrors(rowIndex);
- this.baseRemoveRow(rowIndex);
- this.splice(rowIndex);
- this.emit('editGridDeleteRow', {
- index: rowIndex
- });
- this.editRows.splice(rowIndex, 1);
- this.openWhenEmpty();
- this.updateRowsComponents(rowIndex);
- this.updateValue();
- this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });
- this.checkValidity(null, true);
- this.checkData();
- this.redraw();
- }
-
- createRowComponents(row, rowIndex, recreatePartially) {
- // Iterate through existing components and destroy the ones with the same rowIndex.
- if (this.components) {
- for (let i = 0; i < this.components.length; i++) {
- if (this.components[i].rowIndex === rowIndex) {
- this.components[i].destroy();
- this.components.splice(i, 1);
- }
- }
- }
- const currentRowComponents = _.get(this.editRows, `[${rowIndex}].components`, null);
- return this.component.components.map((col, colIndex) => {
- if (recreatePartially && currentRowComponents && this.variableTypeComponentsIndexes.length) {
- const currentComp = currentRowComponents[colIndex];
- const shouldRecreate = _.includes(this.variableTypeComponentsIndexes, colIndex) && currentComp?.type !== currentComp?.component?.type;
-
- if (!shouldRecreate) {
- return currentComp;
- }
-
- col = currentComp.component;
- }
-
- const column = _.clone(col);
- const options = _.clone(this.options);
- options.name += `[${rowIndex}]`;
- options.row = `${rowIndex}-${colIndex}`;
- options.onChange = (flags = {}, changed, modified) => {
- if (changed.instance.root?.id && (this.root?.id !== changed.instance.root.id)) {
- changed.instance.root.triggerChange(flags, changed, modified);
- }
- else if (!this.component.modal) {
- this.triggerRootChange(flags, changed, modified);
- }
-
- if (this.inlineEditMode) {
- return;
- }
-
- const editRow = this.editRows[rowIndex];
-
- if (editRow?.alerts) {
- this.checkData(null, {
- ...flags,
- changed,
- rowIndex,
- }, this.data);
- }
- else if (editRow) {
- // If drafts allowed, perform validation silently if there was no attempt to submit a form
- const silentCheck = this.component.rowDrafts && !this.shouldValidateDraft(editRow);
-
- this.checkRow('checkData', null, {
- ...flags,
- changed,
- silentCheck
- }, editRow.data, editRow.components, silentCheck);
- }
-
- if (this.variableTypeComponentsIndexes.length) {
- this.checkRowVariableTypeComponents(editRow, rowIndex);
- this.redraw();
- }
- };
-
- const comp = this.createComponent(
- _.assign({}, column, { row: options.row }),
- options,
- row,
- null,
- recreatePartially && currentRowComponents ? currentRowComponents[colIndex] : null
- );
- comp.rowIndex = rowIndex;
- comp.inEditGrid = true;
- return comp;
- });
- }
-
- hasOpenRows() {
- return this.editRows.some(row => this.isOpen(row));
- }
-
- shouldValidateDraft(editRow) {
- // Draft rows should be validated only when there was an attempt to submit a form
- return (editRow.state === EditRowState.Draft &&
- !this.pristine &&
- !this.root?.pristine &&
- !this.hasOpenRows()) ||
- this.root?.submitted;
- }
-
- shouldValidateRow(editRow, dirty) {
- return this.shouldValidateDraft(editRow) ||
- editRow.state === EditRowState.Editing ||
- editRow.alerts ||
- dirty;
- }
-
- validateRow(editRow, dirty, forceSilentCheck) {
- let valid = true;
- const errorsSnapshot = [...this.errors];
-
- if (this.shouldValidateRow(editRow, dirty)) {
- editRow.components.forEach(comp => {
- const silentCheck = (this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck;
-
- valid &= comp.checkValidity(null, dirty, null, silentCheck);
- });
- }
-
- if (this.component.validate && this.component.validate.row) {
- valid = this.evaluate(this.component.validate.row, {
- valid,
- row: editRow.data
- }, 'valid', true);
- if (valid.toString() !== 'true') {
- editRow.error = valid;
- valid = false;
- }
- else {
- editRow.error = null;
- }
- if (valid === null) {
- valid = `Invalid row validation for ${this.key}`;
- }
- }
-
- editRow.errors = !valid ? this.errors.filter((err) => !errorsSnapshot.includes(err)) : null;
-
- if (!this.component.rowDrafts || this.root?.submitted) {
- this.showRowErrorAlerts(editRow, !!valid);
- }
-
- return !!valid;
- }
-
- showRowErrorAlerts(editRow, valid) {
- if (editRow.alerts) {
- if (this.alert) {
- if (editRow.errors?.length && !valid) {
- this.alert.showErrors(editRow.errors, false);
- editRow.alerts = true;
- }
- else {
- this.alert.clear();
- }
- }
- }
- }
-
- checkValidity(data, dirty, row, silentCheck) {
- data = data || this.rootValue;
- row = row || this.data;
-
- if (!this.checkCondition(row, data)) {
- this.setCustomValidity('');
- return true;
- }
-
- return this.checkComponentValidity(data, dirty, row, { silentCheck });
- }
-
- checkComponentValidity(data, dirty, row, options = {}) {
- const { silentCheck } = options;
- const errorsLength = this.errors.length;
- const superValid = super.checkComponentValidity(data, dirty, row, options);
-
- // If super tells us that component invalid and there is no need to update alerts, just return false
- if (!superValid && (!this.alert && !this.hasOpenRows())) {
- return false;
- }
-
- if (this.shouldSkipValidation(data, dirty, row)) {
- return true;
- }
-
- let rowsValid = true;
- let rowsEditing = false;
-
- this.editRows.forEach((editRow, index) => {
- // Trigger all errors on the row.
- const rowValid = this.validateRow(editRow, dirty, silentCheck);
-
- rowsValid &= rowValid;
-
- if (this.rowRefs) {
- const rowContainer = this.rowRefs[index];
-
- if (rowContainer) {
- const errorContainer = rowContainer.querySelector('.editgrid-row-error');
-
- if (!rowValid && errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {
- this.addClass(errorContainer, 'help-block' );
- errorContainer.textContent = this.t(this.errorMessage('invalidRowError'));
- }
- else if (errorContainer) {
- errorContainer.textContent = '';
- }
- }
- }
- // If this is a dirty check, and any rows are still editing, we need to throw validation error.
- rowsEditing |= (dirty && this.isOpen(editRow));
- });
-
- if (!rowsValid) {
- if (!silentCheck && (!this.component.rowDrafts || this.root?.submitted)) {
- this.setCustomValidity(this.t(this.errorMessage('invalidRowsError')), dirty);
- // Delete this class, because otherwise all the components inside EditGrid will has red border even if they are valid
- this.removeClass(this.element, 'has-error');
- }
- return false;
- }
- else if (rowsEditing && this.saveEditMode) {
- this.setCustomValidity(this.t(this.errorMessage('unsavedRowsError')), dirty);
- return false;
- }
-
- const message = this.invalid || this.invalidMessage(data, dirty);
- if (this.errors?.length !== errorsLength && this.root?.submitted && !message) {
- this.setCustomValidity(message, dirty);
- this.root.showErrors();
- }
- else {
- this.setCustomValidity(message, dirty);
- }
- return superValid;
- }
-
- changeState(changed, flags) {
- if (changed || (flags.resetValue && this.component.modalEdit)) {
- this.rebuild();
- }
- else {
- this.redraw();
- }
- }
-
- setValue(value, flags = {}) {
- if (!value) {
- value = this.defaultValue;
- }
-
- if (!Array.isArray(value)) {
- if (typeof value === 'object') {
- value = [value];
- }
- else {
- return false;
- }
- }
-
- const changed = this.hasChanged(value, this.dataValue);
- flags.noValidate = !changed;
- if (this.parent) {
- this.parent.checkComponentConditions();
- }
- this.dataValue = value;
- // Refresh editRow data when data changes.
- this.dataValue.forEach((row, rowIndex) => {
- const editRow = this.editRows[rowIndex];
- if (editRow) {
- editRow.data = row;
- this.restoreRowContext(editRow, flags);
- editRow.state = EditRowState.Saved;
- editRow.backup = null;
- editRow.error = null;
- }
- else {
- this.editRows[rowIndex] = {
- components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),
- data: row,
- state: EditRowState.Saved,
- backup: null,
- error: null,
- };
- }
- });
- let { length: dataLength } = this.dataValue;
-
- // If the last row is a new row, then do not remove it.
- if (this.editRows[dataLength] && (this.editRows[dataLength].state === EditRowState.New)) {
- dataLength = (dataLength + 1);
- }
- this.editRows.slice(dataLength).forEach((editRow, index) => this.baseRemoveRow(dataLength + index));
- this.editRows = this.editRows.slice(0, dataLength);
-
- this.openWhenEmpty();
- this.updateOnChange(flags, changed);
- this.checkData();
-
- this.changeState(changed, flags);
-
- return changed;
- }
-
- openWhenEmpty() {
- const shouldBeOpened = !this.dataValue.length && this.component.openWhenEmpty;
- const hasNoRows = !this.editRows.length;
-
- if (hasNoRows && shouldBeOpened && !this.builderMode) {
- const dataObj = {};
- this.createRow(dataObj, 0);
- }
- }
-
- restoreRowContext(editRow, flags = {}) {
- editRow.components.forEach((component) => {
- component.data = editRow.data;
- this.setNestedValue(component, editRow.data, flags);
- });
- }
-
- emptyRows() {
- this.editRows.forEach((editRow, index) => this.destroyComponents(index));
- this.editRows = [];
- }
-
- resetValue() {
- super.resetValue();
- this.emptyRows();
- }
-}
-
-EditGridComponent.prototype.hasChanged = Component.prototype.hasChanged;
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.unit.js
deleted file mode 100644
index c2aa4a01..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/EditGrid.unit.js
+++ /dev/null
@@ -1,1357 +0,0 @@
-import assert from 'power-assert';
-import _ from 'lodash';
-import Harness from '../../../test/harness';
-import EditGridComponent from './EditGrid';
-import {
- comp1,
- comp4,
- comp3,
- comp5,
- comp6,
- comp7,
- comp8,
- comp9,
- comp10,
- comp11,
- comp12,
- comp13,
- comp14,
- comp15,
- withOpenWhenEmptyAndConditions,
- compOpenWhenEmpty,
-} from './fixtures';
-
-import ModalEditGrid from '../../../test/forms/modalEditGrid';
-import Webform from '../../Webform';
-import { displayAsModalEditGrid } from '../../../test/formtest';
-import Formio from '../../Formio';
-
-describe('EditGrid Component', () => {
- it('Should set correct values in dataMap inside editGrid and allow aditing them', (done) => {
- Harness.testCreate(EditGridComponent, comp4).then((component) => {
- component.setValue([{ dataMap: { key111: '111' } }]);
-
- setTimeout(()=>{
- const clickEvent = new Event('click');
- const editBtn = component.element.querySelector('.editRow');
-
- editBtn.dispatchEvent(clickEvent);
-
- setTimeout(()=>{
- const keyValue = component.element.querySelectorAll('[ref="input"]')[0].value;
- const valueValue = component.element.querySelectorAll('[ref="input"]')[1].value;
- const saveBtnsQty = component.element.querySelectorAll('[ref="editgrid-editGrid-saveRow"]').length;
-
- assert.equal(saveBtnsQty, 1);
- assert.equal(keyValue, 'key111');
- assert.equal(valueValue, '111');
- done();
- }, 500);
- }, 200);
- });
- });
-
- it('Should set correct values after reset', (done) => {
- Harness.testCreate(EditGridComponent, comp5)
- .then((component) => {
- assert.equal(component.components.length, 0);
-
- component.setValue([
- { textField: 'textField1' },
- { textField: 'textField2' }
- ], { resetValue: true });
-
- setTimeout(() => {
- assert.equal(component.components.length, 2);
- done();
- }, 300);
- });
- });
-
- it('Should display saved values if there are more then 1 nested components', (done) => {
- Harness.testCreate(EditGridComponent, comp3).then((component) => {
- component.setValue([{ container: { number: 55555 } }, { container: { number: 666666 } }]);
-
- setTimeout(()=>{
- const firstValue = component.element.querySelectorAll('[ref="editgrid-editGrid-row"]')[0].querySelector('.col-sm-2').textContent.trim();
- const secondValue = component.element.querySelectorAll('[ref="editgrid-editGrid-row"]')[1].querySelector('.col-sm-2').textContent.trim();
-
- assert.equal(firstValue, '55555');
- assert.equal(secondValue, '666666');
- done();
- }, 600);
- });
- });
-
- it('Should build an empty edit grid component', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(1)', 'Field 1');
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(2)', 'Field 2');
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '0');
- Harness.testElements(component, 'li.list-group-header', 1);
- Harness.testElements(component, 'li.list-group-item', 1);
- Harness.testElements(component, 'li.list-group-footer', 0);
- Harness.testElements(component, 'div.editRow', 0);
- Harness.testElements(component, 'div.removeRow', 0);
- assert.equal(component.refs[`${component.editgridKey}-addRow`].length, 1);
- assert(component.checkValidity(component.getValue()), 'Item should be valid');
- });
- });
-
- it('Should build an edit grid component', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(1)', 'Field 1');
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(2)', 'Field 2');
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '0');
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- }
- ]);
- Harness.testElements(component, 'li.list-group-header', 1);
- Harness.testElements(component, 'li.list-group-item', 3);
- Harness.testElements(component, 'li.list-group-footer', 0);
- Harness.testElements(component, 'div.editRow', 2);
- Harness.testElements(component, 'div.removeRow', 2);
- assert.equal(component.refs[`${component.editgridKey}-addRow`].length, 1);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(2) div.row div:nth-child(1)', 'good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(2) div.row div:nth-child(2)', 'foo');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(3) div.row div:nth-child(1)', 'good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(3) div.row div:nth-child(2)', 'bar');
- assert(component.checkValidity(component.getValue()), 'Item should be valid');
- });
- });
-
- it('Should add a row when add another is clicked', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testElements(component, 'li.list-group-item', 1);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '0');
- Harness.clickElement(component, component.refs[`${component.editgridKey}-addRow`][0]);
- Harness.testElements(component, 'li.list-group-item', 2);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '0');
- Harness.clickElement(component, component.refs[`${component.editgridKey}-addRow`][0]);
- Harness.testElements(component, 'li.list-group-item', 3);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '0');
- assert(!component.checkValidity(component.getValue(), true), 'Item should not be valid');
- });
- });
-
- it('Should save a new row when save is clicked', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- component.pristine = false;
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- }
- ]);
- Harness.testElements(component, 'li.list-group-item', 3);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.clickElement(component, component.refs[`${component.editgridKey}-addRow`][0]);
- Harness.testElements(component, 'li.list-group-item', 4);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.setInputValue(component, 'data[editgrid][2][field1]', 'good');
- Harness.setInputValue(component, 'data[editgrid][2][field2]', 'baz');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-primary');
- Harness.testElements(component, 'li.list-group-item', 4);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '3');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(4) div.row div:nth-child(1)', 'good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(4) div.row div:nth-child(2)', 'baz');
- assert(component.checkValidity(component.getValue()), 'Item should be valid');
- });
- });
-
- it('Should cancel add a row when cancel is clicked', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- }
- ]);
- Harness.testElements(component, 'li.list-group-item', 3);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.clickElement(component, component.refs[`${component.editgridKey}-addRow`][0]);
- Harness.testElements(component, 'li.list-group-item', 4);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.setInputValue(component, 'data[editgrid][2][field1]', 'good');
- Harness.setInputValue(component, 'data[editgrid][2][field2]', 'baz');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-danger');
- Harness.testElements(component, 'li.list-group-item', 3);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- assert.equal(component.editRows.length, 2);
- assert(component.checkValidity(component.getValue(), true), 'Item should be valid');
- });
- });
-
- it('Should delete a row when delete is clicked', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- },
- {
- field1: 'good',
- field2: 'baz'
- }
- ]);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '3');
- Harness.clickElement(component, 'li.list-group-item:nth-child(3) div.removeRow');
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(2) div.row div:nth-child(1)', 'good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(2) div.row div:nth-child(2)', 'foo');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(3) div.row div:nth-child(1)', 'good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(3) div.row div:nth-child(2)', 'baz');
- assert(component.checkValidity(component.getValue(), true), 'Item should be valid');
- });
- });
-
- it('Should edit a row when edit is clicked', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- }
- ]);
- Harness.clickElement(component, 'li.list-group-item:nth-child(3) div.editRow');
- Harness.getInputValue(component, 'data[editgrid][1][field1]', 'good');
- Harness.getInputValue(component, 'data[editgrid][1][field2]', 'bar');
- Harness.testElements(component, 'div.editgrid-actions button.btn-primary', 1);
- Harness.testElements(component, 'div.editgrid-actions button.btn-danger', 1);
- assert(!component.checkValidity(component.getValue(), true), 'Item should not be valid');
- });
- });
-
- it('Should save a row when save is clicked', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- }
- ]);
- Harness.clickElement(component, 'li.list-group-item:nth-child(3) div.editRow');
- Harness.setInputValue(component, 'data[editgrid][1][field2]', 'baz');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-primary');
- Harness.testElements(component, 'li.list-group-item', 3);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(3) div.row div:nth-child(1)', 'good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(3) div.row div:nth-child(2)', 'baz');
- assert(component.checkValidity(component.getValue(), true), 'Item should be valid');
- });
- });
-
- it('Should cancel edit row when cancel is clicked', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- }
- ]);
- Harness.clickElement(component, 'li.list-group-item:nth-child(3) div.editRow');
- Harness.setInputValue(component, 'data[editgrid][1][field2]', 'baz');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-danger');
- Harness.testElements(component, 'li.list-group-item', 3);
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(3) div.row div:nth-child(1)', 'good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(3) div.row div:nth-child(2)', 'bar');
- assert(component.checkValidity(component.getValue(), true), 'Item should be valid');
- });
- });
-
- it('Should show error messages for existing data in rows', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- field1: 'bad',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- },
- {
- field1: 'also bad',
- field2: 'baz'
- }
- ]);
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(2) div.has-error div.editgrid-row-error', 'Must be good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(4) div.has-error div.editgrid-row-error', 'Must be good');
- assert(!component.checkValidity(component.getValue(), true), 'Item should not be valid');
- });
- });
-
- it('Should not allow saving when errors exist', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.clickElement(component, 'button.btn-primary');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-primary');
- Harness.getInputValue(component, 'data[editgrid][0][field1]', '');
- Harness.getInputValue(component, 'data[editgrid][0][field2]', '');
- assert(!component.checkValidity(component.getValue(), true), 'Item should not be valid');
- Harness.setInputValue(component, 'data[editgrid][0][field2]', 'baz');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-primary');
- Harness.getInputValue(component, 'data[editgrid][0][field1]', '');
- Harness.getInputValue(component, 'data[editgrid][0][field2]', 'baz');
- assert(!component.checkValidity(component.getValue(), true), 'Item should not be valid');
- Harness.setInputValue(component, 'data[editgrid][0][field1]', 'bad');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-primary');
- Harness.getInputValue(component, 'data[editgrid][0][field1]', 'bad');
- Harness.getInputValue(component, 'data[editgrid][0][field2]', 'baz');
- assert(!component.checkValidity(component.getValue(), true), 'Item should not be valid');
- Harness.setInputValue(component, 'data[editgrid][0][field1]', 'good');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-primary');
- assert(component.checkValidity(component.getValue(), true), 'Item should be valid');
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '1');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(2) div.row div:nth-child(1)', 'good');
- Harness.testInnerHtml(component, 'li.list-group-item:nth-child(2) div.row div:nth-child(2)', 'baz');
- });
- });
-
- it('Should not allow saving when rows are open', () => {
- return Harness.testCreate(EditGridComponent, comp1).then((component) => {
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- }
- ]);
- Harness.clickElement(component, 'li.list-group-item:nth-child(3) div.editRow');
- assert(!component.checkValidity(component.getValue(), true), 'Item should not be valid');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-primary');
- assert(component.checkValidity(component.getValue(), true), 'Item should be valid');
- Harness.clickElement(component, 'li.list-group-item:nth-child(3) div.editRow');
- assert(!component.checkValidity(component.getValue(), true), 'Item should not be valid');
- Harness.clickElement(component, 'div.editgrid-actions button.btn-danger');
- assert(component.checkValidity(component.getValue(), true), 'Item should be valid');
- });
- });
-
- it('Should disable components when in read only', () => {
- return Harness.testCreate(EditGridComponent, comp1, { readOnly: true }).then((component) => {
- Harness.testSetGet(component, [
- {
- field1: 'good',
- field2: 'foo'
- },
- {
- field1: 'good',
- field2: 'bar'
- }
- ]);
- Harness.clickElement(component, 'li.list-group-item:nth-child(3) div.removeRow');
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- Harness.clickElement(component, 'li.list-group-item:nth-child(3) div.editRow');
- Harness.testInnerHtml(component, 'li.list-group-header div.row div:nth-child(3)', '2');
- });
- });
-
- describe('Display As Modal', () => {
- it('Should show add error classes to invalid components', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(displayAsModalEditGrid).then(() => {
- const editGrid = form.components[0];
- const clickEvent = new Event('click');
- editGrid.addRow();
- setTimeout(() => {
- const dialog = document.querySelector('[ref="dialogContents"]');
- const saveButton = dialog.querySelector('.btn.btn-primary');
- saveButton.dispatchEvent(clickEvent);
- setTimeout(() => {
- assert.equal(editGrid.errors.length, 6);
- const components = Array.from(dialog.querySelectorAll('[ref="component"]'));
- const areRequiredComponentsHaveErrorWrapper = components.every((comp) => {
- const { className } = comp;
- return (className.includes('required') && className.includes('formio-error-wrapper')) || true;
- });
- assert.equal(areRequiredComponentsHaveErrorWrapper, true);
- document.body.innerHTML = '';
- done();
- }, 100);
- }, 100);
- }).catch(done);
- });
-
- it('Should set alert with validation errors on save and update them', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(ModalEditGrid).then(() => {
- const editGrid = form.components[0];
-
- form.checkValidity(form._data, true, form._data);
- assert.equal(form.errors.length, 1);
- editGrid.addRow();
-
- setTimeout(() => {
- const editRow = editGrid.editRows[0];
- const dialog = editRow.dialog;
- const saveButton = dialog.querySelector('.btn.btn-primary');
- const clickEvent = new Event('click');
- saveButton.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const alert = dialog.querySelector('.alert.alert-danger');
- assert.equal(form.errors.length, 3);
-
- const errorsLinks = alert.querySelectorAll('li');
- assert.equal(errorsLinks.length, 2);
- const textField = editRow.components[0].getComponent('textField');
- textField.setValue('new value');
-
- setTimeout(() => {
- const alertAfterFixingField = dialog.querySelector('.alert.alert-danger');
- assert.equal(form.errors.length, 2);
-
- const errorsLinksAfterFixingField = alertAfterFixingField.querySelectorAll('li');
- assert.equal(errorsLinksAfterFixingField.length, 1);
-
- document.body.innerHTML = '';
- done();
- }, 450);
- }, 100);
- }, 100);
- }).catch(done);
- });
-
- it('Confirmation dialog', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp6).then(() => {
- const component = form.components[0];
- component.addRow();
- const dialog = document.querySelector('[ref="dialogContents"]');
- Harness.dispatchEvent('input', dialog, '[name="data[editGrid][0][textField]"]', (el) => el.value = '12');
- Harness.dispatchEvent('click', dialog, '[ref="dialogClose"]');
- const confirmationDialog = document.querySelector('[ref="confirmationDialog"]');
- assert(confirmationDialog, 'Should open a confirmation dialog when trying to close');
- Harness.dispatchEvent('click', confirmationDialog, '[ref="dialogCancelButton"]');
- setTimeout(() => {
- assert.equal(component.editRows[0].data.textField, '12', 'Data should not be cleared');
-
- Harness.dispatchEvent('click', dialog, '[ref="dialogClose"]');
- setTimeout(() => {
- const confirmationDialog2 = document.querySelector('[ref="confirmationDialog"]');
- assert(confirmationDialog2, 'Should open again a conformation dialog');
- Harness.dispatchEvent('click', confirmationDialog2, '[ref="dialogYesButton"]');
- setTimeout(() => {
- assert.equal(component.editRows.length, 0, 'Data should be cleared');
- done();
- }, 250);
- }, 250);
- }, 250);
- }).catch(done);
- });
-
- it('Confirmation dialog shouldn\'t occure if no values within the row are changed', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp6).then(() => {
- const component = form.components[0];
- component.setValue([
- { textField: 'v1' }
- ]);
- setTimeout(() => {
- component.editRow(0);
- const dialog = document.querySelector('[ref="dialogContents"]');
- Harness.dispatchEvent('click', dialog, '[ref="dialogClose"]');
- const confirmationDialog = document.querySelector('[ref="confirmationDialog"]');
- assert(!confirmationDialog, 'Shouldn\'t open a confirmation dialog when no values were changed');
- assert.equal(component.editRows[0].data.textField, 'v1', 'Data shouldn\'t be changed');
- done();
- }, 150);
- }).catch(done);
- });
-
- it('Should not produce many components in Edit view when minLength validation set', done => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, comp15, { attachMode:'builder' } )
- .then(form => {
- const editGrid = form.components[0];
- const elements = editGrid.element.querySelectorAll('[ref="input"]');
-
- setTimeout(() => {
- assert.equal(elements.length, 2);
- done();
- }, 200);
- })
- .catch(done);
- });
-
- it('Should close row when Display as Modal checked', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp14).then(() => {
- const editGrid = form.components[0];
- editGrid.addRow();
- setTimeout(() => {
- const dialog = document.querySelector('[ref="dialogContents"]');
- Harness.dispatchEvent('input', dialog, '[name="data[editGrid][0][firstName]"]', (el) => el.value = 'Michael');
- Harness.dispatchEvent('click', dialog, '[ref="dialogClose"]');
- const confirmationDialog = document.querySelector('[ref="confirmationDialog"]');
- Harness.dispatchEvent('click', confirmationDialog, '[ref="dialogYesButton"]');
- setTimeout(() => {
- assert.equal(!!document.querySelector('[ref="dialogContents"]'), false);
- done();
- }, 100);
- }, 100);
- }).catch(done);
- });
- });
-
- describe('Draft Rows', () => {
- it('Check saving rows as draft', (done) => {
- Harness.testCreate(EditGridComponent, comp5).then((component) => {
- component.addRow();
- Harness.clickElement(component, '[ref="editgrid-editGrid1-saveRow"]');
- assert.deepEqual(component.dataValue, [{ textField: '' }]);
- const isInvalid = !component.checkValidity(component.dataValue, true);
- assert(isInvalid, 'Item should not be valid');
- assert(component.editRows[0].state === 'draft', 'Row should be saved as draft if it has errors');
- done();
- }).catch(done);
- });
-
- it('Should not show row errors alerts if drafts enabled in modal-edit EditGrid', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- ModalEditGrid.components[0].rowDrafts = true;
-
- form.setForm(ModalEditGrid).then(() => {
- const editGrid = form.components[0];
- editGrid.addRow();
-
- setTimeout(() => {
- editGrid.saveRow(0);
-
- setTimeout(() => {
- editGrid.editRow(0).then(() => {
- const textField = form.getComponent(['editGrid', 0, 'form', 'textField']);
-
- textField.setValue('someValue');
-
- setTimeout(() => {
- Harness.dispatchEvent('click', editGrid.editRows[0].dialog, `.editgrid-row-modal-${editGrid.id} [ref="dialogClose"]`);
- setTimeout(() => {
- const dialog = editGrid.editRows[0].confirmationDialog;
-
- Harness.dispatchEvent('click', dialog, '[ref="dialogYesButton"]');
-
- setTimeout(() => {
- editGrid.editRow(0).then(() => {
- textField.setValue('someValue');
-
- setTimeout(() => {
- const errorAlert = editGrid.editRows[0].dialog.querySelector(`#error-list-${editGrid.id}`);
- const hasError = textField.className.includes('has-error');
- assert(!hasError, 'Should stay valid until form is submitted');
- assert.equal(errorAlert, null, 'Should be valid');
-
- done();
- }, 100);
- });
- }, 100);
- }, 100);
- }, 100);
- });
- }, 100);
- }, 100);
- }).catch(done)
- .finally(() => {
- ModalEditGrid.components[0].rowDrafts = false;
- });
- });
-
- it('Should keep fields valid inside NestedForms if drafts are enabled', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- ModalEditGrid.components[0].rowDrafts = true;
-
- form.setForm(ModalEditGrid).then(() => {
- const editGrid = form.components[0];
-
- form.checkValidity(form._data, true, form._data);
- assert.equal(form.errors.length, 1, 'Should have an error saying that EditGrid is required');
-
- // 1. Add a row
- editGrid.addRow();
-
- setTimeout(() => {
- const editRow = editGrid.editRows[0];
- const dialog = editRow.dialog;
-
- // 2. Save the row
- Harness.dispatchEvent('click', dialog, '.btn.btn-primary');
-
- setTimeout(() => {
- const alert = dialog.querySelector('.alert.alert-danger');
- assert.equal(form.errors.length, 0, 'Should not add new errors when drafts are enabled');
- assert(!alert, 'Should not show an error alert when drafts are enabled and form is not submitted');
-
- const textField = editRow.components[0].getComponent('textField');
-
- // 3. Edit the row
- editGrid.editRow(0);
-
- setTimeout(() => {
- // 4. Change the value of the text field
- textField.setValue('new value', { modified: true });
-
- setTimeout(() => {
- assert.equal(textField.dataValue, 'new value');
- // 5. Clear the value of the text field
- textField.setValue('', { modified: true });
-
- setTimeout(() => {
- assert.equal(textField.dataValue, '');
- assert.equal(editGrid.editRows[0].errors.length, 0, 'Should not add error to components inside draft row');
-
- const textFieldComponent = textField.element;
- assert(textFieldComponent.className.includes('has-error'), 'Should add error class to component even when drafts enabled if the component is not pristine');
-
- document.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }, 150);
- }, 100);
- }, 100);
- }).catch(done)
- .finally(() => {
- delete ModalEditGrid.components[0].rowDrafts;
- });
- });
-
- it('Should keep fields valid inside NestedForms if drafts are enabled', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- ModalEditGrid.components[0].rowDrafts = true;
-
- form.setForm(ModalEditGrid).then(() => {
- const editGrid = form.components[0];
- // 1. Add a row
- editGrid.addRow();
-
- setTimeout(() => {
- const editRow = editGrid.editRows[0];
- const dialog = editRow.dialog;
-
- // 2. Save the row
- Harness.dispatchEvent('click', dialog, '.btn.btn-primary');
-
- setTimeout(() => {
- // 3. Submit the form
- Harness.dispatchEvent('click', form.element, '[name="data[submit]"]');
-
- setTimeout(() => {
- assert.equal(editGrid.errors.length, 3, 'Should be validated after an attempt to submit');
- assert.equal(editGrid.editRows[0].errors.length, 2, 'Should dd errors to the row after an attempt to submit');
- const rows = editGrid.element.querySelectorAll('[ref="editgrid-editGrid-row"]');
- const firstRow = rows[0];
- Harness.dispatchEvent('click', firstRow, '.editRow');
-
- setTimeout(() => {
- assert(form.submitted, 'Form should be submitted');
- const editRow = editGrid.editRows[0];
- assert(editRow.alerts, 'Should add an error alert to the modal');
- assert.equal(editRow.errors.length, 2, 'Should add errors to components inside draft row aftre it was submitted');
- const textField = editRow.components[0].getComponent('textField');
-
- const alert = editGrid.alert;
- assert(alert, 'Should show an error alert when drafts are enabled and form is submitted');
- assert(textField.element.className.includes('has-error'), 'Should add error class to component even when drafts enabled if the form was submitted');
-
- // 4. Change the value of the text field
- textField.setValue('new value', { modified: true });
-
- setTimeout(() => {
- const textFieldEl = textField.element;
- assert.equal(textField.dataValue, 'new value');
- assert(!textFieldEl.className.includes('has-error'), 'Should remove an error class from component when it was fixed');
- const editRow = editGrid.editRows[0];
- const textField2 = editRow.components[0].getComponent('textField2');
-
- textField2.setValue('test val', { modified: true });
-
- setTimeout(() => {
- assert.equal(textField2.dataValue, 'test val');
- assert(!textField2.element.className.includes('has-error'), 'Should remove an error class from component when it was fixed');
-
- editGrid.saveRow(0);
-
- setTimeout(() => {
- assert(!form.alert, 'Should remove an error alert after all the rows were fixed');
-
- const rows = editGrid.element.querySelectorAll('[ref="editgrid-editGrid-row"]');
- const firstRow = rows[0];
- Harness.dispatchEvent('click', firstRow, '.editRow');
- setTimeout(() => {
- const editRow = editGrid.editRows[0];
- const textField2 = editRow.components[0].getComponent('textField2');
-
- Harness.dispatchEvent(
- 'input',
- editRow.dialog,
- '[name="data[textField2]"',
- (i) => i.value = ''
- );
- setTimeout(() => {
- assert.equal(textField2.dataValue, '');
- Harness.dispatchEvent(
- 'click',
- editGrid.editRows[0].dialog,
- `.editgrid-row-modal-${editGrid.id} [ref="dialogClose"]`
- );
- setTimeout(() => {
- const dialog = editGrid.editRows[0].confirmationDialog;
-
- Harness.dispatchEvent('click', dialog, '[ref="dialogYesButton"]');
-
- setTimeout(() => {
- assert(
- !document.querySelector(`#error-list-${form.id}`),
- 'Should not add an error alert when the changes that made the row invalid, were discarded by Cancel'
- );
- document.innerHTML = '';
- done();
- }, 100);
- }, 100);
- }, 200);
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }, 450);
- }, 250);
- }, 100);
- }, 100);
- }).catch(done)
- .finally(() => {
- delete ModalEditGrid.components[0].rowDrafts;
- });
- });
-
- // it('', (done) => {
- // const formElement = document.createElement('div');
- // const form = new Webform(formElement);
- // form.setForm(ModalEditGrid).then(() => {
- //
- // }).catch(done);
- // });
- });
-
- it('Test simple conditions based on the EditGrid\'s child\'s value and default values when adding rows', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm({ display: 'form', components: [comp7], type: 'form' }).then(() => {
- const component = form.getComponent(['editGrid']);
- component.addRow();
- setTimeout(() => {
- Harness.getInputValue(component, 'data[editGrid][0][checkbox]', true, 'checked');
- Harness.testComponentVisibility(component, '.formio-component-editGridChild', true);
- Harness.testComponentVisibility(component, '.formio-component-panelChild', true);
- done();
- }, 250);
- }).catch(done);
- });
-
- it('Test clearOnHide inside EditGrid', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm({ display: 'form', components: [comp7], type: 'form' }).then(() => {
- form.submission = {
- data: {
- editGrid: [
- {
- checkbox: true,
- editGridChild: 'Has Value',
- panelChild: 'Has Value Too',
- }
- ]
- }
- };
- setTimeout(() => {
- const editGrid = form.getComponent(['editGrid']);
- editGrid.editRow(0).then(() => {
- Harness.dispatchEvent('click', editGrid.element, '[name="data[editGrid][0][checkbox]"]', el => el.checked = false);
- setTimeout(() => {
- Harness.testComponentVisibility(editGrid, '.formio-component-editGridChild', false);
- Harness.testComponentVisibility(editGrid, '.formio-component-panelChild', false);
- editGrid.saveRow(0, true);
- setTimeout(() => {
- assert(!form.data.editGrid[0].editGridChild, 'Should be cleared');
- assert(!form.data.editGrid[0].panelChild, 'Should be cleared');
- done();
- }, 150);
- }, 150);
- }, 150);
- });
- }).catch(done);
- });
-
- it('Test refreshing inside EditGrid', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm({ display: 'form', components: [comp8], type: 'form' }).then(() => {
- const editGrid = form.getComponent(['editGrid1']);
- editGrid.addRow();
- const makeSelect = form.getComponent(['editGrid1', 0, 'make']);
- const modelSelect = form.getComponent(['editGrid1', 0, 'model']);
- makeSelect.setValue('ford');
- setTimeout(() => {
- modelSelect.setValue('Focus');
- setTimeout(() => {
- editGrid.saveRow(0, true);
- setTimeout(() => {
- assert.equal(form.data.editGrid1[0].model, 'Focus', 'Should be saved properly');
- done();
- }, 150);
- }, 100);
- }, 150);
- }).catch(done);
- });
-
- it('Should display summary with values only for components that are visible at least in one row', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp9).then(() => {
- const editGrid = form.getComponent('editGrid');
-
- const checkRows = (columnsNumber, rowsNumber) => {
- const rowWithColumns = editGrid.element.querySelector('.row');
- const rowsWithValues = editGrid.element.querySelectorAll('[ref="editgrid-editGrid-row"]');
-
- assert.equal(rowWithColumns.children.length, columnsNumber, 'Row should contain values only for visible components');
- assert.equal(rowsWithValues.length, rowsNumber, 'Should have corrent number of rows');
- };
-
- checkRows(2, 0);
- form.setValue({
- data: {
- editGrid: [
- { textField: 'test1', checkbox: false },
- { textField: 'test2', checkbox: false },
- ],
- }
- });
- setTimeout(() => {
- checkRows(2, 2);
- form.setValue({
- data: {
- editGrid: [
- { textField: 'test1', checkbox: false },
- { textField: 'test2', checkbox: true },
- ],
- }
- });
-
- setTimeout(() => {
- checkRows(3, 2);
- form.setValue({
- data: {
- editGrid: [
- { textField: 'test1', checkbox: false },
- { textField: 'test2', checkbox: true, textArea: 'test22' },
- { textField: 'show', checkbox: true, container: { number1: 1111 }, textArea: 'test3' }
- ],
- }
- });
-
- setTimeout(() => {
- checkRows(4, 3);
- form.setValue({
- data: {
- editGrid: [
- { textField: 'test1', checkbox: false },
- { textField: 'test2', checkbox: false },
- { textField: 'show', checkbox: false, container: { number1: 1111 } }
- ],
- }
- });
-
- setTimeout(() => {
- checkRows(3, 3);
-
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should add component to the header only if it is visible in saved row', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp9).then(() => {
- const editGrid = form.getComponent('editGrid');
-
- const checkHeader = (componentsNumber) => {
- const header = editGrid.element.querySelector('.list-group-header').querySelector('.row');
-
- assert.equal(editGrid.visibleInHeader.length, componentsNumber);
- assert.equal(header.children.length, componentsNumber);
- };
-
- const clickElem = (elem) => {
- const clickEvent = new Event('click');
- elem.dispatchEvent(clickEvent);
- };
- const clickAddRow = () => {
- const addAnotherBtn = editGrid.refs['editgrid-editGrid-addRow'][0];
- clickElem(addAnotherBtn);
- };
-
- checkHeader(2);
- clickAddRow();
-
- setTimeout(() => {
- assert.equal(editGrid.editRows.length, 1);
- checkHeader(2);
- const checkbox = editGrid.getComponent('checkbox')[0];
- checkbox.setValue(true);
-
- setTimeout(() => {
- checkHeader(2);
- assert.equal(editGrid.getComponent('textArea')[0].visible, true);
- clickAddRow();
-
- setTimeout(() => {
- assert.equal(editGrid.editRows.length, 2);
- checkHeader(2);
- const saveFirstRowBtn = editGrid.refs['editgrid-editGrid-saveRow'][0];
- clickElem(saveFirstRowBtn);
-
- setTimeout(() => {
- assert.equal(editGrid.editRows[0].state, 'saved');
- checkHeader(3);
-
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- }).timeout(3000);
-
- it('Should add/save/cancel/delete/edit rows', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const editGrid = form.getComponent('editGrid');
-
- const click = (btn, index, selector) => {
- let elem;
-
- if (selector) {
- elem = editGrid.element.querySelectorAll(`.${btn}`)[index];
- }
- else {
- elem = editGrid.refs[`editgrid-editGrid-${btn}`][index];
- }
-
- const clickEvent = new Event('click');
- elem.dispatchEvent(clickEvent);
- };
-
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 0, 'Should not have rows');
- assert.equal(editGrid.editRows.length, 0, 'Should not have rows');
-
- click('addRow', 0);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows[0].state, 'new', 'Should have state "new"');
- editGrid.editRows[0].components.forEach((comp) => {
- comp.setValue(11111);
- });
-
- setTimeout(() => {
- assert.deepEqual(editGrid.editRows[0].data, { number: 11111, textField: '11111' }, 'Should set row data');
- click('saveRow', 0);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows[0].state, 'saved', 'Should have state "saved"');
- assert.deepEqual(editGrid.editRows[0].data, { number: 11111, textField: '11111' }, 'Should set row data');
- click('editRow', 0, true);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows[0].state, 'editing', 'Should have state "editing"');
- editGrid.editRows[0].components.forEach((comp) => {
- comp.setValue(22222);
- });
-
- setTimeout(() => {
- assert.deepEqual(editGrid.editRows[0].data, { number: 22222, textField: '22222' }, 'Should set row data');
- click('cancelRow', 0);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows[0].state, 'saved', 'Should have state "saved"');
- assert.deepEqual(editGrid.editRows[0].data, { number: 11111, textField: '11111' }, 'Should cancel changed data');
- click('removeRow', 0, true);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 0, 'Should not have rows');
- assert.equal(editGrid.editRows.length, 0, 'Should have 0 rows');
-
- document.innerHTML = '';
- done();
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }).catch(done);
- }).timeout(3000);
-
- it('Should open first row when empty and allow saving openned row', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
- form.components[0].openWhenEmpty = true;
-
- Formio.createForm(element, form).then(form => {
- const editGrid = form.getComponent('editGrid');
-
- const click = (btn, index, selector) => {
- let elem;
-
- if (selector) {
- elem = editGrid.element.querySelectorAll(`.${btn}`)[index];
- }
- else {
- elem = editGrid.refs[`editgrid-editGrid-${btn}`][index];
- }
-
- const clickEvent = new Event('click');
- elem.dispatchEvent(clickEvent);
- };
-
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows[0].state, 'new', 'Should have state "new"');
- click('saveRow', 0);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows[0].state, 'saved', 'Should have state "saved"');
-
- document.innerHTML = '';
- done();
- }, 200);
- }).catch(done);
- }).timeout(3000);
-
- it('Should disable adding/removing rows', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
- form.components[0].disableAddingRemovingRows = true;
- const value = [{ number: 1, textField: 'test' }, { number: 2, textField: 'test2' }];
-
- Formio.createForm(element, form).then(form => {
- const editGrid = form.getComponent('editGrid');
- editGrid.setValue(value);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-row'].length, 2, 'Should have 2 rows');
- assert.equal(editGrid.editRows.length, 2, 'Should have 2 rows');
- assert.equal(editGrid.refs['editgrid-editGrid-addRow'].length, 0, 'Should not have add row btn');
- assert.equal(editGrid.element.querySelectorAll('.removeRow').length, 0, 'Should not have remove row btn');
-
- document.innerHTML = '';
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should show conditional eddRow btn if condition is met', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
- form.components[0].conditionalAddButton = 'show = data.number11 === 5';
- form.components.unshift({
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'number11',
- type: 'number',
- input: true
- });
- Formio.createForm(element, form).then(form => {
- const editGrid = form.getComponent('editGrid');
- assert.equal(editGrid.refs['editgrid-editGrid-addRow'].length, 0, 'Should not have add row btn');
- const numberComp = form.getComponent('number11');
- const inputEvent = new Event('input');
- const numberInput = numberComp.refs.input[0];
- numberInput.value = 5;
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-addRow'].length, 1, 'Should have add row btn');
-
- document.innerHTML = '';
- done();
- }, 400);
- }).catch(done);
- });
-
- it('Should use custom text for save/cancel/add btns', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
- form.components[0].addAnother = 'add custom';
- form.components[0].saveRow = 'save custom';
- form.components[0].removeRow = 'cancel custom';
-
- Formio.createForm(element, form).then(form => {
- const editGrid = form.getComponent('editGrid');
- assert.equal(editGrid.refs['editgrid-editGrid-addRow'][0].textContent.trim(), 'add custom');
- const clickEvent = new Event('click');
- editGrid.refs['editgrid-editGrid-addRow'][0].dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(editGrid.refs['editgrid-editGrid-saveRow'][0].textContent.trim(), 'save custom');
- assert.equal(editGrid.refs['editgrid-editGrid-cancelRow'][0].textContent.trim(), 'cancel custom');
-
- document.innerHTML = '';
- done();
- }, 400);
- }).catch(done);
- });
-
- it('Should render headers when openWhenEmpry is enabled', (done) => {
- const form = _.cloneDeep(comp11);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const editGrid = form.getComponent('editGrid');
- const rowComponents = editGrid.component.components;
- const headerEls = editGrid.element.querySelector('.list-group-header').firstElementChild.children;
- assert.equal(headerEls.length, rowComponents.length);
- for (let index = 0; index < headerEls.length; index++) {
- const el = headerEls[index];
- assert.equal(el.textContent.trim(), rowComponents[index].label, `Should render ${rowComponents[index].key} component label in header`);
- }
- done();
- }).catch(done);
- });
-
- it('Should show validation when saving a row with required conditional filed inside container', (done) => {
- const form = _.cloneDeep(comp12);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const editGrid = form.getComponent('editGrid');
- const clickEvent = new Event('click');
- editGrid.refs['editgrid-editGrid-addRow'][0].dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const firstRowContainer = editGrid.components[0];
- const firstRowNumber = firstRowContainer.components[0];
- const firstRowTextField = firstRowContainer.components[1];
-
- assert.equal(firstRowTextField.visible, false);
-
- const inputEvent = new Event('input');
- const numberInput = firstRowNumber.refs.input[0];
-
- numberInput.value = 5;
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(firstRowTextField.visible, true);
- editGrid.refs['editgrid-editGrid-saveRow'][0].dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!firstRowTextField.error, true);
- assert.equal(editGrid.editRows[0].errors.length, 1);
- assert.equal(editGrid.editRows[0].state, 'new');
-
- document.innerHTML = '';
- done();
- }, 200);
- }, 250);
- }, 300);
- }).catch(done);
- });
-
- it('Should render form with a submission in a draft-state without validation errors', (done) => {
- const form = _.cloneDeep(comp13);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.submission = {
- data: {
- 'container': {
- 'textField': '',
- },
- 'editGrid': []
- }
- };
-
- setTimeout(() => {
- const editGrid = form.getComponent(['editGrid']);
- assert.equal(editGrid.errors.length, 0);
- done();
- }, 100);
- }).catch(done);
- });
-});
-
-describe('EditGrid Open when Empty', () => {
- it('Should be opened when shown conditionally', (done) => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, withOpenWhenEmptyAndConditions)
- .then((form) => {
- const radio = form.getComponent(['radio']);
- radio.setValue('show');
-
- setTimeout(() => {
- const editGrid = form.getComponent(['editGrid']);
- assert.equal(editGrid.visible, true, 'Should be visible');
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- const textField = editGrid.editRows[0].components[0];
- Harness.dispatchEvent(
- 'input',
- textField.element,
- '[name="data[editGrid][0][textField]"]',
- (input) => input.value = 'Value'
- );
-
- setTimeout(() => {
- const row = editGrid.editRows[0];
- assert.equal(row.data.textField, 'Value', 'Value should be set properly');
- editGrid.saveRow(0);
- setTimeout(() => {
- assert.deepEqual(form.data.editGrid, [{ textField: 'Value', select1: '' }], 'Value should be saved correctly');
- radio.setValue('hide');
-
- setTimeout(() => {
- assert.equal(editGrid.visible, false, 'Should be hidden');
- radio.setValue('show');
-
- setTimeout(() => {
- assert.equal(editGrid.visible, true, 'Should be visible');
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows[0].state, 'new', 'Row should be a new one');
- done();
- }, 300);
- }, 300);
- }, 250);
- }, 350);
- }, 300);
- })
- .catch(done);
- });
-
- it('Should create new row with empty data and no defaults', (done) => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, compOpenWhenEmpty, { noDefaults: true })
- .then((form) => {
- form.data = {};
- setTimeout(() => {
- const editGrid = form.getComponent(['editGrid']);
- assert.equal(editGrid.editRows.length, 1);
- assert.equal(editGrid.editRows[0].state, 'new');
- done();
- }, 300);
- })
- .catch(done);
- });
-
- it('Should always add a first row', (done) => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, compOpenWhenEmpty)
- .then((form) => {
- const editGrid = form.getComponent(['editGrid']);
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row on create');
- const textField = editGrid.editRows[0].components[0];
- Harness.dispatchEvent(
- 'input',
- textField.element,
- '[name="data[editGrid][0][textField]"]',
- (input) => input.value = 'Value'
- );
-
- setTimeout(() => {
- const row = editGrid.editRows[0];
- assert.equal(row.data.textField, 'Value', 'Value should be set properly');
-
- setTimeout(() => {
- editGrid.cancelRow(0);
-
- setTimeout(() => {
- assert.equal(editGrid.editRows.length, 1, 'Should still have 1 row');
- const textField = editGrid.editRows[0].components[0];
- assert.equal(textField.dataValue, '', 'Value should be cleared after cancelling the row');
-
- editGrid.saveRow(0);
-
- setTimeout(() => {
- assert.equal(editGrid.editRows.length, 1, 'Should have 1 row');
- assert.equal(editGrid.editRows[0].state === 'saved', 1, 'Row should be saved');
-
- editGrid.removeRow(0);
-
- setTimeout(() => {
- assert.equal(editGrid.editRows.length, 1, 'Should add the first row when delete the last one');
- assert.equal(editGrid.editRows[0].state === 'new', 1, 'Should add the new row when the last one was deleted');
-
- done();
- }, 250);
- }, 250);
- }, 250);
- }, 250);
- }, 250);
- })
- .catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.data.js
deleted file mode 100644
index 0d29afba..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.data.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default [
- {
- type: 'checkbox',
- input: true,
- weight: 105,
- key: 'inlineEdit',
- label: 'Inline Editing',
- tooltip: 'Check this if you would like your changes within \'edit\' mode to be committed directly to the submission object as that row is being changed',
- },
- {
- key: 'defaultValue',
- ignore: true,
- },
- {
- key: 'multiple',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.display.js
deleted file mode 100644
index 89f4bd8f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.display.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import Evaluator from '../../../utils/Evaluator';
-
-export default [
- {
- key: 'placeholder',
- ignore: true,
- },
- {
- type: 'checkbox',
- label: 'Open First Row when Empty',
- key: 'openWhenEmpty',
- tooltip: 'Check this if you would like to open up the first row when the EditGrid is empty',
- weight: 1000,
- input: true,
- conditional: {
- json: { '!==': [{ var: 'data.modal' }, true] },
- }
- },
- {
- type: 'checkbox',
- label: 'Disable Adding / Removing Rows',
- key: 'disableAddingRemovingRows',
- tooltip: 'Check if you want to hide Add Another button and Remove Row button',
- weight: 1001,
- input: true,
- clearOnHide: false,
- calculateValue: 'value = data.disableAddingRemovingRows;',
- },
- {
- type: 'checkbox',
- label: 'Display EditGrid as Table',
- key: 'displayAsTable',
- tooltip: 'use Table Template',
- weight: 1002,
- input: false,
- customConditional() {
- return !Evaluator.noeval;
- },
- },
- {
- weight: 1010,
- type: 'textarea',
- input: true,
- key: 'conditionalAddButton',
- label: 'Conditional Add Button',
- placeholder: 'show = ...',
- tooltip: 'Specify condition when Add Button should be displayed.',
- editor: 'ace',
- as: 'javascript',
- wysiwyg: {
- minLines: 3,
- },
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.templates.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.templates.js
deleted file mode 100644
index e2b1abfb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.templates.js
+++ /dev/null
@@ -1,127 +0,0 @@
-import Evaluator from '../../../utils/Evaluator';
-
-export default [
- {
- type: 'textarea',
- label: 'Header Template',
- key: 'templates.header',
- rows: 5,
- editor: 'ace',
- as: 'handlebars',
- clearOnHide: false,
- input: true,
- placeholder: '/*** Lodash Template Code ***/',
- description: 'Two available variables. "value" is the array of row data and "components" is the array of components in the grid.',
- tooltip: 'This is the Lodash Template used to render the header of the Edit grid.',
- customConditional({ data }) {
- return (!Evaluator.noeval || Evaluator.protectedEval) && !data.displayAsTable;
- }
- },
- {
- type: 'textarea',
- label: 'Table Header Template',
- key: 'templates.tableHeader',
- rows: 6,
- editor: 'ace',
- as: 'handlebars',
- clearOnHide: false,
- input: true,
- placeholder: '/*** Lodash Template Code ***/',
- description: 'Two available variables. "value" is the array of row data and "components" is the array of components in the grid.',
- tooltip: 'This is the Lodash Template used to render the header of the Edit grid.',
- customConditional({ data }) {
- return (!Evaluator.noeval || Evaluator.protectedEval) && data.displayAsTable;
- }
- },
- {
- type: 'textarea',
- label: 'Row Template',
- key: 'templates.row',
- rows: 5,
- editor: 'ace',
- as: 'handlebars',
- clearOnHide: false,
- input: true,
- placeholder: '/*** Lodash Template Code ***/',
- description: 'Three available variables. "row" is an object of one row\'s data, "components"' +
- ' is the array of components in the grid and "state" is current row\'s state (can be "draft" or "saved").' +
- ' To add click events, add the classes "editRow" and "removeRow" to elements.',
- tooltip: 'This is the Lodash Template used to render each row of the Edit grid.',
- customConditional({ data }) {
- return (!Evaluator.noeval || Evaluator.protectedEval) && !data.displayAsTable;
- }
- },
- {
- type: 'textarea',
- label: 'Table Row Template',
- key: 'templates.tableRow',
- rows: 5,
- editor: 'ace',
- as: 'handlebars',
- clearOnHide: false,
- input: true,
- placeholder: '/*** Lodash Template Code ***/',
- description: 'Three available variables. "row" is an object of one row\'s data, "components"' +
- ' is the array of components in the grid and "state" is current row\'s state (can be "draft" or "saved").' +
- ' To add click events, add the classes "editRow" and "removeRow" to elements.',
- tooltip: 'This is the Lodash Template used to render each row of the Edit grid.',
- customConditional({ data }) {
- return (!Evaluator.noeval || Evaluator.protectedEval) && data.displayAsTable;
- }
- },
- {
- type: 'textarea',
- label: 'Footer Template',
- key: 'templates.footer',
- rows: 5,
- editor: 'ace',
- as: 'handlebars',
- input: true,
- placeholder: '/*** Lodash Template Code ***/',
- description: 'Two available variables. "value" is the array of row data and "components" is the array of components in the grid.',
- tooltip: 'This is the Lodash Template used to render the footer of the Edit grid.',
- customConditional() {
- return !Evaluator.noeval || Evaluator.protectedEval;
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'rowClass',
- label: 'Row CSS Class',
- placeholder: 'Row CSS Class',
- tooltip: 'CSS class to add to the edit row wrapper.'
- },
- {
- type: 'textfield',
- input: true,
- key: 'addAnother',
- label: 'Add Another Text',
- placeholder: 'Add Another',
- tooltip: 'Set the text of the Add Another button.'
- },
- {
- weight: 70,
- type: 'checkbox',
- label: 'Display as Modal',
- tooltip: 'Display a modal to add or edit entries in the table',
- key: 'modal',
- input: true
- },
- {
- type: 'textfield',
- input: true,
- key: 'saveRow',
- label: 'Save Row Text',
- placeholder: 'Save',
- tooltip: 'Set the text of the Save Row button.'
- },
- {
- type: 'textfield',
- input: true,
- key: 'removeRow',
- label: 'Remove Row Text',
- placeholder: 'Remove',
- tooltip: 'Set the text of the remove Row button.'
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.validation.js
deleted file mode 100644
index ec0c5e6f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/editForm/EditGrid.edit.validation.js
+++ /dev/null
@@ -1,32 +0,0 @@
-export default [
- {
- ignore: true,
- key: 'unique',
- },
- {
- weight: 110,
- key: 'validate.minLength',
- label: 'Minimum Length',
- placeholder: 'Minimum Length',
- type: 'number',
- tooltip: 'The minimum length requirement this field must meet.',
- input: true
- },
- {
- weight: 120,
- key: 'validate.maxLength',
- label: 'Maximum Length',
- placeholder: 'Maximum Length',
- type: 'number',
- tooltip: 'The maximum length requirement this field must meet.',
- input: true
- },
- {
- type: 'checkbox',
- input: true,
- weight: 105,
- key: 'rowDrafts',
- label: 'Enable Row Drafts',
- tooltip: 'Allow save rows even if their data is invalid. Errors will occur when try to submit with invalid rows.',
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-openWhenEmpty.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-openWhenEmpty.js
deleted file mode 100644
index 2341f43a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-openWhenEmpty.js
+++ /dev/null
@@ -1,34 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Edit Grid',
- openWhenEmpty: true,
- tableView: false,
- rowDrafts: false,
- key: 'editGrid',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- }
- ]
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
- title: 'FIO-2819',
- display: 'form',
- name: 'fio2819',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-with-basic-components.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-with-basic-components.js
deleted file mode 100644
index 70188f47..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-with-basic-components.js
+++ /dev/null
@@ -1,222 +0,0 @@
-export default {
- type: 'form',
- owner: '5e05a6b7549cdc2ece30c6b0',
- components: [
- {
- label: 'Edit Grid Basic Drafts Enabled Modal',
- tableView: true,
- templates: {
- header: "\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n
{{ component.label }}
\n {% } %}\n {% }) %}\n
",
- row: "\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n
\n {{ getView(component, row[component.key]) }}\n
\n {% } %}\n {% }) %}\n {% if (!instance.disabled) { %}\n
\n
\n \n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n \n {% } %}\n
\n
\n {% } %}\n
"
- },
- modal: true,
- key: 'editGridBasic2',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true
- },
- key: 'textField',
- type: 'textfield',
- input: true
- },
- {
- label: 'Text Area',
- autoExpand: false,
- tableView: true,
- validate: {
- required: true
- },
- key: 'textArea',
- type: 'textarea',
- input: true
- },
- {
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: true,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- validate: {
- required: true
- },
- key: 'number',
- type: 'number',
- input: true
- },
- {
- label: 'Password',
- tableView: true,
- validate: {
- required: true
- },
- key: 'password',
- type: 'password',
- input: true,
- protected: true
- },
- {
- label: 'Checkbox',
- tableView: true,
- defaultValue: false,
- validate: {
- required: true
- },
- key: 'checkbox',
- type: 'checkbox',
- input: true
- },
- {
- label: 'Select Boxes',
- optionsLabelPosition: 'right',
- tableView: true,
- defaultValue: {
- '': false,
- sa: false,
- sb: false,
- sc: false
- },
- values: [
- {
- label: 'sa',
- value: 'sa',
- shortcut: ''
- },
- {
- label: 'sb',
- value: 'sb',
- shortcut: ''
- },
- {
- label: 'sc',
- value: 'sc',
- shortcut: ''
- }
- ],
- validate: {
- required: true
- },
- key: 'selectBoxes1',
- type: 'selectboxes',
- input: true,
- inputType: 'checkbox'
- },
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- data: {
- values: [
- {
- label: 'se1',
- value: 'se1'
- },
- {
- label: 'se2',
- value: 'se2'
- },
- {
- label: 'se3',
- value: 'se3'
- }
- ]
- },
- selectThreshold: 0.3,
- validate: {
- required: true
- },
- key: 'select1',
- type: 'select',
- indexeddb: {
- filter: {
-
- }
- },
- input: true
- },
- {
- label: 'Select URL',
- widget: 'choicesjs',
- tableView: true,
- dataSrc: 'url',
- data: {
- values: [
- {
- label: '',
- value: ''
- }
- ],
- url: 'https://cdn.rawgit.com/mshafrir/2646763/raw/states_titlecase.json',
- headers: [
- {
- key: '',
- value: ''
- }
- ]
- },
- template: '{{ item.name }} ',
- selectThreshold: 0.3,
- validate: {
- required: true
- },
- key: 'selectUrl',
- type: 'select',
- indexeddb: {
- filter: {
-
- }
- },
- input: true,
- disableLimit: false
- },
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: false,
- tableView: true,
- values: [
- {
- label: 'ra1',
- value: 'ra1',
- shortcut: ''
- },
- {
- label: 'ra2',
- value: 'ra2',
- shortcut: ''
- },
- {
- label: 'ra3',
- value: 'ra3',
- shortcut: ''
- }
- ],
- validate: {
- required: true,
- onlyAvailableItems: false
- },
- key: 'radio1',
- type: 'radio',
- input: true
- }
- ]
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'Test EG 2',
- display: 'form',
- name: 'testEg2',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-with-conditions-and-openWhenEmpty.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-with-conditions-and-openWhenEmpty.js
deleted file mode 100644
index 05a12345..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp-with-conditions-and-openWhenEmpty.js
+++ /dev/null
@@ -1,83 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: false,
- tableView: false,
- values: [
- {
- label: 'show',
- value: 'show',
- shortcut: ''
- },
- {
- label: 'hide',
- value: 'hide',
- shortcut: ''
- }
- ],
- key: 'radio',
- type: 'radio',
- input: true
- },
- {
- label: 'Edit Grid',
- openWhenEmpty: true,
- tableView: false,
- rowDrafts: false,
- key: 'editGrid',
- customConditional: 'show = data.radio === \'show\';',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- },
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- data: {
- values: [
- {
- label: 'a',
- value: 'a'
- },
- {
- label: 'b',
- value: 'b'
- },
- {
- label: 'c',
- value: 'c'
- }
- ]
- },
- selectThreshold: 0.3,
- key: 'select1',
- type: 'select',
- indexeddb: {
- filter: {}
- },
- input: true
- }
- ]
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
- display: 'form',
-};
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp1.js
deleted file mode 100644
index 8046b380..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp1.js
+++ /dev/null
@@ -1,126 +0,0 @@
-export default {
- 'components': [
- {
- 'components': [
- {
- 'properties': {
- '': ''
- },
- 'tags': [],
- 'type': 'textfield',
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'validate': {
- 'required': false,
- 'minLength': '',
- 'maxLength': '',
- 'pattern': '',
- 'custom': '',
- 'customPrivate': false
- },
- 'clearOnHide': true,
- 'hidden': false,
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'field1',
- 'label': 'Field 1',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- },
- {
- 'properties': {
- '': ''
- },
- 'tags': [],
- 'type': 'textfield',
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'validate': {
- 'required': true,
- 'minLength': '',
- 'maxLength': '',
- 'pattern': '',
- 'custom': '',
- 'customPrivate': false
- },
- 'clearOnHide': true,
- 'hidden': false,
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'field2',
- 'label': 'Field 2',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ],
- 'clearOnHide': false,
- 'key': 'editgridPanel',
- 'input': false,
- 'title': '',
- 'theme': 'default',
- 'tableView': false,
- 'type': 'panel',
- 'breadcrumb': 'default',
- 'tags': [],
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'properties': {
- '': ''
- }
- }
- ],
- 'validate': {
- 'row': "valid = row.field1 === 'good' ? true : 'Must be good';"
- },
- 'properties': {
- '': ''
- },
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'tags': [],
- 'type': 'editgrid',
- 'templates': {
- 'header': ' \n {%util.eachComponent(components, function(component) { %} \n
\n {{ component.label }} \n
\n {% }) %} \n
{{value.length}}
\n
',
- 'row': ' \n {%util.eachComponent(components, function(component) { %} \n
\n {{ row[component.key] }} \n
\n {% }) %} \n
\n
',
- 'footer': ''
- },
- 'clearOnHide': true,
- 'hidden': false,
- 'persistent': true,
- 'protected': false,
- 'key': 'editgrid',
- 'label': '',
- 'tableView': true,
- 'multiple': false,
- 'tree': true,
- 'input': true,
- 'removeRow': 'Cancel'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp10.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp10.js
deleted file mode 100644
index d873bd9c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp10.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Edit Grid',
- tableView: false,
- rowDrafts: false,
- key: 'editGrid',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- },
- {
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'number',
- type: 'number',
- input: true
- }
- ]
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'test11',
- display: 'form',
- name: 'test11',
- path: 'test11',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp11.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp11.js
deleted file mode 100644
index 8d320e4d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp11.js
+++ /dev/null
@@ -1,48 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Edit Grid',
- openWhenEmpty: true,
- tableView: false,
- rowDrafts: false,
- key: 'editGrid',
- type: 'editgrid',
- displayAsTable: false,
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Number',
- mask: false,
- tableView: true,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- key: 'number',
- type: 'number',
- input: true,
- },
- ],
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- title: 'tetste',
- display: 'form',
- name: 'tetste',
- path: 'tetste',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp12.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp12.js
deleted file mode 100644
index d36042f4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp12.js
+++ /dev/null
@@ -1,48 +0,0 @@
-export default {
- 'type': 'form',
- 'components': [{
- 'label': 'Edit Grid',
- 'tableView': false,
- 'rowDrafts': false,
- 'key': 'editGrid',
- 'type': 'editgrid',
- 'input': true,
- 'components': [{
- 'label': 'Container',
- 'tableView': false,
- 'key': 'container',
- 'type': 'container',
- 'input': true,
- 'components': [{
- 'label': 'Number',
- 'mask': false,
- 'tableView': false,
- 'delimiter': false,
- 'requireDecimal': false,
- 'inputFormat': 'plain',
- 'key': 'number',
- 'type': 'number',
- 'input': true
- }, {
- 'label': 'Text Field',
- 'tableView': true,
- 'validate': {
- 'required': true
- },
- 'key': 'textField',
- 'customConditional': 'show = row.number === 5;',
- 'type': 'textfield',
- 'input': true
- }]
- }]
- }, {
- 'type': 'button',
- 'label': 'Submit',
- 'key': 'submit',
- 'disableOnInvalid': true,
- 'input': true,
- 'tableView': false
- }],
- 'title': 'test form',
- 'display': 'form',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp13.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp13.js
deleted file mode 100644
index b8da8f0d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp13.js
+++ /dev/null
@@ -1,62 +0,0 @@
-export default {
- type: 'form',
- tags: [],
- components: [
- {
- label: 'Container',
- tableView: false,
- key: 'container',
- type: 'container',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true,
- minLength: 2,
- },
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- ],
- },
- {
- label: 'Edit Grid',
- tableView: false,
- validate: {
- required: true,
- },
- rowDrafts: false,
- key: 'editGrid',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true,
- },
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- ],
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- saveOnEnter: false,
- },
- ],
- title: 'FIO-3715',
- display: 'form',
- name: 'fio3715',
- path: 'fio3715',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp14.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp14.js
deleted file mode 100644
index 5dd028b8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp14.js
+++ /dev/null
@@ -1,83 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'editGrid',
- hideLabel: true,
- tableView: false,
- modalEdit: true,
- templates: {
- header:
- '\n
Title
\n
First name
\n
Last name
\n
\n
',
- row: '\n
\n {{ _.get(row, \'title\', \'\') }}\n
\n
\n {{ _.get(row, \'firstName\', \'\') }}\n
\n
\n {{ _.get(row, \'familyName\', \'\') }}\n
\n
\n {% if (instance.options.readOnly) { %}\n
\n {% } else { %}\n
\n \n \n \n \n \n \n
\n {% } %}\n
\n
',
- },
- addAnother: 'Add',
- 'modal': true,
- saveRow: 'Close',
- redrawOn: 'data',
- validate: { required: true, maxLength: 2 },
- rowDrafts: true,
- key: 'editGrid',
- type: 'editgrid',
- displayAsTable: false,
- alwaysEnabled: false,
- input: true,
- components: [
- {
- label: 'Title',
- widget: 'choicesjs',
- tableView: true,
- data: {
- values: [
- { value: 'mr', label: 'Mr' },
- { value: 'ms', label: 'Ms' },
- ],
- },
- validate: { required: true },
- key: 'title',
- type: 'select',
- labelWidth: 30,
- labelMargin: 3,
- alwaysEnabled: false,
- input: true,
- hideOnChildrenHidden: false,
- },
- {
- label: 'First name',
- tableView: true,
- validate: { required: true },
- key: 'firstName',
- type: 'textfield',
- labelWidth: 30,
- labelMargin: 3,
- alwaysEnabled: false,
- input: true,
- hideOnChildrenHidden: false,
- },
- {
- label: 'Family name',
- tableView: true,
- validate: { required: true },
- key: 'familyName',
- type: 'textfield',
- labelWidth: 30,
- labelMargin: 3,
- alwaysEnabled: false,
- input: true,
- hideOnChildrenHidden: false,
- },
- ],
- path: 'editGridPath',
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- title: 'edit grids',
- display: 'form',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp15.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp15.js
deleted file mode 100644
index ccd8e69a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp15.js
+++ /dev/null
@@ -1,49 +0,0 @@
-export default {
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Edit Grid',
- tableView: false,
- validate: {
- minLength: 6
- },
- rowDrafts: false,
- key: 'editGrid',
- type: 'editgrid',
- displayAsTable: false,
- input: true,
- components: [
- {
- label: 'Text',
- applyMaskOn: 'change',
- tableView: true,
- key: 'text',
- type: 'textfield',
- input: true
- },
- {
- label: 'Number',
- applyMaskOn: 'change',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- key: 'number',
- type: 'number',
- input: true
- }
- ]
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp2.js
deleted file mode 100644
index 8c2131b2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp2.js
+++ /dev/null
@@ -1,112 +0,0 @@
-export default {
- 'components': [
- {
- 'components': [
- {
- 'type': 'textfield',
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'validate': {
- 'required': false,
- 'minLength': '',
- 'maxLength': '',
- 'pattern': '',
- 'custom': '',
- 'customPrivate': false
- },
- 'customDefaultValue': "value = 'bar';",
- 'clearOnHide': true,
- 'hidden': false,
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'field1',
- 'label': 'Field 1',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- },
- {
- 'properties': {
- '': ''
- },
- 'tags': [],
- 'type': 'textfield',
- 'conditional': {
- 'show': 'true',
- 'when': 'field1',
- 'eq': 'foo'
- },
- 'validate': {
- 'required': true,
- 'minLength': '',
- 'maxLength': '',
- 'pattern': '',
- 'custom': '',
- 'customPrivate': false
- },
- 'clearOnHide': true,
- 'hidden': false,
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'field2',
- 'label': 'Field 2',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ],
- 'clearOnHide': false,
- 'key': 'editgridPanel',
- 'input': false,
- 'title': '',
- 'theme': 'default',
- 'tableView': false,
- 'type': 'panel',
- 'breadcrumb': 'default',
- 'tags': [],
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'properties': {
- '': ''
- }
- }
- ],
- 'tags': [],
- 'type': 'editgrid',
- 'templates': {
- 'header': ' \n {%util.eachComponent(components, function(component) { %} \n
\n {{ component.label }} \n
\n {% }) %} \n
{{value.length}}
\n
',
- 'row': ' \n {%util.eachComponent(components, function(component) { %} \n
\n {{ row[component.key] }} \n
\n {% }) %} \n
\n
',
- 'footer': ''
- },
- 'clearOnHide': true,
- 'hidden': false,
- 'persistent': true,
- 'protected': false,
- 'key': 'editgrid',
- 'label': '',
- 'tableView': true,
- 'multiple': false,
- 'tree': true,
- 'input': true,
- 'removeRow': 'Cancel'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp3.js
deleted file mode 100644
index 198de29c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp3.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default {
- 'label': 'Edit Grid',
- 'tableView': false,
- 'key': 'editGrid',
- 'type': 'editgrid',
- 'input': true,
- 'components': [{
- 'label': 'Container',
- 'tableView': false,
- 'key': 'container',
- 'type': 'container',
- 'input': true,
- 'components': [{
- 'label': 'Number',
- 'mask': false,
- 'spellcheck': true,
- 'tableView': true,
- 'delimiter': false,
- 'requireDecimal': false,
- 'inputFormat': 'plain',
- 'key': 'number',
- 'type': 'number',
- 'input': true
- }]
- }]
- };
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp4.js
deleted file mode 100644
index b09bbdc6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp4.js
+++ /dev/null
@@ -1,23 +0,0 @@
-export default {
- 'label': 'Edit Grid',
- 'tableView': false,
- 'key': 'editGrid',
- 'type': 'editgrid',
- 'input': true,
- 'components': [{
- 'label': 'Data Map',
- 'tableView': false,
- 'key': 'dataMap',
- 'type': 'datamap',
- 'input': true,
- 'valueComponent': {
- 'type': 'textfield',
- 'key': 'key',
- 'label': 'Value',
- 'input': true,
- 'hideLabel': true,
- 'tableView': true
- }
- }]
-};
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp5.js
deleted file mode 100644
index 3ff7fe13..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp5.js
+++ /dev/null
@@ -1,20 +0,0 @@
-export default {
- label: 'Edit Grid',
- tableView: false,
- rowDrafts: true,
- key: 'editGrid1',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true
- },
- key: 'textField',
- type: 'textfield',
- input: true
- }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp6.js
deleted file mode 100644
index e52dfa64..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp6.js
+++ /dev/null
@@ -1,56 +0,0 @@
-export default {
- '_id': '5ece2d11b8c2fe102c726057',
- 'type': 'form',
- 'owner': '5e05a6b7549cdc2ece30c6b0',
- 'components': [
- {
- 'label': 'Edit Grid',
- 'tableView': false,
- 'modal': true,
- 'validate': {
- 'required': true
- },
- 'key': 'editGrid',
- 'type': 'editgrid',
- 'input': true,
- 'components': [
- {
- 'label': 'Text Field',
- 'tableView': true,
- 'validate': {
- 'required': true,
- 'minLength': 4
- },
- 'key': 'textField',
- 'type': 'textfield',
- 'input': true
- }
- ]
- },
- {
- 'label': 'Submit',
- 'showValidations': false,
- 'tableView': false,
- 'key': 'submit',
- 'type': 'button',
- 'input': true
- }
- ],
- 'controller': '',
- 'revisions': '',
- '_vid': 0,
- 'title': 'modalEditGridConfirm',
- 'display': 'form',
- 'access': [
- {
- 'roles': [
- '5e96e79ee1c3ad3178454100',
- '5e96e79ee1c3ad3178454101',
- '5e96e79ee1c3ad3178454102'
- ],
- 'type': 'read_all'
- }
- ],
- 'name': 'modalEditGridConfirm',
- 'path': 'modaleditgridconfirm'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp7.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp7.js
deleted file mode 100644
index 493cf2ce..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp7.js
+++ /dev/null
@@ -1,121 +0,0 @@
-export default {
- label: 'Edit Grid',
- tableView: false,
- validate: {
- custom: "valid = true;\ndata.editGrid.forEach((r) => {\n if (r.textField === data.name) {\n valid = 'Invalid Name';\n }\n});",
- required: false,
- customPrivate: false,
- strictDateValidation: false,
- multiple: false,
- unique: false
- },
- rowDrafts: false,
- key: 'editGrid',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Checkbox',
- tableView: false,
- defaultValue: true,
- key: 'checkbox',
- type: 'checkbox',
- input: true
- },
- {
- label: 'Text Field',
- tableView: true,
- key: 'editGridChild',
- conditional: {
- show: true,
- when: 'editGrid.checkbox',
- eq: 'true'
- },
- type: 'textfield',
- input: true
- },
- {
- title: 'Child',
- collapsible: false,
- key: 'child',
- type: 'panel',
- label: 'Panel',
- input: false,
- tableView: false,
- components: [
- {
- label: 'Panel Child',
- tableView: true,
- key: 'panelChild',
- conditional: {
- show: true,
- when: 'editGrid.checkbox',
- eq: 'true'
- },
- type: 'textfield',
- input: true
- }
- ]
- }
- ],
- placeholder: '',
- prefix: '',
- customClass: '',
- suffix: '',
- multiple: false,
- defaultValue: null,
- protected: false,
- unique: false,
- persistent: true,
- hidden: false,
- clearOnHide: true,
- refreshOn: '',
- redrawOn: '',
- modalEdit: false,
- labelPosition: 'top',
- description: '',
- errorLabel: '',
- tooltip: '',
- hideLabel: false,
- tabindex: '',
- disabled: false,
- autofocus: false,
- dbIndex: false,
- customDefaultValue: '',
- calculateValue: '',
- calculateServer: false,
- widget: null,
- attributes: {},
- validateOn: 'change',
- conditional: {
- show: null,
- when: null,
- eq: ''
- },
- overlay: {
- style: '',
- left: '',
- top: '',
- width: '',
- height: ''
- },
- allowCalculateOverride: false,
- encrypted: false,
- showCharCount: false,
- showWordCount: false,
- properties: {},
- allowMultipleMasks: false,
- tree: true,
- disableAddingRemovingRows: false,
- removeRow: 'Cancel',
- defaultOpen: false,
- openWhenEmpty: false,
- modal: false,
- inlineEdit: false,
- templates: {
- header: "\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n
{{ component.label }}
\n {% } %}\n {% }) %}\n
",
- row: "\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n
\n {{ getView(component, row[component.key]) }}\n
\n {% } %}\n {% }) %}\n {% if (!instance.disabled) { %}\n
\n
\n \n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n \n {% } %}\n
\n
\n {% } %}\n
",
- footer: ''
- },
- id: 'e10uov'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp8.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp8.js
deleted file mode 100644
index 18cd9d80..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp8.js
+++ /dev/null
@@ -1,154 +0,0 @@
-export default {
- label: 'HTML5',
- tableView: false,
- rowDrafts: false,
- key: 'editGrid1',
- type: 'editgrid',
- input: true,
- components: [
- {
- label: 'Make',
- widget: 'choicesjs',
- placeholder: 'Select your make',
- tableView: true,
- data: {
- values: [
- {
- label: 'Chevy',
- value: 'chevy'
- },
- {
- value: 'honda',
- label: 'Honda'
- },
- {
- label: 'Ford',
- value: 'ford'
- },
- {
- label: 'Toyota',
- value: 'toyota'
- }
- ]
- },
- selectThreshold: 0.3,
- validate: {
- required: true
- },
- key: 'make',
- type: 'select',
- indexeddb: {
- filter: {}
- },
- input: true
- },
- {
- label: 'Model',
- widget: 'choicesjs',
- placeholder: 'Select your model',
- tableView: true,
- dataSrc: 'url',
- data: {
- values: [
- {
- label: '',
- value: ''
- }
- ],
- url: 'https://vpic.nhtsa.dot.gov/api/vehicles/getmodelsformake/{{ row.make }}?format=json',
- headers: [
- {
- key: '',
- value: ''
- }
- ]
- },
- valueProperty: 'Model_Name',
- template: '{{ item.Model_Name }} ',
- refreshOn: 'data',
- clearOnRefresh: true,
- selectThreshold: 0.3,
- clearOnHide: false,
- validate: {
- required: true
- },
- key: 'model',
- type: 'select',
- indexeddb: {
- filter: {}
- },
- selectValues: 'Results',
- input: true,
- disableLimit: false,
- lazyLoad: false
- }
- ],
- placeholder: '',
- prefix: '',
- customClass: '',
- suffix: '',
- multiple: false,
- defaultValue: null,
- protected: false,
- unique: false,
- persistent: true,
- hidden: false,
- clearOnHide: true,
- refreshOn: '',
- redrawOn: '',
- modalEdit: false,
- labelPosition: 'top',
- description: '',
- errorLabel: '',
- tooltip: '',
- hideLabel: false,
- tabindex: '',
- disabled: false,
- autofocus: false,
- dbIndex: false,
- customDefaultValue: '',
- calculateValue: '',
- calculateServer: false,
- widget: null,
- attributes: {},
- validateOn: 'change',
- validate: {
- required: false,
- custom: '',
- customPrivate: false,
- strictDateValidation: false,
- multiple: false,
- unique: false
- },
- conditional: {
- show: null,
- when: null,
- eq: ''
- },
- overlay: {
- style: '',
- left: '',
- top: '',
- width: '',
- height: ''
- },
- allowCalculateOverride: false,
- encrypted: false,
- showCharCount: false,
- showWordCount: false,
- properties: {},
- allowMultipleMasks: false,
- tree: true,
- disableAddingRemovingRows: false,
- removeRow: 'Cancel',
- defaultOpen: false,
- openWhenEmpty: false,
- modal: false,
- inlineEdit: false,
- templates: {
- header: "\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n
{{ component.label }}
\n {% } %}\n {% }) %}\n
",
- row: "\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n
\n {{ getView(component, row[component.key]) }}\n
\n {% } %}\n {% }) %}\n {% if (!instance.disabled) { %}\n
\n
\n \n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n \n {% } %}\n
\n
\n {% } %}\n
",
- footer: ''
- },
- id: 'e7p0y9a'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp9.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp9.js
deleted file mode 100644
index 19fd1ef7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/comp9.js
+++ /dev/null
@@ -1,60 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Edit Grid',
- tableView: false,
- rowDrafts: false,
- key: 'editGrid',
- type: 'editgrid',
- input: true,
- components: [
- { label: 'Text Field', tableView: true, key: 'textField', type: 'textfield', input: true },
- {
- label: 'Checkbox',
- tableView: true,
- key: 'checkbox',
- type: 'checkbox',
- input: true,
- defaultValue: false
- },
- {
- label: 'Text Area',
- autoExpand: false,
- tableView: true,
- key: 'textArea',
- conditional: { show: true, when: 'editGrid.checkbox', eq: 'true' },
- type: 'textarea',
- input: true
- },
- {
- label: 'Container',
- tableView: false,
- key: 'container',
- conditional: { show: true, when: 'editGrid.textField', eq: 'show' },
- type: 'container',
- input: true,
- components: [
- {
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: true,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'number1',
- type: 'number',
- input: true
- }
- ]
- }
- ]
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: true, input: true, tableView: false }
- ],
- title: 'editGrid conditional',
- display: 'form',
- name: 'editGridConditional',
- path: 'editgridconditional',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/index.js
deleted file mode 100644
index 44856a60..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/fixtures/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
-export comp6 from './comp6';
-export comp7 from './comp7';
-export comp8 from './comp8';
-export comp9 from './comp9';
-export comp10 from './comp10';
-export comp11 from './comp11';
-export comp12 from './comp12';
-export comp13 from './comp13';
-export comp14 from './comp14';
-export comp15 from './comp15';
-export withOpenWhenEmptyAndConditions from './comp-with-conditions-and-openWhenEmpty';
-export compOpenWhenEmpty from './comp-openWhenEmpty';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/header.ejs b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/header.ejs
deleted file mode 100644
index 30be61d9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/header.ejs
+++ /dev/null
@@ -1,7 +0,0 @@
-
- {% ctx.util.eachComponent(ctx.components, function(component) { %}
- {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}
-
{{ ctx.t(component.label) }}
- {% } %}
- {% }) %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/index.js b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/index.js
deleted file mode 100644
index c30a3f07..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import row from './row.ejs';
-import header from './header.ejs';
-export default { row, header };
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/row.ejs b/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/row.ejs
deleted file mode 100644
index 464eef18..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/editgrid/templates/row.ejs
+++ /dev/null
@@ -1,17 +0,0 @@
-
- {% ctx.util.eachComponent(ctx.components, function(component) { %}
- {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}
-
- {{ ctx.getView(component, ctx.row[component.key]) }}
-
- {% } %}
- {% }) %}
- {% if (!ctx.self.options.readOnly) { %}
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/Email.form.js b/web-client/core/themes/italia/static/formio/css/src/components/email/Email.form.js
deleted file mode 100644
index 12258dd9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/Email.form.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import baseEditForm from '../textfield/TextField.form';
-import EmailEditFormDisplay from './editForm/Email.edit.display';
-import EmailEditFormValidation from './editForm/Email.edit.validation';
-
-export default function(...extend) {
- return baseEditForm([
- {
- key: 'display',
- components: EmailEditFormDisplay,
- },
- {
- key: 'validation',
- components: EmailEditFormValidation,
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/Email.js b/web-client/core/themes/italia/static/formio/css/src/components/email/Email.js
deleted file mode 100644
index 6104d635..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/Email.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import TextFieldComponent from '../textfield/TextField';
-
-export default class EmailComponent extends TextFieldComponent {
- static schema(...extend) {
- return TextFieldComponent.schema({
- type: 'email',
- label: 'Email',
- key: 'email',
- inputType: 'email',
- kickbox: {
- enabled: false
- }
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Email',
- group: 'advanced',
- icon: 'at',
- documentation: '/userguide/form-building/advanced-components#email',
- weight: 10,
- schema: EmailComponent.schema()
- };
- }
-
- init() {
- super.init();
- this.validators.push('email');
- }
-
- get defaultSchema() {
- return EmailComponent.schema();
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- info.attr.type = this.component.mask ? 'password' : 'email';
- return info;
- }
-
- normalizeValue(value, flags = {}) {
- value = super.normalizeValue(value, flags);
- if (this.options.server && !!value) {
- if (Array.isArray(value)) {
- value = value.map(val => val.toLowerCase());
- }
- else {
- value = value.toLowerCase();
- }
- }
- return value;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/Email.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/email/Email.unit.js
deleted file mode 100644
index 7fdb55e7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/Email.unit.js
+++ /dev/null
@@ -1,216 +0,0 @@
-import Harness from '../../../test/harness';
-import EmailComponent from './Email';
-import Formio from './../../Formio';
-import assert from 'power-assert';
-import _ from 'lodash';
-
-import {
- comp1,
- comp2
-} from './fixtures';
-
-describe('Email Component', () => {
- it('Should build a email component', () => {
- return Harness.testCreate(EmailComponent, comp1);
- });
-
- it('Should provide min/max length validation', (done) => {
- const form = _.cloneDeep(comp2);
- form.components[0].validate = { minLength: 7, maxLength: 10 };
-
- const validValues = [
- '',
- 'test@te.st',
- 't__t@t.st',
- '_t@test.st'
- ];
-
- const invalidMin = [
- 't@t.st',
- ];
-
- const invalidMax = [
- 't@test.test',
- 'test@test.test',
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('email');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidMin, false, 'Email must have at least 7 characters.');
- testValidity(invalidMax, false, 'Email must have no more than 10 characters.', invalidMax[invalidMax.length-1]);
- });
-
- it('Should provide pattern validation', (done) => {
- const form = _.cloneDeep(comp2);
- form.components[0].validate = { pattern: '^[0-9]+@[0-9]+\\.[a-z]{2,4}$' };
-
- const validValues = [
- '000@12.ts',
- '123456@1234.com',
- '123456@1234.come',
- ''
- ];
-
- const invalidValues = [
- '123_456@1234.com',
- '123456@12.34.com',
- 'test@123.com',
- '00000@123t.com'
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('email');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message.trim(), error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues,
- false,
- 'Email does not match the pattern ^[0-9]+@[0-9]+\\.[a-z]{2,4}$',
- invalidValues[invalidValues.length-1]
- );
- });
-
- it('Should provide email validation', (done) => {
- const form = _.cloneDeep(comp2);
-
- const validValues = [
- '',
- 'test_test@test.test',
- '123456@1234.test',
- 'TEST@TEST.test',
- 'te.st_te%st@test.com',
- 'te/st___te%st@test.com',
- '"John..Doe"@example.com',
- 'test-test@test.com',
- 'test-test@te-st.com',
- '0-0-0-0-0@12-3-t.com'
- ];
-
- const invalidValues = [
- 'te.st_te%st@test.123',
- ' ',
- 'test.test',
- 'test-te st@test.com',
- ' test_test@test.test',
- '.test_te%st@test.com',
- 'te/st___t,e%st@test.com',
- 'te[st]t@test.com',
- 'test@test.com ',
- 'test@',
- 'test@test',
- 'test@test.',
- '@test.com',
- 'test@.com',
- '00000@123t.m',
- '00000@123t.m-com',
- 'test(test)@mail.com',
- 'John..Doe@example.com',
- 'john.smith(comment)@example.com',
- 'test-test.@test.com'
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('email');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message.trim(), error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues,
- false,
- 'Email must be a valid email.',
- invalidValues[invalidValues.length-1]
- );
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/editForm/Email.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/email/editForm/Email.edit.display.js
deleted file mode 100644
index 1e8370f5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/editForm/Email.edit.display.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default [
- {
- key: 'inputMask',
- ignore: true,
- },
- {
- key: 'allowMultipleMasks',
- ignore: true,
- },
- {
- key: 'showWordCount',
- ignore: true
- },
- {
- key: 'showCharCount',
- ignore: true
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/editForm/Email.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/email/editForm/Email.edit.validation.js
deleted file mode 100644
index 99c2da18..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/editForm/Email.edit.validation.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default [
- {
- key: 'validate.minWords',
- ignore: true
- },
- {
- key: 'validate.maxWords',
- ignore: true
- },
- {
- type: 'panel',
- label: 'Kickbox',
- title: 'Kickbox',
- weight: 102,
- key: 'kickbox',
- components: [
- {
- type: 'checkbox',
- label: 'Enable',
- tooltip: 'Enable Kickbox validation for this email field.',
- description: 'Validate this email using the Kickbox email validation service.',
- key: 'kickbox.enabled'
- }
- ]
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/comp1.js
deleted file mode 100644
index c2908bc3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/comp1.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'email',
- 'kickbox': {
- 'enabled': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'suffix': '',
- 'prefix': '',
- 'placeholder': 'Enter your email address',
- 'key': 'email',
- 'label': 'Email',
- 'inputType': 'email',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/comp2.js
deleted file mode 100644
index 43722e61..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/comp2.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default {
- type: 'form',
- components: [
- { label: 'Email', tableView: true, key: 'email', type: 'email', input: true },
- { label: 'Submit', showValidations: false, tableView: false, key: 'submit', type: 'button', input: true }
- ],
- title: 'test11',
- display: 'form',
- name: 'test11',
- path: 'test11',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/index.js
deleted file mode 100644
index 63468958..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/values.js
deleted file mode 100644
index b17ef74e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/email/fixtures/values.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- 'admin@example.com',
- 'test@example.com',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.form.js b/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.form.js
deleted file mode 100644
index 8ac01aea..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.form.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import nestedComponentForm from '../_classes/nested/NestedComponent.form';
-import FieldSetEditDisplay from './editForm/Fieldset.edit.display';
-export default function(...extend) {
- return nestedComponentForm([
- {
- key: 'display',
- components: FieldSetEditDisplay
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.js b/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.js
deleted file mode 100644
index 9b71fe87..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import NestedComponent from '../_classes/nested/NestedComponent';
-
-export default class FieldsetComponent extends NestedComponent {
- static schema(...extend) {
- return NestedComponent.schema({
- label: 'Field Set',
- key: 'fieldSet',
- type: 'fieldset',
- legend: '',
- components: [],
- input: false,
- persistent: false
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Field Set',
- icon: 'th-large',
- group: 'layout',
- documentation: '/userguide/form-building/layout-components#field-set',
- showPreview: false,
- weight: 20,
- schema: FieldsetComponent.schema()
- };
- }
-
- static savedValueTypes() {
- return [];
- }
-
- get defaultSchema() {
- return FieldsetComponent.schema();
- }
-
- get className() {
- return `${this.transform('class', 'form-group')} ${super.className}`;
- }
-
- get templateName() {
- return 'fieldset';
- }
-
- constructor(...args) {
- super(...args);
- this.noField = true;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.unit.js
deleted file mode 100644
index 116f373f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/Fieldset.unit.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import Harness from '../../../test/harness';
-import FieldsetComponent from './Fieldset';
-
-import {
- comp1
-} from './fixtures';
-
-describe('Fieldset Component', () => {
- it('Should build a fieldset component', () => {
- return Harness.testCreate(FieldsetComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 2);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/editForm/Fieldset.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/fieldset/editForm/Fieldset.edit.display.js
deleted file mode 100644
index 9692ccf9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/editForm/Fieldset.edit.display.js
+++ /dev/null
@@ -1,42 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'hideLabel',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
- {
- key: 'label',
- hidden: true,
- calculateValue(context) {
- return context.data.legend;
- }
- },
- {
- weight: 1,
- type: 'textfield',
- input: true,
- key: 'legend',
- label: 'Legend',
- placeholder: 'Legend',
- tooltip: 'The legend for this Fieldset.'
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/fieldset/fixtures/comp1.js
deleted file mode 100644
index fbf6a18a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/fixtures/comp1.js
+++ /dev/null
@@ -1,85 +0,0 @@
-export default {
- 'key': 'fieldset1',
- 'input': false,
- 'tableView': true,
- 'legend': 'User Information',
- 'components': [
- {
- 'input': true,
- 'tableView': true,
- 'inputType': 'text',
- 'inputMask': '',
- 'label': 'First Name',
- 'key': 'firstName',
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'multiple': false,
- 'defaultValue': '',
- 'protected': false,
- 'unique': false,
- 'persistent': true,
- 'clearOnHide': true,
- 'validate': {
- 'required': false,
- 'minLength': '',
- 'maxLength': '',
- 'pattern': '',
- 'custom': '',
- 'customPrivate': false
- },
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'type': 'textfield',
- 'tags': [
-
- ]
- },
- {
- 'input': true,
- 'tableView': true,
- 'inputType': 'text',
- 'inputMask': '',
- 'label': 'Last Name',
- 'key': 'lastName',
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'multiple': false,
- 'defaultValue': '',
- 'protected': false,
- 'unique': false,
- 'persistent': true,
- 'clearOnHide': true,
- 'validate': {
- 'required': false,
- 'minLength': '',
- 'maxLength': '',
- 'pattern': '',
- 'custom': '',
- 'customPrivate': false
- },
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'type': 'textfield',
- 'tags': [
-
- ]
- }
- ],
- 'type': 'fieldset',
- 'tags': [
-
- ],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/fieldset/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/fieldset/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/File.form.js b/web-client/core/themes/italia/static/formio/css/src/components/file/File.form.js
deleted file mode 100644
index 686005eb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/File.form.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import Components from '../Components';
-import FileEditData from './editForm/File.edit.data';
-import FileEditDisplay from './editForm/File.edit.display';
-import FileEditFile from './editForm/File.edit.file';
-import FileEditValidation from './editForm/File.edit.validation';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: FileEditDisplay
- },
- {
- key: 'data',
- components: FileEditData
- },
- {
- label: 'File',
- key: 'file',
- weight: 5,
- components: FileEditFile
- },
- {
- key: 'validation',
- components: FileEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/File.js b/web-client/core/themes/italia/static/formio/css/src/components/file/File.js
deleted file mode 100644
index a9efb0f3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/File.js
+++ /dev/null
@@ -1,894 +0,0 @@
-import Field from '../_classes/field/Field';
-import { componentValueTypes, getComponentSavedTypes, uniqueName } from '../../utils/utils';
-import download from 'downloadjs';
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-import fileProcessor from '../../providers/processor/fileProcessor';
-import BMF from 'browser-md5-file';
-
-let Camera;
-let webViewCamera = navigator.camera || Camera;
-
-// canvas.toBlob polyfill.
-
-let htmlCanvasElement;
-if (typeof window !== 'undefined') {
- htmlCanvasElement = window.HTMLCanvasElement;
-}
-else if (typeof global !== 'undefined') {
- htmlCanvasElement = global.HTMLCanvasElement;
-}
-
-if (htmlCanvasElement && !htmlCanvasElement.prototype.toBlob) {
- Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
- value: function(callback, type, quality) {
- var canvas = this;
- setTimeout(function() {
- var binStr = atob(canvas.toDataURL(type, quality).split(',')[1]),
- len = binStr.length,
- arr = new Uint8Array(len);
-
- for (var i = 0; i < len; i++) {
- arr[i] = binStr.charCodeAt(i);
- }
-
- callback(new Blob([arr], { type: type || 'image/png' }));
- });
- }
- });
-}
-
-export default class FileComponent extends Field {
- static schema(...extend) {
- return Field.schema({
- type: 'file',
- label: 'Upload',
- key: 'file',
- image: false,
- privateDownload: false,
- imageSize: '200',
- filePattern: '*',
- fileMinSize: '0KB',
- fileMaxSize: '1GB',
- uploadOnly: false,
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'File',
- group: 'premium',
- icon: 'file',
- documentation: '/userguide/form-building/premium-components#file',
- weight: 100,
- schema: FileComponent.schema(),
- };
- }
-
- static get serverConditionSettings() {
- return FileComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: ['isEmpty', 'isNotEmpty'],
- };
- }
-
- static savedValueTypes(schema) {
- schema = schema || {};
-
- return getComponentSavedTypes(schema) || [componentValueTypes.object];
- }
-
- init() {
- super.init();
- webViewCamera = navigator.camera || Camera;
- const fileReaderSupported = (typeof FileReader !== 'undefined');
- const formDataSupported = typeof window !== 'undefined' ? Boolean(window.FormData) : false;
- const progressSupported = (typeof window !== 'undefined' && window.XMLHttpRequest) ? ('upload' in new XMLHttpRequest) : false;
-
- this.support = {
- filereader: fileReaderSupported,
- formdata: formDataSupported,
- hasWarning: !fileReaderSupported || !formDataSupported || !progressSupported,
- progress: progressSupported,
- };
- this.cameraMode = false;
- this.statuses = [];
- this.fileDropHidden = false;
- }
-
- get dataReady() {
- return this.filesReady || NativePromise.resolve();
- }
-
- get defaultSchema() {
- return FileComponent.schema();
- }
-
- loadImage(fileInfo) {
- if (this.component.privateDownload) {
- fileInfo.private = true;
- }
- return this.fileService.downloadFile(fileInfo).then((result) => result.url);
- }
-
- get emptyValue() {
- return [];
- }
-
- getValueAsString(value) {
- if (_.isArray(value)) {
- return _.map(value, 'originalName').join(', ');
- }
-
- return _.get(value, 'originalName', '');
- }
-
- getValue() {
- return this.dataValue;
- }
-
- get defaultValue() {
- const value = super.defaultValue;
- return Array.isArray(value) ? value : [];
- }
-
- get hasTypes() {
- return this.component.fileTypes &&
- Array.isArray(this.component.fileTypes) &&
- this.component.fileTypes.length !== 0 &&
- (this.component.fileTypes[0].label !== '' || this.component.fileTypes[0].value !== '');
- }
-
- get fileDropHidden() {
- return this._fileBrowseHidden;
- }
-
- set fileDropHidden(value) {
- if (typeof value !== 'boolean' || this.component.multiple) {
- return;
- }
- this._fileBrowseHidden = value;
- }
-
- render() {
- return super.render(this.renderTemplate('file', {
- fileSize: this.fileSize,
- files: this.dataValue || [],
- statuses: this.statuses,
- disabled: this.disabled,
- support: this.support,
- fileDropHidden: this.fileDropHidden
- }));
- }
-
- getVideoStream(constraints) {
- return navigator.mediaDevices.getUserMedia({
- video: {
- width: { min: 640, ideal: 1920 },
- height: { min: 360, ideal: 1080 },
- aspectRatio: { ideal: 16 / 9 },
- ...constraints,
- },
- audio: false,
- });
- }
-
- stopVideoStream(videoStream) {
- videoStream.getVideoTracks().forEach((track) => track.stop());
- }
-
- getFrame(videoPlayer) {
- return new NativePromise((resolve) => {
- const canvas = document.createElement('canvas');
- canvas.height = videoPlayer.videoHeight;
- canvas.width = videoPlayer.videoWidth;
- const context = canvas.getContext('2d');
- context.drawImage(videoPlayer, 0, 0);
- canvas.toBlob(resolve);
- });
- }
-
- startVideo() {
- this.getVideoStream()
- .then((stream) => {
- this.videoStream = stream;
-
- const { videoPlayer } = this.refs;
- if (!videoPlayer) {
- console.warn('Video player not found in template.');
- this.cameraMode = false;
- this.redraw();
- return;
- }
-
- videoPlayer.srcObject = stream;
- const width = parseInt(this.component.webcamSize) || 320;
- videoPlayer.setAttribute('width', width);
- videoPlayer.play();
- })
- .catch((err) => {
- console.error(err);
- this.cameraMode = false;
- this.redraw();
- });
- }
-
- stopVideo() {
- if (this.videoStream) {
- this.stopVideoStream(this.videoStream);
- this.videoStream = null;
- }
- }
-
- takePicture() {
- const { videoPlayer } = this.refs;
- if (!videoPlayer) {
- console.warn('Video player not found in template.');
- this.cameraMode = false;
- this.redraw();
- return;
- }
-
- this.getFrame(videoPlayer)
- .then((frame) => {
- frame.name = `photo-${Date.now()}.png`;
- this.upload([frame]);
- this.cameraMode = false;
- this.redraw();
- });
- }
-
- browseFiles(attrs = {}) {
- return new NativePromise((resolve) => {
- const fileInput = this.ce('input', {
- type: 'file',
- style: 'height: 0; width: 0; visibility: hidden;',
- tabindex: '-1',
- ...attrs,
- });
- document.body.appendChild(fileInput);
-
- fileInput.addEventListener('change', () => {
- resolve(fileInput.files);
- document.body.removeChild(fileInput);
- }, true);
-
- // There is no direct way to trigger a file dialog. To work around this, create an input of type file and trigger
- // a click event on it.
- if (typeof fileInput.trigger === 'function') {
- fileInput.trigger('click');
- }
- else {
- fileInput.click();
- }
- });
- }
-
- set cameraMode(value) {
- this._cameraMode = value;
-
- if (value) {
- this.startVideo();
- }
- else {
- this.stopVideo();
- }
- }
-
- get cameraMode() {
- return this._cameraMode;
- }
-
- get useWebViewCamera() {
- return this.imageUpload && webViewCamera;
- }
-
- get imageUpload() {
- return Boolean(this.component.image);
- }
-
- get browseOptions() {
- const options = {};
-
- if (this.component.multiple) {
- options.multiple = true;
- }
- //use "accept" attribute only for desktop devices because of its limited support by mobile browsers
- if (!this.isMobile.any) {
- const filePattern = this.component.filePattern.trim() || '';
- const imagesPattern = 'image/*';
-
- if (this.imageUpload && (!filePattern || filePattern === '*')) {
- options.accept = imagesPattern;
- }
- else if (this.imageUpload && !filePattern.includes(imagesPattern)) {
- options.accept = `${imagesPattern},${filePattern}`;
- }
- else {
- options.accept = filePattern;
- }
- }
-
- return options;
- }
-
- deleteFile(fileInfo) {
- const { options = {} } = this.component;
-
- if (fileInfo && (['url', 'indexeddb'].includes(this.component.storage))) {
- const { fileService } = this;
- if (fileService && typeof fileService.deleteFile === 'function') {
- fileService.deleteFile(fileInfo, options);
- }
- else {
- const formio = this.options.formio || (this.root && this.root.formio);
-
- if (formio) {
- formio.makeRequest('', fileInfo.url, 'delete');
- }
- }
- }
- }
-
- attach(element) {
- this.loadRefs(element, {
- fileDrop: 'single',
- fileBrowse: 'single',
- galleryButton: 'single',
- cameraButton: 'single',
- takePictureButton: 'single',
- toggleCameraMode: 'single',
- videoPlayer: 'single',
- fileLink: 'multiple',
- removeLink: 'multiple',
- fileStatusRemove: 'multiple',
- fileImage: 'multiple',
- fileType: 'multiple',
- fileProcessingLoader: 'single',
- });
- // Ensure we have an empty input refs. We need this for the setValue method to redraw the control when it is set.
- this.refs.input = [];
- const superAttach = super.attach(element);
-
- if (this.refs.fileDrop) {
- if (!this.statuses.length) {
- this.refs.fileDrop.removeAttribute('hidden');
- }
- const element = this;
- this.addEventListener(this.refs.fileDrop, 'dragover', function(event) {
- this.className = 'fileSelector fileDragOver';
- event.preventDefault();
- });
- this.addEventListener(this.refs.fileDrop, 'dragleave', function(event) {
- this.className = 'fileSelector';
- event.preventDefault();
- });
- this.addEventListener(this.refs.fileDrop, 'drop', function(event) {
- this.className = 'fileSelector';
- event.preventDefault();
- element.upload(event.dataTransfer.files);
- });
- }
-
- if (this.refs.fileBrowse) {
- this.addEventListener(this.refs.fileBrowse, 'click', (event) => {
- event.preventDefault();
- this.browseFiles(this.browseOptions)
- .then((files) => {
- this.upload(files);
- });
- });
- }
-
- this.refs.fileLink.forEach((fileLink, index) => {
- this.addEventListener(fileLink, 'click', (event) => {
- event.preventDefault();
- this.getFile(this.dataValue[index]);
- });
- });
-
- this.refs.removeLink.forEach((removeLink, index) => {
- this.addEventListener(removeLink, 'click', (event) => {
- const fileInfo = this.dataValue[index];
-
- this.deleteFile(fileInfo);
- event.preventDefault();
- this.splice(index);
- this.redraw();
- });
- });
-
- this.refs.fileStatusRemove.forEach((fileStatusRemove, index) => {
- this.addEventListener(fileStatusRemove, 'click', (event) => {
- event.preventDefault();
-
- const fileUpload = this.statuses[index];
- _.pull(this.filesUploading, fileUpload.originalName);
-
- if (fileUpload.abort) {
- fileUpload.abort();
- }
-
- this.statuses.splice(index, 1);
- this.redraw();
- });
- });
-
- if (this.refs.galleryButton && webViewCamera) {
- this.addEventListener(this.refs.galleryButton, 'click', (event) => {
- event.preventDefault();
- webViewCamera.getPicture((success) => {
- window.resolveLocalFileSystemURL(success, (fileEntry) => {
- fileEntry.file((file) => {
- const reader = new FileReader();
- reader.onloadend = (evt) => {
- const blob = new Blob([new Uint8Array(evt.target.result)], { type: file.type });
- blob.name = file.name;
- this.upload([blob]);
- };
- reader.readAsArrayBuffer(file);
- });
- }
- );
- }, (err) => {
- console.error(err);
- }, {
- sourceType: webViewCamera.PictureSourceType.PHOTOLIBRARY,
- });
- });
- }
-
- if (this.refs.cameraButton && webViewCamera) {
- this.addEventListener(this.refs.cameraButton, 'click', (event) => {
- event.preventDefault();
- webViewCamera.getPicture((success) => {
- window.resolveLocalFileSystemURL(success, (fileEntry) => {
- fileEntry.file((file) => {
- const reader = new FileReader();
- reader.onloadend = (evt) => {
- const blob = new Blob([new Uint8Array(evt.target.result)], { type: file.type });
- blob.name = file.name;
- this.upload([blob]);
- };
- reader.readAsArrayBuffer(file);
- });
- }
- );
- }, (err) => {
- console.error(err);
- }, {
- sourceType: webViewCamera.PictureSourceType.CAMERA,
- encodingType: webViewCamera.EncodingType.PNG,
- mediaType: webViewCamera.MediaType.PICTURE,
- saveToPhotoAlbum: true,
- correctOrientation: false,
- });
- });
- }
-
- if (this.refs.takePictureButton) {
- this.addEventListener(this.refs.takePictureButton, 'click', (event) => {
- event.preventDefault();
- this.takePicture();
- });
- }
-
- if (this.refs.toggleCameraMode) {
- this.addEventListener(this.refs.toggleCameraMode, 'click', (event) => {
- event.preventDefault();
- this.cameraMode = !this.cameraMode;
- this.redraw();
- });
- }
-
- this.refs.fileType.forEach((fileType, index) => {
- this.dataValue[index].fileType = this.dataValue[index].fileType || this.component.fileTypes[0].label;
-
- this.addEventListener(fileType, 'change', (event) => {
- event.preventDefault();
-
- const fileType = this.component.fileTypes.find((typeObj) => typeObj.value === event.target.value);
-
- this.dataValue[index].fileType = fileType.label;
- });
- });
-
- const fileService = this.fileService;
- if (fileService) {
- const loadingImages = [];
- this.filesReady = new NativePromise((resolve, reject) => {
- this.filesReadyResolve = resolve;
- this.filesReadyReject = reject;
- });
- this.refs.fileImage.forEach((image, index) => {
- loadingImages.push(this.loadImage(this.dataValue[index]).then((url) => (image.src = url)));
- });
- if (loadingImages.length) {
- NativePromise.all(loadingImages).then(() => {
- this.filesReadyResolve();
- }).catch(() => this.filesReadyReject());
- }
- else {
- this.filesReadyResolve();
- }
- }
- return superAttach;
- }
-
- /* eslint-disable max-len */
- fileSize(a, b, c, d, e) {
- return `${(b = Math, c = b.log, d = 1024, e = c(a) / c(d) | 0, a / b.pow(d, e)).toFixed(2)} ${e ? `${'kMGTPEZY'[--e]}B` : 'Bytes'}`;
- }
-
- /* eslint-enable max-len */
-
- /* eslint-disable max-depth */
- globStringToRegex(str) {
- str = str.replace(/\s/g, '');
-
- let regexp = '', excludes = [];
- if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {
- regexp = str.substring(1, str.length - 1);
- }
- else {
- const split = str.split(',');
- if (split.length > 1) {
- for (let i = 0; i < split.length; i++) {
- const r = this.globStringToRegex(split[i]);
- if (r.regexp) {
- regexp += `(${r.regexp})`;
- if (i < split.length - 1) {
- regexp += '|';
- }
- }
- else {
- excludes = excludes.concat(r.excludes);
- }
- }
- }
- else {
- if (str.startsWith('!')) {
- excludes.push(`^((?!${this.globStringToRegex(str.substring(1)).regexp}).)*$`);
- }
- else {
- if (str.startsWith('.')) {
- str = `*${str}`;
- }
- regexp = `^${str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g'), '\\$&')}$`;
- regexp = regexp.replace(/\\\*/g, '.*').replace(/\\\?/g, '.');
- }
- }
- }
- return { regexp, excludes };
- }
-
- /* eslint-enable max-depth */
-
- translateScalars(str) {
- if (typeof str === 'string') {
- if (str.search(/kb/i) === str.length - 2) {
- return parseFloat(str.substring(0, str.length - 2) * 1024);
- }
- if (str.search(/mb/i) === str.length - 2) {
- return parseFloat(str.substring(0, str.length - 2) * 1024 * 1024);
- }
- if (str.search(/gb/i) === str.length - 2) {
- return parseFloat(str.substring(0, str.length - 2) * 1024 * 1024 * 1024);
- }
- if (str.search(/b/i) === str.length - 1) {
- return parseFloat(str.substring(0, str.length - 1));
- }
- if (str.search(/s/i) === str.length - 1) {
- return parseFloat(str.substring(0, str.length - 1));
- }
- if (str.search(/m/i) === str.length - 1) {
- return parseFloat(str.substring(0, str.length - 1) * 60);
- }
- if (str.search(/h/i) === str.length - 1) {
- return parseFloat(str.substring(0, str.length - 1) * 3600);
- }
- }
- return str;
- }
-
- validatePattern(file, val) {
- if (!val) {
- return true;
- }
- const pattern = this.globStringToRegex(val);
- let valid = true;
- if (pattern.regexp && pattern.regexp.length) {
- const regexp = new RegExp(pattern.regexp, 'i');
- valid = (!_.isNil(file.type) && regexp.test(file.type)) ||
- (!_.isNil(file.name) && regexp.test(file.name));
- }
- valid = pattern.excludes.reduce((result, excludePattern) => {
- const exclude = new RegExp(excludePattern, 'i');
- return result && (_.isNil(file.type) || !exclude.test(file.type)) &&
- (_.isNil(file.name) || !exclude.test(file.name));
- }, valid);
- return valid;
- }
-
- validateMinSize(file, val) {
- return file.size + 0.1 >= this.translateScalars(val);
- }
-
- validateMaxSize(file, val) {
- return file.size - 0.1 <= this.translateScalars(val);
- }
-
- upload(files) {
- // Only allow one upload if not multiple.
- if (!this.component.multiple) {
- if (this.statuses.length) {
- this.statuses = [];
- }
- files = Array.prototype.slice.call(files, 0, 1);
- }
-
- if (this.component.storage && files && files.length) {
- this.fileDropHidden = true;
-
- // files is not really an array and does not have a forEach method, so fake it.
- /* eslint-disable max-statements */
- Array.prototype.forEach.call(files, async(file) => {
- const fileName = uniqueName(file.name, this.component.fileNameTemplate, this.evalContext());
- const escapedFileName = file.name ? file.name.replaceAll('<', '<').replaceAll('>', '>') : file.name;
- const fileUpload = {
- abort: () => null,
- originalName: escapedFileName,
- name: fileName,
- size: file.size,
- status: 'info',
- message: this.t('Processing file. Please wait...'),
- hash: '',
- };
-
- if (this.root.form.submissionRevisions === 'true') {
- this.statuses.push(fileUpload);
- this.redraw();
- const bmf = new BMF();
- const hash = await new Promise((resolve, reject) => {
- this.emit('fileUploadingStart');
- bmf.md5(file, (err, md5)=>{
- if (err) {
- return reject(err);
- }
- return resolve(md5);
- });
- });
- this.emit('fileUploadingEnd');
- fileUpload.hash = hash;
- }
-
- // Check if file with the same name is being uploaded
- if (!this.filesUploading) {
- this.filesUploading = [];
- }
- const fileWithSameNameUploading = this.filesUploading.some(fileUploading => fileUploading === file.name);
- this.filesUploading.push(file.name);
-
- const fileWithSameNameUploaded = this.dataValue.some(fileStatus => fileStatus.originalName === file.name);
- const fileWithSameNameUploadedWithError = this.statuses.findIndex(fileStatus =>
- fileStatus.originalName === file.name
- && fileStatus.status === 'error'
- );
-
- if (fileWithSameNameUploaded || fileWithSameNameUploading) {
- fileUpload.status = 'error';
- fileUpload.message = this.t(`File with the same name is already ${fileWithSameNameUploading ? 'being ' : ''}uploaded`);
- }
-
- if (fileWithSameNameUploadedWithError !== -1) {
- this.statuses.splice(fileWithSameNameUploadedWithError, 1);
- this.redraw();
- }
-
- // Check file pattern
- if (this.component.filePattern && !this.validatePattern(file, this.component.filePattern)) {
- fileUpload.status = 'error';
- fileUpload.message = this.t('File is the wrong type; it must be {{ pattern }}', {
- pattern: this.component.filePattern,
- });
- }
- // Check file minimum size
- if (this.component.fileMinSize && !this.validateMinSize(file, this.component.fileMinSize)) {
- fileUpload.status = 'error';
- fileUpload.message = this.t('File is too small; it must be at least {{ size }}', {
- size: this.component.fileMinSize,
- });
- }
-
- // Check file maximum size
- if (this.component.fileMaxSize && !this.validateMaxSize(file, this.component.fileMaxSize)) {
- fileUpload.status = 'error';
- fileUpload.message = this.t('File is too big; it must be at most {{ size }}', {
- size: this.component.fileMaxSize,
- });
- }
-
- // Get a unique name for this file to keep file collisions from occurring.
- const dir = this.interpolate(this.component.dir || '');
- const { fileService } = this;
- if (!fileService) {
- fileUpload.status = 'error';
- fileUpload.message = this.t('File Service not provided.');
- }
-
- if (this.root.form.submissionRevisions !== 'true') {
- this.statuses.push(fileUpload);
- this.redraw();
- }
-
- if (fileUpload.status !== 'error') {
- if (this.component.privateDownload) {
- file.private = true;
- }
- const { storage, options = {} } = this.component;
- const url = this.interpolate(this.component.url, { file: fileUpload });
- let groupKey = null;
- let groupPermissions = null;
-
- //Iterate through form components to find group resource if one exists
- this.root.everyComponent((element) => {
- if (element.component?.submissionAccess || element.component?.defaultPermission) {
- groupPermissions = !element.component.submissionAccess ? [
- {
- type: element.component.defaultPermission,
- roles: [],
- },
- ] : element.component.submissionAccess;
-
- groupPermissions.forEach((permission) => {
- groupKey = ['admin', 'write', 'create'].includes(permission.type) ? element.component.key : null;
- });
- }
- });
- const fileKey = this.component.fileKey || 'file';
- const groupResourceId = groupKey ? this.currentForm.submission.data[groupKey]._id : null;
- let processedFile = null;
-
- if (this.root.options.fileProcessor) {
- try {
- if (this.refs.fileProcessingLoader) {
- this.refs.fileProcessingLoader.style.display = 'block';
- }
- const fileProcessorHandler = fileProcessor(this.fileService, this.root.options.fileProcessor);
- processedFile = await fileProcessorHandler(file, this.component.properties);
- }
- catch (err) {
- fileUpload.status = 'error';
- fileUpload.message = this.t('File processing has been failed.');
- this.fileDropHidden = false;
- this.redraw();
- return;
- }
- finally {
- if (this.refs.fileProcessingLoader) {
- this.refs.fileProcessingLoader.style.display = 'none';
- }
- }
- }
-
- let count = 0;
- const multipartOptions = this.component.useMultipartUpload && this.component.multipart ? {
- ...this.component.multipart,
- progressCallback: (total) => {
- count++;
- fileUpload.status = 'progress';
- fileUpload.progress = parseInt(100 * count / total);
- delete fileUpload.message;
- this.redraw();
- },
- changeMessage: (message) => {
- fileUpload.message = message;
- this.redraw();
- },
- } : false;
-
- fileUpload.message = this.t('Starting upload...');
- this.redraw();
-
- const filePromise = fileService.uploadFile(
- storage,
- processedFile || file,
- fileName,
- dir,
- // Progress callback
- (evt) => {
- fileUpload.status = 'progress';
- fileUpload.progress = parseInt(100.0 * evt.loaded / evt.total);
- delete fileUpload.message;
- this.redraw();
- },
- url,
- options,
- fileKey,
- groupPermissions,
- groupResourceId,
- // Upload start callback
- () => {
- this.emit('fileUploadingStart', filePromise);
- },
- (abort) => fileUpload.abort = abort,
- multipartOptions
- ).then((fileInfo) => {
- const index = this.statuses.indexOf(fileUpload);
- if (index !== -1) {
- this.statuses.splice(index, 1);
- }
- fileInfo.originalName = escapedFileName;
- fileInfo.hash = fileUpload.hash;
- if (!this.hasValue()) {
- this.dataValue = [];
- }
- this.dataValue.push(fileInfo);
- _.pull(this.filesUploading, fileInfo.originalName);
- this.fileDropHidden = false;
- this.redraw();
- this.triggerChange();
- this.emit('fileUploadingEnd', filePromise);
- })
- .catch((response) => {
- fileUpload.status = 'error';
- fileUpload.message = typeof response === 'string' ? response : response.toString();
- delete fileUpload.progress;
- this.fileDropHidden = false;
- _.pull(this.filesUploading, file.name);
- this.redraw();
- this.emit('fileUploadingEnd', filePromise);
- });
- }
- else {
- this.filesUploading.splice(this.filesUploading.indexOf(file.name),1);
- }
- });
- }
- }
-
- getFile(fileInfo) {
- const { options = {} } = this.component;
- const { fileService } = this;
- if (!fileService) {
- return alert('File Service not provided');
- }
- if (this.component.privateDownload) {
- fileInfo.private = true;
- }
- fileService.downloadFile(fileInfo, options).then((file) => {
- if (file) {
- if (['base64', 'indexeddb'].includes(file.storage)) {
- download(file.url, file.originalName || file.name, file.type);
- }
- else {
- window.open(file.url, '_blank');
- }
- }
- })
- .catch((response) => {
- // Is alert the best way to do this?
- // User is expecting an immediate notification due to attempting to download a file.
- alert(response);
- });
- }
-
- focus() {
- if ('beforeFocus' in this.parent) {
- this.parent.beforeFocus(this);
- }
-
- if (this.refs.fileBrowse) {
- this.refs.fileBrowse.focus();
- }
- }
-
- destroy() {
- this.stopVideo();
- super.destroy();
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/File.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/file/File.unit.js
deleted file mode 100644
index 4977854b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/File.unit.js
+++ /dev/null
@@ -1,260 +0,0 @@
-import assert from 'power-assert';
-import Harness from '../../../test/harness';
-import FileComponent from './File';
-import { comp1, comp2 } from './fixtures';
-import Formio from './../../Formio';
-import _ from 'lodash';
-
-describe('File Component', () => {
- it('Should create a File Component', () => {
- return Harness.testCreate(FileComponent, comp1).then((component) => {
- const parentNode = document.createElement('div');
- const element = document.createElement('div');
- parentNode.appendChild(element);
- component.build(element);
- Harness.testElements(component, 'ul.list-group-striped li.list-group-header', 1);
- Harness.testElements(component, 'ul.list-group-striped li.list-group-item', 1);
- Harness.testElements(component, 'a.browse', 1);
- assert(component.checkValidity(component.getValue()), 'Item should be valid');
- component.setValue([
- {
- storage: 'base64',
- name: 'IMG_5235-ce0abe18-5d3e-4ab4-84ca-b3e06684bc86.jpg',
- url: 'data:image/jpg;base64,AAAAIGZ0eXBoZWljAAAAAG1pZjF',
- size: 1159732,
- type: 'image/jpeg',
- originalName: 'IMG_5235.jpg',
- },
- {
- storage: 'base64',
- name: 'IMG_5235-ce0abe18-5d3e-4ab4-84ca-b3e06684bc86.png',
- url: 'data:image/jpg;base64,AAAAIGZ0eXBoZWljAAAAAG1pZjF',
- size: 34533,
- type: 'image/png',
- originalName: 'IMG_5235.png',
- }
- ]);
- Harness.testElements(component, 'ul.list-group-striped li.list-group-header', 1);
- Harness.testElements(component, 'ul.list-group-striped li.list-group-item', 3);
- Harness.testElements(component, 'a.browse', 0);
- assert(component.checkValidity(component.getValue()), 'Item should be valid');
- });
- });
-
- it('Should hide loader after loading process', () => {
- return Harness.testCreate(FileComponent, comp1).then((component) => {
- const parentNode = document.createElement('div');
- const element = document.createElement('div');
- parentNode.appendChild(element);
- component.build(element);
- Harness.testElements(component, 'div.loader-wrapper', 1);
- component.setValue([
- {
- storage: 'base64',
- name: 'IMG_5235-ce0abe18-5d3e-4ab4-84ca-b3e06684bc86.jpg',
- url: 'data:image/jpg;base64,AAAAIGZ0eXBoZWljAAAAAG1pZjF',
- size: 1159732,
- type: 'image/jpeg',
- originalName: 'IMG_5235.jpg',
- }
- ]);
- Harness.testElements(component, 'div.loader-wrapper', 0);
- });
- });
-
- it('Should create a multiple File Component', () => {
- comp1.multiple = true;
- return Harness.testCreate(FileComponent, comp1).then((component) => {
- const parentNode = document.createElement('div');
- const element = document.createElement('div');
- parentNode.appendChild(element);
- component.build(element);
- Harness.testElements(component, 'ul.list-group-striped li.list-group-header', 1);
- Harness.testElements(component, 'ul.list-group-striped li.list-group-item', 1);
- Harness.testElements(component, 'a.browse', 1);
- assert(component.checkValidity(component.getValue()), 'Item should be valid');
- component.setValue([
- {
- storage: 'base64',
- name: 'IMG_5235-ce0abe18-5d3e-4ab4-84ca-b3e06684bc86.jpg',
- url: 'data:image/jpg;base64,AAAAIGZ0eXBoZWljAAAAAG1pZjF',
- size: 1159732,
- type: 'image/jpeg',
- originalName: 'IMG_5235.jpg',
- },
- {
- storage: 'base64',
- name: 'IMG_5235-ce0abe18-5d3e-4ab4-84ca-b3e06684bc86.png',
- url: 'data:image/jpg;base64,AAAAIGZ0eXBoZWljAAAAAG1pZjF',
- size: 34533,
- type: 'image/png',
- originalName: 'IMG_5235.png',
- }
- ]);
- Harness.testElements(component, 'ul.list-group-striped li.list-group-header', 1);
- Harness.testElements(component, 'ul.list-group-striped li.list-group-item', 3);
- Harness.testElements(component, 'a.browse', 1);
- assert(component.checkValidity(component.getValue()), 'Item should be valid');
- });
- });
-
- it('Should validate uploaded file according to the pattern', (done) => {
- Harness.testCreate(FileComponent, comp1).then((component) => {
- const validFiles =[
- {
- name: 'test.jpg',
- size: 27401,
- type: 'image/jpeg'
- },
- {
- name: 'TypeScript.pdf',
- size: 203123,
- type: 'application/pdf'
- },
- {
- name: 'build with dist.png',
- size: 137321,
- type: 'image/png'
- }
- ];
-
- const invalidFiles = [
- {
- name: 'eventsList.xlsx',
- size: 16022,
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
- },
- {
- name: 'lazy load.mp4',
- size: 9083622,
- type: 'video/mp4'
- },
- ];
-
- const pattern = ' .jpg, .png, .exe, .pdf ';
-
- const checkValidatePattern = (files, valid) => {
- files.forEach(file => {
- assert.equal(component.validatePattern(file, pattern), valid, `File ${file.name} should ${valid ? '' : 'not'} correspond to the pattern`);
- });
- };
-
- checkValidatePattern(validFiles, true);
- checkValidatePattern(invalidFiles, false);
- done();
- });
- });
-
- it('Should display uploaded file in file component only after saving', (done) => {
- const form = _.cloneDeep(comp2);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const value = [
- {
- storage: 'base64',
- name: '33-0ae897b9-c808-4832-a5e1-4e5d0c725f1b.jpg',
- url: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD…CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//2Q==',
- size: 102691,
- type: 'image/jpeg',
- originalName: '33.jpg',
- },
- ];
- const file = form.getComponent('file');
- const openModalButton = file.componentModal.refs.openModal;
- const clickEvent = new Event('click');
- openModalButton.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(file.componentModal.isOpened, true);
- file.dataValue = value;
- file.redraw();
-
- setTimeout(() => {
- assert.equal(file.refs.fileLink.length, 1);
- const modalOverlayButton = file.componentModal.refs.modalOverlay;
- modalOverlayButton.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!file.componentModal.dialogElement, true);
- const dialogYesButton = file.componentModal.dialogElement.refs.dialogYesButton;
- dialogYesButton.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!file.componentModal.dialogElement, false);
- file.componentModal.closeModal();
-
- setTimeout(() => {
- assert.equal(file.componentModal.isOpened, false);
- assert.equal(file.refs.fileLink.length, 0);
- assert.equal(file.componentModal.refs.openModal.textContent.trim(), 'Click to set value');
- done();
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should abort the correct file when user clicks the file remove button', (done) => {
- const cmp = _.cloneDeep(comp1);
- const abortedFiles = [];
- cmp.multiple = true;
- cmp.storage = 'url';
-
- const options = {
- fileService: {
- uploadFile: function(storage, file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, uploadStartCallback, abortCallbackSetter) {
- return new Promise((resolve) => {
- // complete upload after 1s.
- const timeout = setTimeout(function() {
- progressCallback({ loaded: 1, total: 1 });
- const uploadResponse = {
- name: fileName,
- size: file.size,
- type: 'application/pdf',
- url: `fake/url/${fileName}`
- };
- resolve(uploadResponse);
- }, 1000);
-
- abortCallbackSetter(function() {
- abortedFiles.push(file.name);
- clearTimeout(timeout);
- });
- });
- }
- }
- };
-
- Harness.testCreate(FileComponent, cmp, options).then((component) => {
- component.root = { everyComponent: () => {}, options: options, form: { submissionRevisions: false, components: [cmp] } };
- const parentNode = document.createElement('div');
- const element = document.createElement('div');
- parentNode.appendChild(element);
- component.build(element);
-
- const content = [1];
- const files = [new File(content, 'file.0'), new File([content], 'file.1'), new File([content], 'file.2')];
-
- component.upload(files);
-
- setTimeout(function() {
- Harness.testElements(component, 'div.file .fileName', 3);
-
- component.element.querySelectorAll('i[ref="fileStatusRemove"]')[1].click();
-
- setTimeout(() => {
- assert(component !== null);
- assert(abortedFiles[0] === 'file.1' && abortedFiles.length === 1);
- assert(component.filesUploading.join(',') === 'file.0,file.2');
-
- Harness.testElements(component, 'div.file .fileName', 2);
- component.root = null;
- done();
- }, 20);
- }, 50);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.data.js
deleted file mode 100644
index 6765474d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.data.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- {
- key: 'defaultValue',
- ignore: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.display.js
deleted file mode 100644
index 2e7810dd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.display.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- {
- key: 'placeholder',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.file.js b/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.file.js
deleted file mode 100644
index f27bf36a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.file.js
+++ /dev/null
@@ -1,300 +0,0 @@
-import { GlobalFormio as Formio } from '../../../Formio';
-import _ from 'lodash';
-
-export default [
- {
- type: 'select',
- input: true,
- key: 'storage',
- label: 'Storage',
- placeholder: 'Select your file storage provider',
- weight: 0,
- tooltip: 'Which storage to save the files in.',
- valueProperty: 'value',
- dataSrc: 'custom',
- data: {
- custom() {
- return _.map(Formio.Providers.getProviders('storage'), (storage, key) => ({
- label: storage.title,
- value: key
- }));
- }
- }
- },
- {
- type: 'checkbox',
- input: true,
- key: 'useMultipartUpload',
- label: 'Use the S3 Multipart Upload API',
- tooltip: "The S3 Multipart Upload API is designed to improve the upload experience for larger objects (> 5GB).",
- conditional: {
- json: { '===': [{ var: 'data.storage' }, 's3'] }
- },
- },
- {
- label: 'Multipart Upload',
- tableView: false,
- key: 'multipart',
- type: 'container',
- input: true,
- components: [
- {
- label: 'Part Size (MB)',
- applyMaskOn: 'change',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- validate: {
- min: 5,
- max: 5000,
- },
- key: 'partSize',
- type: 'number',
- input: true,
- defaultValue: 500,
- },
- ],
- conditional: {
- json: { '===': [{ var: 'data.useMultipartUpload' }, true] }
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'url',
- label: 'Url',
- weight: 10,
- placeholder: 'Enter the url to post the files to.',
- tooltip: "See https://github.com/danialfarid/ng-file-upload#server-side for how to set up the server.",
- conditional: {
- json: { '===': [{ var: 'data.storage' }, 'url'] }
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'options.indexeddb',
- label: 'Database',
- weight: 10,
- placeholder: 'Enter the indexeddb database name',
- conditional: {
- json: {
- in: [
- {
- var: 'data.storage'
- },
- ['indexeddb']
- ],
- }
- }
- },
- {
- type: 'textfield',
- input: true,
- label: 'Table',
- key: 'options.indexeddbTable',
- weight: 10,
- placeholder: 'Enter the name for indexeddb table',
- conditional: {
- json: {
- in: [
- {
- var: 'data.storage'
- },
- ['indexeddb']
- ],
- }
- }
- },
- {
- type: 'textarea',
- key: 'options',
- label: 'Custom request options',
- tooltip: 'Pass your custom xhr options(optional)',
- rows: 5,
- editor: 'ace',
- input: true,
- weight: 15,
- placeholder: `{
- "withCredentials": true,
- "headers": {
- "Authorization": "Basic "
- }
- }`,
- conditional: {
- json: {
- '===': [{
- var: 'data.storage'
- }, 'url']
- }
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'fileKey',
- label: 'File form-data key',
- weight: 17,
- placeholder: 'Enter the key name of a file for form data.',
- tooltip: 'Key name that you would like to modify for the file while calling API request.',
- conditional: {
- json: {
- '===': [{
- var: 'data.storage'
- }, 'url']
- }
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'dir',
- label: 'Directory',
- placeholder: '(optional) Enter a directory for the files',
- tooltip: 'This will place all the files uploaded in this field in the directory',
- weight: 20,
- conditional: {
- json: {
- '!==': [{
- var: 'data.storage'
- }, 'googledrive']
- }
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'dir',
- label: 'Folder ID',
- placeholder: '(optional) Enter an ID of the folder for the files',
- tooltip: 'This will place all the files uploaded in this field in the folder',
- weight: 20,
- conditional: {
- json: {
- '===': [{
- var: 'data.storage'
- }, 'googledrive']
- }
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'fileNameTemplate',
- label: 'File Name Template',
- placeholder: '(optional) { {name} }-{ {guid} }"',
- tooltip: 'Specify template for name of uploaded file(s). Regular template variables are available (`data`, `component`, `user`, `value`, `moment` etc.), also `fileName`, `guid` variables are available. `guid` part must be present, if not found in template, will be added at the end.',
- weight: 25
- },
- {
- type: 'checkbox',
- input: true,
- key: 'image',
- label: 'Display as image(s)',
- tooltip: 'Instead of a list of linked files, images will be rendered in the view.',
- weight: 30
- },
- {
- type: 'checkbox',
- input: true,
- key: 'uploadOnly',
- label: 'Upload Only',
- tooltip: 'When this is checked, will only allow you to upload file(s) and consequently the download, in this component, will be unavailable.',
- weight: 33,
- },
- {
- type: 'checkbox',
- input: true,
- key: 'privateDownload',
- label: 'Private Download',
- tooltip: 'When this is checked, the file download will send a POST request to the download URL with the x-jwt-token header. This will allow your endpoint to create a Private download system.',
- weight: 31,
- conditional: {
- json: { '===': [{ var: 'data.storage' }, 'url'] }
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'imageSize',
- label: 'Image Size',
- placeholder: '100',
- tooltip: 'The image size for previewing images.',
- weight: 40,
- conditional: {
- json: { '==': [{ var: 'data.image' }, true] }
- }
- },
- {
- type: 'checkbox',
- input: true,
- key: 'webcam',
- label: 'Enable web camera',
- tooltip: 'This will allow using an attached camera to directly take a picture instead of uploading an existing file.',
- weight: 32
- },
- {
- type: 'textfield',
- input: true,
- key: 'webcamSize',
- label: 'Webcam Width',
- placeholder: '320',
- tooltip: 'The webcam size for taking pictures.',
- weight: 38,
- conditional: {
- json: { '==': [{ var: 'data.webcam' }, true] }
- }
- },
- {
- type: 'datagrid',
- input: true,
- label: 'File Types',
- key: 'fileTypes',
- tooltip: 'Specify file types to classify the uploads. This is useful if you allow multiple types of uploads but want to allow the user to specify which type of file each is.',
- weight: 11,
- components: [
- {
- label: 'Label',
- key: 'label',
- input: true,
- type: 'textfield'
- },
- {
- label: 'Value',
- key: 'value',
- input: true,
- type: 'textfield'
- }
- ]
- },
- {
- type: 'textfield',
- input: true,
- key: 'filePattern',
- label: 'File Pattern',
- placeholder: '.jpg,video/*,application/pdf',
- tooltip: 'See https://github.com/danialfarid/ng-file-upload#full-reference for how to specify file patterns.',
- weight: 50
- },
- {
- type: 'textfield',
- input: true,
- key: 'fileMinSize',
- label: 'File Minimum Size',
- placeholder: '1MB',
- tooltip: 'See https://github.com/danialfarid/ng-file-upload#full-reference for how to specify file sizes.',
- weight: 60
- },
- {
- type: 'textfield',
- input: true,
- key: 'fileMaxSize',
- label: 'File Maximum Size',
- placeholder: '10MB',
- tooltip: 'See https://github.com/danialfarid/ng-file-upload#full-reference for how to specify file sizes.',
- weight: 70
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.validation.js
deleted file mode 100644
index ed5bc10a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/editForm/File.edit.validation.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default [
- {
- key: 'unique',
- ignore: true
- },
- {
- key: 'validateOn',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/comp1.js
deleted file mode 100644
index 8a5a609c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/comp1.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export default {
- 'label': 'Upload',
- 'tableView': false,
- 'storage': 'base64',
- 'webcam': false,
- 'fileTypes': [
- {
- 'label': '',
- 'value': ''
- }
- ],
- 'calculateServer': false,
- 'key': 'upload',
- 'type': 'file',
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/comp2.js
deleted file mode 100644
index eef40e54..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/comp2.js
+++ /dev/null
@@ -1,29 +0,0 @@
-export default {
- _id: '6108f1dac7e55d5cabe2627f',
- type: 'form',
- components: [
- {
- label: 'Upload',
- tableView: false,
- modalEdit: true,
- storage: 'base64',
- webcam: false,
- fileTypes: [{ label: '', value: '' }],
- key: 'file',
- type: 'file',
- input: true,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- title: 'testFileForm',
- display: 'form',
- name: 'testFileForm',
- path: 'testfileform',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/index.js
deleted file mode 100644
index 63468958..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/values.js
deleted file mode 100644
index 9afbfcf4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/file/fixtures/values.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default [
- [
- {
- imageSrc: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4w',
- name: 'epaule-3aa10b33-78f8-4b5f-9cba-7dacff042e3c.svg',
- originalName: 'Epaule.svg',
- size: 41978,
- storage: 'base64',
- type: 'image/svg+xml',
- url: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA0MjggODMxIiB3aWR0aD0iNDI4LjBwdCIgaGVpZ2h0PSI4MzEuMHB0Ij4KPHBhdGggZD0iTSAwLjAwIDAuMDAgTCA0MjguMDAgMC4wMCBMIDQyOC4wMCA4MzEuMDAgTCAwLjAwIDgzMS4wMCBMIDAuMDAgMC4wMCBaIiBmaWxsPSIjZmZmZmZmIiAvPgo8cGF0aCBkPSJNIDEyNC4xMSAxMy44MyBDIDEyOC4wMCAxNy4xMSAxMjkuODUgMjEuNTUgMTMwLjc2IDI2LjQ1IEMgMTMyLjE5IDI5LjA5IDEzMy44NSAzMC42NiAxMzMuNTAgMzQuMDAgQyAxMzIuODggNDEuNDAgMTI3LjE1IDQ4LjI5IDEyNC4wOCA1NS4wMCBDIDEyMy45MyA1OS4wNSAxMjMuNjcgNjIuNzcgMTI1LjUxIDY2LjUyIEMgMTI3LjEzIDcwLjQ1IDEzMS4yMSA3Mi42MyAxMzUuMTIgNzMuNjcgQyAxNDIuNzEgNzYuMDMgMTUwLjA5IDc3LjQ0IDE1Ni4zNCA4Mi42NiBDIDE2My41NSA4OC43MyAxNjYuMTYgOTcuODggMTY2LjQ2IDEwNy4wMCBDIDE2Ni43NyAxMTcuMzIgMTY2LjQ2IDEyNy42OSAxNjYuNjAgMTM4LjAyIEMgMTY2LjgyIDE0MC45NyAxNjcuMDQgMTQzLjc2IDE2OC42NSAxNDYuMzQgQyAxNzQuNjIgMTU2Ljk1IDE4MC41OSAxNjguNjQgMTgxLjQ0IDE4MC45OSBDIDE4Mi4xNCAxODUuNzMgMTgxLjY4IDE5MC4zNSAxODMuMjAgMTk0Ljk2IEMgMTg0LjMwIDE5OS42MCAxODcuNDIgMjAyLjMwIDE5MC4xNSAyMDUuOTcgQyAxOTQuNjIgMjExLjcxIDIwMC4xMyAyMTYuODUgMjAzLjkwIDIyMy4wNyBDIDIwNC4xOCAyMjQuOTEgMjA0Ljc4IDIyOC4xMCAyMDIuMDAgMjI4LjEyIEMgMTk5LjA4IDIyNy4yMiAxOTcuNDkgMjI1LjEzIDE5NS4yNiAyMjMuMjIgQyAxOTQuODQgMjI1LjU5IDE5NS42MiAyMjcuNjEgMTk1LjgxIDIyOS45OCBDIDE5Ni4yMCAyMzMuMjcgMTk1LjcwIDIzNi42MyAxOTQuNzEgMjM5Ljc3IEMgMTkzLjU1IDI0Mi45MyAxOTAuNjUgMjQ2LjIzIDE4Ny4wMSAyNDYuMDYgQyAxODIuMjggMjQ2LjU1IDE3OC4zOCAyNDIuMTAgMTc2Ljc5IDIzOC4xMSBDIDE3My45OCAyMzAuODQgMTc0LjY4IDIyMi4xNSAxNzMuNjkgMjE0LjQ5IEMgMTcyLjYwIDIwOC42MiAxNjkuNDkgMjAzLjE0IDE2Ny4xOSAxOTcuNjAgQyAxNjIuMzUgMTg3LjA2IDE1Ny43NCAxNzYuMzMgMTUzLjYzIDE2NS40OCBDIDE1MC4wOSAxNTUuMDcgMTQ5LjI1IDE0My44OSAxNDguNTIgMTMyLjk5IEMgMTQ4LjUyIDEzMS42OCAxNDguMTIgMTMxLjAxIDE0Ny4zMCAxMzAuOTcgQyAxNDYuMDEgMTM4LjM4IDE0My4zNiAxNDUuNTYgMTQyLjIwIDE1My4wMCBDIDE0MC42MCAxNjguNjMgMTQ2LjM4IDE4Mi44NCAxNDguMjkgMTk4Ljk5IEMgMTQ5LjY4IDIwNi45NCAxNTAuMzggMjE0Ljk0IDE1MC45MCAyMjMuMDAgQyAxNTEuMTYgMjM1Ljg1IDE0OC41MSAyNDkuMTkgMTQ1LjU5IDI2MS42OCBDIDE0NC4wMSAyNjcuNjYgMTQyLjA2IDI3NC4zMiAxMzguMzcgMjc5LjM3IEMgMTM2LjQxIDI4MS40OSAxMzcuNzYgMjg1LjM5IDEzNy44NSAyODguMDQgQyAxMzguMDQgMjk0Ljc1IDEzNS43NiAzMDIuMzEgMTM3LjkzIDMwOS4wMSBDIDEzOS45MSAzMTUuMzkgMTQyLjUxIDMyMS4xNiAxNDIuNTkgMzI4LjAwIEMgMTQzLjEzIDM0MS40MSAxMzUuMzQgMzU0LjQyIDEzMS4zOCAzNjcuMDkgQyAxMzAuMjYgMzcyLjIyIDEyOS42NCAzNzcuNTIgMTMxLjQ0IDM4Mi41OCBDIDEzMy4zMSAzODYuNTAgMTM3LjM3IDM4OC42NSAxMzkuNDQgMzkyLjU2IEMgMTQwLjIwIDM5NC4xMyAxNDIuMDYgMzk2LjU5IDE0MC4wMCAzOTcuOTMgQyAxMzUuNzEgNDAwLjY1IDEyOS44NSAzOTkuOTggMTI0Ljk5IDM5OS45OCBDIDEyMi41OCAzOTkuNjAgMTE5LjM2IDM5OS4yMCAxMTcuNTIgMzk3LjQ4IEMgMTE0Ljk2IDM5NC4zNyAxMTMuNjUgMzkwLjAxIDExMy45NyAzODYuMDAgQyAxMTMuMzEgMzc2LjUwIDExOC4xMiAzNjcuODcgMTE3LjIwIDM1OC4wMCBDIDExNy4wMyAzNTEuMjQgMTE1LjEzIDM0NC43NCAxMTQuODUgMzM4LjAwIEMgMTEzLjY5IDMyNy44NiAxMTcuODkgMzE3LjQ5IDExNy4zMyAzMDcuMDAgQyAxMTYuOTggMzAyLjk4IDExNi45MCAyOTguOTggMTE2LjIwIDI5NS4wMCBDIDExNC45MSAyODEuMjkgMTE1LjIyIDI2Ny42NCAxMTQuMTIgMjUzLjk5IEMgMTEzLjgyIDI0My44NiAxMTIuODcgMjMzLjgwIDExMi41MCAyMjMuNjMgQyAxMTEuOTIgMjM1LjM2IDExMS4xMiAyNDcuMzAgMTEwLjEwIDI1OS4wMCBDIDEwOS43OCAyNzAuMjEgMTA5LjE3IDI4MS43OSAxMDkuMTYgMjkzLjAwIEMgMTA4LjI0IDI5Mi45MyAxMDcuNDcgMjkyLjQ1IDEwNi44NSAyOTEuNTQgQyAxMDcuOTIgMjgzLjgyIDEwNy45NCAyNzUuNzkgMTA3Ljk3IDI2OC4wMCBDIDEwOC40MyAyNTAuNzkgMTEwLjQ0IDIzMy4zNSAxMTAuODkgMjE2LjI1IEMgMTA5LjAxIDIxNS4xOCAxMDcuMjAgMjE0LjIxIDEwNS4wNiAyMTMuNzggQyAxMDQuMjkgMjEzLjcyIDEwMy45MCAyMTMuMTAgMTAzLjg4IDIxMS45MCBDIDEwNi45OCAyMTIuMTcgMTA5LjkxIDIxMy45OCAxMTIuOTIgMjE0Ljk2IEMgMTEzLjU2IDIxNC4zOSAxMTQuMjQgMjE0LjA2IDExNC45NiAyMTMuOTkgQyAxMTcuMzMgMjEzLjk3IDExOS4zMSAyMTIuNTcgMTIxLjQxIDIxMS40NiBDIDEyMS43OSAyMTAuNDMgMTIyLjM2IDIwOS45MCAxMjMuMTEgMjA5Ljg3IEMgMTIzLjg0IDIxMy43NCAxMTYuOTIgMjE1LjU4IDExNC4xNCAyMTYuMzMgQyAxMTMuNjIgMjIzLjI5IDExNC40MCAyMzAuMDggMTE0LjkzIDIzNy4wMCBDIDExNS4wMyAyNDEuNjkgMTE1LjU3IDI0Ni4zMyAxMTUuOTggMjUxLjAwIEMgMTE1Ljk3IDI1Ny4wMyAxMTYuNzEgMjYzLjAwIDExNi45MiAyNjkuMDIgQyAxMTcuMTggMjgyLjM1IDExOC4zNSAyOTUuNzIgMTE5LjIyIDMwOS4wMCBDIDExOS42OSAzMTYuNjYgMTE2Ljg5IDMyMy40NCAxMTYuNjcgMzMxLjAwIEMgMTE2LjQyIDMzOS4yMiAxMTcuNjUgMzQ2Ljk1IDExOC45MiAzNTUuMDAgQyAxMTkuNzYgMzYyLjkwIDExNy4xNCAzNzEuMTUgMTE2LjA2IDM3OS4wMCBDIDExNi4xMSAzODQuOTEgMTE1LjA1IDM5MC4yNCAxMTguNjQgMzk1LjM4IEMgMTIyLjI0IDM5OS4zNSAxMjguMjMgMzk4LjMzIDEzMy4wMSAzOTguMDAgQyAxMzQuODAgMzk4LjA3IDEzNy41NiAzOTYuODcgMTM3Ljk5IDM5NC45OSBDIDEzNi40MiAzOTAuMzkgMTMxLjQ4IDM4Ny41NiAxMjkuOTUgMzgyLjk5IEMgMTI4LjUzIDM3OS4zMSAxMjguOTkgMzc0Ljk2IDEyOS4wOCAzNzEuMDAgQyAxMzAuOTQgMzU3Ljc2IDEzOC41MSAzNDYuNjQgMTQwLjI5IDMzMy4wMSBDIDE0MS40NCAzMjYuMjkgMTM5LjYyIDMxOS45NSAxMzcuMzcgMzEzLjY5IEMgMTM1LjUwIDMwOC41NyAxMzUuNjAgMzAzLjM2IDEzNS43OCAyOTguMDAgQyAxMzYuMjMgMjkyLjAyIDEzNS44NCAyODUuOTggMTM2LjAzIDI4MC4wMSBDIDEzNi40OSAyNzguNTggMTM3LjMyIDI3Ny4yNyAxMzguMTEgMjc2LjAwIEMgMTQxLjA2IDI3MS41OSAxNDIuNDUgMjY2LjAyIDE0NC4wNSAyNjEuMDAgQyAxNTEuNjAgMjMzLjY1IDE0OC41NSAyMDUuMjggMTQyLjM3IDE3OC4wMCBDIDE0MC43NiAxNjguOTUgMTM4LjMzIDE1OS4wMSAxNDAuODEgMTQ5Ljk2IEMgMTQzLjI4IDEzOS42MyAxNDYuMzcgMTI5LjU1IDE0Ny44OCAxMTkuMDAgQyAxNDcuNzcgMTE3Ljg5IDE0OC40NSAxMTcuNTQgMTQ5LjkzIDExNy45NSBDIDE0OS4yMiAxMjYuNTMgMTUwLjIzIDEzNS4zNyAxNTEuMjIgMTQzLjkxIEMgMTUyLjM4IDE1MC40MiAxNTMuMDkgMTU2LjY0IDE1NC45MCAxNjMuMDAgQyAxNTcuNDggMTcyLjA4IDE2MS45NyAxODAuODUgMTY1LjY0IDE4OS40NiBDIDE2OS45OCAxOTkuMTkgMTc1LjE2IDIwOC4xMyAxNzYuMDIgMjE5LjAwIEMgMTc1LjgzIDIyNC41NSAxNzYuMzIgMjMwLjA1IDE3Ny40OCAyMzUuNDggQyAxNzguMDggMjM3LjI0IDE3OS4wNCAyNDAuNTggMTgxLjA1IDI0MS4xMyBDIDE4MS42MCAyMzYuOTYgMTc5Ljg1IDIzMi4zMCAxODAuMjIgMjI4LjM3IEwgMTgwLjc5IDIyOC4xMyBDIDE4MS4yMyAyMzIuNzYgMTgxLjg0IDIzNy4zNCAxODEuOTIgMjQyLjAwIEMgMTgyLjE0IDI0My4yOSAxODMuODAgMjQ0LjIwIDE4NS4wNSAyNDMuOTcgQyAxODYuMzAgMjM5LjMxIDE4Mi41NiAyMzMuMTcgMTg0LjY4IDIyOS4yMCBDIDE4NC45OCAyMzQuMTUgMTg1Ljc5IDIzOS4wNCAxODUuODAgMjQ0LjAxIEMgMTg1Ljk2IDI0NC44NyAxODYuNjcgMjQ1LjE2IDE4Ny45NCAyNDQuOTAgQyAxODkuNTIgMjQwLjI2IDE4OC4wNyAyMzUuOTkgMTg4LjE2IDIzMS4yNiBMIDE4OC43NyAyMzEuMjkgQyAxODguNzggMjMyLjg0IDE4OC44MiAyMzQuMzYgMTg5LjE0IDIzNS44OCBDIDE4OS43MiAyMzguNDYgMTg4LjkzIDI0MS4wNSAxODkuNzQgMjQzLjUyIEMgMTkxLjc5IDI0My4wNyAxOTIuNDUgMjQwLjc3IDE5My4wMSAyMzkuMDIgQyAxOTQuNzUgMjMzLjU0IDE5My42MiAyMjcuNzAgMTkyLjY0IDIyMi4xMyBDIDE5Mi41NCAyMjAuOTEgMTkwLjk4IDIxOC43NyAxOTMuMDQgMjE4LjYxIEMgMTk1LjY1IDIyMC4xNCAxOTcuNzQgMjI0LjE0IDIwMC45NSAyMjUuMDcgQyAyMDMuMDQgMjI1LjA4IDIwMS41NCAyMjIuODQgMjAwLjg4IDIyMi4wNCBDIDE5Ni42MCAyMTYuMzggMTkxLjgyIDIxMS4yNSAxODcuMDkgMjA1Ljk4IEMgMTgwLjQ2IDE5OC45MiAxODAuNjcgMTg4LjAxIDE3OS40MyAxNzguOTkgQyAxNzguNjAgMTY5Ljg3IDE3NC44NiAxNjIuMjQgMTcwLjcwIDE1NC4yNSBDIDE2OC44MCAxNTAuNTAgMTY2LjcxIDE0Ny4xOSAxNjUuODEgMTQzLjAxIEMgMTYyLjI2IDEyOC4wMCAxNjYuNzkgMTEzLjc0IDE2My42OCA5OS4xMiBDIDE2Mi4xOCA5Mi44MCAxNTkuNDAgODYuOTggMTUzLjk4IDgzLjE0IEMgMTQ2LjQ1IDc3Ljk1IDEzNi43NSA3Ny4xNSAxMjguOTMgNzMuMjEgQyAxMjMuNDggNjkuODcgMTIxLjQ1IDY0LjExIDEyMS45MCA1Ny45MSBDIDExOS43NSA1OC42NCAxMTguMzAgNjAuMjQgMTE1LjkzIDYwLjQ5IEMgMTExLjEzIDYxLjMyIDEwNy40MiA1OS40NyAxMDMuMTcgNTcuNzEgQyAxMDIuNzQgNjEuMDggMTAyLjQ3IDY0LjY1IDEwMC41OSA2Ny41OSBDIDk3LjkzIDcyLjIyIDkyLjg2IDc0LjQzIDg4LjAzIDc2LjA4IEMgODEuNDIgNzguMTAgNzMuMTkgODAuMTIgNjguMzAgODUuMjkgQyA2Mi45MSA5MC4yNiA2MC42NiA5Ny45MCA2MC4wNSAxMDQuOTkgQyA1OS44OCAxMTQuNjkgNjAuMTggMTI0LjQwIDU5LjkzIDEzNC4wOSBDIDU5LjQ5IDEzOC42NyA1OS40MiAxNDMuOTQgNTcuNDIgMTQ4LjE0IEMgNTMuNTQgMTU1LjY2IDQ5LjAzIDE2My4zOCA0Ni41OSAxNzEuNTEgQyA0NC42NSAxNzkuOTEgNDUuMTEgMTg5LjkzIDQxLjg0IDE5Ny45NCBDIDM5LjgzIDIwMy41OCAzNC44NSAyMDguNDAgMzEuMTIgMjEzLjAyIEMgMjguMTIgMjE3LjA0IDI0LjY0IDIxOS45MiAyMy4xNCAyMjQuOTIgQyAyNi45NSAyMjUuMjQgMzAuNTMgMjE5LjY5IDMzLjczIDIxOC4yNiBMIDM0LjEyIDIxOS45NyBDIDMyLjUzIDIyNS4wOSAzMS4yMCAyMzAuNjIgMzEuMzYgMjM2LjAxIEMgMzEuNTUgMjM3LjAxIDMxLjU3IDI0MC4yNSAzMy4wNCAyNDAuMDYgQyAzMy4yNiAyMzYuNTEgMzMuMTYgMjMyLjk4IDMzLjY0IDIyOS40NCBDIDMzLjk0IDIyOS4wOCAzNC4yNCAyMjguNzEgMzQuNTQgMjI4LjM0IEMgMzQuMTUgMjMyLjYxIDMzLjQwIDIzNi42NyAzMy44NCAyNDEuMDAgQyAzNC43MCAyNDIuNTQgMzcuMzEgMjQyLjQ4IDM3LjQzIDI0MC4zMCBDIDM3LjkzIDI0MC42OCAzOC40MiAyNDEuMDUgMzguOTIgMjQxLjQzIEMgNDEuOTMgMjQwLjQzIDQxLjAyIDIzNS40MiA0MS4yMCAyMzMuMDAgQyA0MS40NyAyMzAuOTAgNDAuODkgMjI3LjY3IDQyLjY1IDIyNi4xOSBDIDQyLjA1IDIzMC40OSA0MS4zNyAyMzQuNTcgNDEuOTkgMjM4Ljk0IEwgNDIuNjcgMjM4LjYwIEMgNDYuMDAgMjMzLjU3IDQ1LjAyIDIyNS41NyA0Ni43MyAyMTkuODkgQyA0OS43NiAyMDguNjcgNTUuMDEgMTk5LjA4IDU5LjQ5IDE4OC40NyBDIDYzLjA4IDE4MC42NCA2Ni45NyAxNzIuNzEgNjkuNDkgMTY0LjQ2IEMgNzAuOTYgMTU5LjgyIDcxLjQ4IDE1NS4xMCA3Mi40NyAxNTAuMzUgQyA3NC4xMyAxMzkuOTMgNzUuNDEgMTI5LjU0IDc0Ljk3IDExOC45NiBDIDc0LjQ5IDExNy42OSA3Ni42MyAxMTYuNjkgNzYuODMgMTE4LjA1IEMgNzguMTggMTMyLjEyIDg0LjUyIDE0NS45NSA4NC45OCAxNjAuMDAgQyA4My4wMyAxODQuOTAgNzMuOTEgMjA3LjUyIDc2LjM2IDIzMi45OSBDIDc3LjI0IDI0My44MyA3OS4xOSAyNTQuNTEgODEuNzEgMjY1LjA4IEMgODMuMDAgMjY5LjMzIDg0LjE3IDI3My40MiA4Ni45NSAyNzYuOTYgQyA4Ny44MCAyNzguMTkgODkuMDggMjc5LjQxIDg5LjE3IDI4MC45NiBDIDg5Ljc0IDI4Ni4zNyA4OC4xMSAyOTEuNTkgODguOTcgMjk3LjAwIEMgODguOTggMzAxLjgyIDg5Ljg5IDMwNy40OCA4Ny45MCAzMTEuOTUgQyA4NS4yOCAzMTguOTcgODMuMDQgMzI2LjM0IDg0LjI5IDMzMy44OSBDIDg2LjU0IDM0NC4wNyA5MC41NiAzNTQuMDIgOTQuNDAgMzYzLjcwIEMgOTYuMjYgMzY4Ljk1IDk2LjIwIDM3NS4wNiA5NS45MSAzODAuNTcgQyA5NS4yMiAzODYuNzEgODguMzAgMzg5LjQyIDg2LjY5IDM5NC45OSBDIDg2LjQ5IDM5Ny43MCA5MC4wNCAzOTguMDcgOTIuMDAgMzk3Ljk4IEMgOTYuNzggMzk4LjAxIDEwMi44OCAzOTkuNzMgMTA2LjI5IDM5NS4yNyBDIDEwOC40NiAzOTAuOTggMTA5Ljg2IDM4NS44MiAxMDkuMTAgMzgxLjAwIEMgMTA4LjQ0IDM3NC45MyAxMDUuNzggMzY5LjI0IDEwNS43NiAzNjMuMDAgQyAxMDUuMDUgMzUyLjM5IDEwOC43OCAzNDIuNTkgMTA4LjA5IDMzMi4wMCBDIDEwNy44NSAzMjQuOTQgMTA1Ljk4IDMxOC4wMyAxMDUuNzMgMzExLjAxIEMgMTA1LjAxIDMwNS4xMSAxMDYuNjggMjk5LjcwIDEwNi44NiAyOTMuOTYgQyAxMDcuNzcgMjk0LjAzIDEwOC41MSAyOTQuNTMgMTA5LjA4IDI5NS40NiBDIDEwOC4xNiAyOTguOTMgMTA4LjI0IDMwMi40OSAxMDcuNTQgMzA2LjAxIEMgMTA2LjQ4IDMxMi41OSAxMDguMzEgMzE4LjQ1IDEwOS4yNSAzMjQuOTAgQyAxMTEuNTIgMzM1LjY2IDEwOC4xNCAzNDguMTkgMTA3LjAyIDM1OS4wMCBDIDEwNy42MyAzNjYuMDQgMTA4LjgxIDM3My4yNCAxMTAuNjkgMzgwLjA3IEMgMTExLjk0IDM4Ni4xOSAxMTAuMjkgMzkyLjAyIDEwNy4zNSAzOTcuMzkgQyAxMDUuNTQgNDAwLjExIDEwMS45MiA0MDAuMTEgOTkuMDAgNDAwLjAyIEMgOTUuMDYgMzk5LjgyIDkwLjU5IDQwMC41NiA4Ni44OCAzOTkuMjUgQyA4NS4zMCAzOTguNjUgODMuNzQgMzk3Ljk4IDgzLjkxIDM5NS45NyBDIDg0Ljc1IDM5MC4yMCA5MS4wNSAzODcuOTAgOTMuMTUgMzgyLjA4IEMgOTYuMDggMzc0LjQyIDkzLjA0IDM2NS4xOSA5MC4xMCAzNTcuOTQgQyA4Ny4xNSAzNDkuNTcgODMuMTkgMzQwLjc5IDgyLjA3IDMzMS45OSBDIDgxLjY1IDMyOC40OCA4Mi4yNiAzMjUuMTQgODMuMDMgMzIxLjc0IEMgODIuNTkgMzIxLjMyIDgyLjE1IDMyMC45MSA4MS43MSAzMjAuNTAgQyA4Mi4zMSAzMjAuMjUgODIuOTAgMzIwLjAxIDgzLjQ5IDMxOS43NyBDIDg0LjQ5IDMxNC42MiA4Ny4wMSAzMTAuNDkgODcuMDAgMzA1LjAwIEMgODYuOTUgMjk3LjY3IDg3LjA0IDI5MC4zMyA4Ni45NSAyODMuMDAgQyA4Ni45NiAyNzkuODMgODQuNzUgMjc3LjM0IDgzLjQ2IDI3NC41NCBDIDc3Ljk3IDI2My41MSA3Ni43NyAyNTEuMDIgNzUuMDcgMjM5LjAwIEMgNzQuODAgMjMyLjM4IDczLjY4IDIyNS41NSA3NC4zOSAyMTkuMDAgQyA3NC45OCAyMDEuNzEgNzkuNTcgMTg2LjAxIDgyLjIxIDE2OS4wMSBDIDgzLjM2IDE2NC4xNyA4My4wMiAxNTguOTUgODIuOTAgMTU0LjAwIEMgODEuMDQgMTQ1LjE1IDc4LjM4IDEzNi40OCA3Ni40OCAxMjcuNjUgQyA3NS43NyAxMzkuMzMgNzQuNzkgMTUwLjY1IDcxLjcwIDE2Mi4wMCBDIDY2Ljc5IDE3OS40NyA1OC4wNyAxOTQuMDIgNTEuNTUgMjEwLjU1IEMgNDguMTMgMjE5LjEzIDQ3LjA1IDIyNy44OCA0NS44OCAyMzYuOTYgQyA0NC42MyAyNDIuMzcgMzguOTkgMjQ0LjA1IDM0LjA4IDI0My42MSBDIDMxLjQ0IDI0My4wNyAzMC4wMCAyNDAuNjMgMjkuNzQgMjM4LjEwIEMgMjguOTkgMjMyLjgyIDMwLjM3IDIyOC4xMCAzMC45OCAyMjIuOTcgQyAyOC4xNSAyMjQuNjggMjYuMjMgMjI2LjkyIDIyLjk5IDIyNy45OSBDIDIxLjA1IDIyNy42NyAxOS4yNSAyMjUuMzkgMjAuNTIgMjIzLjQ4IEMgMjIuMTcgMjIwLjE5IDI1LjE2IDIxNy4zNCAyNy40OSAyMTQuNTAgQyAzMC44NyAyMTAuMjYgMzQuNTMgMjA2LjIwIDM3Ljc4IDIwMS44NiBDIDQyLjk0IDE5NC41NiA0Mi40NCAxODQuOTIgNDMuNzEgMTc2LjUxIEMgNDUuMDQgMTY1LjE3IDUyLjc5IDE1Ni4wNCA1Ni4xNSAxNDUuMDQgQyA1OC4zMSAxMzguNzYgNTguMDQgMTMyLjU0IDU3Ljk1IDEyNi4wMCBDIDU3LjUzIDExOS4zNiA1Ny42OSAxMTIuNjQgNTcuOTggMTA2LjAwIEMgNTguNjkgOTguMTggNjAuODkgOTAuMjggNjYuNTggODQuNTggQyA2OC43MSA4Mi4yNiA3MS4zNCA4MC44NCA3My44MiA3OC45MiBDIDc2LjAyIDc4LjA0IDc4LjI5IDc3LjMwIDgwLjUxIDc2LjQ3IEMgODUuOTQgNzQuNjggOTIuNTAgNzMuNzkgOTcuMDAgNzAuMDEgQyAxMDAuODYgNjYuNTMgMTAxLjI1IDYwLjg2IDEwMC45NCA1Ni4wMSBDIDk5LjY0IDU0LjAyIDk3LjU0IDUyLjc0IDk2LjUxIDUwLjQ2IEMgOTMuODIgNDUuMjEgODkuMTUgNDAuMjggODkuNzcgMzMuOTkgQyA4OS44NCAzMC4xNiA5Mi43NSAyOC4yMSA5My40OSAyNC40NiBDIDk0LjUyIDE5LjgxIDk2LjIwIDE1LjA3IDEwMC4yNSAxMi4yMSBDIDEwNy40MSA3LjA5IDExNy41OCA4LjIzIDEyNC4xMSAxMy44MyBaIiBmaWxsPSIjODE4MTgxIiAvPgo8cGF0aCBkPSJNIDMwNC45OCA5LjYyIEMgMzEwLjIyIDkuNjAgMzE1LjUyIDEwLjEyIDMyMC4xOCAxMi43MiBDIDMyNC45OSAxNS41OSAzMjcuMjMgMjEuNjEgMzI3LjExIDI3LjAwIEMgMzI3LjE5IDMyLjU5IDMyOC40MCAzOS40MiAzMjYuNzEgNDQuNzcgQyAzMjQuODUgNDguNTkgMzIyLjUyIDUxLjQ5IDMyMi4xMyA1NS45OCBDIDMyMi4zNyA1OC41NiAzMjEuMzggNjAuNzAgMzIyLjg3IDYzLjA0IEMgMzI0LjQ4IDY2LjQ3IDMyNy41MCA2Ny45NyAzMzAuODcgNjkuMjIgQyAzNDAuMDMgNzIuOTMgMzQ5LjM5IDc2LjQ0IDM1Ni4xNyA4My45NSBDIDM2Mi4yOCA5MC44NiAzNjMuNTYgMTAwLjEyIDM2Mi41NSAxMDkuMDEgQyAzNjEuOTEgMTE1LjAzIDM2MS43NiAxMjAuOTkgMzYyLjU2IDEyNy4wMSBDIDM2My44NiAxNDQuMjMgMzcyLjMwIDE1OS42NCAzNzcuMTggMTc1Ljk0IEMgMzc4LjY4IDE4MC42MyAzNzkuMjIgMTg1LjAwIDM4MS42NyAxODkuMzIgQyAzODYuMzEgMTk3LjY1IDM5My41MCAyMDMuODEgMzk4LjU1IDIxMS41MCBDIDM5OS41MCAyMTMuMDkgNDAwLjU4IDIxNS45NyAzOTguMTAgMjE2Ljc1IEMgMzk1Ljc0IDIxNy4yNSAzOTIuOTIgMjE1LjcyIDM5MC43MyAyMTQuOTAgQyAzOTAuNjggMjIxLjAxIDM5Mi42NiAyMjYuNzIgMzkwLjk3IDIzMi45MCBDIDM4OC41MiAyMzYuMTkgMzgzLjc3IDIzNi40NCAzODAuMDcgMjM1Ljc2IEMgMzc0LjA5IDIzMy44MCAzNzAuOTcgMjI2LjczIDM2OS45MiAyMjEuMDAgQyAzNjkuMTQgMjE0LjY5IDM3MC40OCAyMDYuMjEgMzY3LjY5IDIwMC4yOCBDIDM2My4zNCAxOTMuNTkgMzU4Ljk1IDE4Ni45NCAzNTQuOTcgMTgwLjAyIEMgMzQ5Ljc2IDE3MS4wMiAzNDUuMzkgMTYxLjY3IDM0NC42MSAxNTEuMTUgQyAzNDMuNjggMTQzLjcyIDM0Mi4yNSAxMzYuMDQgMzQyLjU1IDEyOC41NCBDIDM0Mi4yNCAxMjkuMzMgMzQxLjU4IDEyOS43NiAzNDAuNTcgMTI5LjgyIEMgMzQwLjY3IDEyNS4yMCAzNDIuNzcgMTIwLjcwIDM0Mi45NCAxMTUuOTkgQyAzNDMuMDYgMTE0Ljk1IDM0My4yMyAxMTEuNzUgMzQ0LjkxIDExMi4xMiBDIDM0NS4yNSAxMTIuOTkgMzQ1LjMxIDExMy45NSAzNDUuMDggMTE1LjAxIEMgMzQzLjc0IDEyMi42OSAzNDQuODcgMTMxLjIxIDM0NS4wOSAxMzkuMDAgQyAzNDUuMjMgMTQzLjM1IDM0NS45MSAxNDcuNjQgMzQ2LjIyIDE1MS45OCBDIDM0OC45MiAxNjguNDYgMzU4LjQwIDE4Mi45MCAzNjcuNDMgMTk2LjU3IEMgMzcyLjA4IDIwNC40NSAzNzAuNDkgMjEyLjQ1IDM3MS43MyAyMjEuMDEgQyAzNzIuMTMgMjI0LjM2IDM3NC4wMiAyMjYuNTYgMzc1LjU3IDIyOS40NCBDIDM3Ni41MSAyMzAuODQgMzc3LjI4IDIzMi45NCAzNzkuMjIgMjMzLjA4IEMgMzc5LjMxIDIyOS45OCAzNzcuNjEgMjI2Ljg0IDM3Ny40NiAyMjMuNjUgQyAzNzkuMTAgMjI2LjcxIDM3OS4yOCAyMzAuNzggMzgxLjE2IDIzMy44MyBMIDM4My4zMSAyMzQuMDMgQyAzODMuNjkgMjMwLjUyIDM4MS45NiAyMjcuNDggMzgyLjI1IDIyNC4wMCBDIDM4Mi4zNiAyMjIuNTEgMzgyLjE1IDIyMS41NSAzODEuNTEgMjIwLjIzIEwgMzgyLjQ1IDIyMC41MyBDIDM4Mi43MSAyMjQuOTkgMzgzLjEyIDIyOS4yNSAzODQuNDYgMjMzLjUzIEMgMzg1LjIzIDIzMy45MSAzODYuMTMgMjM0LjA2IDM4Ny4xNiAyMzMuOTggQyAzODcuOTkgMjMyLjcxIDM4Ni45NSAyMzAuODMgMzg2LjcxIDIyOS40NCBDIDM4NS44NCAyMjYuMzcgMzg2LjczIDIyMy4zMyAzODUuMzggMjIwLjMwIEMgMzg3LjEyIDIyMS44NSAzODYuNTQgMjIzLjg3IDM4Ni43NiAyMjYuMDAgQyAzODYuNzQgMjI4LjQwIDM4Ny42MiAyMzAuNTUgMzg4LjAzIDIzMi45NSBDIDM4OC43NyAyMzIuODggMzg5LjI4IDIzMi4yNCAzODkuNTUgMjMxLjAzIEMgMzkwLjE4IDIyNC41NSAzODguMTcgMjE3Ljc4IDM4OC40OSAyMTEuMzkgQyAzOTEuNjUgMjExLjQ5IDM5NC4yMiAyMTQuNDAgMzk3LjYzIDIxNC41MyBDIDM5Ny41NCAyMTMuNzEgMzk3LjI1IDIxMi45NCAzOTYuNzUgMjEyLjI1IEMgMzk0LjM2IDIwOC42OSAzOTEuNjEgMjA1LjQ0IDM4OC42NCAyMDIuMzcgQyAzODQuNzEgMTk3LjgwIDM4MS4xMSAxOTIuNjYgMzc4Ljk0IDE4Ny4wMSBDIDM3Ni40NiAxODEuNDMgMzc1LjQzIDE3NS41MSAzNzMuMzIgMTY5LjgxIEMgMzY5LjY3IDE1OS43OSAzNjUuMzMgMTUwLjQ2IDM2Mi45MiAxNDAuMDAgQyAzNjAuMTIgMTI4LjczIDM2MC4wOCAxMTcuNTIgMzYwLjcxIDEwNi4wMCBDIDM2MC4zMyA5OS4zNiAzNjAuMTIgOTMuMjcgMzU2LjUyIDg3LjQ0IEMgMzUyLjUyIDgwLjIxIDM0My41OSA3Ni45NSAzMzYuNDggNzMuNTggQyAzMzAuMTIgNzAuNjEgMzIyLjc1IDY5LjM4IDMyMC4wNyA2MS45NyBDIDMxNy41NyA1My4yNSAzMjYuMjggNDUuNDggMzI1Ljk5IDM3LjAwIEMgMzI2LjA1IDMxLjYwIDMyNi4xNiAyNS4xMiAzMjQuMDIgMjAuMDUgQyAzMjEuNTAgMTQuNTQgMzE1LjYzIDEyLjQxIDMxMC4wMSAxMS43MCBDIDMwNC43NiAxMC44NCAyOTcuNzYgMTEuNzMgMjk0LjIzIDE2LjE5IEMgMjkxLjQzIDE5LjA1IDI5MS4xOCAyNC4yMCAyOTAuODIgMjguMDAgQyAyOTAuNzMgMzEuMjcgMjg4LjY5IDMzLjcxIDI4OC45OCAzNy4wMCBDIDI4OC45OCA0Mi4xNiAyOTMuNTQgNDYuOTcgMjk0LjkyIDUyLjA1IEMgMjk1Ljk4IDU1Ljk5IDI5Ny4yMiA2MC43MSAyOTMuOTYgNjMuOTkgQyAyODUuOTcgNzMuMDMgMjcwLjE5IDc0LjY4IDI2MC40MCA4MS4zOSBDIDI1Ny44MCA4My41OCAyNTUuNDggODUuODUgMjU0LjI1IDg5LjEwIEMgMjUyLjMwIDk0LjQ0IDI1MS43NCAxMDAuMzQgMjUyLjA4IDEwNi4wMCBDIDI1Mi44MCAxMTcuNDIgMjUxLjMzIDEyOC44NiAyNDguOTAgMTQwLjAwIEMgMjQ3LjM0IDE0Ny40NCAyNDIuNzQgMTUyLjgyIDIzOS41MSAxNTkuNTIgQyAyMzYuNjAgMTY0Ljg1IDIzNi4zMiAxNzAuMzIgMjM0LjY4IDE3NS45MiBDIDIzMi4yMiAxODMuNzEgMjI3LjQxIDE5MS4xMSAyMjIuODAgMTk3LjgxIEMgMjIwLjEyIDIwMS42NSAyMTYuNzIgMjA0LjYyIDIxMy4yMyAyMDcuNjcgQyAyMTUuOTUgMjA4LjI2IDIxOC40MyAyMDcuODQgMjIxLjI0IDIwNy44MiBMIDIyMS41MCAyMDguOTUgQyAyMjAuMjAgMjE0LjM4IDIxOC4zMSAyMjAuMzcgMjE4LjE3IDIyNi4wMSBDIDIxOS41NyAyMjguMTUgMjE4LjMxIDIzMC44MSAyMjAuMDcgMjMyLjUwIEMgMjIyLjI0IDIzMC4yNCAyMjMuNjEgMjI3LjAwIDIyNS4zMyAyMjQuMzQgQyAyMjYuMzAgMjIzLjAyIDIyNi42OCAyMjAuMDcgMjI4LjY4IDIyMC4yNSBDIDIyNy4wNiAyMjQuOTEgMjIzLjkxIDIyOC42NCAyMjEuOTMgMjMzLjA2IEwgMjIzLjA1IDIzMy40OCBMIDIyMy45NyAyMzMuMDMgQyAyMjYuMjkgMjI5LjMyIDIyOC43OSAyMjUuMDcgMjMxLjk1IDIyMi4wNyBMIDIzMi4xOSAyMjMuMDQgQyAyMzAuODMgMjI2LjM3IDIyNi45OCAyMjkuMTkgMjI2LjI2IDIzMi42OCBDIDIyOC44NCAyMzAuNzcgMjMxLjExIDIyOC41MiAyMzIuNzIgMjI1LjczIEMgMjM4LjQ4IDIxNi43NCAyMzcuMDEgMjA0LjkwIDI0MS43OCAxOTQuODggQyAyNDguMDggMTgyLjY4IDI1Ni44NiAxNzAuNzggMjYyLjE5IDE1OC4xMiBDIDI2Ni42NSAxNDguMjQgMjY4LjEwIDEzNi43NiAyNjguMDIgMTI2LjAwIEMgMjY4Ljc4IDEyMS4zMiAyNjcuNTAgMTE2Ljc4IDI2OC4wOCAxMTIuMDcgTCAyNjkuOTIgMTEyLjA4IEMgMjY5LjQ5IDEyNS40MCAyNzUuMzMgMTM4LjM4IDI3NS4wMiAxNTIuMDAgQyAyNzQuOTcgMTU0LjY3IDI3NS4wNiAxNTcuMzMgMjc1LjAyIDE2MC4wMCBDIDI3My44NCAxNzYuNDEgMjcyLjUwIDE5Mi42MSAyNzAuODQgMjA4Ljk5IEMgMjY5Ljk4IDIxNC42MCAyNjkuMzYgMjIwLjMzIDI2OS4wMCAyMjYuMDAgQyAyNjkuNzYgMjM4Ljg1IDI3My4wNCAyNTIuMjMgMjc1LjA5IDI2NC45NyBDIDI3Ni45NSAyNzYuMzkgMjc4LjczIDI4OC40NiAyNzcuMjcgMzAwLjAxIEMgMjc2Ljk3IDMwNi44OCAyNzQuNTUgMzEzLjE4IDI3My44NyAzMjAuMDEgQyAyNzIuOTAgMzI1Ljk5IDI3NC41MSAzMzIuNTkgMjc1Ljg2IDMzOC40MyBDIDI3OS43NCAzNTMuMDUgMjg2LjU1IDM2NS45MyAyODQuNzkgMzgxLjY2IEMgMjgyLjY1IDM4Mi42OCAyODAuMzUgMzgzLjI1IDI3OS45OSAzODUuOTkgQyAyODAuNTkgMzg4LjQ3IDI4My4wNiAzOTAuNTYgMjg1LjAyIDM5Mi4wNSBDIDI4OC40NiAzOTQuMjYgMjkyLjU2IDM5Ni4yNCAyOTYuNjggMzk0LjY4IEMgMjk3LjA1IDM5NC4wOSAyOTcuNDAgMzkzLjQ5IDI5Ny43NCAzOTIuODggQyAyOTkuMTMgMzg2LjE4IDI5OC4xNiAzNzguOTIgMjk3LjUwIDM3Mi4wMSBDIDI5NS4wNCAzNTcuNTcgMjk3LjkwIDM0NC4zOCAyOTguNTkgMzMwLjAwIEMgMjk4LjMwIDMyMy4zMiAyOTcuMzUgMzE2LjY2IDI5Ni45NiAzMTAuMDAgQyAyOTcuMzcgMjk5LjQ4IDI5OC40NSAyODkuMzcgMjk5LjQ3IDI3OC45OSBDIDMwMC4zMCAyNzAuOTQgMjk5LjkwIDI2My4xMSAyOTkuOTcgMjU1LjAwIEMgMzAwLjkzIDI0MC4wMyAzMDIuMzggMjI1LjIwIDMwMy44NSAyMTAuMjggQyAzMDMuMjUgMjEwLjY3IDMwMi42NSAyMTEuMDQgMzAyLjAzIDIxMS40MCBDIDI5Ny4xOCAyMTIuMDEgMjkzLjY4IDIxNC43MiAyODguNDQgMjEzLjc4IEMgMjg3LjIyIDIxMy40MCAyODYuNDcgMjEzLjY1IDI4NS4yOSAyMTMuOTQgQyAyODMuNjUgMjEyLjg3IDI4MS45MiAyMTMuMDcgMjgwLjA2IDIxMi45MyBDIDI3OS42MCAyMTIuMDcgMjc5LjU4IDIxMS4wNyAyNzkuOTkgMjA5Ljk0IEMgMjg0Ljc0IDIwOS45NyAyODkuMTkgMjExLjIzIDI5My45OSAyMTAuNjMgQyAyOTYuODYgMjA5LjY3IDI5OS42NyAyMDguOTAgMzAxLjkyIDIwNi43NSBDIDMwMy40NiAyMDUuMjUgMzA1LjAwIDIwNS44OSAzMDYuOTAgMjA2LjAwIEMgMzA3LjMwIDIwOC40OSAzMDkuMzEgMjA5LjUyIDMxMS4yNSAyMTAuNzUgQyAzMTUuMzMgMjEzLjA3IDMxOS43NSAyMTMuMDggMzI0LjE5IDIxMS44NCBDIDMyNC4yNyAyMTIuNjggMzIzLjc3IDIxMy4zMCAzMjIuNjkgMjEzLjcxIEMgMzE5Ljk0IDIxNC4yOSAzMTcuMTEgMjE0LjE4IDMxNC4zNiAyMTQuODkgQyAzMTMuNDAgMjE0LjM1IDMxMi4zNSAyMTMuOTggMzExLjIzIDIxMy44MCBDIDMwOS4xMiAyMTEuODMgMzA2Ljk5IDIxMi40MyAzMDUuNDMgMjA5LjQ3IEMgMzA2LjE3IDIxNi4yOSAzMDYuMDUgMjIzLjE3IDMwNi45NyAyMzAuMDAgQyAzMDYuODkgMjM3LjAwIDMwNy41NSAyNDQuMjIgMzA2LjIxIDI1MS4wOSBDIDMwNS41NCAyNTkuMDEgMzA1LjM1IDI2Ny4wNyAzMDUuOTYgMjc1LjAwIEMgMzA1Ljk0IDI4My43OSAzMDguMDUgMjkzLjE4IDMwNy4wNSAzMDIuMDAgQyAzMDcuMDQgMzA5LjM1IDMwNS40NyAzMTYuNjcgMzA0Ljk4IDMyNC4wMCBDIDMwNC4yNSAzMzEuMDQgMzA1LjMzIDMzOC4zOSAzMDYuNTUgMzQ1LjMzIEMgMzA5LjAzIDM1OS40NyAzMDUuNzEgMzcyLjA0IDMwNC42OSAzODYuMDAgQyAzMDQuNjIgMzg5LjEzIDMwNC45OSAzOTMuMjQgMzA4LjI0IDM5NC43MiBDIDMxMy41MSAzOTYuMjMgMzE5Ljc5IDM5Mi44MyAzMjIuMDUgMzg3Ljk4IEMgMzIyLjkxIDM4NS42OSAzMjAuNDMgMzg1LjE0IDMxOS4xNCAzODMuODUgQyAzMTUuNTAgMzgwLjEyIDMxNS4yNiAzNzQuNzEgMzE2LjkzIDM2OS45OSBDIDMyMC4wNiAzNTguNDQgMzIyLjYwIDM0Ni43MiAzMjUuNDIgMzM1LjA5IEMgMzI2LjcwIDMyOC43MSAzMjkuNTQgMzIxLjQ5IDMyOC4zNCAzMTQuOTkgQyAzMjcuNzggMzA4LjU2IDMyNi4zMiAzMDIuNTEgMzI2LjQwIDI5Ni4wMCBDIDMyNS45NSAyNjguMTAgMzM3LjM0IDI0My40OCAzMzguMDAgMjE1LjAwIEMgMzM4LjEwIDIwMS4wMyAzMzYuMzYgMTg3LjAzIDMzNS44MiAxNzMuMDkgQyAzMzUuNTQgMTY4LjA3IDMzNC45NiAxNjMuMDMgMzM0Ljk3IDE1OC4wMCBDIDMzNS41OCAxNDguNjAgMzM3LjQ4IDEzOS40MCAzNDAuMDUgMTMwLjM0IEwgMzQxLjQxIDEzMC4yNCBDIDM0MC4wMiAxNDAuMDcgMzM1Ljg3IDE0OC42MyAzMzcuMTQgMTU4Ljk0IEMgMzM2LjY1IDE2Ni4zNyAzMzguMDggMTczLjU1IDMzOC4xNCAxODAuOTkgQyAzMzkuMDIgMTg4LjY0IDMzOS4yMyAxOTYuMzIgMzM5LjgxIDIwMy45OSBDIDM0MC4yOSAyMTUuNjYgMzM5LjQ5IDIyNy41NSAzMzcuMjcgMjM5LjAyIEMgMzMzLjQ1IDI2MS4wMiAzMjYuNTIgMjgyLjM5IDMyOS4xNiAzMDQuOTkgQyAzMzAuODkgMzE0LjM4IDMzMC4wMyAzMjMuNzMgMzI3LjgwIDMzMi45NiBDIDMyNC43OCAzNDYuMzggMzIxLjQ3IDM1OS43MiAzMTguMjMgMzczLjA5IEMgMzE3LjkxIDM3NS40NiAzMTcuNDkgMzc4Ljg2IDMxOS4yNCAzODAuNzggQyAzMjAuNTcgMzgyLjg4IDMyMy41MyAzODMuMjQgMzI0LjY1IDM4NS4zNiBDIDMyNC45MiAzODkuOTggMzIwLjUzIDM5My44NSAzMTYuNzAgMzk1LjY2IEMgMzEzLjEwIDM5Ny42NCAzMDcuNDEgMzk3Ljg1IDMwNC41MSAzOTQuNTMgQyAzMDIuMjEgMzkxLjgxIDMwMy4xNiAzODcuMzcgMzAzLjAwIDM4NC4wMCBDIDMwMy43NiAzNzUuNjYgMzA1LjAwIDM2Ny4zNyAzMDUuNjUgMzU5LjAwIEMgMzA1LjQ1IDM0OC42OCAzMDIuNDggMzM4LjI4IDMwMi45OCAzMjguMDAgQyAzMDIuNzEgMzIzLjU1IDMwMy43NSAzMTkuMzcgMzA0LjM2IDMxNC45OSBDIDMwNy43NiAyOTYuMjYgMzAyLjU0IDI3Ni43NSAzMDQuMzYgMjU4LjAwIEMgMzA0LjY0IDI1MS42NCAzMDUuMjEgMjQ1LjM4IDMwNC45OCAyMzkuMDAgQyAzMDQuODMgMjMzLjQ2IDMwNS40MCAyMjcuNzQgMzA0LjUxIDIyMi4yNyBDIDMwMy4zNyAyMzMuNDQgMzAxLjY1IDI0NC40NSAzMDEuNDggMjU1LjcxIEMgMzAxLjY5IDI2Ny40MiAzMDIuNDQgMjc4LjM4IDMwMC4wNyAyOTAuMDAgQyAyOTguMzYgMjk4LjAxIDI5OS4xOSAzMDUuODcgMjk5LjAxIDMxNC4wMCBDIDI5OS4zNSAzMjAuMDQgMzAwLjQ0IDMyNS45MSAyOTkuOTMgMzMyLjAwIEMgMjk5LjM1IDMzOC42NiAyOTkuMjAgMzQ1LjM2IDI5OC40NSAzNTIuMDAgQyAyOTcuMTEgMzY1LjY5IDMwMi44OSAzNzguNjUgMjk5LjYzIDM5Mi45MiBDIDI5OS4yNiAzOTQuODAgMjk4LjM0IDM5NS43NSAyOTYuOTggMzk2Ljk4IEMgMjkyLjk0IDM5Ny4zNCAyODkuNjQgMzk2Ljg1IDI4Ni4wNiAzOTQuOTAgQyAyODMuMDEgMzkzLjI1IDI3OC42OSAzOTAuNjkgMjc3LjkyIDM4Ny4wMyBDIDI3Ny43MiAzODMuNTYgMjgyLjAzIDM4Mi4yMSAyODIuOTQgMzc5Ljk5IEMgMjgzLjQ2IDM3Mi45NSAyODEuODAgMzY2LjcxIDI4MC40NSAzNTkuOTEgQyAyNzguMTMgMzQ5LjkzIDI3My4wNyAzNDAuMTUgMjcxLjk1IDMzMC4wNCBDIDI3MS4xOSAzMjIuNjUgMjcyLjkzIDMxNi4yMyAyNzQuMDQgMzA5LjAxIEMgMjc1Ljc3IDI5OS43MCAyNzYuODcgMjkwLjUyIDI3NS4xNSAyODEuMTAgQyAyNzMuNjcgMjY1LjkzIDI3MC4zNyAyNTEuMDcgMjY4LjI4IDIzNi4wMCBDIDI2Ny42MSAyMjkuMjggMjY3LjU4IDIyMi43MSAyNjguMjggMjE1Ljk4IEMgMjY5LjE2IDIxMS4yMCAyNjguOTQgMjA2LjM0IDI2OS43NyAyMDEuNTMgQyAyNzAuOTUgMTg0LjA2IDI3My41OSAxNjYuNTIgMjczLjM1IDE0OS4wMCBDIDI3My4zNiAxNDMuMTEgMjcxLjYwIDEzNy43NSAyNzAuNzIgMTMyLjAxIEwgMjcwLjE5IDEzMi4yNSBDIDI2OS4xMSAxMzYuMDcgMjY5LjQwIDE0MC4yNCAyNjguNDMgMTQ0LjE1IEMgMjY3LjEwIDE1My40MyAyNjIuOTMgMTYwLjcwIDI1OS4yMiAxNjkuMTAgQyAyNTMuNzIgMTc5Ljg4IDI0NS4xNSAxODkuMjQgMjQxLjU2IDIwMS4xMSBDIDIzOS40MyAyMDguNTggMjM5LjkwIDIxOC43NiAyMzUuMjggMjI1LjI3IEMgMjMyLjM5IDIyOC44OSAyMjkuMjAgMjM0LjA0IDIyNC43MCAyMzUuNjggQyAyMjEuMjkgMjM2LjM0IDIxNy44MSAyMzMuNzIgMjE2LjAyIDIzMS4wMCBDIDIxNC42OSAyMjguMzYgMjE2LjQwIDIyNC43OSAyMTYuODIgMjIxLjk5IEMgMjE3LjQxIDIxOC4wMiAyMTguOTggMjE0LjA0IDIxOC45NyAyMTAuMDMgQyAyMTYuNzQgMjEwLjAwIDIxNC4xOSAyMTAuNzAgMjEyLjA4IDIwOS45NyBDIDIxMC41NCAyMDguOTAgMjEwLjU3IDIwNy44NCAyMTAuOTYgMjA2LjE0IEMgMjE2LjkyIDIwMy4yMyAyMjAuNjIgMTk4LjQ1IDIyNC4yNCAxOTMuMDkgQyAyMjcuMzMgMTg4LjM0IDIyOS45MiAxODMuMjggMjMxLjkzIDE3Ny45OCBDIDIzMy41NiAxNzMuNTUgMjMzLjk2IDE2OC44OCAyMzUuNDEgMTY0LjQxIEMgMjM2Ljg2IDE1OS41NyAyNDAuMDkgMTU1LjAxIDI0Mi41MSAxNTAuNTQgQyAyNDguNjkgMTQwLjA4IDI1MC42MiAxMjYuOTYgMjUxLjAwIDExNS4wMCBDIDI1MC42NyAxMDUuMTggMjQ4LjQ5IDkzLjE4IDI1NC42NyA4NC42MyBDIDI2MS4wNCA3NS44MyAyNzIuNDcgNzQuMzAgMjgxLjQ3IDY5LjQxIEMgMjg2LjU1IDY2Ljg5IDI5Mi4zOCA2NC4wMCAyOTMuOTMgNTguMDIgQyAyOTQuNzUgNTAuOTMgMjg5LjI3IDQ3LjA0IDI4Ny40NCA0MC45MSBDIDI4NS45NyAzNi44OSAyODguNjEgMzIuMjAgMjg4LjkxIDI4LjAyIEMgMjg4Ljk4IDIzLjQ5IDI4OS43OCAxOC40MyAyOTIuODMgMTQuODkgQyAyOTUuNzIgMTEuMjQgMzAwLjQ3IDkuNzMgMzA0Ljk4IDkuNjIgWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSAxMjUuNjMgMTguNDAgQyAxMjguMzUgMjIuMDcgMTI4LjEzIDI1Ljk4IDEyOS45OSAyOS45OCBDIDEzMS41OSAzMy41NSAxMzIuMTQgMzcuMzAgMTI5LjU1IDQwLjU3IEMgMTI1LjU1IDQ1LjUwIDEyNS40NiA1MS4yOSAxMjAuNzIgNTUuNzIgQyAxMTcuNzUgNTkuMTAgMTEzLjAxIDU5LjgzIDEwOC45MCA1OC4zMiBDIDEwMy4wMSA1Ni4xMCA5OS4wNCA1MS40MCA5Ni4zNSA0NS44NiBDIDk0Ljg2IDQyLjQxIDkyLjAxIDQwLjU4IDkxLjM5IDM2Ljc1IEMgOTAuOTMgMzMuNzIgOTMuMDggMzAuMTggOTQuODAgMjcuODEgQyA5NS45MCAyMi40NyA5Ni40NyAxNy43NiAxMDEuMDkgMTQuMTcgQyAxMDguNjkgOC4xNyAxMjAuMjEgMTAuNzQgMTI1LjYzIDE4LjQwIFoiIGZpbGw9IiNmZmZmZmYiIC8+CjxwYXRoIGQ9Ik0gMTA1LjkxIDI5Ljk1IEMgMTA2Ljg1IDMxLjA5IDEwNy43NSAzMi4xMSAxMDYuNDUgMzMuNDUgQyAxMDQuOTQgMzUuMzAgMTAxLjc4IDMzLjg3IDEwMi40NyAzMS40NyBDIDEwMy4xNiAyOS42NCAxMDQuMjUgMjkuOTggMTA1LjkxIDI5Ljk1IFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMTE2LjQ1IDMwLjQ2IEMgMTE5LjE1IDI4LjMyIDEyMS42MCAzMi40NiAxMTkuNDUgMzQuNDUgQyAxMTcuMDYgMzYuNzAgMTEzLjU3IDMyLjQzIDExNi40NSAzMC40NiBaIiBmaWxsPSIjODE4MTgxIiAvPgo8cGF0aCBkPSJNIDEwOS4xOCA0Mi4wMiBDIDExMS40NiA0MS45MCAxMTMuNzUgNDIuMDAgMTE2LjAzIDQxLjk5IEwgMTE2LjAzIDQ0LjAyIEMgMTE0LjM0IDQ0LjE4IDExMS44OSA0My41OSAxMTAuNDIgNDQuNDEgQyAxMDkuNjEgNDUuMDcgMTA4Ljc5IDQ1LjI3IDEwNy45OCA0NS4wMSBDIDEwNy42NSA0My43OCAxMDguMDUgNDIuNzggMTA5LjE4IDQyLjAyIFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMTA5Ljk4IDQ2Ljk4IEMgMTExLjY2IDQ2Ljk3IDExMy4zNCA0Ni45NyAxMTUuMDEgNDYuOTggQyAxMTUuMDIgNDguMzMgMTE1LjAzIDQ5LjY4IDExNS4wMyA1MS4wNCBDIDExMy4zNSA1MS4wNSAxMTEuNjYgNTEuMDUgMTA5Ljk4IDUxLjAyIEMgMTA5Ljk4IDQ5LjY3IDEwOS45OCA0OC4zMyAxMDkuOTggNDYuOTggWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSAzMDUuNTMgNzguMzcgTCAzMDYuNzIgNzguMzIgQyAzMDcuMzUgODAuNTkgMzA2LjQ5IDgyLjcwIDMwNi44NCA4NC45OSBDIDMwNy4zNiA4OC44MSAzMDYuNDMgOTMuNDQgMzA4LjA5IDk2Ljk2IEMgMzA3LjAzIDEwMS44MiAzMDguMTkgMTA2LjE3IDMwOC4wMiAxMTEuMDAgQyAzMDcuODggMTE2LjY3IDMwOC4yNiAxMjIuMzggMzA3Ljc5IDEyOC4wMyBDIDMwNy44NSAxMzAuNDYgMzA4LjM0IDEzMi42MiAzMDcuNDYgMTM1LjAwIEMgMzA4LjI0IDEzOC42NiAzMDcuODcgMTQyLjMwIDMwOC4wOCAxNDYuMDIgQyAzMDcuOTYgMTQ2LjkxIDMwOC4yNyAxNDcuNjggMzA5LjAzIDE0OC4zMyBDIDMwNy45NCAxNTEuNjggMzA3Ljk3IDE1NS41MiAzMDguMTMgMTU5LjAwIEMgMzA4LjYxIDE2MS43NyAzMDcuNTAgMTY0LjA3IDMwOS4wOCAxNjYuNjggQyAzMDcuMTUgMTY4LjEzIDMwOC4yMSAxNjkuOTMgMzA3Ljk2IDE3Mi4wNCBMIDMwNi44NyAxNzIuMDQgQyAzMDcuMTMgMTYxLjg3IDMwNy4xMyAxNTEuNjIgMzA2LjczIDE0MS40NiBMIDMwNS45OCAxNDAuNzUgQyAzMDYuNDAgMTM4LjM4IDMwNi41NSAxMzYuMzAgMzA2LjAxIDEzMy45MyBDIDMwNi4xMyAxMzMuMjggMzA2LjQyIDEzMi42NSAzMDYuODkgMTMyLjA0IEMgMzA2LjUyIDEyOC4zNiAzMDYuMTkgMTI0LjQ2IDMwNi41NyAxMjAuNzcgQyAzMDYuOTEgMTEzLjgzIDMwNi41MSAxMDYuOTQgMzA2LjMzIDEwMC4wMCBDIDMwNS43MSA5Mi43MyAzMDYuMzYgODUuNjIgMzA1LjUzIDc4LjM3IFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMTM5LjAwIDgxLjA1IEwgMTM5LjAxIDgyLjAxIEMgMTM0LjYzIDgyLjA0IDEzMC4yNCA4Mi4wMCAxMjUuODUgODIuMDYgTCAxMjYuMDIgODEuMDIgQyAxMjkuOTIgNzguOTcgMTM1LjAxIDgwLjI0IDEzOS4wMCA4MS4wNSBaIiBmaWxsPSIjODE4MTgxIiAvPgo8cGF0aCBkPSJNIDk0LjA2IDgwLjkyIEMgOTYuMjUgODIuMDYgOTcuNTQgODIuMTAgMTAwLjAyIDgyLjAwIEwgMTAwLjAyIDgyLjk5IEMgOTcuODcgODIuODkgOTYuNzkgODMuMDQgOTUuMDAgODQuMjMgQyA5Mi43NSA4Mi41MCA5MC41MyA4My4wOSA4Ny44OSA4My4wNyBDIDg3LjUzIDgwLjgzIDkyLjcxIDgxLjQzIDk0LjA2IDgwLjkyIFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMzE1Ljk5IDExNS45MyBDIDMxOC40NiAxMTUuMDUgMzE4LjY5IDExOC4xOCAzMjAuODAgMTE5LjIzIEMgMzIxLjIyIDEyMi4wNiAzMjQuODQgMTIwLjkxIDMyNS4xMSAxMjMuMDMgQyAzMjEuNDcgMTIzLjY0IDMxOS4xOCAxMjEuNDggMzE3LjM2IDExOC42MyBDIDMxNi4wOCAxMTguMTUgMzE1LjYyIDExNy4yNiAzMTUuOTkgMTE1LjkzIFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMjgzLjg3IDExOC45OSBDIDI4Ni4zNyAxMTguNzIgMjg4LjI3IDEyMi4xNCAyOTEuMDAgMTIxLjk5IEMgMjkzLjMxIDEyMi4xMSAyOTUuMzQgMTE5LjQ3IDI5Ny4wNSAxMTguODUgQyAyOTcuNjYgMTIyLjEzIDI5NC43MyAxMjEuMzkgMjkzLjg1IDEyNC4wMCBDIDI5MC4xNyAxMjQuNzcgMjg4LjQ0IDEyMi41OCAyODUuMTQgMTIxLjg5IEMgMjg0LjYyIDEyMC45NCAyODQuMjAgMTE5Ljk4IDI4My44NyAxMTguOTkgWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSAxNDEuMDQgMTI2LjgyIEwgMTQwLjk4IDEyOC44NiBDIDEzOC45MSAxMjkuMzAgMTM3LjcwIDEzMS4xMyAxMzUuNzQgMTMxLjk4IEMgMTMzLjI3IDEzMS45NSAxMzAuNjQgMTMyLjI2IDEyOC4yMCAxMzEuODcgQyAxMjYuMTkgMTMwLjk5IDEyNC4yNyAxMzAuMzEgMTIyLjE2IDEyOS43MyBDIDEyMS4yNCAxMjkuMzggMTIwLjgyIDEyOC43NiAxMjAuOTAgMTI3Ljg3IEMgMTIyLjg2IDEyOC4yNSAxMjQuNzQgMTI4LjgwIDEyNi42MyAxMjkuNDMgQyAxMjkuMTIgMTMwLjMxIDEzMS41MiAxMjkuODUgMTM0LjAyIDEzMC4zOCBDIDEzNS43NSAxMzAuMDEgMTM3LjUwIDEyOS4wNiAxMzguOTcgMTI4LjA3IEMgMTM5LjYwIDEyNy41MyAxNDAuMjkgMTI3LjExIDE0MS4wNCAxMjYuODIgWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSA4NC44OCAxMjcuOTQgQyA4OC40OCAxMjcuODIgOTAuOTMgMTMwLjU2IDk0LjczIDEzMC4wNSBDIDk2LjYzIDEzMS45OCAxMDEuNDcgMTMxLjAwIDEwMy4yNyAxMjkuMTEgQyAxMDQuNzUgMTI4LjM5IDEwNS4zNSAxMjkuMDEgMTA1LjA2IDEzMC45NiBDIDEwMi4wNiAxMzAuOTAgOTkuMDYgMTMzLjU0IDk1Ljk3IDEzMy4wNSBDIDkzLjE3IDEzMy4wNiA5MS4yNCAxMzAuODMgODguMjYgMTMwLjkxIEMgODcuMzggMTI5Ljc5IDg0Ljg3IDEyOS40NCA4NC44OCAxMjcuOTQgWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSAyODAuODYgMTY2LjAwIEMgMjgyLjUwIDE2NS45NiAyODQuMTQgMTY1Ljk2IDI4NS43NyAxNjYuMDEgQyAyODcuNDcgMTY4LjA3IDI5MC43MiAxNjcuODkgMjkwLjA0IDE3MS4xOCBDIDI4Ny40MCAxNzAuMjcgMjg0LjkxIDE2Ny43OSAyODIuMTAgMTY3Ljk1IEMgMjgxLjM1IDE2Ny40MyAyODAuOTQgMTY2Ljc4IDI4MC44NiAxNjYuMDAgWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSAzMjkuNzkgMTY3LjkzIEMgMzMwLjUwIDE2OC40OCAzMzAuOTMgMTY5LjExIDMzMS4wOSAxNjkuODEgQyAzMjkuNjYgMTcxLjY5IDMyNy45NyAxNzAuODkgMzI1LjkxIDE3MS4wNSBDIDMyNS41MCAxNjcuNzYgMzI3LjgxIDE2OS42NyAzMjkuNzkgMTY3LjkzIFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMTM5LjA0IDE3Ni45NiBMIDEzOS4wMiAxNzcuOTYgQyAxMzcuMzggMTc4LjA2IDEzNi40NiAxNzguMDAgMTM1LjM3IDE3OS4zNiBDIDEzMy41NyAxODEuNTIgMTMwLjc3IDE4MS44MyAxMjguOTIgMTgzLjk3IEMgMTI3LjkxIDE4NS4yOSAxMjcuOTYgMTg3LjExIDEyNS45NCAxODcuMTMgQyAxMjUuODggMTgzLjk1IDEyOC4zOSAxODIuMzYgMTMwLjIwIDE4MC4xNSBDIDEzMy41MiAxNzguOTkgMTM1LjI3IDE3Ni40MiAxMzkuMDQgMTc2Ljk2IFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gOTMuNzQgMTgxLjA5IEMgOTUuMjAgMTgxLjk0IDk4LjIyIDE4My4xMiA5OC4wOCAxODUuMTcgQyA5NC4xNSAxODMuODQgOTAuMDYgMTgxLjUxIDg1Ljg4IDE4Mi4wMCBDIDg2LjI3IDE3OC42MiA5MS42MiAxODEuMjUgOTMuNzQgMTgxLjA5IFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMjIzLjg2IDIxOC4xMCBDIDIyNC40OSAyMjAuNDQgMjIxLjcwIDIyMy42NCAyMjAuNzIgMjI1LjgxIEwgMjE5LjY4IDIyNi4xOSBDIDIxOS40OCAyMjQuNTcgMjIyLjQ4IDIxOS4wOCAyMjMuODYgMjE4LjEwIFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMTI1LjMzIDQyNS42OCBDIDEyOC4zNiA0MjguMjcgMTMwLjk5IDQzMS4wMSAxMzEuNzkgNDM1LjA3IEMgMTMyLjQ1IDQzOS4zOCAxMzIuMDYgNDQzLjY2IDEzMy4wOSA0NDguMDAgQyAxMzMuNzEgNDUxLjQzIDEzNy42NSA0NTIuNzMgMTM3LjA5IDQ1Ni4zNSBMIDEzNi4wNSA0NTYuMzYgQyAxMzQuNjAgNDU0LjM2IDEzMi45NiA0NTIuMjggMTMyLjA1IDQ0OS45NyBDIDEzMC4yMCA0NDMuODYgMTMxLjY3IDQzNi42MyAxMjcuOTkgNDMxLjAwIEMgMTIzLjY2IDQyNS4yOSAxMTYuMTQgNDIyLjE1IDEwOS4wOSA0MjIuMTcgQyAxMDEuODAgNDIyLjkwIDk0Ljk1IDQyNi42NCA5MC42MSA0MzIuNTggQyA4Ny4zNCA0MzcuMDQgODQuNjYgNDQyLjM5IDg0LjMzIDQ0Ny45OSBDIDg0LjIyIDQ1Ny41OSA5MS4zNSA0NjUuNjkgOTEuMjggNDc1LjAwIEMgOTEuNjQgNDgxLjQzIDg4LjkzIDQ4Ny4zMyA4NS43MyA0OTIuNzQgQyA4Mi42MiA0OTcuOTkgNzguMzcgNTAxLjQyIDc2LjM3IDUwNy4xMCBDIDc1LjE4IDUxMS4wNCA3NC4yOSA1MTUuMDYgNzMuMTYgNTE5LjAyIEMgNzAuMjQgNTMxLjIxIDY0LjYwIDU0Mi45NyA2MC44NyA1NTQuOTMgQyA1Ny4wNSA1NjcuMTUgNTUuMzAgNTc5Ljk2IDU1LjA0IDU5Mi43MyBMIDUzLjQzIDU5Mi44NCBMIDUzLjA3IDU5MS4xOSBDIDU0LjAzIDU4My4wNCA1My43NyA1NzUuMDEgNTUuODAgNTY2Ljk4IEMgNTkuMTkgNTUxLjAwIDY1LjQ0IDUzNi43MyA3MC40NCA1MjEuNDUgQyA3Mi4wNiA1MTYuNzQgNzIuODcgNTExLjg0IDc0LjI4IDUwNy4wOCBDIDc1Ljg3IDUwMS45MSA3OS43NCA0OTguODcgODIuNzkgNDkzLjkzIEMgODUuNjcgNDg5LjM2IDg5LjI1IDQ4My41NSA4OS4wMiA0NzguMDAgQyA4OS44OSA0NjcuOTMgODIuMzIgNDU4LjA4IDgyLjYwIDQ0OC4wMCBDIDgyLjQyIDQ0NC4xNyA4My41NSA0NDAuNzAgODUuNDAgNDM3LjQwIEMgODkuMTkgNDMwLjE0IDk0LjkxIDQyNC4xNiAxMDIuODUgNDIxLjYxIEMgMTEwLjQwIDQxOC45MSAxMTkuMDUgNDIwLjkzIDEyNS4zMyA0MjUuNjggWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSAzMDAuOTEgNDIxLjUwIEMgMzA3LjM4IDQyMi4yNiAzMTMuMjcgNDI1LjY1IDMxNy42NiA0MzAuMzYgQyAzMjIuMTQgNDM2LjAxIDMyNy4wNSA0NDMuNDYgMzI2LjAwIDQ1MS4wMCBDIDMyNS4xNSA0NTkuNDUgMzE4LjE5IDQ2OC42OCAzMTkuMDQgNDc4LjAwIEMgMzE5Ljk4IDQ4NS42OCAzMjUuNDMgNDkyLjA0IDMzMC44MSA0OTcuMjAgQyAzMzMuNDIgNTAwLjAzIDMzNi40NiA1MDEuODggMzM3LjQyIDUwNS43OSBDIDMzOS4yNCA1MTIuNDAgMzM5Ljk1IDUxOS4zOSAzNDEuNzkgNTI2LjAwIEMgMzQyLjczIDUyOS40MiAzNDQuMjggNTMyLjU5IDM0NS4yOCA1MzUuOTkgQyAzNDguOTkgNTQ4LjkzIDM1Mi4zNyA1NjEuNTggMzUzLjk3IDU3NS4wMCBDIDM1NC4yMCA1NzguNTYgMzU0LjM3IDU4Mi4wMyAzNTUuMTQgNTg1LjUzIEMgMzU0LjUzIDU4Ni40NCAzNTMuNzcgNTg2LjkzIDM1Mi44NiA1ODcuMDAgQyAzNTIuNzQgNTc0LjEwIDM0OS43MSA1NjEuNTAgMzQ2LjcyIDU0OS4wMyBDIDM0NC4yMCA1MzkuMDIgMzQwLjEwIDUyOS4xNiAzMzguMzEgNTE5LjAwIEMgMzM3LjcwIDUxNC40NSAzMzcuNDcgNTA4LjkxIDMzNS4yMiA1MDQuODQgQyAzMzAuNjAgNDk5LjY3IDMyNS4wNyA0OTQuNzkgMzIxLjE4IDQ4OC44MiBDIDMxOC44MSA0ODUuMzIgMzE2LjU3IDQ4MS4zOCAzMTYuOTYgNDc3LjAwIEMgMzE3LjcxIDQ2OC4xMCAzMjEuODYgNDYxLjQyIDMyMy44NiA0NTIuOTkgQyAzMjYuMDkgNDM4LjA0IDMxMi41MCA0MjMuOTUgMjk4LjAwIDQyMy4wMCBDIDI5MC40NiA0MjMuNjggMjgzLjQ1IDQyNi45NCAyNzkuODggNDMzLjkzIEMgMjc3LjEzIDQzOS4yNyAyNzcuNzkgNDQ0LjU5IDI3Ni41OCA0NTAuMTEgQyAyNzYuMTYgNDUyLjg5IDI3My42MCA0NTQuNDIgMjcyLjk4IDQ1Ni45NiBDIDI3My42NiA0NTguNTkgMjc2LjI1IDQ1OS4xMyAyNzYuODIgNDYxLjA0IEMgMjc3LjQ3IDQ2NS44MiAyNzYuMTggNDcwLjAzIDI3OC4zMSA0NzQuNjggQyAyODAuNzYgNDc4LjQwIDI4Ny44OSA0NzQuOTIgMjg5LjY0IDQ3OS4zNCBDIDI5MS45MyA0ODQuNzIgMjkzLjgyIDQ5MS4xNiAyOTEuODUgNDk2LjkyIEMgMjg4LjA3IDUwOC43OSAyNzkuMDUgNTE5LjM0IDI3NS40MSA1MzEuMjggQyAyNzEuOTQgNTQxLjU1IDI3MC40MSA1NTIuMTkgMjcwLjAwIDU2My4wMCBDIDI2OS44MSA1NzIuOTMgMjcxLjU5IDU4My4yMiAyNzMuMDcgNTkzLjAwIEMgMjc0LjI3IDYwMC41MyAyNzQuNzcgNjA4Ljc1IDI3Ni42NSA2MTYuMDkgQyAyNzguMzIgNjIyLjEyIDI4My43NSA2MjYuNDkgMjg1LjcxIDYzMi4wOSBDIDI4Ny44NyA2NDAuNTIgMjg4LjI3IDY0OS40NiAyODkuOTkgNjU4LjAwIEMgMjkyLjc0IDY3NC40OSAyOTcuMjAgNjkxLjQwIDI5OC4yNCA3MDcuOTkgQyAyOTguNzkgNzExLjQzIDI5OS42MyA3MTQuNzggMzAxLjIzIDcxNy45MCBDIDMwMy4yNiA3MjIuNDQgMzA2LjA3IDcyNS44MSAzMDYuMDIgNzMxLjAwIEMgMzA2Ljc3IDc0MS42NyAzMDguMTQgNzUyLjMzIDMwOS4wMSA3NjMuMDAgQyAzMDkuMjAgNzcwLjgyIDMxMi4yOCA3ODAuMjkgMzEwLjMzIDc4OC4wMiBDIDMxMC4wMSA3OTAuNjIgMzA3LjcyIDc5Mi4zNSAzMDUuNzIgNzkzLjc0IEMgMjk4LjI4IDc5OC4wOSAyOTAuNzYgODAyLjI4IDI4My4xMiA4MDYuMjYgQyAyODAuOTUgODA3LjQxIDI3OC43OSA4MDcuNjcgMjc3LjE5IDgwOS42NiBDIDI3OS4xOCA4MTEuNjQgMjgxLjQxIDgxMS4zMCAyODQuMDAgODExLjQ0IEMgMjkzLjMxIDgxMi4wNyAzMDIuNTQgODExLjYzIDMxMS45OSA4MTEuMTkgQyAzMTUuODcgODEwLjgwIDMyMS4yNSA4MTAuOTUgMzI0LjM4IDgwOC4zOCBDIDMyNi45NSA4MDUuODMgMzI2LjM4IDgwMS4yNSAzMjYuMDcgNzk3Ljk5IEMgMzI2LjA1IDc5MC45NCAzMjQuNTUgNzg0LjA5IDMyNC45OSA3NzcuMDAgQyAzMjQuNTYgNzcwLjUyIDMyNS44NiA3NjQuMzYgMzI2Ljg0IDc1OC4wMCBDIDMyNy44NyA3NDguOTIgMzI5LjU1IDczOS4wMSAzMjcuOTIgNzI5Ljk5IEMgMzI1LjI3IDcxNi4zNSAzMTkuNjQgNzA0LjMyIDMxOS45OSA2OTAuMDAgQyAzMTkuNzcgNjgxLjY2IDMyMC43NiA2NzMuMzMgMzIxLjMyIDY2NS4wMCBDIDMyMi4zNSA2NTguMzMgMzIxLjkwIDY1MS43MiAzMjEuOTggNjQ1LjAwIEMgMzIyLjEwIDY0Mi42NiAzMjEuMjkgNjM5LjYyIDMyMi41NSA2MzcuNTggQyAzMjUuNzQgNjMyLjMxIDMyOC4zNSA2MjYuMTggMzI4Ljg4IDYyMC4wMCBDIDMyNy44OCA2MDkuNDcgMzE4LjYzIDYwMC45NCAzMTcuMTkgNTkxLjAwIEMgMzE2LjMxIDU4NC4zMCAzMTcuOTkgNTc4LjczIDMxOC4wOSA1NzIuMDEgQyAzMTguNzcgNTY3LjY3IDMxOC45MCA1NjMuMjQgMzIwLjE2IDU1OS4wNiBDIDMyMS4xNyA1NTguNzAgMzIxLjg5IDU1OC45MSAzMjIuMzEgNTU5LjY5IEMgMzI1LjU3IDU2My45NiAzMjguNjkgNTY4LjA2IDMzMC43NCA1NzMuMDkgQyAzMzMuNDIgNTc5LjcxIDMzMy41NSA1ODYuOTEgMzM1LjQ0IDU5My45OCBDIDMzNy44NSA2MDUuMDUgMzQxLjYxIDYxNC42MyAzNDEuMjkgNjI2LjAwIEMgMzQxLjQzIDYzMy42OSAzMzguMjUgNjQxLjk5IDMzOS40NiA2NDkuNTUgQyAzNDAuNjMgNjQ5LjM5IDM0MS42NCA2NDkuNDggMzQyLjU1IDY0OC42MSBDIDM0My40NyA2NDYuMjUgMzQzLjc5IDY0My44MyAzNDQuNDIgNjQxLjM5IEMgMzQ2LjEzIDY0MC4zMCAzNDYuMzggNjQxLjczIDM0Ni44OCA2NDMuMDMgQyAzNDguNDIgNjQ4LjQ5IDM1MC4xOCA2NTQuNzYgMzUzLjc0IDY1OS4yNyBDIDM1NS4xNSA2NjAuOTkgMzU3LjU5IDY2My4xNSAzNTkuOTYgNjYyLjk0IEMgMzU4Ljk4IDY1OS45OSAzNTcuODkgNjU3LjA0IDM1Ni43MSA2NTQuMTYgQyAzNTYuMDkgNjUyLjcyIDM1NC43NiA2NTEuOTUgMzU0LjM0IDY1MC40MCBDIDM1NS45OSA2NTAuMjQgMzU2LjUyIDY1MS41MSAzNTcuMzEgNjUyLjcwIEMgMzU5LjA4IDY1NS44NiAzNjAuMTUgNjU5LjQ4IDM2MS4yOCA2NjIuOTAgQyAzNjIuODEgNjYzLjA4IDM2My44OSA2NjIuNDkgMzY1LjI0IDY2MS44OSBDIDM2My44MiA2NTcuODEgMzYxLjI3IDY1My45OCAzNTkuODQgNjQ5Ljg4IEwgMzYwLjg5IDY1MC4wMCBDIDM2My41MyA2NTIuOTIgMzYzLjk5IDY1OC4wOSAzNjYuOTQgNjYwLjY3IEMgMzY3LjgwIDY1OS43OCAzNjguNjMgNjU4Ljg3IDM2OS40MyA2NTcuOTQgQyAzNjcuODIgNjU1LjAxIDM2Ni4xMCA2NTIuMjEgMzY0Ljc2IDY0OS4xMyBDIDM2NC4xNyA2NDcuNjUgMzYyLjMyIDY0NS42NyAzNjIuOTkgNjQ0LjA3IEMgMzY2LjIwIDY0Ni45MSAzNjcuMTIgNjUyLjQ5IDM3MC4wMCA2NTUuOTIgQyAzNzIuMjEgNjUzLjY1IDM3MS41MSA2NDguNzEgMzY5LjczIDY0Ni4yNCBDIDM2NC4wOSA2MzcuMTYgMzU2LjMwIDYyOC4wMCAzNTUuMDEgNjE3LjAxIEMgMzU1LjA3IDYxMi43NCAzNTMuODMgNjA4LjI5IDM1NC40MSA2MDQuMTIgTCAzNTUuOTggNjA0LjQ1IEMgMzU1Ljk2IDYwOS42MiAzNTYuNjcgNjE0LjgxIDM1Ny41NSA2MTkuODkgQyAzNjAuMzEgNjI5LjQxIDM2Ny4yMSA2MzguMzggMzcyLjMxIDY0Ni43OSBDIDM3My45MCA2NDkuNjQgMzczLjk4IDY1Mi43MSAzNzIuNjUgNjU1LjY4IEMgMzcwLjk4IDY1OS4yNSAzNjkuMTAgNjYyLjg2IDM2NS4xMSA2NjQuMjEgQyAzNjAuOTggNjY2LjA2IDM1NS44NyA2NjQuMzAgMzUzLjAwIDY2MS4wMCBDIDM0OC42MiA2NTYuNDAgMzQ3LjY5IDY1MC41OSAzNDUuMzYgNjQ1LjE5IEMgMzQ0Ljk4IDY0Ny41NiAzNDQuNDQgNjUxLjIyIDM0Mi4xOCA2NTIuNTggQyAzNDAuNjggNjUzLjUzIDMzOS4zMSA2NTMuMDYgMzM3Ljk5IDY1Mi4xMCBDIDMzNS43NiA2NDIuNTUgMzM5LjAwIDYzNC42MCAzMzkuMzIgNjI1LjAwIEMgMzQwLjA5IDYxNC42OCAzMzUuNDggNjA2LjAzIDMzMy41OCA1OTYuMDIgQyAzMzEuNzYgNTg3LjYyIDMzMi40MSA1NzkuNTIgMzI4LjM1IDU3MS42NiBDIDMyNi4zNCA1NjguMzYgMzI0LjIzIDU2NC41MCAzMjEuMjAgNTYyLjA1IEMgMzIwLjI4IDU3MS40OSAzMTguNjQgNTgwLjQ2IDMxOS4wMSA1OTAuMDEgQyAzMTkuNjMgNjAwLjYyIDMzMC44MSA2MTAuMzIgMzMwLjA0IDYyMS4wMCBDIDMzMC43OSA2MjkuMTMgMzIzLjk1IDYzNS44OCAzMjMuNzUgNjQ0LjAwIEMgMzIzLjU5IDY0OS4zMyAzMjMuNTIgNjU0LjY3IDMyMy4xMCA2NjAuMDAgQyAzMjIuOTYgNjY5LjM1IDMyMS4yMyA2NzguNjUgMzIwLjk4IDY4OC4wMCBDIDMyMS4wMSA3MDEuNDMgMzI2LjIwIDcxMi4yMCAzMjkuMDMgNzI1LjAyIEMgMzMwLjkxIDczMi4yMCAzMzAuMTAgNzM5LjY4IDMyOS45MyA3NDYuOTkgQyAzMjguOTQgNzU0LjYxIDMyOC4wOCA3NjIuMzggMzI3LjEwIDc3MC4wMCBDIDMyNi45MyA3NzQuOTcgMzI2Ljk5IDc4MC4wMiAzMjcuMDYgNzg1LjAwIEMgMzI4LjAyIDc5MS43NCAzMjkuMDYgNzk4LjEyIDMyOC40MyA4MDUuMDEgQyAzMjguMDUgODA3LjUxIDMyNy42MCA4MDkuOTQgMzI0Ljk0IDgxMC44OSBDIDMxNS4wNyA4MTQuNzkgMzAyLjM4IDgxMy4zNSAyOTIuMDAgODEzLjI3IEMgMjg2Ljk5IDgxMy43NiAyODIuMDQgODEzLjUxIDI3Ny4wOCA4MTIuNzUgQyAyNzQuOTkgODEyLjQ2IDI3NC42NSA4MTAuNTMgMjczLjAwIDgxMC4wMCBDIDI2My4wOSA4MTIuMDYgMjUzLjA4IDgxMS45NiAyNDMuMDggODEwLjQ1IEMgMjQwLjY5IDgxMC4wNiAyMzcuNDIgODA4LjY3IDIzNi45MiA4MDYuMDMgQyAyMzcuNTQgODAzLjg1IDIzOS41MCA4MDMuMTIgMjQxLjQ5IDgwMi41NyBDIDI0Ni4yMCA4MDEuNDQgMjUxLjIwIDgwMS4wMyAyNTUuODggNzk5LjY5IEMgMjU5LjMzIDc5OC40NCAyNjIuNDMgNzk2LjU1IDI2NC4yOCA3OTMuMjggQyAyNjguNjMgNzg2LjA3IDI3MS43MiA3NzcuNDggMjcxLjY4IDc2OS4wMCBDIDI3MS4zOCA3NTcuMjAgMjY4LjgwIDc0NS45OSAyNjYuMjYgNzM0LjUzIEMgMjY0LjE4IDcyNC40NiAyNjAuODcgNzEzLjI5IDI2MS4xMyA3MDIuOTkgQyAyNjMuNTQgNjg4Ljk3IDI2MC43MSA2NzQuMTggMjYxLjcxIDY2MC4wMCBDIDI2MS45MyA2NDMuODkgMjYzLjkyIDYyOC4wNiAyNzQuMTUgNjE1LjAwIEMgMjcyLjAzIDYwMy4wNSAyNzEuMDUgNTkxLjAwIDI2OS4yMSA1NzkuMDEgQyAyNjguMTIgNTY2Ljg3IDI2Ny44NCA1NTUuMDIgMjcwLjI4IDU0My4wMCBDIDI3MC41NSA1NDEuNjkgMjcwLjk4IDU0MC40MiAyNzAuOTIgNTM5LjA4IEMgMjYxLjUwIDU0Mi4zOCAyNTEuODAgNTQ1LjA1IDI0Mi4wMSA1NDYuOTcgQyAyMzguOTkgNTQ3LjUzIDIzNi4xNyA1NDguMDAgMjMzLjIzIDU0Ni43NyBDIDIzMS4zOCA1NDUuMTAgMjMwLjY5IDU0Mi4zNyAyMzAuMjIgNTQwLjAxIEMgMjI5LjMyIDUzMS4zOCAyMzAuNjcgNTIzLjUyIDIzMS4wMiA1MTUuMDAgQyAyMzIuOTggNDk1LjA1IDIzNy43MiA0NzUuNzYgMjM5LjkxIDQ1Ni4wMCBDIDI0MC4wMSA0NTEuNjIgMjQwLjMzIDQ0NC45NiAyNDQuMDEgNDQxLjk2IEMgMjQ3LjMzIDQ0MS42NSAyNTIuNjYgNDQyLjM3IDI1My45NSA0NDYuMDIgQyAyNTQuNzMgNDUwLjE4IDI1My44OSA0NTMuODYgMjUzLjg5IDQ1OC4wMiBDIDI1NS41NiA0NTcuMjkgMjU3LjEzIDQ1Ni45MSAyNTguOTcgNDU3LjAwIEMgMjYwLjU4IDQ1Ny45MSAyNjAuMTUgNDYwLjA2IDI1OS44MCA0NjEuNTcgQyAyNTguMjEgNDY1Ljk4IDI1Ni40MSA0NzAuMzQgMjU0LjY1IDQ3NC42OSBDIDI1Mi43MyA0NzkuNjQgMjQ5LjgxIDQ4My42NyAyNDkuMTggNDg5LjA4IEMgMjQ4LjA0IDUwMC42NSAyNTIuMDIgNTEyLjcxIDI1Mi4wNCA1MjQuMzMgQyAyNTMuMzYgNTI0LjQ0IDI1NC42NiA1MjMuMzcgMjU1Ljc4IDUyMi43NiBDIDI2NS41OSA1MTYuNzEgMjc2Ljg5IDUxMS45MyAyODUuOTcgNTA0Ljg4IEMgMjg4LjIxIDUwMi42NiAyODkuMTkgNDk4Ljk3IDI5MC4zNyA0OTYuMTAgQyAyOTIuNDIgNDkwLjY1IDI4OS4zNyA0ODQuNzUgMjg3LjI5IDQ3OS43NSBDIDI4NC43NSA0NzYuNTcgMjgwLjExIDQ3OS40MCAyNzcuMDYgNDc2LjAxIEMgMjc0LjU2IDQ3Mi40MSAyNzUuMzggNDY2LjMzIDI3NC43MyA0NjIuMjMgQyAyNzMuMTQgNDU5LjU0IDI3MC4xMiA0NTcuODAgMjcyLjI4IDQ1NC4yOSBDIDI3NS40MCA0NTAuNjUgMjc1LjI2IDQ0Ni41MiAyNzUuODcgNDQyLjAwIEMgMjc2LjA4IDQzNi40MSAyNzcuOTYgNDMxLjAwIDI4Mi4xMCA0MjcuMTIgQyAyODcuMjUgNDIyLjg1IDI5NC4yNyA0MjAuNzcgMzAwLjkxIDQyMS41MCBaIiBmaWxsPSIjODE4MTgxIiAvPgo8cGF0aCBkPSJNIDE2MC4wNiA0MzUuMTcgQyAxNjMuNjkgNDM1LjM1IDE2NS45MyA0MzkuODMgMTY3LjM2IDQ0Mi42NyBDIDE3MC42MyA0NTAuMDcgMTcxLjMwIDQ1OS4wMCAxNzEuMDAgNDY3LjAwIEMgMTcwLjk5IDQ3OS42NiAxNzAuNjQgNDkxLjU4IDE3NC4yOCA1MDMuOTMgQyAxNzguMDMgNTE2LjE1IDE4MS43OSA1MjkuMTQgMTc5Ljk0IDU0Mi4wMSBDIDE3OS4wMSA1NDUuODkgMTc3LjYyIDU0OS44MiAxNzIuOTkgNTUwLjAzIEMgMTY0LjgxIDU0OC4xMyAxNTcuMTMgNTQ0Ljk5IDE0OS4wOSA1NDIuNjcgQyAxNDUuMzYgNTQxLjgxIDE0MS45MiA1NDAuNjUgMTM4LjAzIDU0MS4wNyBDIDEzOC45MyA1NDcuOTcgMTM5LjkxIDU1NS4wMiAxNDAuMDUgNTYyLjAwIEMgMTM5Ljc1IDU3NC45NSAxMzcuNzMgNTg3LjIyIDEzNi4xNiA2MDAuMDAgQyAxMzYuMDIgNjA0LjA0IDEzNC4yNCA2MDguMDEgMTM0LjA1IDYxMS45NyBDIDE0Mi4wNCA2MjIuMjkgMTQzLjcxIDYzNi40MSAxNDQuOTYgNjQ5LjAwIEMgMTQ1LjExIDY1OS43MyAxNDUuNzYgNjcwLjI4IDE0NC41MiA2ODAuOTkgQyAxNDMuOTAgNjg2LjgxIDE0NC40MiA2OTIuMjggMTQ1LjU5IDY5Ny45OSBDIDE0Ny4wNiA3MDUuMzAgMTQ0LjkwIDcxMS4zMCAxNDMuNDMgNzE4LjM0IEMgMTQxLjUwIDcyNy41NiAxMzkuNDEgNzM2LjcwIDEzNy44NCA3NDUuOTkgQyAxMzYuMjkgNzU0LjU1IDEzNC45OSA3NjMuMzAgMTM2LjAyIDc3Mi4wMSBDIDEzNi43OCA3NzkuNzEgMTM5Ljc0IDc4OC4wOSAxNDUuNDkgNzkzLjUwIEMgMTUwLjAzIDc5Ny40MSAxNTYuMzMgNzk3LjM4IDE2MS45MyA3OTguNDAgQyAxNjQuOTggNzk5LjIxIDE2Ny44NyA3OTkuNDUgMTcwLjA1IDgwMi4wMSBDIDE3MC4wNCA4MDIuOTggMTcwLjAzIDgwMy45NSAxNzAuMDMgODA0LjkxIEMgMTY4Ljc4IDgwNS44OCAxNjcuNjUgODA2LjgwIDE2Ni4wMyA4MDcuMDMgQyAxNTYuMDMgODA5LjEzIDE0NS4wNCA4MDcuNjEgMTM0Ljk1IDgwNi43MCBDIDEzMy42NiA4MDkuMTMgMTMyLjA2IDgwOS43NiAxMjkuMzIgODA5LjM0IEMgMTI5LjY3IDgwOC40OCAxMzAuMTkgODA3LjY4IDEzMC44NyA4MDYuOTYgQyAxMjkuODYgODA1LjU3IDEyOC40NCA4MDQuODggMTI2Ljk1IDgwNC4xMiBDIDEyMC41MSA4MDAuOTggMTE0LjM3IDc5Ny4yOSAxMDcuODggNzk0LjI0IEMgMTAzLjY2IDc5MS45NSA5OS43MyA3ODkuNzkgOTguMDggNzg0Ljk2IEMgOTcuMjQgNzY5LjIwIDk5Ljg0IDc1NC42NSAxMDEuMjAgNzM5LjAxIEMgMTAyLjI1IDczMy4yNSAxMDEuNzEgNzI3LjU2IDEwMy4yMCA3MjIuMDcgQyAxMDQuOTYgNzE2Ljc4IDEwOC40MiA3MTIuNDggMTA5LjgyIDcwNy4wMCBDIDExMC42NCA2OTYuMjUgMTEyLjY2IDY4NS41NSAxMTQuOTMgNjc1LjAxIEMgMTE3LjI1IDY2My41MSAxMTguODMgNjUxLjY5IDEyMC41NyA2NDAuMDggQyAxMjEuMjQgNjM1Ljc4IDEyMS42NCA2MzEuNzkgMTIzLjY4IDYyNy44NiBDIDEyNi4zMiA2MjIuMjUgMTMwLjY5IDYxNi45NyAxMzIuMjMgNjExLjAxIEMgMTM0LjMxIDYwMC43MSAxMzYuMjMgNTkwLjQ1IDEzNy41NSA1NzkuOTkgQyAxMzkuOTIgNTU4LjIwIDEzNy40NyA1MzUuNTQgMTI2Ljc5IDUxNi4wOSBDIDEyMy4wMCA1MDkuMDkgMTE3LjIzIDUwMS45MyAxMTUuOTUgNDk0LjAxIEMgMTE1LjA3IDQ4OC4zNSAxMTYuNzcgNDgzLjI0IDExOS4yNCA0NzguMjUgQyAxMjEuOTAgNDc0LjQ4IDEyNi43OSA0NzcuMjQgMTI5LjcwIDQ3My42OCBDIDEzMi42OSA0NjkuODUgMTI5LjQ1IDQ2My4yMyAxMzIuMDIgNDU5LjAwIEMgMTMyLjg3IDQ1Ny45NSAxMzQuNzcgNDU3Ljc2IDEzNi4wMSA0NTcuMjYgQyAxMzUuMzIgNDU4LjY0IDEzMy44MSA0NTkuNDggMTMzLjQwIDQ2MC45NSBDIDEzMy4yNyA0NjUuMzggMTMzLjc2IDQ3MS40NiAxMzEuMzYgNDc1LjM3IEMgMTI5Ljc1IDQ3Ny44NSAxMjYuNjQgNDc2Ljk1IDEyMy45NSA0NzcuOTQgQyAxMjAuNDkgNDc4LjczIDExOS4yMSA0ODIuOTEgMTE4LjQwIDQ4NS45MCBDIDExNi43NCA0OTMuNDkgMTE5LjI4IDUwMC4zOSAxMjMuMzAgNTA2LjczIEMgMTI0LjQxIDUwNy42NyAxMjUuNjUgNTA3LjY5IDEyNy4wMSA1MDguMDQgQyAxMzMuODggNTA5LjUxIDEzOS45NyA1MTIuNDIgMTQ2LjEwIDUxNS43NiBDIDE0OC4zOSA1MTcuMTggMTUwLjUyIDUxOC43NiAxNTMuMDMgNTE5LjgxIEMgMTU0LjQxIDUxOS4wOSAxNTUuMjMgNTE4LjQyIDE1NS43NiA1MTYuOTQgQyAxNTYuNjggNTEyLjE1IDE1Ni43NSA1MDcuMjggMTU3LjY2IDUwMi40OSBDIDE1OC4yMyA0OTcuMDIgMTU4LjkzIDQ5MS4zMyAxNTcuMTkgNDg2LjAwIEMgMTU1LjM5IDQ4MC40MiAxNTQuMzkgNDc0LjcxIDE1My4xOCA0NjkuMDAgQyAxNTIuMjEgNDY0LjQzIDE0OS4yNiA0NjAuNDAgMTQ3Ljg4IDQ1Ni4wNCBDIDE0Ny42MiA0NTQuMzIgMTQ2LjQzIDQ1MS44MiAxNDguOTQgNDUxLjI2IEMgMTUyLjA3IDQ1MS44NCAxNTQuMDQgNDU1LjUyIDE1NS43OCA0NTcuOTAgQyAxNTYuODQgNDUyLjA2IDE1My45MyA0NDcuMDcgMTU1LjU2IDQ0MS40OCBDIDE1Ni4xOSA0MzguODMgMTU2Ljk2IDQzNS43NyAxNjAuMDYgNDM1LjE3IFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMTYyLjMyIDQzOC4yMCBDIDE2NC4yMiA0NDAuMTYgMTY1LjIwIDQ0My4wNyAxNjYuMjIgNDQ1LjU2IEMgMTcwLjM5IDQ1OS45MiAxNjguOTQgNDczLjgzIDE2OS42OCA0ODguMDEgQyAxNjkuODQgNTAyLjUxIDE3Ny4wNyA1MTUuNjYgMTc4LjM4IDUzMC4wMCBDIDE3OS4wMSA1MzQuNDMgMTc5LjEyIDUzOS45NiAxNzcuMTUgNTQ0LjA0IEMgMTc1LjQxIDU0Ny4zNSAxNzIuNDEgNTQ3Ljg5IDE2OC45OCA1NDYuOTYgQyAxNjAuMjcgNTQ0LjQ5IDE1Mi4wNiA1NDEuNDcgMTQzLjA5IDUzOS43OCBDIDE0MS4wNCA1MzkuNTEgMTM5LjE1IDUzOS45NCAxMzcuMjQgNTM4Ljg4IEMgMTM0Ljk4IDUyOC42MCAxMzAuOTggNTE4LjgyIDEyNS4xNSA1MTAuMDMgQyAxMjYuNDQgNTA5Ljk4IDEyNy42OCA1MTAuMTcgMTI4Ljg4IDUxMC42MCBDIDEzNy4wMiA1MTMuMTggMTQ1LjE3IDUxNi45MCAxNTEuOTYgNTIyLjEzIEMgMTUyLjc5IDUyMi44OCAxNTMuNzcgNTIzLjE5IDE1NC45MCA1MjMuMDUgQyAxNTkuMTMgNTE2LjIyIDE1OC40NyA1MDkuMTkgMTU5LjMwIDUwMS40OSBDIDE1OS44MiA0OTguNjQgMTYwLjE0IDQ5NS45MCAxNjAuMDMgNDkzLjAwIEMgMTYwLjMyIDQ4OC4xMiAxNTguMjkgNDgzLjY1IDE1Ny4yMyA0NzguOTcgQyAxNTYuMzAgNDc0LjU2IDE1NS41NyA0NzAuMjIgMTU0LjMzIDQ2NS44NyBDIDE1My4yNiA0NjEuOTEgMTUwLjgwIDQ1OC4wNCAxNTAuMDIgNDU0LjAwIEMgMTUyLjc1IDQ1NS41MCAxNTQuMzQgNDU4LjgxIDE1NS40MyA0NjEuNTggQyAxNTcuMTQgNDYzLjczIDE1OC4wNiA0NjAuNDMgMTU4LjAyIDQ1OS4wNCBDIDE1OC41NSA0NTQuMjggMTU3LjE5IDQ0OS43OSAxNTcuMjUgNDQ1LjExIEMgMTU3Ljc4IDQ0NS43MSAxNTguMzEgNDQ2LjMyIDE1OC44NCA0NDYuOTMgQyAxNTguNjUgNDQ0LjMwIDE1Ny40NiA0NDEuNTAgMTU3LjkwIDQzOC45MSBMIDE1OC42OCA0MzkuMjEgQyAxNjAuNDIgNDQyLjU4IDE1OS44OCA0NDYuNDQgMTYxLjYxIDQ0OS43MyBDIDE2MS45NyA0NDYuNjYgMTYwLjcxIDQ0My44NyAxNjEuMDUgNDQwLjc5IEMgMTYzLjYxIDQ0Mi40MSAxNjIuNTIgNDQ3LjkxIDE2NC44MSA0NDkuOTUgQyAxNjQuMzUgNDQ1LjkxIDE2My41MCA0NDIuMDkgMTYyLjMyIDQzOC4yMCBaIiBmaWxsPSIjZmZmZmZmIiAvPgo8cGF0aCBkPSJNIDI0Ni4wOCA0NDQuMDYgQyAyNDYuODAgNDQ2LjUwIDI0NC40MiA0NDguOTUgMjQ1LjQ4IDQ1MS43NSBDIDI0NS44MCA0NDkuMTQgMjQ2LjQ1IDQ0Ni42MCAyNDYuOTYgNDQ0LjAyIEwgMjQ4LjA2IDQ0NC4xMyBDIDI0OS4wNiA0NDYuOTIgMjQ3Ljg5IDQ1MS4wMyAyNDcuMjMgNDUzLjkwIEMgMjQ5LjE5IDQ1MS41MiAyNDguMzggNDQ3Ljg0IDI0OC45NSA0NDUuMDkgTCAyNTAuMDYgNDQ1LjA3IEMgMjUxLjEyIDQ0Ny41NyAyNTAuMDkgNDUyLjAxIDI0OS4zOCA0NTQuNzIgQyAyNTEuMjQgNDUyLjg3IDI1MC41NyA0NDkuNDMgMjUwLjg5IDQ0Ni45OCBMIDI1MS44OSA0NDcuMTUgQyAyNTMuOTQgNDUxLjEyIDI1MS4yNSA0NTcuMTcgMjUxLjQzIDQ2MS41OCBDIDI1My41NiA0NjMuNjAgMjU1LjU1IDQ1Ny40NyAyNTcuOTQgNDU3LjcxIEMgMjU4LjAyIDQ1OS4zOCAyNTguMDcgNDYwLjkxIDI1Ny4zOSA0NjIuNDggQyAyNTQuOTEgNDY5LjQ1IDI1Mi4wMyA0NzYuMjUgMjQ4Ljc2IDQ4Mi44OCBDIDI0Ni44OCA0ODYuODYgMjQ3LjI5IDQ5MC43MyAyNDcuNDggNDk1LjAwIEMgMjQ4LjMyIDUwNS41OSAyNTAuNTkgNTE1Ljg2IDI1MC42MiA1MjYuNTUgQyAyNTEuNzIgNTI4LjIyIDI1Mi44NSA1MjYuNTkgMjUzLjk3IDUyNS45MyBDIDI2MC43OCA1MjAuODUgMjY4Ljg2IDUxNy43NCAyNzYuMDkgNTEzLjIyIEMgMjc4LjczIDUxMi4wNiAyODEuMjggNTA5LjUzIDI4NC4wNCA1MDkuMDEgQyAyODMuNTEgNTEwLjQ2IDI4Mi42MCA1MTEuNjIgMjgxLjc4IDUxMi45MiBDIDI3Ny4yNSA1MjAuMzYgMjc0LjIxIDUyOC4zOSAyNzEuNzUgNTM2LjcyIEMgMjYxLjI2IDU0MC44NCAyNTAuMTMgNTQzLjUwIDIzOS4wOSA1NDUuNjcgQyAyMzcuMjMgNTQ2LjA2IDIzNS4wMSA1NDUuNzMgMjMzLjc3IDU0NC4xNyBDIDIzMi4wMSA1NDEuNjYgMjMxLjg4IDUzOC45OCAyMzIuMDAgNTM2LjAwIEMgMjMxLjgxIDUxMC45NyAyMzcuNTcgNDg4LjYyIDI0MS4wMiA0NjQuMDAgQyAyNDEuMjQgNDU4LjMzIDI0MS45NiA0NTIuNTQgMjQzLjI2IDQ0Ny4wMiBDIDI0My44MSA0NDUuNTUgMjQzLjg3IDQ0My40MCAyNDYuMDggNDQ0LjA2IFoiIGZpbGw9IiNmZmZmZmYiIC8+CjxwYXRoIGQ9Ik0gMTI2Ljg2IDQ0OC43NyBDIDEyNS41NyA0NTAuOTkgMTI0LjExIDQ1MC41NSAxMjMuMjggNDQ4LjMzIEMgMTI0LjE4IDQ0Ni40NyAxMjcuMDcgNDQ2LjUzIDEyNi44NiA0NDguNzcgWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSAyODcuNjEgNDUwLjM3IEMgMjg3LjA3IDQ1Mi45OSAyODMuODQgNDUyLjQ2IDI4My45OSA0NTAuMDYgQyAyODUuNDUgNDQ4LjE2IDI4Ni4zMCA0NDguNzUgMjg3LjYxIDQ1MC4zNyBaIiBmaWxsPSIjODE4MTgxIiAvPgo8cGF0aCBkPSJNIDEwOC42MyA0NTAuMzggQyAxMDkuMDcgNDUyLjcyIDEwNS43NyA0NTEuNDAgMTA0Ljc1IDQ1Mi43NSBDIDEwMi45OCA0NTQuNTAgMTA0LjQwIDQ1Ny42NyAxMDUuNTggNDU5LjQxIEMgMTA3LjExIDQ2MS43NCAxMDYuODYgNDY0LjExIDEwNy4zMCA0NjYuNzAgQyAxMDguNTggNDY4LjIwIDExMS41NSA0NjYuMjIgMTEzLjA5IDQ2NS44MSBDIDExNC4yNCA0NjkuMjQgMTA4LjE4IDQ2OS4yOCAxMDYuMjEgNDY4Ljg0IEMgMTA1LjQxIDQ2Ni42MSAxMDUuMDYgNDY0LjM5IDEwNC44MiA0NjIuMDQgQyAxMDMuOTIgNDU5Ljg0IDEwMS44NSA0NTcuNDQgMTAxLjk2IDQ1NS4wMCBDIDEwMS43NiA0NTEuODcgMTA1LjcwIDQ0OC44MSAxMDguNjMgNDUwLjM4IFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMzA1Ljk5IDQ1Mi4wMCBDIDMwNi43OSA0NTIuODggMzA3Ljk5IDQ1My42OSAzMDguMzEgNDU0Ljg1IEMgMzA5LjI5IDQ1Ny4yNSAzMDcuODIgNDU5LjY1IDMwNi43MSA0NjEuNzEgQyAzMDUuMTUgNDY0LjE1IDMwNS41OCA0NjcuMjYgMzA0LjY4IDQ2OS43MSBDIDMwMy40MCA0NzEuMzUgMjk3LjQzIDQ2OS45OCAyOTcuODkgNDY3Ljc3IEMgMjk5LjkzIDQ2OC41MyAzMDEuNTUgNDY5LjMwIDMwMy44MSA0NjguODggQyAzMDQuMDcgNDY2LjI3IDMwNC4xMCA0NjMuNzIgMzA1LjM4IDQ2MS4zOCBDIDMwNi4zNiA0NTkuMTkgMzA3Ljk3IDQ1Ny41NyAzMDYuOTYgNDU1LjAzIEMgMzA2LjMxIDQ1My4xNCAzMDMuNzggNDUzLjA2IDMwMi4xNSA0NTIuNzQgQyAzMDIuODIgNDUxLjQ2IDMwNC43OCA0NTIuMTQgMzA1Ljk5IDQ1Mi4wMCBaIiBmaWxsPSIjODE4MTgxIiAvPgo8cGF0aCBkPSJNIDg3Ljk0IDU1OC4wMiBDIDg4LjM0IDU1OC42NyA4OC42MSA1NTkuMzQgODguNzUgNTYwLjA0IEMgODkuODEgNTY2LjMzIDkwLjI3IDU3Mi42NiA5MC45NiA1NzkuMDAgQyA5MS4xMiA1ODIuNTMgOTEuOTEgNTg1LjY1IDkxLjQwIDU4OS4wMSBDIDkxLjA2IDU5My42MyA4OC40MCA1OTguMDggODYuMzAgNjAyLjEzIEMgODUuNjIgNjAzLjkxIDgzLjcxIDYwNC4yOSA4My4xMiA2MDYuMDYgQyA4MS40MSA2MTAuMDMgNzkuNzIgNjE0LjYzIDgwLjAxIDYxOS4wMCBDIDgwLjQ1IDYyNC4yMiA4Mi41MCA2MjguNTEgODQuODEgNjMzLjA4IEMgODcuODQgNjM5LjI4IDg2LjA2IDY0NS40MSA4Ni44NSA2NTIuMDEgQyA4Ny4xMiA2NjQuMzYgODguMzYgNjc2LjYwIDg4LjQ0IDY4OS4wMSBDIDg4LjEyIDcwMy40NCA4Mi4xMSA3MTUuNTUgODAuMzEgNzI5LjUwIEMgNzguMjcgNzQ2LjczIDg0Ljg5IDc2MS44NSA4My4xNyA3NzkuMDAgQyA4My4zOCA3ODYuNDcgODEuMzIgNzkzLjU3IDgxLjY5IDgwMS4wMSBDIDgxLjk1IDgwMi43NSA4MS44MCA4MDQuNTMgODMuMzEgODA1LjcwIEMgODUuODYgODA3LjI2IDg5LjAyIDgwOC4wNSA5Mi4wMCA4MDcuOTkgQyAxMDIuOTIgODA4LjYyIDExMy4wMyA4MDguOTcgMTIzLjk5IDgwOC42MiBDIDEyNS4zNyA4MDguNzAgMTI5LjMxIDgwNy40MSAxMjguNjMgODA5Ljk5IEMgMTIzLjA4IDgxMC4zNiAxMTcuNTUgODEwLjI5IDExMi4wMCA4MTAuMjcgQyAxMDMuMTAgODEwLjIzIDkzLjgzIDgxMC40MiA4NS4wNyA4MDguODAgQyA4MC40OSA4MDcuNjQgNzkuODYgODAzLjAyIDgwLjEwIDc5OS4wMSBDIDgwLjM4IDc5My42NyA4MC45MyA3ODguMzUgODEuMDkgNzgzLjAxIEMgODMuMzggNzY3LjI4IDc3LjQ4IDc1MC42OSA3Ny45NyA3MzUuMDAgQyA3Ny41NSA3MTkuNjIgODcuMDcgNzA1Ljk4IDg3LjAwIDY5MC4wMCBDIDg2Ljg1IDY4NC4zMyA4Ni42NSA2NzguNjQgODYuMDEgNjczLjAxIEMgODUuOTYgNjY3LjUwIDg1LjUxIDY2MS45MyA4NC44MiA2NTYuNDcgQyA4NS4zNiA2NTAuOTUgODQuMzggNjQ1LjUzIDg0LjY2IDY0MC4wMCBDIDg0LjgzIDYzMy44MSA3OS41MyA2MjguMjkgNzguNTUgNjIyLjI1IEMgNzcuMDQgNjE3LjIwIDc4Ljk1IDYxMS42MyA4MC43MyA2MDYuODcgQyA4MS4yNyA2MDUuMDcgODIuNDEgNjA0LjA1IDgzLjY0IDYwMi43MyBDIDg3LjAyIDU5Ni40MSA4OS44OSA1OTAuNDAgODkuMjEgNTgzLjAwIEMgODguODUgNTc1LjY5IDg4LjQxIDU2OC4xOSA4Ni43OCA1NjEuMDMgQyA4Mi40MCA1NjYuMjcgNzguMDcgNTcyLjU0IDc3LjMwIDU3OS40OCBDIDc2LjE4IDU4OC40MSA3NS41NiA1OTcuMDEgNzEuMTEgNjA1LjA4IEMgNjkuMDEgNjEwLjQ4IDY4LjQxIDYxNS40NSA2Ny40MiA2MjAuOTkgQyA2Ny4zMyA2MzIuNjcgNzIuNjIgNjQyLjEzIDcxLjAwIDY1My45NSBDIDY5LjA1IDY1NC44OCA2OC4wNiA2NTUuMDIgNjYuMTIgNjUzLjkzIEMgNjQuODEgNjUyLjc1IDY0LjM3IDY1MC42NyA2Mi45MiA2NDkuNzIgQyA2MC40NyA2NTYuNDUgNTYuNjMgNjYzLjY5IDUwLjAwIDY2Ny4xMiBDIDQ2LjEzIDY2OC45NiA0Mi4zMCA2NjYuODAgNDAuNjUgNjYzLjE1IEMgMzguMjcgNjU5LjQ3IDM4LjY3IDY1NS4yNCAzOS4wOSA2NTEuMDYgQyA0MS4zNSA2NDYuNDUgNDMuNjYgNjQyLjAxIDQ1LjA5IDYzNy4wNSBDIDQ3Ljc2IDYyOC42OCA1MC45NyA2MjAuOTYgNTEuNjggNjEyLjA4IEMgNTIuMDcgNjA1Ljg0IDUzLjA3IDU5OS43MSA1My4wMyA1OTMuNDUgTCA1NC41OSA1OTMuMTIgQyA1NS40OSA1OTcuMjMgNTQuNDEgNjAxLjgyIDU0LjI1IDYwNi4wMCBDIDUzLjk1IDYxMy41NyA1Mi4yMiA2MjAuNzggNTAuMTkgNjI4LjAzIEMgNDguMDcgNjM1LjI2IDQ1LjU0IDY0Mi4zMyA0Mi4yMiA2NDkuMDkgQyA0MS4wNSA2NTEuNDMgMzkuNjUgNjUzLjMwIDQwLjAzIDY1Ni4wOCBDIDQxLjY5IDY1NC45MyA0Mi41MSA2NTIuMzQgNDMuNjQgNjUwLjY2IEMgNDQuNjcgNjQ5LjMzIDQ0Ljc0IDY0Ni43MCA0Ni45MSA2NDcuMDYgQyA0NS4xNiA2NTAuODQgNDIuOTcgNjU0LjM2IDQxLjAxIDY1OC4wMiBDIDQwLjkwIDY1OS4yMyA0MS4yMyA2NjAuMDcgNDIuMDAgNjYwLjUxIEMgNDQuMzMgNjU3LjIxIDQ2LjQ1IDY1My43MSA0OC4wOCA2NTAuMDAgQyA0OC42NSA2NDkuNzYgNDkuMjMgNjQ5LjUyIDQ5LjgwIDY0OS4yOCBDIDQ4LjQwIDY1My44NyA0NC45MSA2NTcuODQgNDIuOTggNjYyLjAzIEMgNDIuOTggNjYzLjQ3IDQ0Ljk4IDY2NC4zNCA0Ni4wMSA2NjUuMDMgQyA0Ny40MyA2NjIuMDAgNDguODkgNjU5LjU3IDUxLjAwIDY1Ni45NyBDIDUyLjA4IDY1NS43MiA1My4xNyA2NTMuMDYgNTUuMDEgNjUzLjAzIEMgNTMuNjcgNjU3LjE5IDQ4LjUxIDY2MC42MSA0Ny45NyA2NjQuOTcgQyA0OS41MSA2NjUuMDYgNTAuNDQgNjY0LjU1IDUxLjYxIDY2My42NCBDIDU2LjQ5IDY2MC40MCA1OS42MiA2NTQuNTQgNjAuODAgNjQ4LjkxIEMgNjEuMzAgNjQ2LjgyIDYwLjU4IDY0NC4zMiA2MS4zNiA2NDIuMzQgQyA2My4zMiA2NDEuMDcgNjMuMjIgNjQzLjkwIDYzLjg2IDY0NS4wNSBDIDY0LjU0IDY0Ny41MiA2Ni41MiA2NTIuMDYgNjkuNjUgNjUxLjcyIEMgNjkuODUgNjQyLjU3IDY2LjA5IDYzMy4yNSA2NS43OSA2MjQuMDkgQyA2NS4zNCA2MTcuNjQgNjcuMTIgNjEyLjA3IDY4LjgzIDYwNS45OCBDIDcxLjk2IDU5OS4xNiA3My40NCA1OTEuMzcgNzQuODAgNTgzLjk5IEMgNzUuNjcgNTc1LjU0IDc5LjA4IDU2Ny45MCA4NC4xOSA1NjEuMTkgQyA4NS4wOSA1NjAuMjEgODYuMzUgNTU3LjQzIDg3Ljk0IDU1OC4wMiBaIiBmaWxsPSIjODE4MTgxIiAvPgo8cGF0aCBkPSJNIDM1NS4xNCA1ODcuOTQgQyAzNTQuNzAgNTkzLjIyIDM1Ni4yMSA1OTguNzEgMzU1LjU5IDYwMy44OCBMIDM1NC4wMSA2MDMuNTUgQyAzNTMuOTAgNTk4Ljg3IDM1My42NiA1OTQuMTYgMzUzLjAyIDU4OS41MSBDIDM1My4zOSA1ODguNTQgMzU0LjEwIDU4OC4wMiAzNTUuMTQgNTg3Ljk0IFoiIGZpbGw9IiM4MTgxODEiIC8+CjxwYXRoIGQ9Ik0gMTA2Ljg1IDU5NC4xMyBDIDEwOS4zMSA1OTYuMTEgMTExLjc0IDU5OC45NSAxMTMuMDQgNjAxLjc5IEwgMTExLjc4IDYwMy4wNyBDIDEwOS40NiA2MDEuNzAgMTA2LjIxIDYwMS4zNSAxMDUuNTcgNTk4LjM2IEMgMTA0LjY4IDU5Ni44OSAxMDMuMzkgNTk3LjIxIDEwMS45MSA1OTYuODggQyAxMDIuODQgNTk0Ljk0IDEwNC41MyA1OTMuMzAgMTA2Ljg1IDU5NC4xMyBaIiBmaWxsPSIjODE4MTgxIiAvPgo8cGF0aCBkPSJNIDMwNS4wMCA1OTYuODIgQyAzMDUuMDIgNTk3LjgxIDMwNS4wMyA1OTguODEgMzA1LjAzIDU5OS44MSBDIDMwMy4wMiA2MDEuODggMzAxLjI1IDYwMy42OSAyOTguMzkgNjA0LjUyIEMgMjk4LjIwIDYwNS4zNyAyOTguMDAgNjA2LjIxIDI5Ny44MSA2MDcuMDUgQyAyOTUuNzEgNjA2LjQzIDI5NC45NyA2MDMuNzMgMjk1LjY5IDYwMS45OSBDIDI5Ny42OCA1OTkuNDYgMzAwLjEwIDU5OC45OCAzMDIuOTIgNTk3LjkzIEMgMzAzLjYwIDU5Ny41MyAzMDQuMjkgNTk3LjE1IDMwNS4wMCA1OTYuODIgWiIgZmlsbD0iIzgxODE4MSIgLz4KPHBhdGggZD0iTSAxMzMuNjYgNjE1LjI3IEMgMTQxLjMxIDYyNi44OCAxNDIuNjggNjQwLjQ3IDE0My42MSA2NTQuMDAgQyAxNDQuNTUgNjY0LjM3IDE0My41MCA2NzUuMTQgMTQyLjcyIDY4NS41MiBDIDE0MS43NSA2OTAuOTQgMTQzLjE0IDY5NS43MiAxNDMuOTMgNzAxLjAwIEMgMTQ0Ljg4IDcxMi43MyAxNDAuMDcgNzI1LjQ4IDEzNy43MSA3MzYuOTYgQyAxMzYuMTUgNzQ1LjAzIDEzNC4xMCA3NTMuMjkgMTMzLjcyIDc2MS41MSBDIDEzMi45NSA3NzEuODUgMTM1Ljc0IDc4Mi4xNiAxNDEuMTAgNzkwLjk5IEMgMTQyLjQ5IDc5My4yNyAxNDQuMDUgNzk1LjMyIDE0Ni40NyA3OTYuNTggQyAxNTMuMDYgODAwLjE4IDE2MC44MSA3OTguNzggMTY3LjY0IDgwMi4zNSBDIDE2OC43MyA4MDMuNjYgMTY3LjAxIDgwNC41NSAxNjUuOTMgODA0Ljg1IEMgMTYwLjkwIDgwNi4yMCAxNTUuMTYgODA1Ljk5IDE1MC4wMCA4MDUuOTkgQyAxNDQuNjUgODA2LjA4IDEzOS4yNCA4MDUuNzAgMTMzLjk5IDgwNC42NyBDIDEyOS43MiA4MDMuNTIgMTI1LjY1IDgwMS4yOCAxMjEuNjggNzk5LjMzIEMgMTE5LjI0IDc5Ny45OCAxMTYuODcgNzk3LjI3IDExNS43NSA3OTQuNDQgQyAxMTUuMjcgNzk0LjY4IDExNC43OSA3OTQuOTIgMTE0LjMxIDc5NS4xNyBDIDExMS43MSA3OTQuMTAgMTA5LjQ1IDc5Mi40MCAxMDYuOTEgNzkxLjE2IEMgMTA0LjU1IDc4OS44NCAxMDEuNTggNzg4LjI0IDEwMC4yMyA3ODUuODAgQyA5OS4xNiA3ODEuMTAgMTAwLjE1IDc3Ni43NSAxMDAuMTAgNzcyLjAwIEMgMTAxLjMxIDc1Ni4zNCAxMDMuMjggNzQwLjYyIDEwNC40MyA3MjUuMDggQyAxMDUuNTAgNzIxLjUzIDEwNy45NCA3MTguNTUgMTA5LjE2IDcxNS4wMiBDIDExMi40MSA3MDcuNDAgMTEyLjgwIDY5OS42NiAxMTMuODMgNjkxLjUzIEwgMTE0LjU1IDY5MS4xOCBDIDExNi4yMSA2OTQuMzkgMTE3Ljg4IDY5Ny41NyAxMTkuMjAgNzAwLjkzIEMgMTIwLjQ3IDcwMy42MSAxMTkuOTMgNzA3LjEwIDExOS45NCA3MTAuMDEgQyAxMTguNTIgNzE4LjU2IDExMy4yNSA3MjYuODggMTExLjI5IDczNS4wNiBDIDExMC40MiA3NDAuMTYgMTExLjM1IDc0Ni4wNSAxMTEuODAgNzUxLjA5IEMgMTEyLjMyIDc2Mi4yMiAxMTUuNTQgNzczLjA3IDExNC45OCA3ODQuMDAgQyAxMTUuMTAgNzg3LjMwIDExNC4wMSA3OTAuNTggMTE0LjM3IDc5My44NCBMIDExNS45NCA3OTMuNTIgQyAxMTYuMTkgNzg4Ljk3IDExNy4xMiA3ODQuNTggMTE3LjAyIDc4MC4wMSBDIDExNy40OCA3NzAuNzkgMTE0LjU2IDc2MS4yMSAxMTMuODIgNzUyLjAxIEMgMTEyLjk1IDc0Ni42OCAxMTIuODcgNzQxLjM3IDExMy4wNiA3MzUuOTggQyAxMTMuNzcgNzMwLjQxIDExNi42MCA3MjYuMDQgMTE4LjQ2IDcyMC4zOSBDIDEyMC43OSA3MTQuMjIgMTIzLjA5IDcwOC44NiAxMjEuNzAgNzAyLjA4IEMgMTIwLjAwIDY5Ni44MSAxMTcuMDggNjkyLjM0IDExNC42NSA2ODcuNDcgQyAxMTQuNTggNjgzLjg4IDExNS45MCA2ODAuMDggMTE2LjQ4IDY3Ni41MyBDIDExOS42MiA2NjIuNjQgMTIxLjI0IDY0OC41NSAxMjMuMzggNjM0LjUwIEMgMTI0LjczIDYyNy44NCAxMjguOTYgNjIzLjYyIDEzMS42MiA2MTcuNjggQyAxMzIuMTIgNjE2Ljk1IDEzMi4zOCA2MTQuNzIgMTMzLjY2IDYxNS4yNyBaIiBmaWxsPSIjZmZmZmZmIiAvPgo8cGF0aCBkPSJNIDI3NC4xNCA2MTcuOTMgTCAyNzUuMDcgNjE3LjY0IEMgMjc3LjA1IDYyMi4wMiAyNzkuNTQgNjI1Ljg1IDI4Mi4yMyA2MjkuODAgQyAyODQuNzggNjMzLjU0IDI4NC44OSA2MzcuNjQgMjg1Ljc3IDY0Mi4wMSBDIDI4Ny41NSA2NTcuMTUgMjkwLjM1IDY3Mi4xMSAyOTMuNTQgNjg3LjAxIEMgMjkzLjgyIDY4Ny45NiAyOTMuNzYgNjg4Ljc3IDI5My4zNSA2ODkuNDQgQyAyOTAuNTYgNjk0LjA5IDI4Ny45OSA2OTguOTQgMjg1Ljg5IDcwMy45NCBDIDI4NC42MSA3MDYuODAgMjg0LjQ3IDcwOS45NCAyODQuOTIgNzEzLjAwIEMgMjg2LjIxIDcyMi40MSAyOTEuOTkgNzMwLjMzIDI5My42MCA3MzkuMjYgQyAyOTQuMzkgNzQzLjM5IDI5My44NCA3NDcuODAgMjkzLjk5IDc1Mi4wMCBDIDI5Mi45NCA3NjUuNTIgMjg4LjMyIDc4MC42MCAyOTAuNjEgNzkzLjk5IEMgMjkwLjgxIDc5Ni4yOCAyOTAuNjMgNzk5LjEzIDI4OC43MiA4MDAuNzIgQyAyODUuODUgODAzLjI3IDI4MS41MiA4MDQuNTAgMjc4LjA3IDgwNi4xMyBDIDI3MS44MCA4MDkuMjIgMjYzLjg5IDgwOS42MCAyNTcuMDAgODA5Ljk1IEMgMjUxLjQ2IDgwOS4zNCAyNDUuNTIgODA5LjQ2IDI0MC4yMCA4MDcuNzMgQyAyMzkuMjcgODA1Ljc4IDI0MS42MSA4MDQuNzMgMjQzLjA2IDgwNC4xOCBDIDI0OS42MSA4MDIuMTAgMjU3Ljc5IDgwMy4xOCAyNjMuMDEgNzk3LjkyIEMgMjY5LjA4IDc5MS44MSAyNzIuMTQgNzgyLjM5IDI3My4xOCA3NzQuMDAgQyAyNzQuNjAgNzU1LjEyIDI2OC4xMiA3MzQuMzQgMjY0LjE5IDcxNS45MSBDIDI2Mi44NiA3MTEuNjUgMjYyLjY3IDcwNy40MiAyNjMuMzUgNzAzLjAxIEMgMjY1LjYzIDY5MS45MCAyNjIuOTEgNjc5LjM0IDI2My4yOCA2NjguMDAgQyAyNjMuNTkgNjYxLjM1IDI2My43NCA2NTQuNjQgMjY0LjMzIDY0OC4wMSBDIDI2NS41NyA2MzcuOTIgMjY4LjAwIDYyNi4yNCAyNzQuMTQgNjE3LjkzIFoiIGZpbGw9IiNmZmZmZmYiIC8+CjxwYXRoIGQ9Ik0gMjk0LjM0IDY5MS41NCBMIDI5NC40NyA2OTEuNDAgQyAyOTYuMDUgNzAxLjI3IDI5NS43MyA3MDkuODUgMjk5LjU1IDcxOC4zOSBDIDMwMC44MCA3MjEuOTYgMzAzLjMwIDcyNS4yOSAzMDQuMDEgNzI4Ljk4IEMgMzA1LjQzIDc0Ny45MCAzMDcuODYgNzY1Ljk1IDMwOC43MyA3ODUuMDAgQyAzMDguNTEgNzg3LjQ5IDMwNy42NyA3OTAuMDAgMzA1LjQ3IDc5MS40MSBDIDMwMS41NCA3OTQuMTEgMjk3LjI3IDc5Ni4zMiAyOTMuMjAgNzk4Ljc5IEMgMjkyLjEzIDc5MS41MiAyOTEuNjEgNzg0LjM0IDI5Mi4yMyA3NzcuMDEgQyAyOTMuNDggNzcwLjcxIDI5NC4xNSA3NjQuMzYgMjk0LjkxIDc1Ny45OSBDIDI5NS4xMyA3NTAuMjYgMjk3LjAyIDc0My42MiAyOTUuMTAgNzM1Ljk5IEMgMjkyLjUwIDcyNy40OCAyODcuMjUgNzE4LjkyIDI4Ni4zNCA3MTAuMDAgQyAyODYuMjMgNzAzLjYyIDI5MS4zMyA2OTYuOTggMjk0LjM0IDY5MS41NCBaIiBmaWxsPSIjZmZmZmZmIiAvPgo8L3N2Zz4=',
-
- },
- ],
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/Form.form.js b/web-client/core/themes/italia/static/formio/css/src/components/form/Form.form.js
deleted file mode 100644
index 5edcd85f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/Form.form.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import nestedComponentForm from '../_classes/nested/NestedComponent.form';
-import FormEditDisplay from './editForm/Form.edit.display';
-import FormEditForm from './editForm/Form.edit.form';
-import FormEditData from './editForm/Form.edit.data';
-
-export default function(...extend) {
- return nestedComponentForm([
- {
- key: 'display',
- components: FormEditDisplay
- },
- {
- label: 'Form',
- key: 'form',
- weight: 10,
- components: FormEditForm
- },
- {
- label: 'Data',
- key: 'data',
- weight: 10,
- components: FormEditData
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/Form.js b/web-client/core/themes/italia/static/formio/css/src/components/form/Form.js
deleted file mode 100644
index 54adca51..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/Form.js
+++ /dev/null
@@ -1,855 +0,0 @@
-import _ from 'lodash';
-import Component from '../_classes/component/Component';
-import ComponentModal from '../_classes/componentModal/ComponentModal';
-import EventEmitter from 'eventemitter3';
-import NativePromise from 'native-promise-only';
-import {
- isMongoId,
- eachComponent,
- getStringFromComponentPath,
- getArrayFromComponentPath,
- componentValueTypes
-} from '../../utils/utils';
-import { GlobalFormio as Formio } from '../../Formio';
-import Form from '../../Form';
-
-export default class FormComponent extends Component {
- static schema(...extend) {
- return Component.schema({
- label: 'Form',
- type: 'form',
- key: 'form',
- src: '',
- reference: true,
- form: '',
- path: '',
- tableView: true,
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Nested Form',
- icon: 'wpforms',
- group: 'premium',
- documentation: '/userguide/form-building/premium-components#nested-form',
- weight: 110,
- schema: FormComponent.schema()
- };
- }
-
- static savedValueTypes() {
- return [componentValueTypes.object];
- }
-
- init() {
- super.init();
- this.formObj = {
- display: this.component.display,
- settings: this.component.settings,
- components: this.component.components
- };
- this.valueChanged = false;
- this.subForm = null;
- this.formSrc = '';
- if (this.component.src) {
- this.formSrc = this.component.src;
- }
-
- if (
- !this.component.src &&
- !this.options.formio &&
- (this.component.form || this.component.path)
- ) {
- if (this.component.project) {
- this.formSrc = Formio.getBaseUrl();
- // Check to see if it is a MongoID.
- if (isMongoId(this.component.project)) {
- this.formSrc += '/project';
- }
- this.formSrc += `/${this.component.project}`;
- this.options.project = this.formSrc;
- }
- else {
- this.formSrc = Formio.getProjectUrl();
- this.options.project = this.formSrc;
- }
- if (this.component.form) {
- if (isMongoId(this.component.form)) {
- this.formSrc += `/form/${this.component.form}`;
- }
- else {
- this.formSrc += `/${this.component.form}`;
- }
- }
- else if (this.component.path) {
- this.formSrc += `/${this.component.path}`;
- }
- }
-
- // Build the source based on the root src path.
- if (!this.formSrc && this.options.formio) {
- const rootSrc = this.options.formio.formsUrl;
- if (this.component.form && isMongoId(this.component.form)) {
- this.formSrc = `${rootSrc}/${this.component.form}`;
- }
- else {
- const formPath = this.component.path || this.component.form;
- this.formSrc = `${rootSrc.replace(/\/form$/, '')}/${formPath}`;
- }
- }
-
- if (this.builderMode && this.component.hasOwnProperty('formRevision')) {
- this.component.revision = this.component.formRevision;
- delete this.component.formRevision;
- }
-
- // Add revision version if set.
- if (this.component.revision || this.component.revision === 0 ||
- this.component.formRevision || this.component.formRevision === 0
- || this.component.revisionId
- ) {
- this.setFormRevision(this.component.revisionId || this.component.revision || this.component.formRevision);
- }
-
- return this.createSubForm();
- }
-
- get dataReady() {
- return this.subFormReady || NativePromise.resolve();
- }
-
- get defaultValue() {
- // Not not provide a default value unless the subform is ready so that it will initialize correctly.
- return this.subForm ? super.defaultValue : null;
- }
-
- get defaultSchema() {
- return FormComponent.schema();
- }
-
- get emptyValue() {
- return { data: {} };
- }
-
- get ready() {
- return this.subFormReady || NativePromise.resolve();
- }
-
- get useOriginalRevision() {
- return this.component?.useOriginalRevision && !!this.formObj?.revisions;
- }
-
- setFormRevision(rev) {
- // Remove current revisions from src if it is
- this.formSrc = this.formSrc.replace(/\/v\/[0-9a-z]+/, '');
- const revNumber = Number.parseInt(rev);
-
- if (!isNaN(revNumber)) {
- this.subFormRevision = rev;
- this.formSrc += `/v/${rev}`;
- }
- else {
- this.subFormRevision = undefined;
- }
- }
-
- getComponent(path, fn) {
- path = getArrayFromComponentPath(path);
- if (path[0] === 'data') {
- path.shift();
- }
- const originalPathStr = `${this.path}.data.${getStringFromComponentPath(path)}`;
- if (this.subForm) {
- return this.subForm.getComponent(path, fn, originalPathStr);
- }
- }
-
- getSubOptions(options = {}) {
- options.parentPath = `${this.path}.data.`;
- options.events = this.createEmitter();
-
- // Make sure to not show the submit button in wizards in the nested forms.
- _.set(options, 'buttonSettings.showSubmit', false);
-
- if (!this.options) {
- return options;
- }
- if (this.options.base) {
- options.base = this.options.base;
- }
- if (this.options.project) {
- options.project = this.options.project;
- }
- if (this.options.readOnly || this.component.disabled) {
- options.readOnly = this.options.readOnly || this.component.disabled;
- }
- if (this.options.breadcrumbSettings) {
- options.breadcrumbSettings = this.options.breadcrumbSettings;
- }
- if (this.options.buttonSettings) {
- options.buttonSettings = _.clone(this.options.buttonSettings);
- }
- if (this.options.viewAsHtml) {
- options.viewAsHtml = this.options.viewAsHtml;
- }
- if (this.options.language) {
- options.language = this.options.language;
- }
- if (this.options.template) {
- options.template = this.options.template;
- }
- if (this.options.templates) {
- options.templates = this.options.templates;
- }
- if (this.options.renderMode) {
- options.renderMode = this.options.renderMode;
- }
- if (this.options.attachMode) {
- options.attachMode = this.options.attachMode;
- }
- if (this.options.iconset) {
- options.iconset = this.options.iconset;
- }
- if (this.options.fileService) {
- options.fileService = this.options.fileService;
- }
- if (this.options.onChange) {
- options.onChange = this.options.onChange;
- }
- if (this.options.preview) {
- options.preview = this.options.preview;
- }
- return options;
- }
-
- render() {
- if (this.builderMode) {
- return super.render(this.component.label || 'Nested form');
- }
- const subform = this.subForm ? this.subForm.render() : this.renderTemplate('loading');
- return super.render(subform);
- }
-
- asString(value) {
- return this.getValueAsString(value);
- }
-
- /**
- * Prints out the value of form components as a datagrid value.
- */
-
- getValueAsString(value, options) {
- if (!value) {
- return 'No data provided';
- }
- if (!value.data && value._id) {
- return value._id;
- }
- if (!value.data || !Object.keys(value.data).length) {
- return 'No data provided';
- }
- if (options?.email) {
- let result = (`
-
-
- `);
-
- this.everyComponent((component) => {
- if (component.isInputComponent && component.visible && !component.skipInEmail) {
- result += (`
-
- ${component.label}
- ${component.getView(component.dataValue, options)}
-
- `);
- }
- }, {
- ...options,
- fromRoot: true,
- });
-
- result += (`
-
-
- `);
-
- return result;
- }
- if (_.isEmpty(value)) {
- return '';
- }
-
- return '[Complex Data]';
- }
-
- attach(element) {
- // Don't attach in builder.
- if (this.builderMode) {
- return super.attach(element);
- }
- return super.attach(element)
- .then(() => {
- if (this.isSubFormLazyLoad() && !this.hasLoadedForm && !this.subFormLoading) {
- this.createSubForm(true);
- }
-
- return this.subFormReady.then(() => {
- this.empty(element);
- if (this.options.builder) {
- this.setContent(element, this.ce('div', {
- class: 'text-muted text-center p-2'
- }, this.text(this.formObj.title)));
- return;
- }
-
- this.setContent(element, this.render());
- if (this.subForm) {
- if (this.isNestedWizard) {
- element = this.root.element;
- }
- this.subForm.attach(element);
- this.valueChanged = this.hasSetValue;
-
- if (!this.valueChanged && this.dataValue.state !== 'submitted') {
- this.setDefaultValue();
- }
- else {
- this.restoreValue();
- }
- }
- if (!this.builderMode && this.component.modalEdit) {
- const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;
- const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;
- this.componentModal = new ComponentModal(this, element, modalShouldBeOpened, currentValue);
- this.setOpenModalElement();
- }
-
- this.calculateValue();
- });
- });
- }
-
- detach() {
- if (this.subForm) {
- this.subForm.detach();
- }
- super.detach();
- }
-
- get currentForm() {
- return this._currentForm;
- }
-
- get hasLoadedForm() {
- return this.formObj
- && this.formObj.components
- && Array.isArray(this.formObj.components)
- && this.formObj.components.length;
- }
-
- set currentForm(instance) {
- this._currentForm = instance;
- if (!this.subForm) {
- return;
- }
- this.subForm.getComponents().forEach(component => {
- component.currentForm = this;
- });
- }
-
- get isRevisionChanged() {
- return _.isNumber(this.subFormRevision)
- && _.isNumber(this.formObj._vid)
- && this.formObj._vid !== this.subFormRevision;
- }
-
- destroy() {
- if (this.subForm) {
- this.subForm.destroy();
- this.subForm = null;
- this.subFormReady = null;
- }
- super.destroy();
- }
-
- redraw() {
- if (this.subForm) {
- this.subForm.form = this.formObj;
- this.setSubFormDisabled(this.subForm);
- }
- return super.redraw();
- }
-
- /**
- * Pass everyComponent to subform.
- * @param args
- * @returns {*|void}
- */
- everyComponent(...args) {
- if (this.subForm) {
- this.subForm.everyComponent(...args);
- }
- }
-
- setSubFormDisabled(subForm) {
- subForm.disabled = this.disabled; // When the Nested Form is disabled make the subForm disabled
- }
-
- updateSubWizards(subForm) {
- if (this.isNestedWizard && this.root?.subWizards && subForm?._form?.display === 'wizard') {
- const existedForm = this.root.subWizards.findIndex(form => form.component.form === this.component.form);
- if (existedForm !== -1) {
- this.root.subWizards[existedForm] = this;
- }
- else {
- this.root.subWizards.push(this);
- }
- this.emit('subWizardsUpdated', subForm);
- }
- }
-
- /**
- * Create a subform instance.
- *
- * @return {*}
- */
- createSubForm(fromAttach) {
- this.subFormReady = this.loadSubForm(fromAttach).then((form) => {
- if (!form) {
- return;
- }
-
- // Iterate through every component and hide the submit button.
- eachComponent(form.components, (component) => {
- this.hideSubmitButton(component);
- });
-
- // If the subform is already created then destroy the old one.
- if (this.subForm) {
- this.subForm.destroy();
- }
-
- // Render the form.
- return (new Form(form, this.getSubOptions())).ready.then((instance) => {
- this.subForm = instance;
- this.subForm.currentForm = this;
- this.subForm.parent = this;
- this.subForm.parentVisible = this.visible;
- this.subForm.on('change', () => {
- if (this.subForm) {
- this.dataValue = this.subForm.getValue();
- this.triggerChange({
- noEmit: true
- });
- }
- });
- this.subForm.url = this.formSrc;
- this.subForm.nosubmit = true;
- this.subForm.root = this.root;
- this.subForm.localRoot = this.isNestedWizard ? this.localRoot : this.subForm;
- this.restoreValue();
- this.valueChanged = this.hasSetValue;
- this.onChange();
- return this.subForm;
- });
- }).then((subForm) => {
- this.updateSubWizards(subForm);
- return subForm;
- });
- return this.subFormReady;
- }
-
- hideSubmitButton(component) {
- const isSubmitButton = (component.type === 'button') &&
- ((component.action === 'submit') || !component.action);
-
- if (isSubmitButton) {
- component.hidden = true;
- }
- }
-
- /**
- * Load the subform.
- */
- loadSubForm(fromAttach) {
- if (this.builderMode || this.isHidden() || (this.isSubFormLazyLoad() && !fromAttach)) {
- return NativePromise.resolve();
- }
-
- if (this.hasLoadedForm && !this.isRevisionChanged &&
- !(this.options.pdf && this.component?.useOriginalRevision && _.isNull(this.subForm) && !this.subFormLoading)
- ) {
- // Pass config down to sub forms.
- if (this.root && this.root.form && this.root.form.config && !this.formObj.config) {
- this.formObj.config = this.root.form.config;
- }
- return NativePromise.resolve(this.formObj);
- }
- else if (this.formSrc) {
- this.subFormLoading = true;
- return (new Formio(this.formSrc)).loadForm({ params: { live: 1 } })
- .then((formObj) => {
- this.formObj = formObj;
- if (this.options.pdf && this.component.useOriginalRevision) {
- this.formObj.display = 'form';
- }
- this.subFormLoading = false;
- return formObj;
- })
- .catch((err) => {
- console.log(err);
- return null;
- });
- }
- return NativePromise.resolve();
- }
-
- get subFormData() {
- return this.dataValue?.data || {};
- }
-
- checkComponentValidity(data, dirty, row, options) {
- options = options || {};
- const silentCheck = options.silentCheck || false;
-
- if (this.subForm) {
- return this.subForm.checkValidity(this.subFormData, dirty, null, silentCheck);
- }
-
- return super.checkComponentValidity(data, dirty, row, options);
- }
-
- checkComponentConditions(data, flags, row) {
- const visible = super.checkComponentConditions(data, flags, row);
-
- // Return if already hidden
- if (!visible) {
- return visible;
- }
-
- if (this.subForm) {
- return this.subForm.checkConditions(this.subFormData);
- }
- // There are few cases when subForm is not loaded when a change is triggered,
- // so we need to perform checkConditions after it is ready, or some conditional fields might be hidden in View mode
- else if (this.subFormReady) {
- this.subFormReady.then(() => {
- if (this.subForm) {
- return this.subForm.checkConditions(this.subFormData);
- }
- });
- }
-
- return visible;
- }
-
- calculateValue(data, flags, row) {
- if (this.subForm) {
- return this.subForm.calculateValue(this.subFormData, flags);
- }
-
- return super.calculateValue(data, flags, row);
- }
-
- setPristine(pristine) {
- super.setPristine(pristine);
- if (this.subForm) {
- this.subForm.setPristine(pristine);
- }
- }
-
- /**
- * Determine if the subform should be submitted.
- * @return {*|boolean}
- */
- get shouldSubmit() {
- return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && !this.isHidden();
- }
-
- /**
- * Returns the data for the subform.
- *
- * @return {*}
- */
- getSubFormData() {
- if (_.get(this.subForm, 'form.display') === 'pdf') {
- return this.subForm.getSubmission();
- }
- else {
- return NativePromise.resolve(this.dataValue);
- }
- }
-
- /**
- * Submit the subform if configured to do so.
- *
- * @return {*}
- */
- submitSubForm(rejectOnError) {
- // If we wish to submit the form on next page, then do that here.
- if (this.shouldSubmit) {
- return this.subFormReady.then(() => {
- if (!this.subForm) {
- return this.dataValue;
- }
- this.subForm.nosubmit = false;
- return this.subForm.submitForm().then(result => {
- this.subForm.loading = false;
- this.subForm.showAllErrors = false;
- this.dataValue = result.submission;
- return this.dataValue;
- }).catch(err => {
- this.subForm.showAllErrors = true;
- if (rejectOnError) {
- this.subForm.onSubmissionError(err);
- return NativePromise.reject(err);
- }
- else {
- return {};
- }
- });
- });
- }
- return this.getSubFormData();
- }
-
- /**
- * Submit the form before the next page is triggered.
- */
- beforePage(next) {
- // Should not submit child forms if we are going to the previous page
- if (!next) {
- return super.beforePage(next);
- }
- return this.submitSubForm(true).then(() => super.beforePage(next));
- }
-
- /**
- * Submit the form before the whole form is triggered.
- */
- beforeSubmit() {
- const submission = this.dataValue;
-
- const isAlreadySubmitted = submission && submission._id && submission.form;
-
- // This submission has already been submitted, so just return the reference data.
- if (isAlreadySubmitted && !this.subForm?.wizard) {
- this.dataValue = submission;
- return NativePromise.resolve(this.dataValue);
- }
- return this.submitSubForm(false)
- .then(() => {
- return this.dataValue;
- })
- .then(() => super.beforeSubmit());
- }
-
- isSubFormLazyLoad() {
- return this.root?._form?.display === 'wizard' && this.component.lazyLoad;
- }
-
- isHidden() {
- if (!this.visible) {
- return true;
- }
-
- return !super.checkConditions(this.rootValue);
- }
-
- setValue(submission, flags = {}) {
- const changed = super.setValue(submission, flags);
- this.valueChanged = true;
- if (this.subForm) {
- const revisionPath = submission._frid ? '_frid' : '_vid';
- const shouldLoadOriginalRevision = this.useOriginalRevision
- && (_.isNumber(submission[revisionPath]) || _.isNumber(submission._fvid))
- && _.isNumber(this.subForm.form?.[revisionPath])
- && submission._fvid !== this.subForm.form[revisionPath];
-
- if (shouldLoadOriginalRevision) {
- this.setFormRevision( submission._frid || submission._fvid);
- this.createSubForm().then(() => {
- this.attach(this.element);
- });
- }
- else {
- this.setSubFormValue(submission, flags);
- }
- }
- return changed;
- }
-
- setSubFormValue(submission, flags) {
- const shouldLoadSubmissionById = submission
- && submission._id
- && this.subForm.formio
- && _.isEmpty(submission.data);
-
- if (shouldLoadSubmissionById) {
- const formId = submission.form || this.formObj.form || this.component.form;
- const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id}`;
- this.subForm.setUrl(submissionUrl, this.options);
- this.subForm.loadSubmission().catch((err) => {
- console.error(`Unable to load subform submission ${submission._id}:`, err);
- });
- }
- else {
- this.subForm.setValue(submission, flags);
- }
- }
-
- isEmpty(value = this.dataValue) {
- return value === null || _.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value?.data) && !value?._id);
- }
-
- areAllComponentsEmpty(data) {
- let res = true;
- if (this.subForm) {
- this.subForm.everyComponent((comp) => {
- const componentValue = _.get(data, comp.key);
- res &= comp.isEmpty(componentValue);
- });
- }
- else {
- res = false;
- }
- return res;
- }
-
- getValue() {
- if (this.subForm) {
- return this.subForm.getValue();
- }
- return this.dataValue;
- }
-
- get errors() {
- let errors = super.errors;
- if (this.subForm) {
- errors = errors.concat(this.subForm.errors);
- }
- return errors;
- }
-
- updateSubFormVisibility() {
- if (this.subForm) {
- this.subForm.parentVisible = this.visible;
- }
- }
-
- /**
- * Determines if this form is a Nested Wizard
- * which means it should be a Wizard itself and should be a direct child of a Wizard's page
- * @returns {boolean}
- */
- get isNestedWizard() {
- return this.subForm?._form?.display === 'wizard' && this.parent?.parent?._form?.display === 'wizard';
- }
-
- get visible() {
- return super.visible;
- }
-
- set visible(value) {
- const isNestedWizard = this.isNestedWizard;
-
- if (this._visible !== value) {
- this._visible = value;
- // Form doesn't load if hidden. If it becomes visible, create the form.
- if (!this.subForm && value) {
- this.createSubForm();
- this.subFormReady.then(() => {
- this.updateSubFormVisibility();
- this.clearOnHide();
- });
- this.redraw();
- return;
- }
- this.updateSubFormVisibility();
- this.clearOnHide();
- isNestedWizard ? this.rebuild() : this.redraw();
- }
- if (!value && isNestedWizard) {
- this.root.redraw();
- }
- }
-
- get parentVisible() {
- return super.parentVisible;
- }
-
- set parentVisible(value) {
- if (this._parentVisible !== value) {
- this._parentVisible = value;
- this.clearOnHide();
- // Form doesn't load if hidden. If it becomes visible, create the form.
- if (!this.subForm && value) {
- this.createSubForm();
- this.subFormReady.then(() => {
- this.updateSubFormVisibility();
- });
- this.redraw();
- return;
- }
- this.updateSubFormVisibility();
- this.redraw();
- }
- }
-
- isInternalEvent(event) {
- switch (event) {
- case 'focus':
- case 'blur':
- case 'componentChange':
- case 'componentError':
- case 'error':
- case 'formLoad':
- case 'languageChanged':
- case 'render':
- case 'checkValidity':
- case 'initialized':
- case 'submit':
- case 'submitButton':
- case 'nosubmit':
- case 'updateComponent':
- case 'submitDone':
- case 'submissionDeleted':
- case 'requestDone':
- case 'nextPage':
- case 'prevPage':
- case 'wizardNavigationClicked':
- case 'updateWizardNav':
- case 'restoreDraft':
- case 'saveDraft':
- case 'saveComponent':
- case 'pdfUploaded':
- return true;
- default:
- return false;
- }
- }
-
- createEmitter() {
- const emitter = new EventEmitter();
- const nativeEmit = emitter.emit;
- const that = this;
- emitter.emit = function(event, ...args) {
- const eventType = event.replace(`${that.options.namespace}.`, '');
- nativeEmit.call(this, event, ...args);
- if (!that.isInternalEvent(eventType)) {
- that.emit(eventType, ...args);
- }
- };
-
- return emitter;
- }
-
- deleteValue() {
- super.setValue(null, {
- noUpdateEvent: true,
- noDefault: true
- });
- this.unset();
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/Form.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/form/Form.unit.js
deleted file mode 100644
index 9d2d8c54..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/Form.unit.js
+++ /dev/null
@@ -1,275 +0,0 @@
-import Harness from '../../../test/harness';
-import FormComponent from './Form';
-import { expect } from 'chai';
-import assert from 'power-assert';
-
-import {
- comp1,
- comp3,
- comp4,
- comp5,
- comp6
-} from './fixtures';
-import Webform from '../../Webform';
-import formModalEdit from './fixtures/formModalEdit';
-import { formComponentWithConditionalRenderingForm } from '../../../test/formtest';
-
-describe('Form Component', () => {
- it('Should build a form component', () => {
- return Harness.testCreate(FormComponent, comp1);
- });
-
- describe('Value inside Nested Form', () => {
- it('Should be able to set value to Nested Form Component and check result in the email template', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp5)
- .then(() => {
- const textField = form.getComponent(['form', 'textField']);
- textField.setValue('123', { modified: true });
- assert.equal(textField.dataValue, '123', 'Should set value');
- const toString = form.getValueAsString(textField.data, { email: true });
- assert.ok(toString.includes('table'), 'Email template should render html table');
- assert.ok(toString.includes(textField.label), 'Email template should have Text Field label');
- assert.ok(toString.includes(textField.dataValue), 'Email template should have Text Field value');
- done();
- })
- .catch(done);
- });
- });
-
- it('Test refreshOn inside NestedForm', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp4)
- .then(() => {
- const make = form.getComponent(['form', 'make']);
- const model = form.getComponent(['form', 'model']);
- make.setValue('ford');
- setTimeout(() => {
- assert.equal(make.dataValue, 'ford', 'Should set value');
- model.setValue('Focus', { modified: true });
- setTimeout(() => {
- assert.equal(model.dataValue, 'Focus', 'Should set value');
- make.setValue('honda', { modified: true });
- setTimeout(() => {
- assert.equal(make.dataValue, 'honda', 'Should set value');
- assert.equal(model.dataValue, '', 'Should refresh and clear value');
- done();
- }, 300);
- }, 300);
- }, 300);
- })
- .catch(done);
- });
-
- describe('renderSubForm', () => {
- let formcmp = null;
- it('should set sub form parentVisible', done => {
- Harness.testCreate(FormComponent, comp1)
- .then(cmp => {
- formcmp = cmp;
- formcmp.visible = false;
- return formcmp.subFormReady;
- }, done)
- .then(subForm => {
- expect(formcmp).to.not.be.null;
- expect(formcmp.visible).to.be.false;
- expect(subForm.parentVisible).to.be.false;
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('set visible', () => {
- it('should set visible flag on instance', done => {
- Harness.testCreate(FormComponent, comp1)
- .then(formcmp => {
- expect(formcmp._visible).to.be.true;
- formcmp.visible = false;
- expect(formcmp._visible).to.be.false;
- done();
- }, done)
- .catch(done);
- });
-
- it('should update sub form visibility', done => {
- let formcmp;
- Harness.testCreate(FormComponent, comp1)
- .then(cmp => {
- formcmp = cmp;
- return formcmp.subFormReady;
- }, done)
- .then(subform => {
- expect(formcmp.visible).to.be.true;
- expect(subform.parentVisible).to.be.true;
- formcmp.visible = false;
- expect(formcmp.visible).to.be.false;
- expect(subform.parentVisible).to.be.false;
- formcmp.visible = true;
- expect(formcmp.visible).to.be.true;
- expect(subform.parentVisible).to.be.true;
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('get visible', () => {
- it('should get visible flag from instance', done => {
- Harness.testCreate(FormComponent, comp1)
- .then(formcmp => {
- expect(formcmp._visible).to.be.true;
- expect(formcmp.visible).to.be.true;
- formcmp.visible = false;
- expect(formcmp.visible).to.be.false;
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('set parentVisible', () => {
- it('should set parentVisible flag on instance', done => {
- Harness.testCreate(FormComponent, comp1)
- .then(formcmp => {
- expect(formcmp._parentVisible).to.be.true;
- formcmp.parentVisible = false;
- expect(formcmp._parentVisible).to.be.false;
- done();
- }, done)
- .catch(done);
- });
-
- it('should update sub form visibility', done => {
- let formcmp;
- Harness.testCreate(FormComponent, comp1)
- .then(cmp => {
- formcmp = cmp;
- return formcmp.subFormReady;
- }, done)
- .then(subform => {
- expect(formcmp.parentVisible).to.be.true;
- expect(subform.parentVisible).to.be.true;
- formcmp.parentVisible = false;
- expect(formcmp.parentVisible).to.be.false;
- expect(subform.parentVisible).to.be.false;
- formcmp.parentVisible = true;
- expect(formcmp.parentVisible).to.be.true;
- expect(subform.parentVisible).to.be.true;
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('get parentVisible', () => {
- it('should get parentVisible flag from instance', done => {
- Harness.testCreate(FormComponent, comp1)
- .then(formcmp => {
- expect(formcmp._parentVisible).to.be.true;
- expect(formcmp.parentVisible).to.be.true;
- formcmp.parentVisible = false;
- expect(formcmp.parentVisible).to.be.false;
- done();
- }, done)
- .catch(done);
- });
- });
-
- describe('Modal Edit', () => {
- it('Should render preview when modalEdit', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(formModalEdit).then(() => {
- const preview = form.element.querySelector('[ref="openModal"]');
- assert(preview, 'Should contain element to open a modal window');
- done();
- }).catch(done);
- });
- });
-
- describe('Conditional rendering', () => {
- it('Should render and set submission to conditional form component', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(formComponentWithConditionalRenderingForm).then(() => {
- form.setSubmission({
- data: {
- checkbox: true,
- form: {
- data: {
- textField: 'test'
- }
- }
- }
- }).then(() => {
- setTimeout(() => {
- const checkbox = formElement.querySelector('input[name="data[checkbox]"]');
- const textField = formElement.querySelector('input[name="data[textField]"]');
- expect(checkbox).to.not.be.null;
- assert.equal(checkbox.checked, true);
- expect(textField).to.not.be.null;
- assert.equal(textField.value, 'test');
- done();
- }, 250);
- });
- }).catch(done);
- });
- });
-
- describe('Advanced Logic', () => {
- it('Should disable all components of the form', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp6)
- .then(() => {
- const textField = form.getComponent(['textField']);
- const nestedForm = form.getComponent(['form']);
- textField.setValue('test', { modified: true });
- setTimeout(() => {
- assert.equal(textField.dataValue, 'test', 'Should set value');
- assert.equal(nestedForm.disabled, true, 'Nested Form should be disabled');
- done();
- }, 300);
- })
- .catch(done);
- });
- });
-
- describe('Inside Collapsed Panel', () => {
- it('Should be able to set value to Nested Form Component inside collapsed Panel', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp5)
- .then(() => {
- const textField = form.getComponent(['form', 'textField']);
- const panel = form.getComponent('panel333');
- textField.setValue('123', { modified: true });
- setTimeout(() => {
- assert.equal(textField.dataValue, '123', 'Should set value');
- panel.collapsed = false;
- setTimeout(() => {
- assert.equal(textField.dataValue, '123', 'Should keep the set value after the panel was expanded');
- done();
- }, 300);
- }, 300);
- })
- .catch(done);
- });
- });
-});
-
-describe('Wizard Component', () => {
- it('Should build a wizard component and disable cancel, next and breadcrumbs', (done) => {
- Harness.testCreate(FormComponent, comp3, {
- breadcrumbSettings:
- { clickable: false },
- buttonSettings:
- { showCancel: false, showPrevious: false }
- }).then(() => {
- done();
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.data.js
deleted file mode 100644
index c091424e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.data.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import EditFormUtils from '../../_classes/component/editForm/utils';
-/* eslint-disable max-len */
-export default [
- EditFormUtils.javaScriptValue('Custom Default Value', 'customDefaultValue', 'customDefaultValue', 120,
- '
Example: value = data.firstName + " " + data.lastName; ',
- '
Example: {"cat": [{"var": "data.firstName"}, " ", {"var": "data.lastName"}]} '
- ),
- EditFormUtils.javaScriptValue('Calculated Value', 'calculateValue', 'calculateValue', 130,
- '
Example: value = data.a + data.b + data.c; ',
- '
Example: {"+": [{"var": "data.a"}, {"var": "data.b"}, {"var": "data.c"}]} Click here for an example
'
- ),
- {
- weight: 140,
- type: 'checkbox',
- label: 'Clear Value When Hidden',
- key: 'clearOnHide',
- defaultValue: true,
- tooltip: 'When a field is hidden, clear the value.',
- input: true
- },
-];
-/* eslint-enable max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.display.js
deleted file mode 100644
index a913d738..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.display.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'tabIndex',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
-];
-/* eslint-enable max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.form.js b/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.form.js
deleted file mode 100644
index 7fab9e94..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/editForm/Form.edit.form.js
+++ /dev/null
@@ -1,73 +0,0 @@
-export default [
- {
- type: 'select',
- input: true,
- dataSrc: 'url',
- data: {
- url: '/form?limit=1000000&select=_id,title,display'
- },
- searchField: 'title__regex',
- template: '{{ item.title }} ',
- valueProperty: '_id',
- authenticate: true,
- label: 'Form',
- key: 'form',
- weight: 10,
- lazyLoad: false,
- tooltip: 'The form to load within this form component.',
- validate: {
- required: true,
- },
- },
- {
- label: 'Lazy Load',
- inputType: 'checkbox',
- defaultValue: true,
- clearOnHide: true,
- errorLabel: '',
- key: 'lazyLoad',
- type: 'checkbox',
- tooltip: 'if it is checked, the subform is loaded after navigation to the page with this component within the wizard.',
- input: true,
- customConditional( { instance, data }) {
- const formInfo = instance.root?.getComponent('form')?.defaultDownloadedResources.find(res => res._id === data.form);
- const displayMode = 'wizard';
-
- return instance.options?.editForm?.display === displayMode && formInfo && formInfo.display !== displayMode;
- },
- },
- {
- type: 'select',
- input: true,
- dataSrc: 'url',
- data: {
- url: '/form/{{ data.form }}/v'
- },
- searchField: 'title__regex',
- template: '{{ item._vid }} ',
- valueProperty: '_id',
- authenticate: true,
- label: 'Form Revision',
- key: 'revision',
- weight: 10,
- lazyLoad: true,
- tooltip: 'You can lock the nested form to a specific revision by choosing the revision number here.',
- customConditional: 'show = !!data.form'
- },
- {
- type: 'checkbox',
- input: true,
- weight: 19,
- key: 'useOriginalRevision',
- label: 'Use Original Revision while Submissions Viewing',
- tooltip: 'Using this option will make form load the original revision (the one which was used to make a submission) when viewing a submission.'
- },
- {
- type: 'checkbox',
- input: true,
- weight: 20,
- key: 'reference',
- label: 'Save as reference',
- tooltip: 'Using this option will save this field as a reference and link its value to the value of the origin record.'
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp1.js
deleted file mode 100644
index 058f9950..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp1.js
+++ /dev/null
@@ -1,84 +0,0 @@
-export default {
- key: 'form1',
- input: false,
- tableView: true,
- components: [
- {
- input: true,
- tableView: true,
- inputType: 'text',
- inputMask: '',
- label: 'First Name',
- key: 'firstName',
- placeholder: '',
- prefix: '',
- suffix: '',
- multiple: false,
- defaultValue: '',
- protected: false,
- unique: false,
- persistent: true,
- clearOnHide: true,
- validate: {
- required: false,
- minLength: '',
- maxLength: '',
- pattern: '',
- custom: '',
- customPrivate: false
- },
- conditional: {
- show: '',
- when: null,
- eq: ''
- },
- type: 'textfield',
- tags: [
-
- ]
- },
- {
- input: true,
- tableView: true,
- inputType: 'text',
- inputMask: '',
- label: 'Last Name',
- key: 'lastName',
- placeholder: '',
- prefix: '',
- suffix: '',
- multiple: false,
- defaultValue: '',
- protected: false,
- unique: false,
- persistent: true,
- clearOnHide: true,
- validate: {
- required: false,
- minLength: '',
- maxLength: '',
- pattern: '',
- custom: '',
- customPrivate: false
- },
- conditional: {
- show: '',
- when: null,
- eq: ''
- },
- type: 'textfield',
- tags: [
-
- ]
- }
- ],
- type: 'form',
- tags: [
-
- ],
- conditional: {
- show: '',
- when: null,
- eq: ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp2.js
deleted file mode 100644
index 761be558..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp2.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export default {
- key: 'form1',
- input: false,
- tableView: true,
- src: 'https://remote.form.io/testproject/example',
- type: 'form',
- tags: [
-
- ],
- conditional: {
- show: '',
- when: null,
- eq: ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp3.js
deleted file mode 100644
index b0caf740..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp3.js
+++ /dev/null
@@ -1,168 +0,0 @@
-export default {
- type: 'form',
- tags: [],
- components: [
- {
- type: 'panel',
- title: 'Page 1',
- isNew: false,
- components: [
- {
- autofocus: false,
- input: true,
- tableView: true,
- inputType: 'text',
- inputMask: '',
- label: 'Text',
- key: 'page1Text',
- placeholder: '',
- prefix: '',
- suffix: '',
- multiple: false,
- defaultValue: '',
- protected: false,
- unique: false,
- persistent: true,
- hidden: false,
- clearOnHide: true,
- spellcheck: true,
- validate: {
- required: false,
- minLength: '',
- maxLength: '',
- pattern: '',
- custom: '',
- customPrivate: false
- },
- conditional: {
- show: '',
- when: null,
- eq: ''
- },
- type: 'textfield',
- labelPosition: 'top',
- inputFormat: 'plain',
- tags: [],
- properties: { }
- }
- ],
- input: false,
- key: 'page1',
- clearOnHide: false,
- theme: 'default',
- tableView: false,
- hideLabel: false
- },
- {
- type: 'panel',
- title: 'Page 2',
- isNew: false,
- components: [
- {
- autofocus: false,
- input: true,
- tableView: true,
- inputType: 'number',
- label: 'Number',
- key: 'page2Number',
- placeholder: '',
- prefix: '',
- suffix: '',
- defaultValue: '',
- protected: false,
- persistent: true,
- hidden: false,
- clearOnHide: true,
- validate: {
- required: false,
- min: '',
- max: '',
- step: 'any',
- integer: '',
- multiple: '',
- custom: ''
- },
- type: 'number',
- labelPosition: 'top',
- tags: [],
- conditional: {
- show: '',
- when: null,
- eq: ''
- },
- properties: { }
- }
- ],
- input: false,
- key: 'page2',
- clearOnHide: false,
- theme: 'default',
- tableView: false,
- hideLabel: false
- },
- {
- type: 'panel',
- title: 'Page 3',
- isNew: false,
- components: [
- {
- autofocus: false,
- input: true,
- inputType: 'checkbox',
- tableView: true,
- label: 'Hola',
- dataGridLabel: false,
- key: 'page3Hola',
- defaultValue: false,
- protected: false,
- persistent: true,
- hidden: false,
- name: '',
- value: '',
- clearOnHide: true,
- validate: {
- required: false
- },
- type: 'checkbox',
- labelPosition: 'right',
- hideLabel: false,
- tags: [],
- conditional: {
- show: '',
- when: null,
- eq: ''
- },
- properties: { }
- }
- ],
- input: false,
- key: 'page3',
- clearOnHide: false,
- theme: 'default',
- tableView: false,
- hideLabel: false
- },
- {
- autofocus: false,
- input: true,
- label: 'Submit',
- tableView: false,
- key: 'submit',
- size: 'md',
- leftIcon: '',
- rightIcon: '',
- block: false,
- action: 'submit',
- disableOnInvalid: false,
- theme: 'primary',
- type: 'button'
- }
- ],
- revisions: '',
- title: 'Wiizard',
- display: 'wizard',
- submissionAccess: [],
- settings: { },
- name: 'wiizard',
- path: 'wiizard'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp4.js
deleted file mode 100644
index d433aaac..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp4.js
+++ /dev/null
@@ -1,89 +0,0 @@
-export default {
- type: 'form',
- owner: null,
- components: [
- {
- label: 'Form',
- tableView: true,
- display: 'form',
- components: [
- {
- input: true,
- tableView: true,
- label: 'Make',
- key: 'make',
- data: {
- values: [
- {
- value: 'ford',
- label: 'Ford'
- },
- {
- value: 'honda',
- label: 'Honda'
- }
- ],
- },
- dataSrc: 'values',
- template: '{{ item.label }} ',
- validate: {
- required: true
- },
- type: 'select',
- },
- {
- label: 'Model',
- widget: 'choicesjs',
- placeholder: 'Select your model',
- tableView: true,
- dataSrc: 'url',
- data: {
- url: 'https://vpic.nhtsa.dot.gov/api/vehicles/getmodelsformake/{{ data.make }}?format=json',
- headers: [
- {
- key: '',
- value: ''
- }
- ]
- },
- valueProperty: 'Model_Name',
- template: '{{ item.Model_Name }} ',
- refreshOn: 'make',
- clearOnRefresh: true,
- selectThreshold: 0.3,
- clearOnHide: false,
- validate: {
- required: true
- },
- key: 'model',
- type: 'select',
- indexeddb: {
- filter: {}
- },
- selectValues: 'Results',
- input: true,
- disableLimit: false,
- lazyLoad: false
- },
- {
- input: true,
- label: 'Submit',
- tableView: false,
- key: 'submit',
- type: 'button'
- }
- ],
- key: 'form',
- type: 'form',
- input: true
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp5.js
deleted file mode 100644
index be8dfd0c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp5.js
+++ /dev/null
@@ -1,43 +0,0 @@
-export default {
- type: 'form',
- owner: null,
- components: [
- {
- title: 'Panel 333',
- collapsible: true,
- key: 'panel333',
- type: 'panel',
- label: 'Panel 333',
- input: false,
- tableView: false,
- components: [
- {
- label: 'Form',
- tableView: true,
- display: 'form',
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- ],
- key: 'form',
- type: 'form',
- input: true,
- },
- ],
- collapsed: true,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp6.js
deleted file mode 100644
index 5bc0f6a4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/comp6.js
+++ /dev/null
@@ -1,92 +0,0 @@
-export default {
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Form',
- tableView: true,
- display: 'form',
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Text Area',
- autoExpand: false,
- tableView: true,
- key: 'textArea',
- type: 'textarea',
- input: true,
- },
- ],
- logic: [
- {
- name: 'disabled',
- trigger: {
- type: 'simple',
- simple: { show: true, when: 'textField', eq: 'test' },
- conditionConditionGrid: [],
- },
- actions: [
- {
- name: 'Disable',
- type: 'property',
- property: {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean',
- },
- state: true,
- variableVariableGrid: [],
- },
- ],
- },
- {
- name: 'required',
- trigger: {
- type: 'simple',
- simple: { show: true, when: 'textField', eq: 'required' },
- conditionConditionGrid: [],
- },
- actions: [
- {
- name: 'required',
- type: 'property',
- property: {
- label: 'Required',
- value: 'validate.required',
- type: 'boolean',
- },
- state: true,
- variableVariableGrid: [],
- },
- ],
- },
- ],
- key: 'form',
- type: 'form',
- input: true,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- title: 'MainFormWithNested',
- display: 'form',
- path: 'nestedmain',
- name: 'mainFormWithNested',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/formModalEdit.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/formModalEdit.js
deleted file mode 100644
index ba020d71..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/formModalEdit.js
+++ /dev/null
@@ -1,50 +0,0 @@
-export default {
- '_id': '5ed8d0f9b507cf407c61f2d6',
- 'type': 'form',
- 'owner': '5e05a6b7549cdc2ece30c6b0',
- 'components': [
- {
- 'label': 'Form',
- 'tableView': true,
- 'modalEdit': true,
- 'components': [
- {
- 'label': 'Nested Text Field',
- 'tableView': true,
- 'key': 'nestedTextField',
- 'type': 'textfield',
- 'input': true
- }
- ],
- 'key': 'form',
- 'type': 'form',
- 'input': true
- },
- {
- 'type': 'button',
- 'label': 'Submit',
- 'key': 'submit',
- 'disableOnInvalid': true,
- 'input': true,
- 'tableView': false
- }
- ],
- 'controller': '',
- 'revisions': '',
- '_vid': 0,
- 'title': 'nestedModal',
- 'display': 'form',
- 'access': [
- {
- 'roles': [
- '5e96e79ee1c3ad3178454100',
- '5e96e79ee1c3ad3178454101',
- '5e96e79ee1c3ad3178454102'
- ],
- 'type': 'read_all'
- }
- ],
- 'name': 'nestedModal',
- 'path': 'nestedmodal',
-};
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/index.js
deleted file mode 100644
index 29026a46..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export formModalEdit from './formModalEdit';
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
-export comp6 from './comp6';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/values.js
deleted file mode 100644
index 50fb1e80..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/form/fixtures/values.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default [
- {
- data: {
- foo: 'bar',
- },
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.form.js b/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.form.js
deleted file mode 100644
index 1e11a940..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.form.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import Components from '../Components';
-import HiddenEditDisplay from './editForm/Hidden.edit.display';
-import HiddenEditData from './editForm/Hidden.edit.data';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: HiddenEditDisplay
- },
- {
- key: 'data',
- components: HiddenEditData
- },
- {
- key: 'validation',
- ignore: true
- },
- {
- key: 'conditional',
- ignore: true
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.js b/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.js
deleted file mode 100644
index 0f09c4ad..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import Input from '../_classes/input/Input';
-
-export default class HiddenComponent extends Input {
- static schema(...extend) {
- return Input.schema({
- type: 'hidden',
- tableView: false,
- inputType: 'hidden'
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Hidden',
- group: 'data',
- icon: 'user-secret',
- weight: 0,
- documentation: '/userguide/form-building/data-components#hidden',
- showPreview: false,
- schema: HiddenComponent.schema()
- };
- }
-
- get defaultSchema() {
- return HiddenComponent.schema();
- }
-
- get inputInfo() {
- const info = super.elementInfo();
- info.type = 'input';
- info.attr.type = 'hidden';
- info.changeEvent = 'change';
- return info;
- }
-
- get skipInEmail() {
- return true;
- }
-
- /**
- * Check if a component is eligible for multiple validation
- *
- * @return {boolean}
- */
- validateMultiple() {
- // Since "arrays" are able to be stored in hidden components, we need to turn off multiple validation.
- return false;
- }
-
- labelIsHidden() {
- return true;
- }
-
- get emptyValue() {
- return '';
- }
-
- setValue(value, flags = {}) {
- return this.updateValue(value, flags);
- }
-
- getValue() {
- return this.dataValue;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.unit.js
deleted file mode 100644
index ba3e6b78..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/hidden/Hidden.unit.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import Harness from '../../../test/harness';
-import HiddenComponent from './Hidden';
-
-import {
- comp1
-} from './fixtures';
-
-describe('Hidden Component', () => {
- it('Should build a hidden component', () => {
- return Harness.testCreate(HiddenComponent, comp1);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/hidden/editForm/Hidden.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/hidden/editForm/Hidden.edit.data.js
deleted file mode 100644
index 1f1b9c78..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/hidden/editForm/Hidden.edit.data.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true
- },
- {
- key: 'clearOnHide',
- ignore: true
- },
- {
- key: 'allowCalculateOverride',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/hidden/editForm/Hidden.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/hidden/editForm/Hidden.edit.display.js
deleted file mode 100644
index 2b10976d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/hidden/editForm/Hidden.edit.display.js
+++ /dev/null
@@ -1,42 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'hideLabel',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- key: 'hidden',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
- {
- key: 'disabled',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/comp1.js
deleted file mode 100644
index 6ab57051..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/comp1.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'hidden',
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'label': 'Secret',
- 'key': 'secret',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/values.js
deleted file mode 100644
index 142a5b4e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/hidden/fixtures/values.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- 'one',
- 1,
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.form.js b/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.form.js
deleted file mode 100644
index 7f793d24..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.form.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import Components from '../Components';
-import HTMLEditDisplay from './editForm/HTML.edit.display';
-import HTMLEditLogic from './editForm/HTML.edit.logic';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: HTMLEditDisplay,
- },
- {
- key: 'data',
- ignore: true,
- },
- {
- key: 'validation',
- ignore: true,
- },
- {
- key: 'logic',
- components: HTMLEditLogic,
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.js b/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.js
deleted file mode 100644
index cd4838da..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.js
+++ /dev/null
@@ -1,99 +0,0 @@
-import Component from '../_classes/component/Component';
-import _ from 'lodash';
-
-export default class HTMLComponent extends Component {
- static schema(...extend) {
- return Component.schema({
- label: 'HTML',
- type: 'htmlelement',
- tag: 'p',
- attrs: [],
- content: '',
- input: false,
- persistent: false
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'HTML Element',
- group: 'layout',
- icon: 'code',
- weight: 0,
- documentation: '/userguide/form-building/layout-components#html-element',
- showPreview: false,
- schema: HTMLComponent.schema()
- };
- }
-
- static savedValueTypes() {
- return [];
- }
-
- get defaultSchema() {
- return HTMLComponent.schema();
- }
-
- get content() {
- if (this.builderMode) {
- return this.component.content;
- }
-
- // i18n returns error exactly with word 'select', spaces will be trimmed
- if (this.component.content.replace(/(<(\/?[^>]+)>)/g, '').trim() === 'select') {
- return ` ${this.component.content} `;
- }
-
- const submission = _.get(this.root, 'submission', {});
- const content = this.component.content ? this.interpolate(this.component.content, {
- metadata: submission.metadata || {},
- submission: submission,
- data: this.rootValue,
- row: this.data
- }) : '';
- return this.sanitize(content, this.shouldSanitizeValue);
- }
-
- get singleTags() {
- return ['br', 'img', 'hr'];
- }
-
- checkRefreshOn(changed) {
- super.checkRefreshOn(changed);
- if (!this.builderMode && this.component.refreshOnChange && this.element &&
- !_.isUndefined(changed) && ((_.isBoolean(changed) && changed) || !_.isEmpty(changed)) &&
- this.conditionallyVisible(this.data, this.row)) {
- this.setContent(this.element, this.renderContent());
- }
- }
-
- renderContent() {
- const submission = _.get(this.root, 'submission', {});
- return this.renderTemplate('html', {
- component: this.component,
- tag: this.component.tag,
- attrs: (this.component.attrs || []).map((attr) => {
- return {
- attr: attr.attr,
- value: this.interpolate(attr.value, {
- metadata: submission.metadata || {},
- submission: submission,
- data: this.rootValue,
- row: this.data
- })
- };
- }),
- content: this.content,
- singleTags: this.singleTags,
- });
- }
-
- render() {
- return super.render(this.renderContent());
- }
-
- attach(element) {
- this.loadRefs(element, { html: 'single' });
- return super.attach(element);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.unit.js
deleted file mode 100644
index 1ffe31eb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/html/HTML.unit.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import Harness from '../../../test/harness';
-import HTMLComponent from './HTML';
-import sinon from 'sinon';
-import assert from 'power-assert';
-
-import {
- comp1,
- comp2
-} from './fixtures';
-
-describe('HTML Component', () => {
- it('Should build an html component', () => {
- return Harness.testCreate(HTMLComponent, comp1);
- });
-
- it('Should build an html component and ignore empty attribute name', () => {
- const comp = comp1;
- comp.attrs.push({
- 'attr': '',
- 'value': ''
- });
-
- return Harness.testCreate(HTMLComponent, comp1);
- });
-
- it('setContent should not be called if it is not conditionally visible', () => {
- return Harness.testCreate(HTMLComponent, comp2).then((component) => {
- const emit = sinon.spy(component, 'setContent');
- component.checkRefreshOn(null);
- assert.equal(emit.callCount, 0);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/html/editForm/HTML.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/html/editForm/HTML.edit.display.js
deleted file mode 100644
index 3e02c682..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/html/editForm/HTML.edit.display.js
+++ /dev/null
@@ -1,98 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'hideLabel',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'disabled',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
- {
- type: 'textfield',
- input: true,
- key: 'tag',
- weight: 50,
- label: 'HTML Tag',
- placeholder: 'HTML Element Tag',
- tooltip: 'The tag of this HTML element.'
- },
- {
- type: 'textfield',
- input: true,
- key: 'className',
- weight: 60,
- label: 'CSS Class',
- placeholder: 'CSS Class',
- tooltip: 'The CSS class for this HTML element.'
- },
- {
- type: 'datagrid',
- input: true,
- label: 'Attributes',
- key: 'attrs',
- tooltip: 'The attributes for this HTML element. Only safe attributes are allowed, such as src, href, and title.',
- weight: 70,
- components: [
- {
- label: 'Attribute',
- key: 'attr',
- input: true,
- type: 'textfield'
- },
- {
- label: 'Value',
- key: 'value',
- input: true,
- type: 'textfield'
- }
- ]
- },
- {
- type: 'textarea',
- input: true,
- editor: 'ace',
- rows: 10,
- as: 'html',
- label: 'Content',
- tooltip: 'The content of this HTML element.',
- defaultValue: 'Content
',
- key: 'content',
- weight: 80
- },
- {
- weight: 85,
- type: 'checkbox',
- label: 'Refresh On Change',
- tooltip: 'Rerender the field whenever a value on the form changes.',
- key: 'refreshOnChange',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/html/editForm/HTML.edit.logic.js b/web-client/core/themes/italia/static/formio/css/src/components/html/editForm/HTML.edit.logic.js
deleted file mode 100644
index e71f4596..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/html/editForm/HTML.edit.logic.js
+++ /dev/null
@@ -1,98 +0,0 @@
-export default [
- {
- key: 'logic',
- components: [
- {
- key: 'actions',
- components: [
- {
- key: 'actionPanel',
- components: [
- {
- data: {
- json: [
- {
- label: 'Hidden',
- value: 'hidden',
- type: 'boolean',
- },
- {
- label: 'Required',
- value: 'validate.required',
- type: 'boolean',
- },
- {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean',
- },
- {
- label: 'Label',
- value: 'label',
- type: 'string',
- },
- {
- label: 'Title',
- value: 'title',
- type: 'string',
- },
- {
- label: 'Tooltip',
- value: 'tooltip',
- type: 'string',
- },
- {
- label: 'Description',
- value: 'description',
- type: 'string',
- },
- {
- label: 'Placeholder',
- value: 'placeholder',
- type: 'string',
- },
- {
- label: 'CSS Class',
- value: 'className',
- type: 'string',
- },
- {
- label: 'Container Custom Class',
- value: 'customClass',
- type: 'string',
- },
- {
- label: 'Content',
- value: 'content',
- type: 'string',
- component: 'content',
- },
- ],
- },
- key: 'property',
- },
- {
- type: 'textarea',
- editor: 'ace',
- rows: 10,
- as: 'html',
- label: 'Content',
- tooltip: 'The content of this HTML element.',
- defaultValue: 'Content
',
- key: 'content',
- weight: 30,
- input: true,
- customConditional(context) {
- return context.row.type === 'property' &&
- context.row.hasOwnProperty('property') &&
- context.row.property.type === 'string' &&
- context.row.property.component === 'content';
- },
- },
- ],
- },
- ],
- },
- ],
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/comp1.js
deleted file mode 100644
index ebc33259..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/comp1.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export default {
- 'key': 'html1',
- 'input': false,
- 'tag': 'img',
- 'attrs': [
- {
- 'value': 'https://www.w3.org/html/logo/downloads/HTML5_Logo_512.png',
- 'attr': 'src'
- }
- ],
- 'className': 'thumbnail',
- 'content': '',
- 'type': 'htmlelement',
- 'tags': [
-
- ],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/comp2.js
deleted file mode 100644
index e2e248e4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/comp2.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export default {
- 'key': 'html1',
- 'input': false,
- 'tag': 'img',
- 'attrs': [
- {
- 'value': 'https://www.w3.org/html/logo/downloads/HTML5_Logo_512.png',
- 'attr': 'src'
- }
- ],
- 'className': 'thumbnail',
- 'content': '',
- 'type': 'htmlelement',
- 'tags': [
-
- ],
- 'customConditional':'show = false;',
- 'conditional': {
- 'show': '',
- 'when': '',
- 'eq': ''
- },
- 'refreshOnChange': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/index.js
deleted file mode 100644
index 63468958..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/html/fixtures/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/index.js b/web-client/core/themes/italia/static/formio/css/src/components/index.js
deleted file mode 100644
index 5ec679e6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/index.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import AddressComponent from './address/Address';
-import ButtonComponent from './button/Button';
-import CheckBoxComponent from './checkbox/Checkbox';
-import ColumnsComponent from './columns/Columns';
-import Component from './_classes/component/Component';
-import ComponentModal from './_classes/componentModal/ComponentModal';
-import ContainerComponent from './container/Container';
-import ContentComponent from './content/Content';
-import CurrencyComponent from './currency/Currency';
-import DataGridComponent from './datagrid/DataGrid';
-import DataMapComponent from './datamap/DataMap';
-import DateTimeComponent from './datetime/DateTime';
-import DayComponent from './day/Day';
-import EditGridComponent from './editgrid/EditGrid';
-import EmailComponent from './email/Email';
-import FieldsetComponent from './fieldset/Fieldset';
-import FileComponent from './file/File';
-import FormComponent from './form/Form';
-import HiddenComponent from './hidden/Hidden';
-import Input from './_classes/input/Input';
-import Multivalue from './_classes/multivalue/Multivalue';
-import Field from './_classes/field/Field';
-import ListComponent from './_classes/list/ListComponent';
-import HTMLComponent from './html/HTML';
-import NestedComponent from './_classes/nested/NestedComponent';
-import NestedDataComponent from './_classes/nesteddata/NestedDataComponent';
-import NestedArrayComponent from './_classes/nestedarray/NestedArrayComponent';
-import NumberComponent from './number/Number';
-import PanelComponent from './panel/Panel';
-import PasswordComponent from './password/Password';
-import PhoneNumberComponent from './phonenumber/PhoneNumber';
-import RadioComponent from './radio/Radio';
-import ReCaptchaComponent from './recaptcha/ReCaptcha';
-import ResourceComponent from './resource/Resource';
-import SelectBoxesComponent from './selectboxes/SelectBoxes';
-import SelectComponent from './select/Select';
-import SignatureComponent from './signature/Signature';
-import SurveyComponent from './survey/Survey';
-import TableComponent from './table/Table';
-import TabsComponent from './tabs/Tabs';
-import TagsComponent from './tags/Tags';
-import TextAreaComponent from './textarea/TextArea';
-import TextFieldComponent from './textfield/TextField';
-import TimeComponent from './time/Time';
-import TreeComponent from './tree/Tree';
-import UnknownComponent from './unknown/Unknown';
-import UrlComponent from './url/Url';
-import WellComponent from './well/Well';
-
-export default {
- address: AddressComponent,
- base: Component,
- component: Component,
- componentmodal: ComponentModal,
- button: ButtonComponent,
- checkbox: CheckBoxComponent,
- columns: ColumnsComponent,
- container: ContainerComponent,
- content: ContentComponent,
- currency: CurrencyComponent,
- datagrid: DataGridComponent,
- datamap: DataMapComponent,
- datetime: DateTimeComponent,
- day: DayComponent,
- editgrid: EditGridComponent,
- email: EmailComponent,
- input: Input,
- field: Field,
- multivalue: Multivalue,
- list: ListComponent,
- fieldset: FieldsetComponent,
- file: FileComponent,
- form: FormComponent,
- hidden: HiddenComponent,
- htmlelement: HTMLComponent,
- nested: NestedComponent,
- nesteddata: NestedDataComponent,
- nestedarray: NestedArrayComponent,
- number: NumberComponent,
- panel: PanelComponent,
- password: PasswordComponent,
- phoneNumber: PhoneNumberComponent,
- radio: RadioComponent,
- recaptcha: ReCaptchaComponent,
- resource: ResourceComponent,
- select: SelectComponent,
- selectboxes: SelectBoxesComponent,
- signature: SignatureComponent,
- survey: SurveyComponent,
- table: TableComponent,
- tabs: TabsComponent,
- tags: TagsComponent,
- textarea: TextAreaComponent,
- textfield: TextFieldComponent,
- time: TimeComponent,
- tree: TreeComponent,
- unknown: UnknownComponent,
- url: UrlComponent,
- well: WellComponent,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/Number.form.js b/web-client/core/themes/italia/static/formio/css/src/components/number/Number.form.js
deleted file mode 100644
index 08197329..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/Number.form.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import textEditForm from '../textfield/TextField.form';
-
-import NumberEditDisplay from './editForm/Number.edit.display';
-import NumberEditData from './editForm/Number.edit.data';
-import NumberEditValidation from './editForm/Number.edit.validation';
-
-export default function(...extend) {
- return textEditForm([
- {
- key: 'display',
- components: NumberEditDisplay
- },
- {
- key: 'data',
- components: NumberEditData
- },
- {
- key: 'validation',
- components: NumberEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/Number.js b/web-client/core/themes/italia/static/formio/css/src/components/number/Number.js
deleted file mode 100644
index 7e8e953a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/Number.js
+++ /dev/null
@@ -1,237 +0,0 @@
-import { createNumberMask } from '@formio/text-mask-addons';
-import { conformToMask,maskInput } from '@formio/vanilla-text-mask';
-import _ from 'lodash';
-import Input from '../_classes/input/Input';
-import { getNumberSeparators, getNumberDecimalLimit, componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-
-export default class NumberComponent extends Input {
- static schema(...extend) {
- return Input.schema({
- type: 'number',
- label: 'Number',
- key: 'number',
- validate: {
- min: '',
- max: '',
- step: 'any',
- integer: ''
- }
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Number',
- icon: 'hashtag',
- group: 'basic',
- documentation: '/userguide/form-building/form-components#number',
- weight: 30,
- schema: NumberComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return NumberComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: [...super.conditionOperatorsSettings.operators, 'lessThan', 'greaterThan', 'lessThanOrEqual','greaterThanOrEqual'],
- valueComponent(classComp) {
- return { ... classComp, type: 'number' };
- }
- };
- }
-
- static savedValueTypes(schema) {
- schema = schema || {};
- return getComponentSavedTypes(schema) || [componentValueTypes.number];
- }
-
- constructor(...args) {
- super(...args);
- this.validators = this.validators.concat(['min', 'max']);
-
- const separators = getNumberSeparators(this.options.language || navigator.language);
-
- this.decimalSeparator = this.options.decimalSeparator = this.options.decimalSeparator
- || this.options.properties?.decimalSeparator
- || separators.decimalSeparator;
-
- if (this.component.delimiter) {
- if (this.options.hasOwnProperty('thousandsSeparator')) {
- console.warn("Property 'thousandsSeparator' is deprecated. Please use i18n to specify delimiter.");
- }
-
- this.delimiter = this.options.properties?.thousandsSeparator || this.options.thousandsSeparator || separators.delimiter;
- }
- else {
- this.delimiter = '';
- }
-
- const requireDecimal = _.get(this.component, 'requireDecimal', false);
- this.decimalLimit = getNumberDecimalLimit(this.component, requireDecimal ? 2 : 20);
-
- // Currencies to override BrowserLanguage Config. Object key {}
- if (_.has(this.options, `languageOverride.${this.options.language}`)) {
- const override = _.get(this.options, `languageOverride.${this.options.language}`);
- this.decimalSeparator = override.decimalSeparator;
- this.delimiter = override.delimiter;
- }
- this.numberMask = this.createNumberMask();
- }
-
- /**
- * Creates the number mask for normal numbers.
- *
- * @return {*}
- */
- createNumberMask() {
- return createNumberMask({
- prefix: '',
- suffix: '',
- requireDecimal: _.get(this.component, 'requireDecimal', false),
- thousandsSeparatorSymbol: _.get(this.component, 'thousandsSeparator', this.delimiter),
- decimalSymbol: _.get(this.component, 'decimalSymbol', this.decimalSeparator),
- decimalLimit: _.get(this.component, 'decimalLimit', this.decimalLimit),
- allowNegative: _.get(this.component, 'allowNegative', true),
- allowDecimal: this.isDecimalAllowed(),
- });
- }
-
- get defaultSchema() {
- return NumberComponent.schema();
- }
-
- get defaultValue() {
- let defaultValue = super.defaultValue;
- if (!defaultValue && this.component.defaultValue === 0) {
- defaultValue = this.component.defaultValue;
- }
-
- if (!this.component.multiple && _.isArray(defaultValue)) {
- defaultValue = !defaultValue[0] && defaultValue[0] !== 0 ? null : defaultValue[0];
- }
- return defaultValue;
- }
-
- isDecimalAllowed() {
- return _.get(this.component, 'allowDecimal', !(this.component.validate && this.component.validate.integer));
- }
-
- parseNumber(value) {
- // Remove delimiters and convert decimal separator to dot.
- value = value.split(this.delimiter).join('').replace(this.decimalSeparator, '.');
-
- if (this.component.validate && this.component.validate.integer) {
- return parseInt(value, 10);
- }
- else {
- return parseFloat(value);
- }
- }
-
- setInputMask(input) {
- let numberPattern = '[0-9';
- numberPattern += this.decimalSeparator || '';
- numberPattern += this.delimiter || '';
- numberPattern += ']*';
- input.setAttribute('pattern', numberPattern);
- input.mask = maskInput({
- inputElement: input,
- mask: this.numberMask,
- shadowRoot: this.root ? this.root.shadowRoot : null,
- });
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- if (this.component.mask) {
- info.attr.type = 'password';
- }
- else {
- info.attr.type = 'text';
- }
- info.attr.inputmode = this.isDecimalAllowed() ? 'decimal' : 'numeric';
- info.changeEvent = 'input';
- return info;
- }
-
- getValueAt(index) {
- if (!this.refs.input.length || !this.refs.input[index]) {
- return null;
- }
-
- const val = this.refs.input[index].value;
- return val && val !== '-_' ? this.parseNumber(val) : null;
- }
-
- setValueAt(index, value, flags = {}) {
- return super.setValueAt(index, this.formatValue(this.parseValue(value)), flags);
- }
-
- parseValue(input) {
- if (typeof input === 'string') {
- input = input.split(this.delimiter).join('').replace(this.decimalSeparator, '.');
- }
- let value = parseFloat(input);
-
- if (!_.isNaN(value)) {
- value = String(value).replace('.', this.decimalSeparator);
- }
- else {
- value = null;
- }
-
- return value;
- }
-
- formatValue(value) {
- if (this.component.requireDecimal && value && !value.includes(this.decimalSeparator)) {
- return `${value}${this.decimalSeparator}${_.repeat('0', this.decimalLimit)}`;
- }
- else if (this.component.requireDecimal && value && value.includes(this.decimalSeparator)) {
- return `${value}${_.repeat('0', this.decimalLimit - value.split(this.decimalSeparator)[1].length)}`;
- }
-
- return value;
- }
-
- focus() {
- const input = this.refs.input[0];
- if (input) {
- super.focus.call(this);
- input.setSelectionRange(0, input.value.length);
- }
- }
-
- getMaskedValue(value) {
- value = value === null ? '0' : value.toString();
-
- if (value.includes('.') && '.'!== this.decimalSeparator) {
- value = value.replace('.', this.decimalSeparator);
- }
-
- return conformToMask(this.formatValue(value), this.numberMask).conformedValue;
- }
-
- getValueAsString(value, options) {
- if (!value && value !== 0) {
- return '';
- }
- value = this.getWidgetValueAsString(value, options);
- if (Array.isArray(value)) {
- return value.map((val) => this.getMaskedValue(val)).join(', ');
- }
- return this.getMaskedValue(value);
- }
-
- addFocusBlurEvents(element) {
- super.addFocusBlurEvents(element);
-
- this.addEventListener(element, 'blur', () => {
- element.value = this.getValueAsString(this.formatValue(this.parseValue(element.value)));
- });
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/Number.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/number/Number.unit.js
deleted file mode 100644
index c0e718d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/Number.unit.js
+++ /dev/null
@@ -1,519 +0,0 @@
-import assert from 'power-assert';
-import _ from 'lodash';
-import _merge from 'lodash/merge';
-import Harness from '../../../test/harness';
-import Formio from './../../Formio';
-import NumberComponent from './Number';
-
-import {
- comp1,
- comp2,
- comp3,
- comp4,
- comp5,
- comp6,
- comp7,
-} from './fixtures';
-
-describe('Number Component', () => {
- it('Should build an number component', () => {
- return Harness.testCreate(NumberComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 1);
- });
- });
-
- it('Should format submissions for table view for French locale', () => {
- return Harness.testCreate(NumberComponent, comp4, { language: 'fr' }).then((component) => {
- const value1 = component.getValueAsString(1);
- const value2 = component.getValueAsString(1.1);
- const value3 = component.getValueAsString(1.11);
- const value4 = component.getValueAsString(1111);
- const value5 = component.getValueAsString(1111111);
- const value6 = component.getValueAsString(-11111);
-
- assert.equal(value1, '1,00');
- assert.equal(value2, '1,10');
- assert.equal(value3, '1,11');
- assert.equal(value4, '1 111,00');
- assert.equal(value5, '1 111 111,00');
- assert.equal(value6, '-11 111,00');
- });
- });
-
- it('Should format sumbissions for table view for USA locale', () => {
- return Harness.testCreate(NumberComponent, comp4, { language: 'en-US' }).then((component) => {
- const value1 = component.getValueAsString(1);
- const value2 = component.getValueAsString(1.1);
- const value3 = component.getValueAsString(1.11);
- const value4 = component.getValueAsString(1111);
- const value5 = component.getValueAsString(1111111);
- const value6 = component.getValueAsString(-11111);
-
- assert.equal(value1, '1.00');
- assert.equal(value2, '1.10');
- assert.equal(value3, '1.11');
- assert.equal(value4, '1,111.00');
- assert.equal(value5, '1,111,111.00');
- assert.equal(value6, '-11,111.00');
- });
- });
-
- it('Should format value on blur for USA locale', () => {
- return Harness.testCreate(NumberComponent, comp4, { language: 'en-US' }).then((component) => {
- component.root = {
- onChange: ()=>{},
- triggerChange: ()=>{},
- };
-
- const blurEvent = new Event('blur');
- const inputEvent = new Event('input');
- const valueElement = component.element.querySelector('[name="data[number]"]');
-
- valueElement.value = 22222222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '22,222,222.00');
-
- valueElement.value = 22222222.2;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '22,222,222.20');
-
- valueElement.value = 22222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '22,222.00');
-
- valueElement.value = 2;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.equal(valueElement.value, '2.00');
- });
- });
-
- it('Should format value on blur for French locale', (done) => {
- Harness.testCreate(NumberComponent, comp4, { language: 'fr' }).then((component) => {
- component.root = {
- onChange: ()=>{},
- triggerChange: ()=>{},
- };
-
- const blurEvent = new Event('blur');
- const inputEvent = new Event('input');
- const valueElement = component.element.querySelector('[name="data[number]"]');
-
- valueElement.value = 22222222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '22 222 222,00');
-
- valueElement.value = '22222222,2';
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '22 222 222,20');
-
- valueElement.value = 22222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '22 222,00');
-
- valueElement.value = 222;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '222,00');
-
- valueElement.value = 2;
- valueElement.dispatchEvent(inputEvent);
- valueElement.dispatchEvent(blurEvent);
- assert.deepEqual(valueElement.value, '2,00');
-
- done();
- });
- });
-
- it('Should not change entered value on blur if multiple value is set', (done) => {
- Harness.testCreate(NumberComponent, comp5).then((component) => {
- component.root = {
- onChange: ()=>{},
- triggerChange: ()=>{},
- };
- const blurEvent = new Event('blur');
- const clickEvent = new Event('click');
- const addBtn = component.refs.addButton[0];
-
- addBtn.dispatchEvent(clickEvent);
-
- const firstValueElement = component.element.querySelectorAll('[name="data[number]"]')[0];
- const secondValueElement = component.element.querySelectorAll('[name="data[number]"]')[1];
-
- component.setValue([111,222]);
-
- firstValueElement.dispatchEvent(blurEvent);
- secondValueElement.dispatchEvent(blurEvent);
-
- assert.equal(component.dataValue[0], component.getValue()[0]);
- assert.equal(component.dataValue[1], component.getValue()[1]);
- done();
- });
- });
-
- it('Should limit decimals using step', () => {
- return Harness.testCreate(NumberComponent, _merge({}, comp2, {
- validate: {
- step: '0.001'
- }
- })).then((component) => {
- Harness.testSetInput(component, 123456789.123456789, 123456789.123, '123,456,789.123');
- Harness.testSetInput(component, -123456789.123456789, -123456789.123, '-123,456,789.123');
- Harness.testSetInput(component, '123456789.123456789', 123456789.123, '123,456,789.123');
- Harness.testSetInput(component, '-123456789.123456789', -123456789.123, '-123,456,789.123');
- });
- });
-
- it('Should format submissions for table view for French locale', () => {
- return Harness.testCreate(NumberComponent, comp2, { language: 'fr' }).then((component) => {
- const value1 = component.getValueAsString(1);
- const value2 = component.getValueAsString(1.1);
- const value3 = component.getValueAsString(1.1111111);
- const value4 = component.getValueAsString(1111);
- const value5 = component.getValueAsString(1111111);
- const value6 = component.getValueAsString(-11111.1111);
-
- assert.equal(value1, '1');
- assert.equal(value2, '1,1');
- assert.equal(value3, '1,1111111');
- assert.equal(value4, '1 111');
- assert.equal(value5, '1 111 111');
- assert.equal(value6, '-11 111,1111');
- });
- });
-
- it('Should format sumissions for table view for USA locale', () => {
- return Harness.testCreate(NumberComponent, comp2, { language: 'en-US' }).then((component) => {
- const value1 = component.getValueAsString(1);
- const value2 = component.getValueAsString(1.1);
- const value3 = component.getValueAsString(1.1111111);
- const value4 = component.getValueAsString(1111);
- const value5 = component.getValueAsString(1111111);
- const value6 = component.getValueAsString(-11111.1111);
-
- assert.equal(value1, '1');
- assert.equal(value2, '1.1');
- assert.equal(value3, '1.1111111');
- assert.equal(value4, '1,111');
- assert.equal(value5, '1,111,111');
- assert.equal(value6, '-11,111.1111');
- });
- });
-
- it('Should format numbers for USA locale', () => {
- /* eslint-disable max-statements */
- return Harness.testCreate(NumberComponent, comp2, { language: 'en-US' }).then((component) => {
- Harness.testSetInput(component, null, null, '');
- Harness.testSetInput(component, undefined, null, '');
- Harness.testSetInput(component, '', null, '');
- Harness.testSetInput(component, {}, null, '');
- Harness.testSetInput(component, [], null, '');
- Harness.testSetInput(component, [''], null, '');
- Harness.testSetInput(component, ['1'], 1, '1');
- Harness.testSetInput(component, 0, 0, '0');
- Harness.testSetInput(component, 1, 1, '1');
- Harness.testSetInput(component, -1, -1, '-1');
- Harness.testSetInput(component, 1000, 1000, '1,000');
- Harness.testSetInput(component, -1000, -1000, '-1,000');
- Harness.testSetInput(component, 1000.00, 1000, '1,000');
- Harness.testSetInput(component, -1000.00, -1000, '-1,000');
- Harness.testSetInput(component, 1000.01, 1000.01, '1,000.01');
- Harness.testSetInput(component, -1000.01, -1000.01, '-1,000.01');
- Harness.testSetInput(component, 1000.001, 1000.001, '1,000.001');
- Harness.testSetInput(component, -1000.001, -1000.001, '-1,000.001');
- Harness.testSetInput(component, 1234567890.12, 1234567890.12, '1,234,567,890.12');
- Harness.testSetInput(component, -1234567890.12, -1234567890.12, '-1,234,567,890.12');
- Harness.testSetInput(component, 12.123456789, 12.123456789, '12.123456789');
- Harness.testSetInput(component, -12.123456789, -12.123456789, '-12.123456789');
- // These tests run into the maximum number of significant digits for floats.
- Harness.testSetInput(component, 123456789.123456789, 123456789.123456789, '123,456,789.12345679');
- Harness.testSetInput(component, -123456789.123456789, -123456789.123456789, '-123,456,789.12345679');
- Harness.testSetInput(component, '0', 0, '0');
- Harness.testSetInput(component, '1', 1, '1');
- Harness.testSetInput(component, '-1', -1, '-1');
- Harness.testSetInput(component, '1000', 1000, '1,000');
- Harness.testSetInput(component, '-1000', -1000, '-1,000');
- Harness.testSetInput(component, '1000.01', 1000.01, '1,000.01');
- Harness.testSetInput(component, '-1000.01', -1000.01, '-1,000.01');
- Harness.testSetInput(component, '1000.00', 1000, '1,000');
- Harness.testSetInput(component, '-1000.00', -1000, '-1,000');
- Harness.testSetInput(component, '1000.001', 1000.001, '1,000.001');
- Harness.testSetInput(component, '-1000.001', -1000.001, '-1,000.001');
- Harness.testSetInput(component, '1234567890.12', 1234567890.12, '1,234,567,890.12');
- Harness.testSetInput(component, '-1234567890.12', -1234567890.12, '-1,234,567,890.12');
- Harness.testSetInput(component, '12.123456789', 12.123456789, '12.123456789');
- Harness.testSetInput(component, '-12.123456789', -12.123456789, '-12.123456789');
- Harness.testSetInput(component, '123456789.123456789', 123456789.123456789, '123,456,789.12345679');
- Harness.testSetInput(component, '-123456789.123456789', -123456789.123456789, '-123,456,789.12345679');
- });
- /* eslint-enable max-statements */
- });
-
- it('Should format numbers for British locale', () => {
- return Harness.testCreate(NumberComponent, comp2, { language: 'en-GB' }).then((component) => {
- Harness.testSetInput(component, null, null, '');
- Harness.testSetInput(component, 0, 0, '0');
- Harness.testSetInput(component, 1, 1, '1');
- Harness.testSetInput(component, -1, -1, '-1');
- Harness.testSetInput(component, 1000, 1000, '1,000');
- Harness.testSetInput(component, -1000, -1000, '-1,000');
- Harness.testSetInput(component, 1000.00, 1000, '1,000');
- Harness.testSetInput(component, -1000.00, -1000, '-1,000');
- Harness.testSetInput(component, 1000.01, 1000.01, '1,000.01');
- Harness.testSetInput(component, -1000.01, -1000.01, '-1,000.01');
- Harness.testSetInput(component, 1000.001, 1000.001, '1,000.001');
- Harness.testSetInput(component, -1000.001, -1000.001, '-1,000.001');
- Harness.testSetInput(component, 1234567890.12, 1234567890.12, '1,234,567,890.12');
- Harness.testSetInput(component, -1234567890.12, -1234567890.12, '-1,234,567,890.12');
- Harness.testSetInput(component, 12.123456789, 12.123456789, '12.123456789');
- Harness.testSetInput(component, -12.123456789, -12.123456789, '-12.123456789');
- });
- });
-
- it('Should format numbers for French locale', () => {
- return Harness.testCreate(NumberComponent, comp2, { language: 'fr' }).then((component) => {
- // The spaces in these tests are a weird unicode space so be careful duplicating the tests.
- Harness.testSetInput(component, null, null, '');
- Harness.testSetInput(component, 0, 0, '0');
- Harness.testSetInput(component, 1, 1, '1');
- Harness.testSetInput(component, -1, -1, '-1');
- Harness.testSetInput(component, 1000, 1000, '1 000');
- Harness.testSetInput(component, -1000, -1000, '-1 000');
- Harness.testSetInput(component, 1000.00, 1000, '1 000');
- Harness.testSetInput(component, -1000.00, -1000, '-1 000');
- Harness.testSetInput(component, 1000.01, 1000.01, '1 000,01');
- Harness.testSetInput(component, -1000.01, -1000.01, '-1 000,01');
- Harness.testSetInput(component, 1000.001, 1000.001, '1 000,001');
- Harness.testSetInput(component, -1000.001, -1000.001, '-1 000,001');
- Harness.testSetInput(component, 1234567890.12, 1234567890.12, '1 234 567 890,12');
- Harness.testSetInput(component, -1234567890.12, -1234567890.12, '-1 234 567 890,12');
- Harness.testSetInput(component, 12.123456789, 12.123456789, '12,123456789');
- Harness.testSetInput(component, -12.123456789, -12.123456789, '-12,123456789');
- });
- });
-
- it('Should format numbers for German locale', () => {
- return Harness.testCreate(NumberComponent, comp2, { language: 'de' }).then((component) => {
- Harness.testSetInput(component, null, null, '');
- Harness.testSetInput(component, 0, 0, '0');
- Harness.testSetInput(component, 1, 1, '1');
- Harness.testSetInput(component, -1, -1, '-1');
- Harness.testSetInput(component, 1000, 1000, '1.000');
- Harness.testSetInput(component, -1000, -1000, '-1.000');
- Harness.testSetInput(component, 1000.00, 1000, '1.000');
- Harness.testSetInput(component, -1000.00, -1000, '-1.000');
- Harness.testSetInput(component, 1000.01, 1000.01, '1.000,01');
- Harness.testSetInput(component, -1000.01, -1000.01, '-1.000,01');
- Harness.testSetInput(component, 1000.001, 1000.001, '1.000,001');
- Harness.testSetInput(component, -1000.001, -1000.001, '-1.000,001');
- Harness.testSetInput(component, 1234567890.12, 1234567890.12, '1.234.567.890,12');
- Harness.testSetInput(component, -1234567890.12, -1234567890.12, '-1.234.567.890,12');
- Harness.testSetInput(component, 12.123456789, 12.123456789, '12,123456789');
- Harness.testSetInput(component, -12.123456789, -12.123456789, '-12,123456789');
- });
- });
-
- it('Should display default integer value', () => {
- return Harness.testCreate(NumberComponent, comp3).then(number => {
- assert.deepEqual(_.get(number, ['refs', 'input', '0', 'value']), '42');
- });
- });
-
- it('Should display default decimal value', () => {
- const TEST_VAL = 4.2;
- const comp = _.cloneDeep(comp3);
-
- comp.defaultValue = TEST_VAL;
- comp.decimalLimit = 2;
- comp.requireDecimal = true;
-
- return Harness.testCreate(NumberComponent, comp).then(number => {
- assert.deepEqual(_.get(number, ['refs', 'input', '0', 'value']), '4.20');
- });
- });
-
- it('Should provide min/max validation', (done) => {
- const form = _.cloneDeep(comp6);
-
- const validValues = [
- null,
- 20,
- 555,
- 34,
- 20.000001,
- 554.999
- ];
-
- const invalidMin = [
- 19.99,
- 0,
- 1,
- 0.34,
- -0.1,
- -20
- ];
-
- const invalidMax = [
- 555.00000001,
- 100000,
- 5555,
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form, { language: 'en-US' }).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('number');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidMin, false, 'Number cannot be less than 20.');
- testValidity(invalidMax, false, 'Number cannot be greater than 555.', invalidMax[invalidMax.length-1]);
- });
-
- it('Should be able to switch between multiple and single values', (done) => {
- Harness.testCreate(NumberComponent, comp5).then((component) => {
- assert.equal(_.isEqual(component.defaultValue, [null]), true);
- component.component.multiple = false;
- component.redraw().then(() => {
- assert.equal(component.defaultValue, null);
- done();
- });
- });
- });
-
- it('Should return value as string properly for multiple values', (done) => {
- Harness.testCreate(NumberComponent, comp7).then((component) => {
- component.refs.input = null;
- assert.equal(component.getValueAsString([1, 2, 3, 4, 5]), '1, 2, 3, 4, 5');
- done();
- }).catch(done);
- });
-
- // it('Should add trailing zeros on blur, if decimal required', (done) => {
- // const comp = _.cloneDeep(comp3);
- //
- // comp.decimalLimit = 2;
- // comp.requireDecimal = true;
- //
- // Harness.testCreate(NumberComponent, comp).then(number => {
- // const testset = [
- // // [inv, outv, display]
- // ['42', 42, '42.00'],
- // ['42.1', 42.1, '42.10'],
- // ['42.01', 42.01, '42.01'],
- // ['4200', 4200, '4200.00'],
- // ['4200.4', 4200.4, '4200.40'],
- // ['4200.42', 4200.42, '4200.42'],
- // ['4200.', 4200, '4200.00'],
- // ['99999999.', 99999999, '99999999.00']
- // ];
- //
- // testset.forEach((set, index) => {
- // try {
- // Harness.testNumberBlur(number, ...set);
- // }
- // catch (err) {
- // done(new Error(`Test case #${index}, set: ${set}, err: ${err.message}`));
- // }
- // });
- //
- // done();
- // }, done);
- // });
- //
- // it('Should add trailing zeros on blur, if decimal and delimiter is required', (done) => {
- // const comp = _.cloneDeep(comp3);
- //
- // comp.decimalLimit = 2;
- // comp.requireDecimal = true;
- // comp.delimiter = true;
- //
- // /* eslint-disable max-statements */
- // Harness.testCreate(NumberComponent, comp).then(number => {
- // const testset = [
- // // [inv, outv, display]
- // ['42', 42, '42.00'],
- // ['42.1', 42.1, '42.10'],
- // ['42.01', 42.01, '42.01'],
- // ['4200', 4200, '4,200.00'],
- // ['4200.4', 4200.4, '4,200.40'],
- // ['4200.42', 4200.42, '4,200.42'],
- // ['4200.', 4200, '4,200.00'],
- // ['99999999.', 99999999, '99,999,999.00']
- // ];
- //
- // testset.forEach((set, index) => {
- // try {
- // Harness.testNumberBlur(number, ...set);
- // }
- // catch (err) {
- // done(new Error(`Test case #${index}, set: ${set}, err: ${err.message}`));
- // }
- // });
- //
- // done();
- // }, done);
- // });
- //
- // it('Should add trailing zeros on blur with `multiple` flag', (done) => {
- // Harness.testCreate(NumberComponent, comp4).then(number => {
- // const testset = [
- // ['42', 42, '42.00'],
- // ['42.1', 42.1, '42.10'],
- // ['42.01', 42.01, '42.01'],
- // ['4200', 4200, '4,200.00'],
- // ['4200.4', 4200.4, '4,200.40'],
- // ['4200.42', 4200.42, '4,200.42'],
- // ['4200.', 4200, '4,200.00'],
- // ['99999999.', 99999999, '99,999,999.00']
- // ];
- //
- // testset.forEach((set, index) => {
- // try {
- // assert.strictEqual(number.inputs.length, index + 1);
- // Harness.testNumberBlur(number, ...set, index);
- // number.addValue();
- // }
- // catch (err) {
- // done(new Error(`Test case #${index}, set: ${set}, err: ${err.message}`));
- // }
- // });
- //
- // done();
- // }, done);
- // });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.data.js
deleted file mode 100644
index 1c937e49..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.data.js
+++ /dev/null
@@ -1,30 +0,0 @@
-export default [
- {
- type: 'checkbox',
- input: true,
- weight: 70,
- key: 'delimiter',
- label: 'Use Thousands Separator',
- tooltip: 'Separate thousands by local delimiter.'
- },
- {
- type: 'number',
- input: true,
- weight: 80,
- key: 'decimalLimit',
- label: 'Decimal Places',
- tooltip: 'The maximum number of decimal places.'
- },
- {
- type: 'checkbox',
- input: true,
- weight: 90,
- key: 'requireDecimal',
- label: 'Require Decimal',
- tooltip: 'Always show decimals, even if trailing zeros.'
- },
- {
- key: 'case',
- ignore: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.display.js
deleted file mode 100644
index 06689713..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.display.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export default [
- {
- key: 'spellcheck',
- ignore: true
- },
- {
- key: 'inputMask',
- ignore: true
- },
- {
- key: 'allowMultipleMasks',
- ignore: true
- },
- {
- key: 'showWordCount',
- ignore: true,
- },
- {
- key: 'showCharCount',
- ignore: true,
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.validation.js
deleted file mode 100644
index 458e4b79..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/editForm/Number.edit.validation.js
+++ /dev/null
@@ -1,44 +0,0 @@
-export default [
- {
- key: 'unique',
- ignore: true
- },
- {
- key: 'validate.minLength',
- ignore: true
- },
- {
- key: 'validate.maxLength',
- ignore: true
- },
- {
- key: 'validate.minWords',
- ignore: true
- },
- {
- key: 'validate.maxWords',
- ignore: true
- },
- {
- key: 'validate.pattern',
- ignore: true
- },
- {
- type: 'number',
- label: 'Minimum Value',
- key: 'validate.min',
- input: true,
- placeholder: 'Minimum Value',
- tooltip: 'The minimum value this field must have before the form can be submitted.',
- weight: 150
- },
- {
- type: 'number',
- label: 'Maximum Value',
- key: 'validate.max',
- input: true,
- placeholder: 'Maximum Value',
- tooltip: 'The maximum value this field can have before the form can be submitted.',
- weight: 160
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp1.js
deleted file mode 100644
index b8e39306..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp1.js
+++ /dev/null
@@ -1,32 +0,0 @@
-export default {
- 'multiple': true,
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'number',
- 'validate': {
- 'custom': '',
- 'multiple': '',
- 'integer': '',
- 'step': 'any',
- 'max': '',
- 'min': '',
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'defaultValue': '',
- 'suffix': 'USD',
- 'prefix': '$',
- 'placeholder': 'Enter some money!',
- 'key': 'money',
- 'label': 'Money',
- 'inputType': 'number',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp2.js
deleted file mode 100644
index 28e4e209..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp2.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- 'multiple': false,
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'number',
- 'validate': {
- 'custom': '',
- 'multiple': '',
- 'integer': '',
- 'step': 'any',
- 'max': '',
- 'min': '',
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'defaultValue': '',
- 'placeholder': 'Enter a number',
- 'key': 'number',
- 'label': 'Number',
- 'inputType': 'number',
- 'tableView': true,
- 'delimiter': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp3.js
deleted file mode 100644
index 14931a4a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp3.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default {
- label: 'Number',
- mask: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'number',
- input: true,
- key: 'number',
- delimiter: false,
- requireDecimal: false,
- encrypted: false,
- defaultValue: 42
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp4.js
deleted file mode 100644
index efdf080f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp4.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default {
- 'label': 'Number',
- 'mask': false,
- 'spellcheck': true,
- 'tableView': true,
- 'delimiter': true,
- 'requireDecimal': true,
- 'inputFormat': 'plain',
- 'key': 'number',
- 'type': 'number',
- 'decimalLimit': 2,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp5.js
deleted file mode 100644
index 77857918..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp5.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default {
- 'label': 'Number',
- 'mask': false,
- 'spellcheck': true,
- 'tableView': false,
- 'multiple': true,
- 'delimiter': false,
- 'requireDecimal': false,
- 'inputFormat': 'plain',
- 'calculateServer': false,
- 'validate': {
- 'multiple': true
- },
- 'key': 'number',
- 'type': 'number',
- 'input': true,
- 'defaultValue': [null]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp6.js
deleted file mode 100644
index 1329193f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp6.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- validate: { min: 20, max: 555 },
- key: 'number',
- type: 'number',
- input: true
- },
- { label: 'Submit', showValidations: false, tableView: false, key: 'submit', type: 'button', input: true }
- ],
- revisions: '',
- _vid: 0,
- title: 'number tests',
- display: 'form',
- name: 'numberTests',
- path: 'numbertests',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp7.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp7.js
deleted file mode 100644
index b4a027e1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/comp7.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default {
- label: 'Number',
- mask: false,
- tableView: false,
- modalEdit: true,
- multiple: true,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- key: 'number',
- type: 'number',
- input: true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/index.js
deleted file mode 100644
index c66e70ec..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
-export comp6 from './comp6';
-export comp7 from './comp7';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/values.js
deleted file mode 100644
index 05aefb23..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/number/fixtures/values.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export default [
- 1,
- -1,
- 0,
- 1.000,
- 10000,
- 10000.0001,
- 1234567890,
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.form.js b/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.form.js
deleted file mode 100644
index 33353322..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.form.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import nestedComponentForm from '../_classes/nested/NestedComponent.form';
-
-import PanelEditDisplay from './editForm/Panel.edit.display';
-import PanelEditConditional from './editForm/Panel.edit.conditional';
-
-export default function(...extend) {
- return nestedComponentForm([
- {
- key: 'display',
- components: PanelEditDisplay
- },
- {
- key: 'conditional',
- components: PanelEditConditional,
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.js b/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.js
deleted file mode 100644
index b6a3aeb3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import NestedComponent from '../_classes/nested/NestedComponent';
-import { hasInvalidComponent } from '../../utils/utils';
-import FormComponent from '../form/Form';
-
-export default class PanelComponent extends NestedComponent {
- static schema(...extend) {
- return NestedComponent.schema({
- label: 'Panel',
- type: 'panel',
- key: 'panel',
- title: 'Panel',
- theme: 'default',
- breadcrumb: 'default',
- components: [],
- clearOnHide: false,
- input: false,
- tableView: false,
- persistent: false
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Panel',
- icon: 'list-alt',
- group: 'layout',
- documentation: '/userguide/form-building/layout-components#panel',
- weight: 30,
- schema: PanelComponent.schema()
- };
- }
-
- get defaultSchema() {
- return PanelComponent.schema();
- }
-
- get templateName() {
- return 'panel';
- }
-
- static savedValueTypes() {
- return [];
- }
-
- constructor(...args) {
- super(...args);
- this.noField = true;
- this.on('componentError', () => {
- //change collapsed value only when the panel is collapsed to avoid additional redrawing that prevents validation messages
- if (hasInvalidComponent(this) && this.collapsed) {
- this.collapsed = false;
- }
- });
- }
-
- getComponent(path, fn, originalPath) {
- if (this.root?.parent instanceof FormComponent) {
- path = path.replace(this._parentPath, '');
- }
- return super.getComponent(path, fn, originalPath);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.unit.js
deleted file mode 100644
index 1ede35cb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/panel/Panel.unit.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import assert from 'power-assert';
-import Harness from '../../../test/harness';
-import { flattenComponents } from '../../utils/formUtils';
-import PanelComponent from './Panel';
-import panelEditForm from './Panel.form';
-import Formio from '../../Formio';
-import {
- comp1,
- comp2
-} from './fixtures';
-
-describe('Panel Component', () => {
- it('Should build a panel component', () => {
- return Harness.testCreate(PanelComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 2);
- });
- });
-
- it('Should keep validation errors after expanding collapsed panel', (done) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, comp2).then(form => {
- const panel = form.getComponent('panel');
- const numberComp = form.getComponent('number');
- const textComp = form.getComponent('textField');
-
- assert.equal(panel.collapsed, false);
- assert.equal(!!numberComp.error, false);
- assert.equal(!!textComp.error, false);
-
- const numberInput = numberComp.refs?.input[0];
- numberInput.value = 5;
- const inputEvent = new Event('input');
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(!!numberComp.error, true);
- assert.equal(numberComp.error.messages.length, 1);
- assert.equal(numberComp.refs.messageContainer.querySelectorAll('.error').length, 1);
- assert.equal(!!textComp.error, false);
-
- const clickEvent = new Event('click');
- panel.refs.header.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(panel.collapsed, true);
- panel.refs.header.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(panel.collapsed, false);
- assert.equal(!!numberComp.error, true);
- assert.equal(numberComp.error.messages.length, 1);
- assert.equal(numberComp.refs.messageContainer.querySelectorAll('.error').length, 1);
- assert.equal(!!textComp.error, false);
- done();
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- describe('Edit Form', () => {
- it('should include components for important settings', () => {
- const components = flattenComponents(panelEditForm().components);
- const keys = Object.keys(components).map(path => components[path].key);
- const settings = [
- 'breadcrumb',
- 'breadcrumbClickable'
- ];
-
- assert(settings.every(s => keys.includes(s)));
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/panel/editForm/Panel.edit.conditional.js b/web-client/core/themes/italia/static/formio/css/src/components/panel/editForm/Panel.edit.conditional.js
deleted file mode 100644
index 14455dfb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/panel/editForm/Panel.edit.conditional.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import EditFormUtils from '../../_classes/component/editForm/utils';
-import _isEqual from 'lodash/isEqual';
-import _omit from 'lodash/omit';
-import _difference from 'lodash/difference';
-import _keys from 'lodash/keys';
-/* eslint-disable quotes, max-len */
-const title = 'Advanced Next Page';
-const jsonProp = 'nextPage';
-const jsProp = 'nextPage';
-const jsDocHTML = (`
- You must assign the next variable with the API key of the next page.
- The global variable data is provided, and allows you to access the data of any form component, by using its API key.
- Also moment library is available, and allows you to manipulate dates in a convenient way.
- Example next = data.addComment ? 'page3' : 'page4';
-`);
-const jsonDocHTML = (`
- Submission data is available as JsonLogic variables, with the same api key as your components.
-`);
-
-const settingComponent = EditFormUtils.javaScriptValue(
- title,
- jsProp,
- jsonProp,
- 110,
- jsDocHTML,
- jsonDocHTML
-);
-
-export default [
- {
- ...settingComponent,
- customConditional(context) {
- let isWizardPanel = false;
- if (context.instance.options.editForm.display === 'wizard') {
- const { components } = context.instance.options.editForm;
- const component = context.instance.options.editComponent;
- if (components && component) {
- isWizardPanel = components.some((comp) => {
- const diff = _difference(_keys(comp), _keys(component)) || [];
- diff.push('components');
- return _isEqual(_omit(comp, diff), _omit(component, diff));
- });
- }
- }
- return isWizardPanel;
- }
- }
-];
-/* eslint-enable quotes, max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/panel/editForm/Panel.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/panel/editForm/Panel.edit.display.js
deleted file mode 100644
index ce97999c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/panel/editForm/Panel.edit.display.js
+++ /dev/null
@@ -1,208 +0,0 @@
-import _isEqual from 'lodash/isEqual';
-import _omit from 'lodash/omit';
-import _difference from 'lodash/difference';
-import _keys from 'lodash/keys';
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
- {
- key: 'label',
- hidden: true,
- calculateValue(context) {
- return context.data.title;
- }
- },
- {
- key: 'tabindex',
- hidden: true,
- },
- {
- weight: 1,
- type: 'textfield',
- input: true,
- placeholder: 'Panel Title',
- label: 'Title',
- key: 'title',
- tooltip: 'The title text that appears in the header of this panel.'
- },
- {
- weight: 20,
- type: 'textarea',
- input: true,
- key: 'tooltip',
- label: 'Tooltip',
- placeholder: 'To add a tooltip to this field, enter text here.',
- tooltip: 'Adds a tooltip to the side of this field.'
- },
- {
- weight: 30,
- type: 'select',
- input: true,
- label: 'Theme',
- key: 'theme',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Default', value: 'default' },
- { label: 'Primary', value: 'primary' },
- { label: 'Info', value: 'info' },
- { label: 'Success', value: 'success' },
- { label: 'Danger', value: 'danger' },
- { label: 'Warning', value: 'warning' }
- ]
- }
- },
- {
- weight: 40,
- type: 'fieldset',
- input: false,
- components: [
- {
- type: 'select',
- input: true,
- label: 'Breadcrumb Type',
- key: 'breadcrumb',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Default', value: 'default' },
- { label: 'Condensed', value: 'condensed' },
- { label: 'Hidden', value: 'none' },
- ]
- }
- },
- {
- input: true,
- type: 'checkbox',
- label: 'Allow click on Breadcrumb',
- key: 'breadcrumbClickable',
- defaultValue: true,
- conditional: {
- json: { '!==': [{ var: 'data.breadcrumb' }, 'none'] }
- }
- },
- {
- input: true,
- type: 'checkbox',
- label: 'Allow Previous',
- key: 'allowPrevious',
- defaultValue: false,
- tooltip: 'Determines if the breadcrumb bar is clickable or not for visited tabs.',
- conditional: {
- json: { '===': [{ var: 'data.breadcrumbClickable' }, false] }
- }
- },
- {
- weight: 50,
- label: 'Panel Navigation Buttons',
- optionsLabelPosition: 'right',
- values: [
- {
- label: 'Previous',
- value: 'previous',
- },
- {
- label: 'Cancel',
- value: 'cancel',
- },
- {
- label: 'Next',
- value: 'next',
- }
- ],
- inline: true,
- type: 'selectboxes',
- key: 'buttonSettings',
- input: true,
- inputType: 'checkbox',
- defaultValue: {
- previous: true,
- cancel: true,
- next: true
- },
- },
- {
- weight: 55,
- label: 'Navigate Wizard on Enter',
- type: 'checkbox',
- key: 'navigateOnEnter',
- input: true,
- inputType: 'checkbox',
- defaultValue: false,
- tooltip: 'Use the Enter key to go forward through pages.'
- },
- {
- weight: 56,
- label: 'Save on Enter',
- type: 'checkbox',
- key: 'saveOnEnter',
- input: true,
- inputType: 'checkbox',
- defaultValue: false,
- tooltip: 'Use the Enter key to submit form on last page.'
- },
- {
- weight: 60,
- label: 'Scroll up on page opening',
- type: 'checkbox',
- key: 'scrollToTop',
- input: true,
- inputType: 'checkbox',
- defaultValue: false,
- tooltip: 'Scroll to the top of the wizard page when user navigates to it'
- }
- ],
- customConditional(context) {
- let isWizardPanel = false;
- if (context.instance.options.editForm.display === 'wizard') {
- const { components } = context.instance.options.editForm;
- const component = context.instance.options.editComponent;
- if (components && component) {
- isWizardPanel = components.some((comp) => {
- const diff = _difference(_keys(comp), _keys(component)) || [];
- diff.push('components');
- return _isEqual(_omit(comp, diff), _omit(component, diff));
- });
- }
- }
- return isWizardPanel;
- }
- },
- {
- weight: 650,
- type: 'checkbox',
- label: 'Collapsible',
- tooltip: 'If checked, this will turn this Panel into a collapsible panel.',
- key: 'collapsible',
- input: true
- },
- {
- weight: 651,
- type: 'checkbox',
- label: 'Initially Collapsed',
- tooltip: 'Determines the initial collapsed state of this Panel.',
- key: 'collapsed',
- input: true,
- conditional: {
- json: { '===': [{ var: 'data.collapsible' }, true] }
- }
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/comp1.js
deleted file mode 100644
index ee20ac07..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/comp1.js
+++ /dev/null
@@ -1,84 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'panel',
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'firstName',
- 'label': 'First Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- },
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'lastName',
- 'label': 'Last Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ],
- 'nextPage': null,
- 'theme': 'default',
- 'title': 'User Information',
- 'input': false,
- 'key': 'panel1'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/comp2.js
deleted file mode 100644
index 63c99b89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/comp2.js
+++ /dev/null
@@ -1,67 +0,0 @@
-export default {
- title: 'test panel',
- name: 'testPanel',
- path: 'testpanel',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- minLength: 8,
- },
- key: 'textField1',
- type: 'textfield',
- input: true,
- },
- {
- collapsible: true,
- key: 'panel',
- type: 'panel',
- label: 'Panel',
- collapsed: false,
- input: false,
- tableView: false,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true,
- },
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- label: 'Number',
- mask: false,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- truncateMultipleSpaces: false,
- validate: {
- min: 100,
- },
- key: 'number',
- type: 'number',
- input: true,
- },
- ],
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- saveOnEnter: false,
- },
- ],
- created: '2022-12-21T09:39:36.394Z',
- modified: '2022-12-21T12:37:15.497Z',
- machineName: 'uljpnhxgtzkilfa:testPanel',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/index.js
deleted file mode 100644
index 63468958..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/panel/fixtures/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/Password.form.js b/web-client/core/themes/italia/static/formio/css/src/components/password/Password.form.js
deleted file mode 100644
index 6c4e9bd1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/Password.form.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import textEditForm from '../textfield/TextField.form';
-
-import PasswordEditDisplay from './editForm/Password.edit.display';
-import PasswordEditData from './editForm/Password.edit.data';
-import PasswordEditValidation from './editForm/Password.edit.validation';
-
-export default function(...extend) {
- return textEditForm([
- {
- key: 'data',
- components: PasswordEditData
- },
- {
- key: 'display',
- components: PasswordEditDisplay
- },
- {
- key: 'validation',
- components: PasswordEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/Password.js b/web-client/core/themes/italia/static/formio/css/src/components/password/Password.js
deleted file mode 100644
index 3f7fae6e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/Password.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import TextFieldComponent from '../textfield/TextField';
-import _ from 'lodash';
-
-export default class PasswordComponent extends TextFieldComponent {
- static schema(...extend) {
- return TextFieldComponent.schema({
- type: 'password',
- label: 'Password',
- key: 'password',
- protected: true,
- tableView: false,
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Password',
- icon: 'asterisk',
- group: 'basic',
- documentation: '/userguide/form-building/form-components#password',
- weight: 40,
- schema: PasswordComponent.schema()
- };
- }
-
- get defaultSchema() {
- return _.omit(PasswordComponent.schema(), ['protected', 'tableView']);
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- info.attr.type = 'password';
- return info;
- }
-
- get autocompleteDisableAttrName() {
- return 'new-password';
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/Password.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/password/Password.unit.js
deleted file mode 100644
index 0e4fb45e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/Password.unit.js
+++ /dev/null
@@ -1,147 +0,0 @@
-import Harness from '../../../test/harness';
-import PasswordComponent from './Password';
-import Formio from './../../Formio';
-import assert from 'power-assert';
-import _ from 'lodash';
-
-import {
- comp1,
- comp2
-} from './fixtures';
-
-describe('Password Component', () => {
- it('Should build a password component', () => {
- return Harness.testCreate(PasswordComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="password"]', 1);
- });
- });
-
- it('Should provide min/max length validation', (done) => {
- const form = _.cloneDeep(comp2);
- form.components[0].validate = { minLength: 5, maxLength: 10 };
-
- const validValues = [
- '',
- 'te_st',
- 'test value',
- ' ',
- 'What?',
- 'test: ',
- 't ',
- ' t '
- ];
-
- const invalidMin = [
- 't',
- 'tt',
- 'ttt',
- 'tttt',
- ' t ',
- ' t',
- '_4_'
- ];
-
- const invalidMax = [
- 'test__value',
- 'test value ',
- ' test value',
- 'test: value',
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('password');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidMin, false, 'Password must have at least 5 characters.');
- testValidity(invalidMax, false, 'Password must have no more than 10 characters.', invalidMax[invalidMax.length-1]);
- });
-
- it('Should provide pattern validation', (done) => {
- const form = _.cloneDeep(comp2);
- form.components[0].validate = { pattern: '\\D+' };
-
- const validValues = [
- '',
- ' ',
- 'test value',
- '& "" (test) _ ,.*',
- ' some - test - value ',
- ];
-
- const invalidValues = [
- 'test(2)',
- '123',
- '0 waste',
- '"9"',
- ' 9',
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('password');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message.trim(), error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues, false, 'Password does not match the pattern \\D+', invalidValues[invalidValues.length-1]);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.data.js
deleted file mode 100644
index acea1bd2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.data.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export default [
- {
- key: 'inputFormat',
- ignore: true
- },
- {
- key: 'persistent',
- ignore: true
- },
- {
- key: 'protected',
- ignore: true
- },
- {
- key: 'dbIndex',
- ignore: true
- },
- {
- key: 'encrypted',
- ignore: true
- },
- {
- key: 'multiple',
- ignore: true
- },
- {
- key: 'defaultValue',
- ignore: true
- },
- {
- key: 'customDefaultValuePanel',
- ignore: true
- },
- {
- key: 'calculateValuePanel',
- ignore: true
- },
- {
- key: 'passwordInfo',
- weight: 0,
- type: 'htmlelement',
- tag: 'div',
- className: 'alert alert-info',
- content: 'Password fields are automatically encrypted using 1-way salted bcrypt hashes. These hashes are also protected and not returned in the API.'
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.display.js
deleted file mode 100644
index 73ddba3f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.display.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default [
- {
- ignore: true,
- key: 'mask',
- },
- {
- key: 'inputMask',
- ignore: true
- },
- {
- key: 'allowMultipleMasks',
- ignore: true
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.validation.js
deleted file mode 100644
index 3943fe16..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/editForm/Password.edit.validation.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default [
- {
- key: 'unique',
- ignore: true
- },
- {
- key: 'validate.minWords',
- ignore: true
- },
- {
- key: 'validate.maxWords',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/comp1.js
deleted file mode 100644
index 3d3acd52..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/comp1.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export default {
- 'input': true,
- 'tableView': false,
- 'inputType': 'password',
- 'label': 'Password',
- 'key': 'password',
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'protected': true,
- 'persistent': true,
- 'type': 'password',
- 'tags': [
-
- ],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- },
- 'isNew': false
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/comp2.js
deleted file mode 100644
index 1f3cbbc4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/comp2.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Password',
- tableView: false,
- key: 'password',
- type: 'password',
- input: true,
- protected: true
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- revisions: '',
- _vid: 0,
- title: 'password tests',
- display: 'form',
- name: 'passwordTests',
- path: 'passwordtests',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/index.js
deleted file mode 100644
index 63468958..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/values.js
deleted file mode 100644
index 078e7243..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/password/fixtures/values.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- 'secret',
- 'supersecret',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.form.js b/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.form.js
deleted file mode 100644
index 9dfbaf5b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.form.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import textEditForm from '../textfield/TextField.form';
-
-import PhoneNumberEditValidation from './editForm/PhoneNumber.edit.validation';
-
-export default function(...extend) {
- return textEditForm([
- {
- key: 'display',
- components: [
- {
- key: 'showWordCount',
- ignore: true
- },
- {
- key: 'showCharCount',
- ignore: true
- }
- ]
- },
- {
- key: 'validation',
- components: PhoneNumberEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.js b/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.js
deleted file mode 100644
index c927b945..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import TextFieldComponent from '../textfield/TextField';
-import _ from 'lodash';
-
-export default class PhoneNumberComponent extends TextFieldComponent {
- static schema(...extend) {
- return TextFieldComponent.schema({
- type: 'phoneNumber',
- label: 'Phone Number',
- key: 'phoneNumber',
- inputType: 'tel',
- inputMask: '(999) 999-9999',
- inputMode: 'decimal',
- displayMask: '',
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Phone Number',
- group: 'advanced',
- icon: 'phone-square',
- weight: 30,
- documentation: '/userguide/form-building/advanced-components#phone-number',
- schema: PhoneNumberComponent.schema()
- };
- }
-
- get defaultSchema() {
- return PhoneNumberComponent.schema();
- }
-
- getValueAsString(value, options) {
- if (options?.email && this.visible && !this.skipInEmail && _.isObject(value)) {
- const result = (`
-
-
-
- ${value.maskName}
- ${value.value}
-
-
-
- `);
-
- return result;
- }
-
- return super.getValueAsString(value, options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.unit.js
deleted file mode 100644
index f361584f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/PhoneNumber.unit.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import Harness from '../../../test/harness';
-import PhoneNumberComponent from './PhoneNumber';
-import assert from 'power-assert';
-import Formio from '../../Formio';
-
-import {
- comp1,
-} from './fixtures';
-
-describe('PhoneNumber Component', () => {
- it('Should build a phone number component', () => {
- return Harness.testCreate(PhoneNumberComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 1);
- });
- });
-
- it('Should check mask and value in the phone component in the email template', (done) => {
- const formJson = {
- components: [{
- label: 'Phone Number',
- tableView: true,
- allowMultipleMasks: true,
- inputMasks: [{
- label: 'mask1',
- mask: 'mask1'
- }],
- key: 'phoneNumber',
- type: 'phoneNumber',
- input: true
- }]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson)
- .then(form => {
- form.setSubmission({
- data: {
- phoneNumber: {
- value: 'mask1',
- maskName: 'mask2'
- }
- },
- });
-
- const phoneNumber = form.getComponent('phoneNumber');
-
- setTimeout(() => {
- assert.equal(phoneNumber.dataValue.value, 'mask1', 'Should check value');
- assert.equal(phoneNumber.dataValue.maskName, 'mask2', 'Should check maskName');
- const toString = phoneNumber.getValueAsString(phoneNumber.dataValue, { email: true });
- assert.ok(toString.includes('table'), 'Email template should render html table');
- assert.ok(toString.includes(phoneNumber.dataValue.maskName), 'Email template should have Phone Number mackName');
- assert.ok(toString.includes(phoneNumber.dataValue.value), 'Email template should have Phone Number value');
- done();
- }, 300);
- })
- .catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/editForm/PhoneNumber.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/editForm/PhoneNumber.edit.validation.js
deleted file mode 100644
index a455b2bb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/editForm/PhoneNumber.edit.validation.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export default [
- {
- key: 'validate.minLength',
- ignore: true
- },
- {
- key: 'validate.maxLength',
- ignore: true
- },
- {
- key: 'validate.pattern',
- ignore: true
- },
- {
- key: 'validate.minWords',
- ignore: true
- },
- {
- key: 'validate.maxWords',
- ignore: true
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/comp1.js
deleted file mode 100644
index e4982544..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/comp1.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default {
- 'input': true,
- 'tableView': true,
- 'inputMask': '(999) 999-9999',
- 'label': 'Phone Number',
- 'key': 'phoneNumber',
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'multiple': false,
- 'protected': false,
- 'unique': false,
- 'persistent': true,
- 'defaultValue': '',
- 'validate': {
- 'required': false
- },
- 'type': 'phoneNumber',
- 'tags': [
-
- ],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/values.js
deleted file mode 100644
index 1083075d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/phonenumber/fixtures/values.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- '(123) 456-7890',
- '(098) 765-4321',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.form.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.form.js
deleted file mode 100644
index 165a41f2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.form.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import listComponentForm from '../_classes/list/ListComponent.form';
-import RadioEditData from './editForm/Radio.edit.data';
-import RadioEditDisplay from './editForm/Radio.edit.display';
-import RadioEditValidation from './editForm/Radio.edit.validation';
-
-export default function(...extend) {
- return listComponentForm([
- {
- key: 'display',
- components: RadioEditDisplay
- },
- {
- key: 'data',
- components: RadioEditData
- },
- {
- key: 'validation',
- components: RadioEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.js
deleted file mode 100644
index ea3cfadd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.js
+++ /dev/null
@@ -1,434 +0,0 @@
-import _ from 'lodash';
-import ListComponent from '../_classes/list/ListComponent';
-import NativePromise from 'native-promise-only';
-import { GlobalFormio as Formio } from '../../Formio';
-import { boolValue, componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-
-export default class RadioComponent extends ListComponent {
- static schema(...extend) {
- return ListComponent.schema({
- type: 'radio',
- inputType: 'radio',
- label: 'Radio',
- key: 'radio',
- values: [{ label: '', value: '' }],
- data: {
- url: '',
- },
- fieldSet: false
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Radio',
- group: 'basic',
- icon: 'dot-circle-o',
- weight: 80,
- documentation: '/userguide/form-building/form-components#radio',
- schema: RadioComponent.schema()
- };
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- valueComponent(classComp) {
- return {
- type: 'select',
- dataSrc: 'custom',
- valueProperty: 'value',
- dataType: classComp.dataType || '',
- data: {
- custom() {
- return classComp.values;
- }
- },
- };
- }
- };
- }
-
- static savedValueTypes(schema) {
- const { boolean, string, number, object, array } = componentValueTypes;
- const { dataType } = schema;
- const types = getComponentSavedTypes(schema);
-
- if (types) {
- return types;
- }
-
- if (dataType === 'object') {
- return [object, array];
- }
-
- if (componentValueTypes[dataType]) {
- return [componentValueTypes[dataType]];
- }
-
- return [boolean, string, number, object, array];
- }
-
- constructor(component, options, data) {
- super(component, options, data);
- this.previousValue = this.dataValue || null;
- }
-
- get defaultSchema() {
- return RadioComponent.schema();
- }
-
- get defaultValue() {
- let defaultValue = super.defaultValue;
- if (!defaultValue && this.component.defaultValue === false) {
- defaultValue = this.component.defaultValue;
- }
- return defaultValue;
- }
-
- get inputInfo() {
- const info = super.elementInfo();
- info.type = 'input';
- info.changeEvent = 'click';
- info.attr.class = 'form-check-input';
- info.attr.name = info.attr.name += `[${this.root?.id}-${this.id}]`;
- return info;
- }
-
- get emptyValue() {
- return '';
- }
-
- get isRadio() {
- return this.component.inputType === 'radio';
- }
-
- get optionSelectedClass() {
- return 'radio-selected';
- }
-
- get listData() {
- const listData = _.get(this.root, 'submission.metadata.listData', {});
- return _.get(listData, this.path);
- }
-
- init() {
- super.init();
- this.templateData = {};
- this.validators = this.validators.concat(['select', 'onlyAvailableItems', 'availableValueProperty']);
-
- // Trigger an update.
- let updateArgs = [];
- const triggerUpdate = _.debounce((...args) => {
- updateArgs = [];
- return this.updateItems.apply(this, args);
- }, 100);
- this.triggerUpdate = (...args) => {
- // Make sure we always resolve the previous promise before reassign it
- if (typeof this.itemsLoadedResolve === 'function') {
- this.itemsLoadedResolve();
- }
- this.itemsLoaded = new NativePromise((resolve) => {
- this.itemsLoadedResolve = resolve;
- });
- if (args.length) {
- updateArgs = args;
- }
- return triggerUpdate(...updateArgs);
- };
-
- this.itemsLoaded = new NativePromise((resolve) => {
- this.itemsLoadedResolve = resolve;
- });
- this.optionsLoaded = false;
- this.loadedOptions = [];
-
- // Get the template keys for this radio component.
- this.getTemplateKeys();
- }
-
- render() {
- return super.render(this.renderTemplate('radio', {
- input: this.inputInfo,
- inline: this.component.inline,
- values: this.component.dataSrc === 'values' ? this.component.values : this.loadedOptions,
- value: this.dataValue,
- row: this.row,
- }));
- }
-
- attach(element) {
- this.loadRefs(element, { input: 'multiple', wrapper: 'multiple' });
- this.refs.input.forEach((input, index) => {
- this.addEventListener(input, this.inputInfo.changeEvent, () => {
- this.updateValue(null, {
- modified: true,
- });
- });
- if (this.component.values[index]) {
- this.addShortcut(input, this.component.values[index].shortcut);
- }
-
- if (this.isRadio) {
- let dataValue = this.dataValue;
-
- if (!_.isString(this.dataValue)) {
- dataValue = _.toString(this.dataValue);
- }
-
- if (this.isSelectURL && _.isObject(this.loadedOptions[index].value)) {
- input.checked = _.isEqual(this.loadedOptions[index].value, this.dataValue);
- }
- else {
- input.checked = (dataValue === input.value && (input.value || this.component.dataSrc !== 'url'));
- }
- this.addEventListener(input, 'keyup', (event) => {
- if (event.key === ' ' && dataValue === input.value) {
- event.preventDefault();
-
- this.updateValue(null, {
- modified: true,
- });
- }
- });
- }
- });
- this.triggerUpdate();
- this.setSelectedClasses();
- return super.attach(element);
- }
-
- detach(element) {
- if (element && this.refs.input) {
- this.refs.input.forEach((input, index) => {
- if (this.component.values[index]) {
- this.removeShortcut(input, this.component.values[index].shortcut);
- }
- });
- }
- super.detach();
- }
-
- getValue() {
- if (this.viewOnly || !this.refs.input || !this.refs.input.length) {
- return this.dataValue;
- }
- let value = this.dataValue;
- this.refs.input.forEach((input, index) => {
- if (input.checked) {
- value = (this.isSelectURL && _.isObject(this.loadedOptions[index].value)) ?
- this.loadedOptions[index].value :
- input.value;
- }
- });
- return value;
- }
-
- validateValueProperty() {
- if (this.component.dataSrc === 'values') {
- return true;
- }
-
- return !_.some(this.refs.wrapper, (wrapper, index) => this.refs.input[index].checked && this.loadedOptions[index].invalid);
- }
-
- validateValueAvailability(setting, value) {
- if (!boolValue(setting) || !value) {
- return true;
- }
-
- const values = this.component.values;
- if (values) {
- return values.findIndex(({ value: optionValue }) => this.normalizeValue(optionValue) === value) !== -1;
- }
-
- return false;
- }
-
- getValueAsString(value) {
- if (_.isObject(value)) {
- value = JSON.stringify(value);
- }
- else if (!_.isString(value)) {
- value = _.toString(value);
- }
- if (this.component.dataSrc !== 'values') {
- return value;
- }
-
- const option = _.find(this.component.values, (v) => v.value === value);
-
- if (!value) {
- return _.get(option, 'label', '');
- }
-
- return _.get(option, 'label', '');
- }
-
- setValueAt(index, value) {
- if (this.refs.input && this.refs.input[index] && value !== null && value !== undefined) {
- const inputValue = this.refs.input[index].value;
- this.refs.input[index].checked = (inputValue === value.toString());
- }
- }
-
- loadItems(url, search, headers, options, method, body) {
- if (this.optionsLoaded) {
- return;
- }
-
- if (!this.shouldLoad && this.listData) {
- this.loadItemsFromMetadata();
- return;
- }
-
- // Ensure we have a method and remove any body if method is get
- method = method || 'GET';
- if (method.toUpperCase() === 'GET') {
- body = null;
- }
-
- // Set ignoreCache if it is
- options.ignoreCache = this.component.ignoreCache;
- // Make the request.
- options.header = headers;
-
- this.loading = true;
- Formio.makeRequest(this.options.formio, 'select', url, method, body, options)
- .then((response) => {
- this.loading = false;
- this.error = null;
- this.setItems(response);
- this.optionsLoaded = true;
- this.redraw();
- })
- .catch((err) => {
- this.handleLoadingError(err);
- });
- }
-
- loadItemsFromMetadata() {
- this.listData.forEach((item, i) => {
- this.loadedOptions[i] = {
- label: this.itemTemplate(item)
- };
- if (_.isEqual(item, this.selectData || _.pick(this.dataValue, _.keys(item)))) {
- this.loadedOptions[i].value = this.dataValue;
- }
- });
- this.optionsLoaded = true;
- this.redraw();
- }
-
- setItems(items) {
- const listData = [];
- items?.forEach((item, i) => {
- this.loadedOptions[i] = {
- value: this.component.valueProperty ? item[this.component.valueProperty] : item,
- label: this.component.valueProperty ? this.itemTemplate(item, item[this.component.valueProperty]) : this.itemTemplate(item, item, i)
- };
- listData.push(this.templateData[this.component.valueProperty ? item[this.component.valueProperty] : i]);
-
- if ((this.component.valueProperty || !this.isRadio) && (
- _.isUndefined(item[this.component.valueProperty]) ||
- (!this.isRadio && _.isObject(item[this.component.valueProperty])) ||
- (!this.isRadio && _.isBoolean(item[this.component.valueProperty]))
- )) {
- this.loadedOptions[i].invalid = true;
- }
- });
-
- if (this.isSelectURL) {
- const submission = this.root.submission;
- if (!submission.metadata) {
- submission.metadata = {};
- }
- if (!submission.metadata.listData) {
- submission.metadata.listData = {};
- }
- _.set(submission.metadata.listData, this.path, listData);
- }
- }
-
- setSelectedClasses() {
- if (this.refs.wrapper) {
- //add/remove selected option class
- const value = this.dataValue;
- this.refs.wrapper.forEach((wrapper, index) => {
- const input = this.refs.input[index];
- const checked = (input.type === 'checkbox') ? value[input.value] : (input.value.toString() === value.toString());
- if (checked) {
- //add class to container when selected
- this.addClass(wrapper, this.optionSelectedClass);
- //change "checked" attribute
- input.setAttribute('checked', 'true');
- }
- else {
- this.removeClass(wrapper, this.optionSelectedClass);
- input.removeAttribute('checked');
- }
- });
- }
- }
-
- updateValue(value, flags) {
- const changed = super.updateValue(value, flags);
- if (changed) {
- this.setSelectedClasses();
- }
-
- if (!flags || !flags.modified || !this.isRadio) {
- if (changed) {
- this.previousValue = this.dataValue;
- }
-
- return changed;
- }
-
- // If they clicked on the radio that is currently selected, it needs to reset the value.
- this.currentValue = this.dataValue;
- const shouldResetValue = flags && flags.modified && !flags.noUpdateEvent && this.previousValue === this.currentValue;
- if (shouldResetValue) {
- this.resetValue();
- this.triggerChange(flags);
- this.setSelectedClasses();
- }
- this.previousValue = this.dataValue;
- return changed;
- }
-
- /**
- * Normalize values coming into updateValue.
- *
- * @param value
- * @return {*}
- */
- normalizeValue(value) {
- if (value === this.emptyValue) {
- return value;
- }
-
- const isEquivalent = _.toString(value) === Number(value).toString();
-
- if (!isNaN(parseFloat(value)) && isFinite(value) && isEquivalent) {
- value = +value;
- }
- if (value === 'true') {
- value = true;
- }
- if (value === 'false') {
- value = false;
- }
-
- if (this.isSelectURL && this.templateData && this.templateData[value]) {
- const submission = this.root.submission;
- if (!submission.metadata.selectData) {
- submission.metadata.selectData = {};
- }
-
- _.set(submission.metadata.selectData, this.path, this.templateData[value]);
- }
-
- return super.normalizeValue(value);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.unit.js
deleted file mode 100644
index 2a4c10ed..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/Radio.unit.js
+++ /dev/null
@@ -1,365 +0,0 @@
-import assert from 'power-assert';
-import Formio from './../../Formio';
-import _ from 'lodash';
-import Harness from '../../../test/harness';
-import RadioComponent from './Radio';
-
-import {
- comp1,
- comp2,
- comp3,
- comp4,
- comp5,
- comp6,
- comp7,
- comp8,
- comp9,
- comp10
-} from './fixtures';
-
-describe('Radio Component', () => {
- it('Should build a radio component', () => {
- return Harness.testCreate(RadioComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="radio"]', 4);
- Harness.testElements(component, 'span', 4);
- });
- });
-
- it('Should return correct string values if storage type is Number', () => {
- return Harness.testCreate(RadioComponent, comp2).then((component) => {
- assert.equal(component.getValueAsString(1), 'one');
- assert.equal(component.getValueAsString(2), 'two');
- });
- });
-
- it('Should build a radio component with URL DataSrc', (done) => {
- const form = _.cloneDeep(comp9);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [
- { name : 'Alabama', abbreviation : 'AL' },
- { name : 'Alaska', abbreviation: 'AK' },
- { name: 'American Samoa', abbreviation: 'AS' }
- ];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const radio = form.getComponent('radio');
-
- setTimeout(()=>{
- assert.equal(radio.loadedOptions.length, 3);
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should provide metadata.selectData for radio component with URL DataSrc', (done) => {
- const form = _.cloneDeep(comp9);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [
- { name : 'Alabama', abbreviation : 'AL' },
- { name : 'Alaska', abbreviation: 'AK' },
- { name: 'American Samoa', abbreviation: 'AS' }
- ];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const radio = form.getComponent('radio');
-
- setTimeout(()=>{
- const value = 'AK';
- radio.setValue(value);
- setTimeout(() => {
- assert.equal(radio.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
- setTimeout(() => {
- assert.equal(_.isEqual(form.submission.metadata.selectData.radio, { name : 'Alaska' }), true);
- assert.equal(form.submission.metadata.listData.radio.length, 3);
- Formio.makeRequest = originalMakeRequest;
- done();
- },200);
- },200);
- }, 200);
- }).catch(done);
- });
-
- it('Should save checked value after redrawing if storage type is Number', (done) => {
- Harness.testCreate(RadioComponent, comp3).then((component) => {
- component.setValue(22);
- component.redraw();
-
- setTimeout(()=>{
- assert.equal(component.refs.input[0].checked, false);
- assert.equal(component.refs.input[1].value, '22');
- assert.equal(component.refs.input[1].checked, true);
- assert.equal(component.refs.input[2].checked, false);
- done();
- }, 700);
- });
- });
-
- it('Should set correct data for 0s values', (done) => {
- Harness.testCreate(RadioComponent, comp10).then((component) => {
- component.setValue('01');
- component.redraw();
-
- setTimeout(()=>{
- assert.equal(component._data.radio, '01');
- component.setValue(1);
- component.redraw();
- setTimeout(()=>{
- assert.equal(component._data.radio, 1);
- done();
- }, 200);
- }, 200);
- });
- });
-
- it('Span should have correct text label', () => {
- return Harness.testCreate(RadioComponent, comp1).then((component) => {
- component.element.querySelectorAll('input').forEach((input) => {
- assert(input.getAttribute('class').indexOf('form-check-input') !== -1, 'No form-check-input on radios.');
- });
- const spans = component.element.querySelectorAll('span');
- assert.equal(spans[0].innerHTML, 'Red');
- assert.equal(spans[1].innerHTML, 'Green');
- assert.equal(spans[2].innerHTML, 'Blue');
- assert.equal(spans[3].innerHTML, 'Yellow');
- });
- });
-
- it('Should set false as defaultValue correctly', (done) => {
- Harness.testCreate(RadioComponent, comp4).then((component) => {
- assert.equal(component.dataValue, false, 'Should be equal to false');
- const input = component.element.querySelector('input[value="false"]');
- assert.equal(input.getAttribute('checked'), 'true', 'Should be checked');
- done();
- });
- });
-
- it('Should provide "Allow only available values" validation', (done) => {
- const form = _.cloneDeep(comp5);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const radio = form.getComponent('radio');
- let value = 'five';
- radio.setValue(value);
-
- setTimeout(() => {
- assert.equal(radio.getValue(), value);
- assert.equal(radio.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(form.errors.length, 1);
- assert.equal(radio.error.message, 'Radio is an invalid value.');
- value = 'one';
- radio.setValue(value);
-
- setTimeout(() => {
- assert.equal(radio.getValue(), value);
- assert.equal(radio.dataValue, value);
- assert.equal(form.errors.length, 0);
- assert.equal(!!radio.error, false);
-
- document.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }, 200);
- }).catch(done);
- });
-
- it('Should use whole Object as value if URL DataSrc and ValueProperty is not set', (done) => {
- const form = _.cloneDeep(comp9);
- delete form.components[0].valueProperty;
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
- const values = [
- { name : 'Alabama', abbreviation : 'AL' },
- { name : 'Alaska', abbreviation: 'AK' }
- ];
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const radio = form.getComponent('radio');
-
- setTimeout(()=>{
- values.forEach((value, i) => {
- assert.equal(_.isEqual(value, radio.loadedOptions[i].value), true);
- });
- radio.setValue(values[1]);
-
- setTimeout(() => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(form.errors.length, 0);
- assert.equal(!!radio.error, false);
- assert.equal(radio.getValue(), values[1]);
- assert.equal(radio.dataValue, values[1]);
- document.innerHTML = '';
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 300);
- }, 300);
- }, 200);
- }).catch(done);
- });
-
- it('Should not have default values in schema', (done) => {
- const form = _.cloneDeep(comp6);
- const element = document.createElement('div');
-
- const requiredSchema = {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: true,
- tableView: false,
- key: 'radio',
- type: 'radio',
- input: true
- };
-
- Formio.createForm(element, form).then(form => {
- const radio = form.getComponent('radio');
- assert.deepEqual(requiredSchema, radio.schema);
- done();
- }).catch(done);
- });
-});
-
-describe('Radio Component', () => {
- it('should have red asterisk left hand side to the options labels if component is required and label is hidden', () => {
- return Harness.testCreate(RadioComponent, comp7).then(component => {
- const options = component.element.querySelectorAll('.form-check-label');
- options.forEach(i => {
- assert.deepEqual(!!getComputedStyle(i, ':before'), true);
- });
- });
- });
-
- it('Should not provide empty error message when hidden radio has storage type as string', (done) => {
- const form = _.cloneDeep(comp8);
- const element = document.createElement('div');
-
- Formio.createForm(element, form)
- .then(form => {
- form.submission = {
- data: {
- radio: 'no'
- }
- };
- const alerts = document.querySelectorAll('.alert-danger');
- setTimeout(() => {
- assert.equal(alerts.length, 0);
- done();
- }, 100);
- })
- .catch(done);
- });
-
- it('Should show correct attributes during performance', function(done) {
- const formElement = document.createElement('div');
-
- const JSON = {
- components: [
- {
- key: 'whichOneIsYourFavoriteFruit',
- type: 'radio',
- input: true,
- label: 'Which one is your favorite fruit?',
- inline: false,
- values: [
- {
- label: 'Apple ',
- value: 'apple',
- shortcut: '',
- },
- {
- label: 'Orange',
- value: 'orange',
- shortcut: '',
- },
- {
- label: 'Banana',
- value: 'banana',
- shortcut: '',
- },
- ],
- tableView: false,
- optionsLabelPosition: 'right',
- },
- ],
- };
-
- Formio.createForm(formElement, JSON)
- .then((form) => {
- const component = form.getComponent('whichOneIsYourFavoriteFruit');
-
- const appleRadioInput = component.refs.input[0];
- const appleComponentWrapper = formElement.querySelector('.form-check');
- const isContainClass =
- appleComponentWrapper.classList.contains('radio-selected');
-
- assert.equal(
- appleRadioInput.checked,
- false,
- 'should be false by default'
- );
- assert.equal(isContainClass, false, 'should be false by default');
-
- appleRadioInput.click();
-
- setTimeout(() => {
- assert.equal(appleRadioInput.checked, true);
-
- const elementWrapper = formElement.querySelector('.form-check');
- const isContainClass =
- elementWrapper.classList.contains('radio-selected');
- assert.equal(isContainClass, true);
-
- appleRadioInput.click();
-
- setTimeout(() => {
- assert.equal(appleRadioInput.checked, false);
- const elementWrapper = formElement.querySelector('.form-check');
- const isContainClass =
- elementWrapper.classList.contains('radio-selected');
- assert.equal(isContainClass, false);
-
- done();
- }, 200);
- }, 200);
- })
- .catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.data.js
deleted file mode 100644
index f46f60aa..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.data.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import BuilderUtils from '../../../utils/builder';
-import _ from 'lodash';
-
-export default [
- {
- key: 'multiple',
- ignore: true,
- },
- {
- key: 'dataSrc',
- data: {
- values: [
- { label: 'Values', value: 'values' },
- { label: 'URL', value: 'url' },
- ],
- },
- 'validate': {
- 'required': true
- },
- onChange(context) {
- if (context && context.flags && context.flags && context.flags.modified) {
- context.data.values = [{ label: '', value: '' }];
- }
- },
- },
- {
- type: 'datagrid',
- input: true,
- label: 'Values',
- key: 'values',
- tooltip: 'The radio button values that can be picked for this field. Values are text submitted with the form data. Labels are text that appears next to the radio buttons on the form.',
- weight: 10,
- reorder: true,
- defaultValue: [{ label: '', value: '' }],
- components: [
- {
- label: 'Label',
- key: 'label',
- input: true,
- type: 'textfield',
- },
- {
- label: 'Value',
- key: 'value',
- input: true,
- type: 'textfield',
- allowCalculateOverride: true,
- calculateValue: 'value = _.camelCase(row.label);',
- validate: {
- required: true
- }
- },
- {
- type: 'select',
- input: true,
- weight: 180,
- label: 'Shortcut',
- key: 'shortcut',
- tooltip: 'The shortcut key for this option.',
- dataSrc: 'custom',
- valueProperty: 'value',
- customDefaultValue: () => '',
- template: '{{ item.label }}',
- data: {
- custom(context) {
- return BuilderUtils.getAvailableShortcuts(
- _.get(context, 'instance.options.editForm', {}),
- _.get(context, 'instance.options.editComponent', {})
- );
- },
- },
- },
- ],
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'values'] },
- },
- },
- {
- key: 'template',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'url'] },
- },
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.display.js
deleted file mode 100644
index f540db7a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.display.js
+++ /dev/null
@@ -1,32 +0,0 @@
-export default [
- {
- key: 'placeholder',
- ignore: true
- },
- {
- type: 'select',
- input: true,
- label: 'Options Label Position',
- key: 'optionsLabelPosition',
- tooltip: 'Position for the label for options for this field.',
- dataSrc: 'values',
- weight: 32,
- defaultValue: 'right',
- data: {
- values: [
- { label: 'Top', value: 'top' },
- { label: 'Left', value: 'left' },
- { label: 'Right', value: 'right' },
- { label: 'Bottom', value: 'bottom' }
- ]
- }
- },
- {
- type: 'checkbox',
- input: true,
- key: 'inline',
- label: 'Inline Layout',
- tooltip: 'Displays the checkboxes/radios horizontally.',
- weight: 650
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.validation.js
deleted file mode 100644
index 64be4ae0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/editForm/Radio.edit.validation.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default [
- {
- key: 'validateOn',
- ignore: true
- },
- {
- key: 'unique',
- ignore: true
- },
- {
- weight: 52,
- type: 'checkbox',
- label: 'Allow only available values',
- tooltip: 'Check this if you would like to perform a validation check to ensure the selected value is an available option.',
- key: 'validate.onlyAvailableItems',
- input: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp1.js
deleted file mode 100644
index dbdfd924..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp1.js
+++ /dev/null
@@ -1,42 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'radio',
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'defaultValue': '',
- 'values': [
- {
- 'label': 'Red',
- 'value': 'red'
- },
- {
- 'label': 'Green',
- 'value': 'green'
- },
- {
- 'label': 'Blue',
- 'value': 'blue'
- },
- {
- 'label': 'Yellow',
- 'value': 'yellow'
- }
- ],
- 'key': 'favoriteColor',
- 'label': 'Favorite Color',
- 'inputType': 'radio',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp10.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp10.js
deleted file mode 100644
index 8ff36422..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp10.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export default {
- 'label': 'Radio',
- 'optionsLabelPosition': 'right',
- 'inline': false,
- 'tableView': false,
- 'values': [
- {
- 'label': '01',
- 'value': '01',
- 'shortcut': ''
- },
- {
- 'label': '1',
- 'value': '1',
- 'shortcut': ''
- }
- ],
- 'key': 'radio',
- 'type': 'radio',
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp2.js
deleted file mode 100644
index 582bf201..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp2.js
+++ /dev/null
@@ -1,84 +0,0 @@
-export default {
- 'label': 'Radio Test',
- 'labelPosition': 'top',
- 'optionsLabelPosition': 'right',
- 'description': '',
- 'tooltip': '',
- 'customClass': '',
- 'tabindex': '',
- 'inline': false,
- 'hidden': false,
- 'hideLabel': false,
- 'autofocus': false,
- 'disabled': false,
- 'tableView': true,
- 'modalEdit': false,
- 'values': [{
- 'label': 'one',
- 'value': '1',
- 'shortcut': ''
- }, {
- 'label': 'two',
- 'value': '2',
- 'shortcut': ''
- }],
- 'dataType': 'number',
- 'persistent': true,
- 'protected': false,
- 'dbIndex': false,
- 'encrypted': false,
- 'redrawOn': '',
- 'clearOnHide': true,
- 'customDefaultValue': '',
- 'calculateValue': '',
- 'calculateServer': false,
- 'allowCalculateOverride': false,
- 'validate': {
- 'required': false,
- 'customMessage': '',
- 'custom': '',
- 'customPrivate': false,
- 'json': '',
- 'strictDateValidation': false,
- 'multiple': false,
- 'unique': false
- },
- 'errorLabel': '',
- 'key': 'radioTest',
- 'tags': [],
- 'properties': {},
- 'conditional': {
- 'show': null,
- 'when': null,
- 'eq': '',
- 'json': ''
- },
- 'customConditional': '',
- 'logic': [],
- 'attributes': {},
- 'overlay': {
- 'style': '',
- 'page': '',
- 'left': '',
- 'top': '',
- 'width': '',
- 'height': ''
- },
- 'type': 'radio',
- 'input': true,
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'multiple': false,
- 'unique': false,
- 'refreshOn': '',
- 'widget': null,
- 'validateOn': 'change',
- 'showCharCount': false,
- 'showWordCount': false,
- 'allowMultipleMasks': false,
- 'inputType': 'radio',
- 'fieldSet': false,
- 'id': 'ed0srhn',
- 'defaultValue': ''
- };
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp3.js
deleted file mode 100644
index 59f4692d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp3.js
+++ /dev/null
@@ -1,88 +0,0 @@
-export default {
- 'label': 'Number ST Radio',
- 'labelPosition': 'top',
- 'optionsLabelPosition': 'right',
- 'description': '',
- 'tooltip': '',
- 'customClass': '',
- 'tabindex': '',
- 'inline': false,
- 'hidden': false,
- 'hideLabel': false,
- 'autofocus': false,
- 'disabled': false,
- 'tableView': false,
- 'modalEdit': false,
- 'values': [{
- 'label': '11',
- 'value': '11',
- 'shortcut': ''
- }, {
- 'label': '22',
- 'value': '22',
- 'shortcut': ''
- }, {
- 'label': '33',
- 'value': '33',
- 'shortcut': ''
- }],
- 'dataType': 'number',
- 'persistent': true,
- 'protected': false,
- 'dbIndex': false,
- 'encrypted': false,
- 'redrawOn': '',
- 'clearOnHide': true,
- 'customDefaultValue': '',
- 'calculateValue': '',
- 'calculateServer': false,
- 'allowCalculateOverride': false,
- 'validate': {
- 'required': false,
- 'customMessage': '',
- 'custom': '',
- 'customPrivate': false,
- 'json': '',
- 'strictDateValidation': false,
- 'multiple': false,
- 'unique': false
- },
- 'errorLabel': '',
- 'key': 'numberStRadio',
- 'tags': [],
- 'properties': {},
- 'conditional': {
- 'show': null,
- 'when': null,
- 'eq': '',
- 'json': ''
- },
- 'customConditional': '',
- 'logic': [],
- 'attributes': {},
- 'overlay': {
- 'style': '',
- 'page': '',
- 'left': '',
- 'top': '',
- 'width': '',
- 'height': ''
- },
- 'type': 'radio',
- 'input': true,
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'multiple': false,
- 'unique': false,
- 'refreshOn': '',
- 'widget': null,
- 'validateOn': 'change',
- 'showCharCount': false,
- 'showWordCount': false,
- 'allowMultipleMasks': false,
- 'inputType': 'radio',
- 'fieldSet': false,
- 'id': 'er5lmse',
- 'defaultValue': ''
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp4.js
deleted file mode 100644
index dc9d1cdd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp4.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: false,
- tableView: false,
- defaultValue: false,
- values: [
- {
- label: 'Yes',
- value: 'true',
- shortcut: ''
- },
- {
- label: 'No',
- value: 'false',
- shortcut: ''
- }
- ],
- validate: {
- onlyAvailableItems: false
- },
- key: 'radio1',
- type: 'radio',
- input: true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp5.js
deleted file mode 100644
index a725f2d6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp5.js
+++ /dev/null
@@ -1,33 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: true,
- tableView: false,
- values: [
- { label: 'one', value: 'one', shortcut: '' },
- { label: 'two', value: 'two', shortcut: '' },
- { label: 'three', value: 'three', shortcut: '' }
- ],
- validate: { onlyAvailableItems: true },
- key: 'radio',
- type: 'radio',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- alwaysEnabled: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'test testrer',
- display: 'form',
- name: 'testTestrer',
- path: 'testtestrer',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp6.js
deleted file mode 100644
index 50df750d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp6.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: true,
- tableView: false,
- values: [
- { label: '', value: '' },
- ],
- validate: { onlyAvailableItems: false },
- key: 'radio',
- type: 'radio',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- alwaysEnabled: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'test testrer',
- display: 'form',
- name: 'testTestrer',
- path: 'testtestrer',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp7.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp7.js
deleted file mode 100644
index 1e792403..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp7.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default {
- _id: '61135ec3e4188f021c7ad390',
- label: 'Label hidden',
- optionsLabelPosition: 'right',
- inline: false,
- hideLabel: true,
- tableView: false,
- values: [
- { label: '3', value: '3', shortcut: '' },
- { label: '4', value: '4', shortcut: '' },
- ],
- validate: { required: true },
- key: 'labelHidden',
- type: 'radio',
- input: true,
- title: 'FIO-2959',
- name: 'fio2959',
- path: 'fio2959',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp8.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp8.js
deleted file mode 100644
index 9740ad97..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp8.js
+++ /dev/null
@@ -1,111 +0,0 @@
-export default {
- title: '4405',
- name: '4405',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'HTML',
- attrs: [{ attr: '', value: '' }],
- content: 'Assessment Checklist ',
- refreshOnChange: false,
- type: 'htmlelement',
- input: false,
- key: 'html',
- tableView: false,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- {
- title: 'Panel1',
- theme: 'primary',
- collapsible: false,
- type: 'panel',
- label: 'Panel',
- input: false,
- key: 'panel',
- tableView: false,
- components: [
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: true,
- dataType: 'string',
- values: [
- { label: 'Yes', value: 'yes', shortcut: '' },
- { label: 'No', value: 'no', shortcut: '' },
- ],
- type: 'radio',
- input: true,
- key: 'radio',
- tableView: false,
- },
- ],
- },
- {
- title: 'Panel2',
- theme: 'primary',
- collapsible: false,
- conditional: { show: false, when: 'radio', eq: 'no' },
- type: 'panel',
- label: 'Panel2',
- input: false,
- key: 'panel1',
- tableView: false,
- components: [
- {
- label: 'Text Area',
- isEditor: false,
- autoExpand: false,
- type: 'textarea',
- input: true,
- key: 'textArea',
- tableView: true,
- },
- ],
- },
- {
- title: 'Panel3',
- theme: 'primary',
- collapsible: false,
- conditional: { show: false, when: 'radio', eq: 'no' },
- type: 'panel',
- label: 'Panel3',
- input: false,
- key: 'panel2',
- tableView: false,
- components: [
- {
- label: 'Radio',
- optionsLabelPosition: 'right',
- inline: false,
- tableView: false,
- values: [
- { label: 'Yes', value: 'yes', shortcut: '' },
- { label: 'No', value: 'no', shortcut: '' },
- ],
- dataType: 'string',
- key: 'radio2',
- type: 'radio',
- input: true,
- },
- {
- label: 'Text Area',
- isEditor: false,
- autoExpand: false,
- type: 'textarea',
- input: true,
- key: 'textArea1',
- tableView: true,
- },
- ],
- },
- ],
- project: '61547bb9b027c7a861d855b6',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp9.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp9.js
deleted file mode 100644
index 4c215868..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/comp9.js
+++ /dev/null
@@ -1,30 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- type: 'radio',
- label: 'Radio',
- key: 'radio',
- dataSrc: 'url',
- data: {
- url: 'https://cdn.rawgit.com/mshafrir/2646763/raw/states_titlecase.json'
- },
- valueProperty: 'abbreviation',
- template: '{{ item.name }} ',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- alwaysEnabled: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'test radio Url',
- display: 'form',
- name: 'testRadioUrl',
- path: 'testRadioUrl',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/index.js
deleted file mode 100644
index ae9428f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
-export comp6 from './comp6';
-export comp7 from './comp7';
-export comp8 from './comp8';
-export comp9 from './comp9';
-export comp10 from './comp10';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/values.js
deleted file mode 100644
index cd49a610..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/radio/fixtures/values.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- 'one',
- 'two',
- false,
-];
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.form.js b/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.form.js
deleted file mode 100644
index 6171a710..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.form.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import Components from '../Components';
-import ReCaptchaEditDisplay from './editForm/ReCaptcha.edit.display';
-
-export default function() {
- return Components.baseEditForm([
- {
- key: 'display',
- components: ReCaptchaEditDisplay
- },
- {
- key: 'data',
- ignore: true
- },
- {
- key: 'validation',
- ignore: true
- },
- {
- key: 'conditional',
- ignore: true
- },
- {
- key: 'logic',
- ignore: true
- },
- ]);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.js b/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.js
deleted file mode 100644
index f6af1455..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/*globals grecaptcha*/
-import Component from '../_classes/component/Component';
-import { GlobalFormio as Formio } from '../../Formio';
-import _get from 'lodash/get';
-import _debounce from 'lodash/debounce';
-import NativePromise from 'native-promise-only';
-
-export default class ReCaptchaComponent extends Component {
- static schema(...extend) {
- return Component.schema({
- type: 'recaptcha',
- key: 'recaptcha',
- label: 'reCAPTCHA'
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'reCAPTCHA',
- group: 'premium',
- icon: 'refresh',
- documentation: '/userguide/form-building/premium-components#recaptcha',
- weight: 40,
- schema: ReCaptchaComponent.schema()
- };
- }
-
- static savedValueTypes() {
- return [];
- }
-
- render() {
- this.recaptchaResult = null;
- if (this.builderMode) {
- return super.render('reCAPTCHA');
- }
- else {
- return super.render('', true);
- }
- }
-
- createInput() {
- if (this.builderMode) {
- // We need to see it in builder mode.
- this.append(this.text(this.name));
- }
- else {
- const siteKey = _get(this.root.form, 'settings.recaptcha.siteKey');
- if (siteKey) {
- const recaptchaApiScriptUrl = `https://www.google.com/recaptcha/api.js?render=${siteKey}`;
- this.recaptchaApiReady = Formio.requireLibrary('googleRecaptcha', 'grecaptcha', recaptchaApiScriptUrl, true);
- }
- else {
- console.warn('There is no Site Key specified in settings in form JSON');
- }
- }
- }
-
- createLabel() {
- return;
- }
-
- get skipInEmail() {
- return true;
- }
-
- verify(actionName) {
- const siteKey = _get(this.root.form, 'settings.recaptcha.siteKey');
- if (!siteKey) {
- console.warn('There is no Site Key specified in settings in form JSON');
- return;
- }
- if (!this.recaptchaApiReady) {
- const recaptchaApiScriptUrl = `https://www.google.com/recaptcha/api.js?render=${_get(this.root.form, 'settings.recaptcha.siteKey')}`;
- this.recaptchaApiReady = Formio.requireLibrary('googleRecaptcha', 'grecaptcha', recaptchaApiScriptUrl, true);
- }
- if (this.recaptchaApiReady) {
- this.recaptchaVerifiedPromise = new NativePromise((resolve, reject) => {
- this.recaptchaApiReady
- .then(() => {
- if (!this.isLoading) {
- this.isLoading= true;
- grecaptcha.ready(_debounce(() => {
- grecaptcha
- .execute(siteKey, {
- action: actionName
- })
- .then((token) => {
- return this.sendVerificationRequest(token).then(({ verificationResult, token }) => {
- this.recaptchaResult = {
- ...verificationResult,
- token,
- };
- this.updateValue(this.recaptchaResult);
- return resolve(verificationResult);
- });
- })
- .catch(() => {
- this.isLoading = false;
- });
- }, 1000));
- }
- })
- .catch(() => {
- return reject();
- });
- }).then(() => {
- this.isLoading = false;
- });
- }
- }
-
- beforeSubmit() {
- if (this.recaptchaVerifiedPromise) {
- return this.recaptchaVerifiedPromise
- .then(() => super.beforeSubmit());
- }
- return super.beforeSubmit();
- }
-
- sendVerificationRequest(token) {
- return Formio.makeStaticRequest(`${Formio.projectUrl}/recaptcha?recaptchaToken=${token}`)
- .then((verificationResult) => ({ verificationResult, token }));
- }
-
- checkComponentValidity(data, dirty, row, options = {}) {
- data = data || this.rootValue;
- row = row || this.data;
- const { async = false } = options;
-
- // Verification could be async only
- if (!async) {
- return super.checkComponentValidity(data, dirty, row, options);
- }
-
- const componentData = row[this.component.key];
- if (!componentData || !componentData.token) {
- this.setCustomValidity('ReCAPTCHA: Token is not specified in submission');
- return NativePromise.resolve(false);
- }
-
- if (!componentData.success) {
- this.setCustomValidity('ReCAPTCHA: Token validation error');
- return NativePromise.resolve(false);
- }
-
- return this.hook('validateReCaptcha', componentData.token, () => NativePromise.resolve(true))
- .then((success) => success)
- .catch((err) => {
- this.setCustomValidity(err.message || err);
- return false;
- });
- }
-
- normalizeValue(newValue) {
- // If a recaptcha result has already been established, then do not allow it to be reset.
- return this.recaptchaResult ? this.recaptchaResult : newValue;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.unit.js
deleted file mode 100644
index c0b4c7ad..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/ReCaptcha.unit.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import ReCaptchaComponent from './ReCaptcha';
-
-import {
- comp1
-} from './fixtures';
-
-describe('reCAPTCHA Component', () => {
- it('Should build a reCAPTCHA component in builder mode', (done) => {
- new ReCaptchaComponent(comp1, {
- builder: true
- });
- done();
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/editForm/ReCaptcha.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/editForm/ReCaptcha.edit.display.js
deleted file mode 100644
index 37cedf27..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/editForm/ReCaptcha.edit.display.js
+++ /dev/null
@@ -1,106 +0,0 @@
-import { getContextButtons } from '../../../utils/utils';
-export default [
- {
- key: 'eventType',
- label: 'Type of event',
- tooltip: 'Specify type of event that this reCAPTCHA would react to',
- type: 'radio',
- values: [
- {
- label: 'Form Load',
- value: 'formLoad'
- },
- {
- label: 'Button Click',
- value: 'buttonClick'
- }
- ],
- weight: 650
- },
- {
- type: 'select',
- input: true,
- label: 'Button Key',
- key: 'buttonKey',
- dataSrc: 'custom',
- valueProperty: 'value',
- tooltip: 'Specify key of button on this form that this reCAPTCHA should react to',
- weight: 660,
- customConditional(context) {
- return context.data.eventType === 'buttonClick';
- },
- data: {
- custom(context) {
- return getContextButtons(context);
- }
- }
- },
- {
- key: 'label',
- ignore: true
- },
- {
- key: 'hideLabel',
- ignore: true
- },
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'errorLabel',
- ignore: true
- },
- {
- key: 'customClass',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- key: 'multiple',
- ignore: true
- },
- {
- key: 'clearOnHide',
- ignore: true
- },
- {
- key: 'hidden',
- ignore: true
- },
- {
- key: 'mask',
- ignore: true
- },
- {
- key: 'dataGridLabel',
- ignore: true
- },
- {
- key: 'disabled',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/fixtures/comp1.js
deleted file mode 100644
index b2b59e79..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/fixtures/comp1.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default {
- 'eventType': 'buttonClick',
- 'type': 'recaptcha',
- 'key': 'reCaptcha',
- 'label': 'reCAPTCHA',
- 'buttonKey': 'test'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/recaptcha/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.form.js b/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.form.js
deleted file mode 100644
index ce941705..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.form.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import Components from '../Components';
-import ResourceEditDisplay from './editForm/Resource.edit.display';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: ResourceEditDisplay
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.js b/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.js
deleted file mode 100644
index db69fdf1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import SelectComponent from '../select/Select';
-
-export default class ResourceComponent extends SelectComponent {
- static schema(...extend) {
- return SelectComponent.schema({
- type: 'resource',
- label: 'Resource',
- key: 'resource',
- dataSrc: 'resource',
- resource: '',
- project: '',
- template: '{{ item.data }} ',
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Resource',
- icon: 'files-o',
- weight: 90,
- documentation: '/userguide/form-building/form-components#resource',
- schema: ResourceComponent.schema(),
- };
- }
-
- init() {
- super.init();
- this.component.dataSrc = 'resource';
- this.component.data = {
- resource: this.component.resource,
- };
- }
-
- get defaultSchema() {
- return ResourceComponent.schema();
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.unit.js
deleted file mode 100644
index 84113a67..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/resource/Resource.unit.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import Harness from '../../../test/harness';
-import ResourceComponent from './Resource';
-import assert from 'power-assert';
-import Formio from './../../Formio';
-import _ from 'lodash';
-
-import {
- comp1,
- comp2
-} from './fixtures';
-
-describe('Resource Component', () => {
- it('Should build a resource component', (done) => {
- Harness.testCreate(ResourceComponent, comp1).then((component) => {
- Harness.testElements(component, 'select', 1);
- done();
- });
- });
-
- it('Should provide correct value', (done) => {
- const form = _.cloneDeep(comp2);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const resource = form.getComponent('resource');
- const value = 'API key: textField';
- resource.setValue(value);
-
- setTimeout(() => {
- assert.equal(resource.getValue(), value);
- assert.equal(resource.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(resource.dataValue, value);
-
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/resource/editForm/Resource.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/resource/editForm/Resource.edit.display.js
deleted file mode 100644
index 0fdf0638..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/resource/editForm/Resource.edit.display.js
+++ /dev/null
@@ -1,100 +0,0 @@
-export default [
- {
- key: 'resourceInfo',
- weight: -10,
- type: 'htmlelement',
- tag: 'div',
- className: 'alert alert-danger',
- content: 'This component has been deprecated and will be removed in a future version of Formio.js.',
- },
- {
- type: 'select',
- input: true,
- dataSrc: 'url',
- data: {
- url: '/form?type=resource&limit=1000000&select=_id,title',
- },
- authenticate: true,
- template: '{{ item.title }} ',
- valueProperty: '_id',
- label: 'Resource',
- key: 'resource',
- weight: 50,
- tooltip: 'The resource to be used with this field.',
- },
- {
- type: 'tags',
- input: true,
- key: 'selectFields',
- label: 'Select Fields',
- tooltip: 'The properties on the resource to return as part of the options. If left blank, all properties will be returned.',
- placeholder: 'Enter the fields to select.',
- weight: 51,
- },
- {
- type: 'tags',
- input: true,
- key: 'searchFields',
- label: 'Search Fields',
- tooltip: 'A list of search filters based on the fields of the resource. See the Resource.js documentation for the format of these filters.',
- placeholder: 'The fields to query on the server',
- weight: 52,
- },
- {
- type: 'textfield',
- input: true,
- key: 'filter',
- label: 'Filter Query',
- weight: 53,
- description: 'The filter query for results.',
- tooltip: 'Use this to provide additional filtering using query parameters.',
- },
- {
- type: 'textfield',
- input: true,
- key: 'sort',
- label: 'Sort Query',
- weight: 53,
- description: 'The sort query for results',
- tooltip: 'Use this to provide additional sorting using query parameters',
- },
- {
- type: 'textarea',
- input: true,
- key: 'template',
- label: 'Item Template',
- editor: 'ace',
- as: 'html',
- rows: 3,
- weight: 53,
- tooltip: 'The HTML template for the result data items.',
- },
- {
- type: 'checkbox',
- input: true,
- weight: 54,
- key: 'addResource',
- label: 'Add Resource',
- tooltip: 'Allows to create a new resource while entering a submission.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- },
- },
- {
- type: 'textfield',
- label: 'Add Resource Label',
- key: 'addResourceLabel',
- tooltip: 'Set the text of the Add Resource button.',
- placeholder: 'Add Resource',
- weight: 55,
- input: true,
- conditional: {
- json: {
- and: [
- { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- { '!!': { var: 'data.addResource' } },
- ],
- },
- },
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/comp1.js
deleted file mode 100644
index dc2da8b3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/comp1.js
+++ /dev/null
@@ -1,30 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'resource',
- 'defaultPermission': '',
- 'validate': {
- 'required': false
- },
- 'clearOnHide': true,
- 'persistent': true,
- 'protected': false,
- 'multiple': false,
- 'searchFields': '',
- 'selectFields': '',
- 'template': '{{ item.data }} ',
- 'defaultValue': '',
- 'project': '58c21742e4d02b009660a6ee',
- 'resource': '58c21742e4d02b009660a6f2',
- 'placeholder': 'Select the user',
- 'key': 'user',
- 'label': 'User',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/comp2.js
deleted file mode 100644
index d29c47fd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/comp2.js
+++ /dev/null
@@ -1,29 +0,0 @@
-export default {
- title: 'FIO-3744',
- name: 'fio3744',
- path: 'fio3744',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Resource',
- resource: '61377a53c202989e4ed9ff21',
- template: '{{ item.data.textField }} ',
- tableView: true,
- unique: true,
- key: 'resource',
- type: 'resource',
- input: true,
- data: { resource: '61377a53c202989e4ed9ff21' },
- addResource: false,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/index.js
deleted file mode 100644
index 63468958..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/resource/fixtures/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/Select.form.js b/web-client/core/themes/italia/static/formio/css/src/components/select/Select.form.js
deleted file mode 100644
index 93e6d01c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/Select.form.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import listComponentForm from '../_classes/list/ListComponent.form';
-import SelectEditData from './editForm/Select.edit.data';
-import SelectEditDisplay from './editForm/Select.edit.display';
-import SelectEditValidation from './editForm/Select.edit.validation';
-
-export default function(...extend) {
- return listComponentForm([
- {
- key: 'display',
- components: SelectEditDisplay
- },
- {
- key: 'data',
- components: SelectEditData
- },
- {
- key: 'validation',
- components: SelectEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/Select.js b/web-client/core/themes/italia/static/formio/css/src/components/select/Select.js
deleted file mode 100644
index 452dd6ba..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/Select.js
+++ /dev/null
@@ -1,1839 +0,0 @@
-import _ from 'lodash';
-import { GlobalFormio as Formio } from '../../Formio';
-import ListComponent from '../_classes/list/ListComponent';
-import Form from '../../Form';
-import NativePromise from 'native-promise-only';
-import { getRandomComponentId, boolValue, isPromise, componentValueTypes, getComponentSavedTypes, unescapeHTML, isSelectResourceWithObjectValue } from '../../utils/utils';
-
-let Choices;
-if (typeof window !== 'undefined') {
- Choices = require('../../utils/ChoicesWrapper').default;
-}
-
-export default class SelectComponent extends ListComponent {
- static schema(...extend) {
- return ListComponent.schema({
- type: 'select',
- label: 'Select',
- key: 'select',
- idPath: 'id',
- data: {
- values: [{ label: '', value: '' }],
- json: '',
- url: '',
- resource: '',
- custom: ''
- },
- clearOnRefresh: false,
- limit: 100,
- valueProperty: '',
- lazyLoad: true,
- filter: '',
- searchEnabled: true,
- searchDebounce: 0.3,
- searchField: '',
- minSearch: 0,
- readOnlyValue: false,
- selectFields: '',
- selectThreshold: 0.3,
- uniqueOptions: false,
- tableView: true,
- fuseOptions: {
- include: 'score',
- threshold: 0.3,
- },
- indexeddb: {
- filter: {}
- },
- customOptions: {},
- useExactSearch: false,
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Select',
- group: 'basic',
- icon: 'th-list',
- weight: 70,
- documentation: '/userguide/form-building/form-components#select',
- schema: SelectComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return SelectComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- valueComponent(classComp) {
- const valueComp = { ... classComp, type: 'select' };
-
- if (isSelectResourceWithObjectValue(classComp)) {
- valueComp.reference = false;
- valueComp.onSetItems = `
- var templateKeys = utils.getItemTemplateKeys(component.template) || [];
- items = _.map(items || [], i => {
- var item = {};
- _.each(templateKeys, k => _.set(item, k, _.get(i, k)));
- return item;
- })
- `;
- }
-
- return valueComp;
- }
- };
- }
-
- static savedValueTypes(schema) {
- const { boolean, string, number, object, array } = componentValueTypes;
- const { dataType, reference } = schema;
- const types = getComponentSavedTypes(schema);
-
- if (types) {
- return types;
- }
-
- if (reference) {
- return [object];
- }
-
- if (dataType === 'object') {
- return [object, array];
- }
-
- if (componentValueTypes[dataType]) {
- return [componentValueTypes[dataType]];
- }
-
- return [boolean, string, number, object, array];
- }
-
- init() {
- super.init();
- this.templateData = {};
- this.validators = this.validators.concat(['select', 'onlyAvailableItems']);
-
- // Trigger an update.
- let updateArgs = [];
- const triggerUpdate = _.debounce((...args) => {
- updateArgs = [];
- return this.updateItems.apply(this, args);
- }, 100);
- this.triggerUpdate = (...args) => {
- // Make sure we always resolve the previous promise before reassign it
- if (typeof this.itemsLoadedResolve === 'function') {
- this.itemsLoadedResolve();
- }
- this.itemsLoaded = new NativePromise((resolve) => {
- this.itemsLoadedResolve = resolve;
- });
- if (args.length) {
- updateArgs = args;
- }
- return triggerUpdate(...updateArgs);
- };
-
- // Keep track of the select options.
- this.selectOptions = [];
-
- if (this.itemsFromUrl) {
- this.isFromSearch = false;
-
- this.searchServerCount = null;
- this.defaultServerCount = null;
-
- this.isScrollLoading = false;
-
- this.searchDownloadedResources = [];
- this.defaultDownloadedResources = [];
- }
-
- // If this component has been activated.
- this.activated = false;
- this.itemsLoaded = new NativePromise((resolve) => {
- this.itemsLoadedResolve = resolve;
- });
-
- this.shouldPositionDropdown = this.hasDataGridAncestor();
-
- if (this.isHtmlRenderMode()) {
- this.activate();
- }
-
- // Get the template keys for this select component.
- this.getTemplateKeys();
- }
-
- get dataReady() {
- // If the root submission has been set, and we are still not attached, then assume
- // that our data is ready.
- if (
- this.root &&
- this.root.submissionSet &&
- !this.attached
- ) {
- return NativePromise.resolve();
- }
- return this.itemsLoaded;
- }
-
- get defaultSchema() {
- return SelectComponent.schema();
- }
-
- get emptyValue() {
- if (this.component.multiple) {
- return [];
- }
- // if select has JSON data source type, we are defining if empty value would be an object or a string by checking JSON's first item
- if (this.component.dataSrc === 'json' && this.component.data.json) {
- const firstItem = this.component.data.json[0];
- let firstValue;
- if (this.valueProperty) {
- firstValue = _.get(firstItem, this.valueProperty);
- }
- else {
- firstValue = firstItem;
- }
- if (firstValue && typeof firstValue === 'string') {
- return '';
- }
- else {
- return {};
- }
- }
- if (this.valueProperty) {
- return '';
- }
- return {};
- }
-
- get valueProperty() {
- if (this.component.valueProperty) {
- return this.component.valueProperty;
- }
- // Force values datasource to use values without actually setting it on the component settings.
- if (this.component.dataSrc === 'values') {
- return 'value';
- }
- return '';
- }
-
- get inputInfo() {
- const info = super.elementInfo();
- info.type = 'select';
- info.changeEvent = 'change';
- return info;
- }
-
- get isSelectResource() {
- return this.component.dataSrc === 'resource';
- }
-
- get itemsFromUrl() {
- return this.isSelectResource || this.isSelectURL;
- }
-
- get isInfiniteScrollProvided() {
- return this.itemsFromUrl;
- }
-
- get shouldDisabled() {
- return super.shouldDisabled || this.parentDisabled;
- }
-
- get shouldInitialLoad() {
- if (this.component.widget === 'html5' &&
- this.isEntireObjectDisplay() &&
- this.component.searchField &&
- this.dataValue) {
- return false;
- }
-
- return super.shouldLoad;
- }
-
- isEntireObjectDisplay() {
- return this.component.dataSrc === 'resource' && this.valueProperty === 'data';
- }
-
- selectValueAndLabel(data) {
- const value = this.getOptionValue((this.isEntireObjectDisplay() && !this.itemValue(data)) ? data : this.itemValue(data));
- return {
- value,
- label: this.itemTemplate((this.isEntireObjectDisplay() && !_.isObject(data.data)) ? { data: data } : data, value)
- };
- }
-
- itemTemplate(data, value) {
- if (!_.isNumber(data) && _.isEmpty(data)) {
- return '';
- }
-
- // If they wish to show the value in read only mode, then just return the itemValue here.
- if (this.options.readOnly && this.component.readOnlyValue) {
- return this.itemValue(data);
- }
- // Perform a fast interpretation if we should not use the template.
- if (data && !this.component.template) {
- const itemLabel = data.label || data;
- const value = (typeof itemLabel === 'string') ? this.t(itemLabel, { _userInput: true }) : itemLabel;
- return this.sanitize(value, this.shouldSanitizeValue);
- }
-
- if (this.component.multiple && _.isArray(this.dataValue) ? this.dataValue.find((val) => value === val) : (this.dataValue === value)) {
- const selectData = this.selectData;
- if (selectData) {
- const templateValue = this.component.reference && value?._id ? value._id.toString() : value;
- if (!this.templateData || !this.templateData[templateValue]) {
- this.getOptionTemplate(data, value);
- }
- if (this.component.multiple) {
- if (selectData[templateValue]) {
- data = selectData[templateValue];
- }
- }
- else {
- data = selectData;
- }
- }
- }
-
- if (typeof data === 'string' || typeof data === 'number') {
- return this.sanitize(this.t(data, { _userInput: true }), this.shouldSanitizeValue);
- }
- if (Array.isArray(data)) {
- return data.map((val) => {
- if (typeof val === 'string' || typeof val === 'number') {
- return this.sanitize(this.t(val, { _userInput: true }), this.shouldSanitizeValue);
- }
- return val;
- });
- }
-
- if (data.data) {
- // checking additional fields in the template for the selected Entire Object option
- const hasNestedFields = /item\.data\.\w*/g.test(this.component.template);
- data.data = this.isEntireObjectDisplay() && _.isObject(data.data) && !hasNestedFields
- ? JSON.stringify(data.data)
- : data.data;
- }
- return super.itemTemplate(data, value);
- }
-
- /**
- * Adds an option to the select dropdown.
- *
- * @param value
- * @param label
- */
- addOption(value, label, attrs = {}, id = getRandomComponentId()) {
- if (_.isNil(label)) return;
- const idPath = this.component.idPath
- ? this.component.idPath.split('.').reduceRight((obj, key) => ({ [key]: obj }), id)
- : {};
- const option = {
- value: this.getOptionValue(value),
- label,
- ...idPath
- };
-
- const skipOption = this.component.uniqueOptions
- ? !!this.selectOptions.find((selectOption) => _.isEqual(selectOption.value, option.value))
- : false;
-
- if (skipOption) {
- return;
- }
-
- if (value) {
- this.selectOptions.push(option);
- }
-
- if (this.refs.selectContainer && (this.component.widget === 'html5')) {
- // Replace an empty Object value to an empty String.
- if (option.value && _.isObject(option.value) && _.isEmpty(option.value)) {
- option.value = '';
- }
- // Add element to option so we can reference it later.
- const div = document.createElement('div');
- div.innerHTML = this.sanitize(this.renderTemplate('selectOption', {
- selected: _.isEqual(this.getOptionValue(this.dataValue), option.value),
- option,
- attrs,
- id,
- useId: (this.valueProperty === '' || this.isEntireObjectDisplay()) && _.isObject(value) && id,
- }), this.shouldSanitizeValue).trim();
-
- option.element = div.firstChild;
- this.refs.selectContainer.appendChild(option.element);
- }
- }
-
- addValueOptions(items) {
- items = items || [];
- let added = false;
- let data = this.dataValue;
-
- // preset submission value with value property before request.
- if (this.options.pdf && !items.length && this.component.dataSrc === 'url' && this.valueProperty) {
- data = Array.isArray(data)
- ? data.map(item => _.set({}, this.valueProperty, item))
- : _.set({}, this.valueProperty, data);
- }
-
- if (!this.selectOptions.length) {
- // Add the currently selected choices if they don't already exist.
- const currentChoices = Array.isArray(data) && this.component.multiple ? data : [data];
- added = this.addCurrentChoices(currentChoices, items);
- if (!added && !this.component.multiple) {
- this.addPlaceholder();
- }
- }
- return added;
- }
-
- disableInfiniteScroll() {
- if (!this.downloadedResources) {
- return;
- }
-
- this.downloadedResources.serverCount = this.downloadedResources.length;
- this.serverCount = this.downloadedResources.length;
- }
-
- /* eslint-disable max-statements */
- setItems(items, fromSearch) {
- this.selectItems = items;
- // If the items is a string, then parse as JSON.
- if (typeof items == 'string') {
- try {
- items = JSON.parse(items);
- }
- catch (err) {
- console.warn(err.message);
- items = [];
- }
- }
-
- // Allow js processing (needed for form builder)
- if (this.component.onSetItems) {
- const newItems = typeof this.component.onSetItems === 'function'
- ? this.component.onSetItems(this, items)
- : this.evaluate(this.component.onSetItems, { items: items }, 'items');
- if (newItems) {
- items = newItems;
- }
- }
-
- if (!this.choices && this.refs.selectContainer) {
- this.empty(this.refs.selectContainer);
- }
-
- // If they provided select values, then we need to get them instead.
- if (this.component.selectValues) {
- items = _.get(items, this.component.selectValues, items) || [];
- }
-
- let areItemsEqual;
-
- if (this.itemsFromUrl) {
- areItemsEqual = this.isSelectURL ? _.isEqual(items, this.downloadedResources) : false;
-
- const areItemsEnded = this.component.limit > items.length;
- const areItemsDownloaded = areItemsEqual
- && this.downloadedResources
- && this.downloadedResources.length === items.length;
-
- if (areItemsEnded) {
- this.disableInfiniteScroll();
- }
- else if (areItemsDownloaded) {
- this.selectOptions = [];
- }
- else {
- this.serverCount = items.serverCount;
- }
- }
-
- if (this.isScrollLoading && items) {
- if (!areItemsEqual) {
- this.downloadedResources = this.downloadedResources
- ? this.downloadedResources.concat(items)
- : items;
- }
-
- this.downloadedResources.serverCount = items.serverCount || this.downloadedResources.serverCount;
- }
- else {
- this.downloadedResources = items || [];
- this.selectOptions = [];
- // If there is new select option with same id as already selected, set the new one
- if (!_.isEmpty(this.dataValue) && this.component.idPath) {
- const selectedOptionId = _.get(this.dataValue, this.component.idPath, null);
- const newOptionWithSameId = !_.isNil(selectedOptionId) && items.find(item => {
- const itemId = _.get(item, this.component.idPath);
-
- return itemId === selectedOptionId;
- });
-
- if (newOptionWithSameId) {
- this.setValue(newOptionWithSameId);
- }
- }
- }
-
- // Add the value options.
- if (!fromSearch) {
- this.addValueOptions(items);
- }
-
- if (this.component.widget === 'html5' && !this.component.placeholder) {
- this.addOption(null, '');
- }
-
- // Iterate through each of the items.
- _.each(items, (item, index) => {
- // preventing references of the components inside the form to the parent form when building forms
- if (this.root && this.root.options.editForm && this.root.options.editForm._id && this.root.options.editForm._id === item._id) return;
- const itemValueAndLabel = this.selectValueAndLabel(item);
- this.addOption(itemValueAndLabel.value, itemValueAndLabel.label, {}, _.get(item, this.component.idPath, String(index)));
- });
-
- if (this.choices) {
- this.choices.setChoices(this.selectOptions, 'value', 'label', true);
- }
- else if (this.loading) {
- // Re-attach select input.
- // this.appendTo(this.refs.input[0], this.selectContainer);
- }
-
- // We are no longer loading.
- this.isScrollLoading = false;
- this.loading = false;
-
- const searching = fromSearch && this.choices?.input?.isFocussed;
-
- if (!searching) {
- // If a value is provided, then select it.
- if (!this.isEmpty() || this.isRemoveButtonPressed) {
- this.setValue(this.dataValue, {
- noUpdateEvent: true
- });
- }
- else if (this.shouldAddDefaultValue && !this.options.readOnly) {
- // If a default value is provided then select it.
- const defaultValue = this.defaultValue;
- if (!this.isEmpty(defaultValue)) {
- this.setValue(defaultValue);
- }
- }
- }
-
- // Say we are done loading the items.
- this.itemsLoadedResolve();
- }
-
- getSingleItemValueForHTMLMode(data) {
- const option = this.selectOptions?.find(({ value }) => _.isEqual(value, data));
- if (option) {
- return option.label || data;
- }
-
- return data;
- }
-
- itemValueForHTMLMode(value) {
- if (!this.isHtmlRenderMode()) {
- return super.itemValueForHTMLMode(value);
- }
-
- if (Array.isArray(value)) {
- const values = value.map(item => Array.isArray(item)
- ? this.itemValueForHTMLMode(item)
- : this.getSingleItemValueForHTMLMode(item));
-
- return values.join(', ');
- }
-
- return this.getSingleItemValueForHTMLMode(value);
- }
-
- /* eslint-enable max-statements */
-
- get defaultValue() {
- let defaultValue = super.defaultValue;
- if (!defaultValue && (this.component.defaultValue === false || this.component.defaultValue === 0)) {
- defaultValue = this.component.defaultValue;
- }
- return defaultValue;
- }
-
- get loadingError() {
- return !this.component.refreshOn && !this.component.refreshOnBlur && this.networkError;
- }
-
- loadItems(url, search, headers, options, method, body) {
- options = options || {};
-
- // See if we should load items or not.
- if (!this.shouldLoad || (!this.itemsFromUrl && this.options.readOnly)) {
- this.isScrollLoading = false;
- this.loading = false;
- this.itemsLoadedResolve();
- return;
- }
-
- // See if they have not met the minimum search requirements.
- const minSearch = parseInt(this.component.minSearch, 10);
- if (
- this.component.searchField &&
- (minSearch > 0) &&
- (!search || (search.length < minSearch))
- ) {
- // Set empty items.
- return this.setItems([]);
- }
-
- // Ensure we have a method and remove any body if method is get
- method = method || 'GET';
- if (method.toUpperCase() === 'GET') {
- body = null;
- }
-
- const limit = this.component.limit || 100;
- const skip = this.isScrollLoading ? this.selectOptions.length : 0;
- const query = this.component.disableLimit ? {} : {
- limit,
- skip,
- };
-
- // Allow for url interpolation.
- url = this.interpolate(url, {
- formioBase: Formio.getBaseUrl(),
- search,
- limit,
- skip,
- page: Math.abs(Math.floor(skip / limit))
- });
-
- // Add search capability.
- if (this.component.searchField && search) {
- const searchValue = Array.isArray(search)
- ? search.join(',')
- : typeof search === 'object'
- ? JSON.stringify(search)
- : search;
-
- query[this.component.searchField] = this.component.searchField.endsWith('__regex')
- ? _.escapeRegExp(searchValue)
- : searchValue;
- }
-
- // If they wish to return only some fields.
- if (this.component.selectFields) {
- query.select = this.component.selectFields;
- }
-
- // Add sort capability
- if (this.component.sort) {
- query.sort = this.component.sort;
- }
-
- if (!_.isEmpty(query)) {
- // Add the query string.
- url += (!url.includes('?') ? '?' : '&') + Formio.serialize(query, (item) => this.interpolate(item));
- }
-
- // Add filter capability
- if (this.component.filter) {
- url += (!url.includes('?') ? '?' : '&') + this.interpolate(this.component.filter);
- }
-
- // Set ignoreCache if it is
- options.ignoreCache = this.component.ignoreCache;
-
- // Make the request.
- options.header = headers;
- this.loading = true;
-
- Formio.makeRequest(this.options.formio, 'select', url, method, body, options)
- .then((response) => {
- this.loading = false;
- this.error = null;
- this.setItems(response, !!search);
- })
- .catch((err) => {
- if (this.itemsFromUrl) {
- this.setItems([]);
- this.disableInfiniteScroll();
- }
-
- this.isScrollLoading = false;
- this.handleLoadingError(err);
- });
- }
-
- handleLoadingError(err) {
- this.loading = false;
- if (err.networkError) {
- this.networkError = true;
- }
- this.itemsLoadedResolve();
- this.emit('componentError', {
- component: this.component,
- message: err.toString(),
- });
- console.warn(`Unable to load resources for ${this.key}`);
- }
- /**
- * Get the request headers for this select dropdown.
- */
- get requestHeaders() {
- // Create the headers object.
- const headers = new Formio.Headers();
-
- // Add custom headers to the url.
- if (this.component.data && this.component.data.headers) {
- try {
- _.each(this.component.data.headers, (header) => {
- if (header.key) {
- headers.set(header.key, this.interpolate(header.value));
- }
- });
- }
- catch (err) {
- console.warn(err.message);
- }
- }
-
- return headers;
- }
-
- getCustomItems() {
- const customItems = this.evaluate(this.component.data.custom, {
- values: []
- }, 'values');
-
- this.asyncValues = isPromise(customItems);
-
- return customItems;
- }
-
- asyncCustomValues() {
- if (!_.isBoolean(this.asyncValues)) {
- this.getCustomItems();
- }
-
- return this.asyncValues;
- }
-
- updateCustomItems(forceUpdate) {
- if (this.asyncCustomValues()) {
- if (!forceUpdate && !this.active) {
- this.itemsLoadedResolve();
- return;
- }
-
- this.loading = true;
- this.getCustomItems()
- .then(items => {
- this.loading = false;
- this.setItems(items || []);
- })
- .catch(err => {
- this.handleLoadingError(err);
- });
- }
- else {
- this.setItems(this.getCustomItems() || []);
- }
- }
-
- isEmpty(value = this.dataValue) {
- return super.isEmpty(value) || value === undefined;
- }
-
- refresh(value, { instance }) {
- if (this.component.clearOnRefresh && (instance && !instance.pristine)) {
- this.setValue(this.emptyValue);
- }
-
- this.updateItems(null, true);
- }
-
- get additionalResourcesAvailable() {
- return _.isNil(this.serverCount) || (this.serverCount > this.downloadedResources.length);
- }
-
- get serverCount() {
- if (this.isFromSearch) {
- return this.searchServerCount;
- }
-
- return this.defaultServerCount;
- }
-
- set serverCount(value) {
- if (this.isFromSearch) {
- this.searchServerCount = value;
- }
- else {
- this.defaultServerCount = value;
- }
- }
-
- get downloadedResources() {
- if (this.isFromSearch) {
- return this.searchDownloadedResources;
- }
-
- return this.defaultDownloadedResources;
- }
-
- set downloadedResources(value) {
- if (this.isFromSearch) {
- this.searchDownloadedResources = value;
- }
- else {
- this.defaultDownloadedResources = value;
- }
- }
-
- addPlaceholder() {
- if (!this.component.placeholder) {
- return;
- }
-
- this.addOption('', this.component.placeholder, { placeholder: true });
- }
-
- /**
- * Activate this select control.
- */
- activate() {
- if (this.loading || !this.active) {
- this.setLoadingItem();
- }
- if (this.active) {
- return;
- }
- this.activated = true;
- this.triggerUpdate();
- }
-
- setLoadingItem(addToCurrentList = false) {
- if (this.choices) {
- if (addToCurrentList) {
- this.choices.setChoices([{
- value: `${this.id}-loading`,
- label: 'Loading...',
- disabled: true,
- }], 'value', 'label');
- }
- else {
- this.choices.setChoices([{
- value: '',
- label: ` `,
- disabled: true,
- }], 'value', 'label', true);
- }
- }
- else if (this.component.dataSrc === 'url' || this.component.dataSrc === 'resource') {
- this.addOption('', this.t('loading...'));
- }
- }
-
- get active() {
- return !this.component.lazyLoad || this.activated;
- }
-
- render() {
- const info = this.inputInfo;
- info.attr = info.attr || {};
- info.multiple = this.component.multiple;
- return super.render(this.wrapElement(this.renderTemplate('select', {
- input: info,
- selectOptions: '',
- index: null,
- })));
- }
-
- wrapElement(element) {
- return this.component.addResource && !this.options.readOnly
- ? (
- this.renderTemplate('resourceAdd', {
- element
- })
- )
- : element;
- }
-
- choicesOptions() {
- const useSearch = this.component.hasOwnProperty('searchEnabled') ? this.component.searchEnabled : true;
- const placeholderValue = this.t(this.component.placeholder, { _userInput: true });
- let customOptions = this.component.customOptions || {};
- if (typeof customOptions == 'string') {
- try {
- customOptions = JSON.parse(customOptions);
- }
- catch (err) {
- console.warn(err.message);
- customOptions = {};
- }
- }
-
- const commonFuseOptions = {
- maxPatternLength: 1000,
- distance: 1000,
- };
-
- return {
- removeItemButton: this.component.disabled ? false : _.get(this.component, 'removeItemButton', true),
- itemSelectText: '',
- classNames: {
- containerOuter: 'choices form-group formio-choices',
- containerInner: this.transform('class', 'form-control ui fluid selection dropdown')
- },
- addItemText: false,
- allowHTML: true,
- placeholder: !!this.component.placeholder,
- placeholderValue: placeholderValue,
- noResultsText: this.t('No results found'),
- noChoicesText: this.t('No choices to choose from'),
- searchPlaceholderValue: this.t('Type to search'),
- shouldSort: false,
- position: (this.component.dropdown || 'auto'),
- searchEnabled: useSearch,
- searchChoices: !this.component.searchField,
- searchFields: _.get(this, 'component.searchFields', ['label']),
- shadowRoot: this.root ? this.root.shadowRoot : null,
- fuseOptions: this.component.useExactSearch
- ? {
- tokenize: true,
- matchAllTokens: true,
- ...commonFuseOptions
- }
- : Object.assign(
- {},
- _.get(this, 'component.fuseOptions', {}),
- {
- include: 'score',
- threshold: _.get(this, 'component.selectThreshold', 0.3),
- ...commonFuseOptions
- }
- ),
- valueComparer: _.isEqual,
- resetScrollPosition: false,
- ...customOptions,
- };
- }
-
- /* eslint-disable max-statements */
- attach(element) {
- const superAttach = super.attach(element);
- this.loadRefs(element, {
- selectContainer: 'single',
- addResource: 'single',
- autocompleteInput: 'single'
- });
- //enable autocomplete for select
- const autocompleteInput = this.refs.autocompleteInput;
- if (autocompleteInput) {
- this.addEventListener(autocompleteInput, 'change', (event) => {
- this.setValue(event.target.value);
- });
- }
- const input = this.refs.selectContainer;
- if (!input) {
- return;
- }
- this.addEventListener(input, this.inputInfo.changeEvent, () => this.updateValue(null, {
- modified: true
- }));
- this.attachRefreshOnBlur();
-
- if (this.component.widget === 'html5') {
- this.addFocusBlurEvents(input);
- this.triggerUpdate(null, true);
-
- if (this.visible) {
- this.setItems(this.selectItems || []);
- }
-
- this.focusableElement = input;
- this.addEventListener(input, 'focus', () => this.update());
- this.addEventListener(input, 'keydown', (event) => {
- const { key } = event;
-
- if (['Backspace', 'Delete'].includes(key)) {
- this.setValue(this.emptyValue);
- }
- });
-
- return;
- }
-
- const tabIndex = input.tabIndex;
- this.addPlaceholder();
- input.setAttribute('dir', this.i18next.dir());
- if (this.choices?.containerOuter?.element?.parentNode) {
- this.choices.destroy();
- }
-
- const choicesOptions = this.choicesOptions();
-
- if (Choices) {
- this.choices = new Choices(input, choicesOptions);
-
- if (this.selectOptions && this.selectOptions.length) {
- this.choices.setChoices(this.selectOptions, 'value', 'label', true);
- }
-
- if (this.component.multiple) {
- this.focusableElement = this.choices.input.element;
- }
- else {
- this.focusableElement = this.choices.containerInner.element;
- this.choices.containerOuter.element.setAttribute('tabIndex', '-1');
- this.addEventListener(this.choices.containerOuter.element, 'focus', () => this.focusableElement.focus());
- }
-
- this.addFocusBlurEvents(this.focusableElement);
-
- if (this.itemsFromUrl && !this.component.noRefreshOnScroll) {
- this.scrollList = this.choices.choiceList.element;
- this.addEventListener(this.scrollList, 'scroll', () => this.onScroll());
- }
-
- if (choicesOptions.removeItemButton) {
- this.addEventListener(input, 'removeItem', () => {
- this.isRemoveButtonPressed = true;
- });
- }
- }
-
- if (window && this.choices && this.shouldPositionDropdown) {
- this.addEventListener(window.document, 'scroll', () => {
- this.positionDropdown(true);
- }, false, true);
- }
-
- this.focusableElement.setAttribute('tabIndex', tabIndex);
-
- // If a search field is provided, then add an event listener to update items on search.
- if (this.component.searchField) {
- // Make sure to clear the search when no value is provided.
- if (this.choices && this.choices.input && this.choices.input.element) {
- this.addEventListener(this.choices.input.element, 'input', (event) => {
- this.isFromSearch = !!event.target.value;
-
- if (!event.target.value) {
- this.triggerUpdate();
- }
- else {
- this.serverCount = null;
- this.downloadedResources = [];
- }
- });
- }
-
- this.addEventListener(input, 'choice', () => {
- if (this.component.multiple && this.component.dataSrc === 'resource' && this.isFromSearch) {
- this.triggerUpdate();
- }
- this.isFromSearch = false;
- });
- // avoid spamming the resource/url endpoint when we have server side filtering enabled.
- const debounceTimeout = this.component.searchField && (this.isSelectResource || this.isSelectURL) ?
- (this.component.searchDebounce === 0 ? 0 : this.component.searchDebounce || this.defaultSchema.searchDebounce) * 1000
- : 0;
- const updateComponent = (evt) => {
- this.triggerUpdate(evt.detail.value);
- };
-
- this.addEventListener(input, 'search', _.debounce((e) => {
- updateComponent(e);
- this.positionDropdown();
- }, debounceTimeout));
-
- this.addEventListener(input, 'stopSearch', () => this.triggerUpdate());
- this.addEventListener(input, 'hideDropdown', () => {
- if (this.choices && this.choices.input && this.choices.input.element) {
- this.choices.input.element.value = '';
- }
-
- this.updateItems(null, true);
- });
- }
-
- this.addEventListener(input, 'showDropdown', () => {
- this.update();
- this.positionDropdown();
- });
-
- if (this.shouldPositionDropdown) {
- this.addEventListener(input, 'highlightChoice', () => {
- this.positionDropdown();
- });
- }
-
- if (this.choices && choicesOptions.placeholderValue && this.choices._isSelectOneElement) {
- this.addPlaceholderItem(choicesOptions.placeholderValue);
-
- this.addEventListener(input, 'removeItem', () => {
- this.addPlaceholderItem(choicesOptions.placeholderValue);
- });
- }
-
- // Add value options.
- this.addValueOptions();
- this.setChoicesValue(this.dataValue);
-
- if (this.isSelectResource && this.refs.addResource) {
- this.addEventListener(this.refs.addResource, 'click', (event) => {
- event.preventDefault();
-
- const formioForm = this.ce('div');
- const dialog = this.createModal(formioForm);
-
- const projectUrl = _.get(this.root, 'formio.projectUrl', Formio.getProjectUrl());
- const formUrl = `${projectUrl}/form/${this.component.data.resource}`;
- new Form(formioForm, formUrl, {}).ready
- .then((form) => {
- form.on('submit', (submission) => {
- // If valueProperty is set, replace the submission with the corresponding value
- let value = this.valueProperty ? _.get(submission, this.valueProperty) : submission;
-
- if (this.component.multiple) {
- value = [...this.dataValue, value];
- }
- this.setValue(value);
- this.triggerUpdate();
- dialog.close();
- });
- });
- });
- }
-
- // Force the disabled state with getters and setters.
- this.disabled = this.shouldDisabled;
- this.triggerUpdate();
- return superAttach;
- }
-
- setDropdownPosition() {
- const dropdown = this.choices?.dropdown?.element;
- const container = this.choices?.containerOuter?.element;
-
- if (!dropdown || !container) {
- return;
- }
-
- const containerPosition = container.getBoundingClientRect();
- const isFlipped = container.classList.contains('is-flipped');
-
- _.assign(dropdown.style, {
- top: `${isFlipped ? containerPosition.top - dropdown.offsetHeight : containerPosition.top + containerPosition.height}px`,
- left: `${containerPosition.left}px`,
- width: `${containerPosition.width}px`,
- position: 'fixed',
- bottom: 'unset',
- right: 'unset',
- });
- }
-
- hasDataGridAncestor(comp) {
- comp = comp || this;
-
- if (comp.inDataGrid || comp.type === 'datagrid') {
- return true;
- }
- else if (comp.parent) {
- return this.hasDataGridAncestor(comp.parent);
- }
- else {
- return false;
- }
- }
-
- positionDropdown(scroll) {
- if (!this.shouldPositionDropdown || !this.choices || (!this.choices.dropdown?.isActive && scroll)) {
- return;
- }
-
- this.setDropdownPosition();
-
- this.itemsLoaded.then(() => {
- this.setDropdownPosition();
- });
- }
-
- get isLoadingAvailable() {
- return !this.isScrollLoading && this.additionalResourcesAvailable;
- }
-
- onScroll() {
- if (this.isLoadingAvailable) {
- this.isScrollLoading = true;
- this.setLoadingItem(true);
- this.triggerUpdate(this.choices.input.element.value);
- }
- }
-
- attachRefreshOnBlur() {
- if (this.component.refreshOnBlur) {
- this.on('blur', (instance) => {
- this.checkRefreshOn([{ instance, value: instance.dataValue }], { fromBlur: true });
- });
- }
- }
-
- addPlaceholderItem(placeholderValue) {
- const items = this.choices._store.activeItems;
- if (!items.length) {
- this.choices._addItem({
- value: placeholderValue,
- label: placeholderValue,
- choiceId: 0,
- groupId: -1,
- customProperties: null,
- placeholder: true,
- keyCode: null
- });
- }
- }
-
- /* eslint-enable max-statements */
- update() {
- if (this.component.dataSrc === 'custom') {
- this.updateCustomItems();
- }
- // Activate the control.
- this.activate();
- }
-
- set disabled(disabled) {
- super.disabled = disabled;
- if (!this.choices) {
- return;
- }
- if (disabled) {
- this.setDisabled(this.choices.containerInner.element, true);
- this.focusableElement.removeAttribute('tabIndex');
- this.choices.disable();
- }
- else {
- this.setDisabled(this.choices.containerInner.element, false);
- this.focusableElement.setAttribute('tabIndex', this.component.tabindex || 0);
- this.choices.enable();
- }
- }
-
- get disabled() {
- return super.disabled;
- }
-
- set visible(value) {
- // If we go from hidden to visible, trigger a refresh.
- if (value && (!this._visible !== !value)) {
- this.triggerUpdate();
- }
- super.visible = value;
- }
-
- get visible() {
- return super.visible;
- }
-
- /**
- * @param {*} value
- * @param {Array} items
- */
- addCurrentChoices(values, items, keyValue) {
- if (!values) {
- return false;
- }
- const notFoundValuesToAdd = [];
- const added = values.reduce((defaultAdded, value) => {
- if (!value || _.isEmpty(value)) {
- return defaultAdded;
- }
- let found = false;
-
- // Make sure that `items` and `this.selectOptions` points
- // to the same reference. Because `this.selectOptions` is
- // internal property and all items are populated by
- // `this.addOption` method, we assume that items has
- // 'label' and 'value' properties. This assumption allows
- // us to read correct value from the item.
- const isSelectOptions = items === this.selectOptions;
- if (items && items.length) {
- _.each(items, (choice) => {
- if (choice._id && value._id && (choice._id === value._id)) {
- found = true;
- return false;
- }
- const itemValue = keyValue ? choice.value : this.itemValue(choice, isSelectOptions);
- found |= _.isEqual(itemValue, value);
- return found ? false : true;
- });
- }
-
- // Add the default option if no item is found.
- if (!found) {
- notFoundValuesToAdd.push(this.selectValueAndLabel(value));
- return true;
- }
- return found || defaultAdded;
- }, false);
-
- if (notFoundValuesToAdd.length) {
- if (this.choices) {
- this.choices.setChoices(notFoundValuesToAdd, 'value', 'label');
- }
- notFoundValuesToAdd.map(notFoundValue => {
- this.addOption(notFoundValue.value, notFoundValue.label);
- });
- }
- return added;
- }
-
- getValueAsString(data, options) {
- return (this.component.multiple && Array.isArray(data))
- ? data.map((v) => this.asString(v, options)).join(', ')
- : this.asString(data, options);
- }
-
- getValue() {
- // If the widget isn't active.
- if (
- this.viewOnly || this.loading
- || (!this.component.lazyLoad && !this.selectOptions.length)
- || !this.element
- ) {
- return this.dataValue;
- }
-
- let value = this.emptyValue;
- if (this.choices) {
- value = this.choices.getValue(true);
-
- // Make sure we don't get the placeholder
- if (
- !this.component.multiple &&
- this.component.placeholder &&
- (value === this.t(this.component.placeholder, { _userInput: true }))
- ) {
- value = this.emptyValue;
- }
- }
- else if (this.refs.selectContainer) {
- value = this.refs.selectContainer.value;
-
- if (this.valueProperty === '' || this.isEntireObjectDisplay()) {
- if (value === '') {
- return {};
- }
-
- const option = this.selectOptions[value] || this.selectOptions.find(option => option.id === value);
- if (option && _.isObject(option.value)) {
- value = option.value;
- }
- }
- }
- else {
- value = this.dataValue;
- }
- // Choices will return undefined if nothing is selected. We really want '' to be empty.
- if (value === undefined || value === null) {
- value = '';
- }
- return value;
- }
-
- redraw() {
- const done = super.redraw();
- this.triggerUpdate();
- return done;
- }
-
- normalizeSingleValue(value, retainObject) {
- if (_.isNil(value)) {
- return;
- }
- const valueIsObject = _.isObject(value);
- //check if value equals to default emptyValue
- if (valueIsObject && Object.keys(value).length === 0) {
- return value;
- }
- // Check to see if we need to save off the template data into our metadata.
- if (retainObject) {
- const templateValue = this.component.reference && value?._id ? value._id.toString() : value;
- const shouldSaveData = !valueIsObject || this.component.reference;
- if (templateValue && shouldSaveData && (this.templateData && this.templateData[templateValue]) && this.root?.submission) {
- const submission = this.root.submission;
- if (!submission.metadata) {
- submission.metadata = {};
- }
- if (!submission.metadata.selectData) {
- submission.metadata.selectData = {};
- }
-
- let templateData = this.templateData[templateValue];
- if (this.component.multiple) {
- templateData = {};
- const dataValue = this.dataValue;
- if (dataValue && _.isArray(dataValue) && dataValue.length) {
- dataValue.forEach((dataValueItem) => {
- const dataValueItemValue = this.component.reference ? dataValueItem._id.toString() : dataValueItem;
- templateData[dataValueItemValue] = this.templateData[dataValueItemValue];
- });
- }
- templateData[value] = this.templateData[value];
- }
-
- _.set(submission.metadata.selectData, this.path, templateData);
- }
- }
-
- const dataType = this.component.dataType || 'auto';
- const normalize = {
- value,
-
- number() {
- const numberValue = Number(this.value);
- const isEquivalent = value.toString() === numberValue.toString();
-
- if (!Number.isNaN(numberValue) && Number.isFinite(numberValue) && value !== '' && isEquivalent) {
- this.value = numberValue;
- }
-
- return this;
- },
-
- boolean() {
- if (
- _.isString(this.value)
- && (this.value.toLowerCase() === 'true'
- || this.value.toLowerCase() === 'false')
- ) {
- this.value = (this.value.toLowerCase() === 'true');
- }
-
- return this;
- },
-
- string() {
- this.value = String(this.value);
- return this;
- },
-
- object() {
- return this;
- },
-
- auto() {
- if (_.isObject(this.value)) {
- this.value = this.object().value;
- }
- else {
- this.value = this.string().number().boolean().value;
- }
-
- return this;
- }
- };
-
- try {
- return normalize[dataType]().value;
- }
- catch (err) {
- console.warn('Failed to normalize value', err);
- return value;
- }
- }
-
- /**
- * Normalize values coming into updateValue.
- *
- * @param value
- * @return {*}
- */
- normalizeValue(value) {
- if (this.component.multiple && Array.isArray(value)) {
- return value.map((singleValue) => this.normalizeSingleValue(singleValue, true));
- }
-
- return super.normalizeValue(this.normalizeSingleValue(value, true));
- }
-
- setValue(value, flags = {}) {
- const previousValue = this.dataValue;
- if (this.component.widget === 'html5' && (_.isEqual(value, previousValue) || _.isEqual(previousValue, {}) && _.isEqual(flags, {})) && !flags.fromSubmission ) {
- return false;
- }
- const changed = this.updateValue(value, flags);
- value = this.dataValue;
- const hasPreviousValue = !this.isEmpty(previousValue);
- const hasValue = !this.isEmpty(value);
-
- // Undo typing when searching to set the value.
- if (this.component.multiple && Array.isArray(value)) {
- value = value.map(value => {
- if (typeof value === 'boolean' || typeof value === 'number') {
- return value.toString();
- }
- return value;
- });
- }
- else {
- if (typeof value === 'boolean' || typeof value === 'number') {
- value = value.toString();
- }
- }
-
- if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {
- this.itemsLoaded.then(() => {
- this.redraw();
- });
-
- return changed;
- }
-
- // Do not set the value if we are loading... that will happen after it is done.
- if (this.loading) {
- return changed;
- }
-
- // Determine if we need to perform an initial lazyLoad api call if searchField is provided.
- if (this.isInitApiCallNeeded(hasValue)) {
- this.loading = true;
- this.lazyLoadInit = true;
- const searchProperty = this.component.searchField || this.component.valueProperty;
- this.triggerUpdate(_.get(value.data || value, searchProperty, value), true);
- return changed;
- }
-
- // Add the value options.
- this.itemsLoaded.then(() => {
- this.addValueOptions();
- this.setChoicesValue(value, hasPreviousValue, flags);
- });
-
- return changed;
- }
-
- isInitApiCallNeeded(hasValue) {
- return this.component.lazyLoad &&
- !this.lazyLoadInit &&
- !this.active &&
- !this.selectOptions.length &&
- hasValue &&
- this.shouldInitialLoad &&
- this.visible && (this.component.searchField || this.component.valueProperty);
- }
-
- setChoicesValue(value, hasPreviousValue, flags = {}) {
- const hasValue = !this.isEmpty(value) || flags.fromSubmission;
- hasPreviousValue = (hasPreviousValue === undefined) ? true : hasPreviousValue;
- if (this.choices) {
- // Now set the value.
- if (hasValue) {
- this.choices.removeActiveItems();
- // Add the currently selected choices if they don't already exist.
- const currentChoices = Array.isArray(value) && this.component.multiple ? value : [value];
- if (!this.addCurrentChoices(currentChoices, this.selectOptions, true)) {
- this.choices.setChoices(this.selectOptions, 'value', 'label', true);
- }
- this.choices.setChoiceByValue(currentChoices);
- }
- else if (hasPreviousValue || flags.resetValue) {
- this.choices.removeActiveItems();
- }
- }
- else {
- if (hasValue) {
- const values = Array.isArray(value) ? value : [value];
- if (!_.isEqual(this.dataValue, this.defaultValue) && this.selectOptions.length < 2
- || (this.selectData && flags.fromSubmission)) {
- const { value, label } = this.selectValueAndLabel(this.dataValue);
- this.addOption(value, label);
- }
- _.each(this.selectOptions, (selectOption) => {
- _.each(values, (val) => {
- if (selectOption.value === '') {
- selectOption.value = {};
- }
- if (_.isEqual(val, selectOption.value) && selectOption.element) {
- selectOption.element.selected = true;
- selectOption.element.setAttribute('selected', 'selected');
- return false;
- }
- });
- });
- }
- else {
- _.each(this.selectOptions, (selectOption) => {
- if (selectOption.element) {
- selectOption.element.selected = false;
- selectOption.element.removeAttribute('selected');
- }
- });
- }
- }
- }
-
- get itemsLoaded() {
- return this._itemsLoaded || NativePromise.resolve();
- }
-
- set itemsLoaded(promise) {
- this._itemsLoaded = promise;
- }
-
- validateValueAvailability(setting, value) {
- if (!boolValue(setting) || !value) {
- return true;
- }
-
- const values = this.getOptionsValues();
-
- if (values) {
- if (_.isObject(value)) {
- const compareComplexValues = (optionValue) => {
- const normalizedOptionValue = this.normalizeSingleValue(optionValue, true);
-
- if (!_.isObject(normalizedOptionValue)) {
- return false;
- }
-
- try {
- return (JSON.stringify(normalizedOptionValue) === JSON.stringify(value));
- }
- catch (err) {
- console.warn.error('Error while comparing items', err);
- return false;
- }
- };
-
- return values.findIndex((optionValue) => compareComplexValues(optionValue)) !== -1;
- }
-
- return values.findIndex((optionValue) => this.normalizeSingleValue(optionValue) === value) !== -1;
- }
- return false;
- }
-
- /**
- * Performs required transformations on the initial value to use in selectOptions
- * @param {*} value
- */
- getOptionValue(value) {
- return _.isObject(value) && this.isEntireObjectDisplay()
- ? this.normalizeSingleValue(value)
- : _.isObject(value) && (this.valueProperty || this.component.key !== 'resource')
- ? value
- : _.isObject(value) && !this.valueProperty
- ? this.interpolate(this.component.template, { item: value }).replace(/<\/?[^>]+(>|$)/g, '')
- : _.isNull(value)
- ? this.emptyValue
- : String(this.normalizeSingleValue(value));
- }
-
- /**
- * If component has static values (values, json) or custom values, returns an array of them
- * @returns {Array<*>|undefined}
- */
- getOptionsValues() {
- let rawItems = [];
- switch (this.component.dataSrc) {
- case 'values':
- rawItems = this.component.data.values;
- break;
- case 'json':
- rawItems = this.component.data.json;
- break;
- case 'custom':
- rawItems = this.getCustomItems();
- break;
- }
-
- if (typeof rawItems === 'string') {
- try {
- rawItems = JSON.parse(rawItems);
- }
- catch (err) {
- console.warn(err.message);
- rawItems = [];
- }
- }
-
- if (!Array.isArray(rawItems)) {
- return;
- }
-
- return rawItems.map((item) => this.getOptionValue(this.itemValue(item)));
- }
-
- /**
- * Deletes the value of the component.
- */
- deleteValue() {
- this.setValue('', {
- noUpdateEvent: true
- });
- this.unset();
- }
-
- /**
- * Check if a component is eligible for multiple validation
- *
- * @return {boolean}
- */
- validateMultiple() {
- // Select component will contain one input when flagged as multiple.
- return false;
- }
-
- /**
- * Output this select dropdown as a string value.
- * @return {*}
- */
-
- isBooleanOrNumber(value) {
- return typeof value === 'number' || typeof value === 'boolean';
- }
-
- getNormalizedValues() {
- if (!this.component || !this.component.data || !this.component.data.values) {
- return;
- }
- return this.component.data.values.map(
- value => ({ label: value.label, value: String(this.normalizeSingleValue(value.value)) })
- );
- }
-
- asString(value, options = {}) {
- value = value ?? this.getValue();
- //need to convert values to strings to be able to compare values with available options that are strings
- const convertToString = (data, valueProperty) => {
- if (valueProperty) {
- if (Array.isArray(data)) {
- data.forEach((item) => item[valueProperty] = item[valueProperty].toString());
- }
- else {
- data[valueProperty] = data[valueProperty].toString();
- }
- return data;
- }
-
- if (this.isBooleanOrNumber(data)) {
- data = data.toString();
- }
-
- if (Array.isArray(data) && data.some(item => this.isBooleanOrNumber(item))) {
- data = data.map(item => {
- if (this.isBooleanOrNumber(item)) {
- item = item.toString();
- }
- });
- }
-
- return data;
- };
-
- value = convertToString(value);
-
- if (['values', 'custom'].includes(this.component.dataSrc) && !this.asyncCustomValues()) {
- const {
- items,
- valueProperty,
- } = this.component.dataSrc === 'values'
- ? {
- items: convertToString(this.getNormalizedValues(), 'value'),
- valueProperty: 'value',
- }
- : {
- items: convertToString(this.getCustomItems(), this.valueProperty),
- valueProperty: this.valueProperty,
- };
-
- const getFromValues = () => {
- const initialValue = _.find(items, [valueProperty, value]);
- const values = this.defaultSchema.data.values || [];
- return _.isEqual(initialValue, values[0]) ? '-' : initialValue;
- };
- value = (this.component.multiple && Array.isArray(value))
- ? _.filter(items, (item) => value.includes(item.value))
- : valueProperty
- ? getFromValues() ?? { value, label: value }
- : value;
- }
-
- if (_.isString(value)) {
- return value;
- }
-
- const getTemplateValue = (v) => {
- const itemTemplate = this.itemTemplate(v);
- return options.csv && itemTemplate
- ? unescapeHTML(itemTemplate)
- : itemTemplate;
- };
-
- if (Array.isArray(value)) {
- const items = [];
- value.forEach(item => items.push(getTemplateValue(item)));
- if (this.component.dataSrc === 'resource' && items.length > 0 ) {
- return items.join(', ');
- }
- else if (items.length > 0) {
- return items.join(' ');
- }
- else {
- return '-';
- }
- }
-
- if (this.isEntireObjectDisplay() && _.isObject(value)) {
- return JSON.stringify(value);
- }
-
- return !_.isNil(value)
- ? getTemplateValue(value)
- : '-';
- }
-
- detach() {
- this.off('blur');
- if (this.choices) {
- if (this.choices.containerOuter?.element?.parentNode) {
- this.choices.destroy();
- }
- this.choices = null;
- }
- super.detach();
- }
-
- focus() {
- if (this.focusableElement) {
- super.focus.call(this);
- this.focusableElement.focus();
- }
- }
-
- setErrorClasses(elements, dirty, hasError, hasMessages, element = this.element) {
- super.setErrorClasses(elements, dirty, hasError, hasMessages, element);
- if (this.choices) {
- super.setErrorClasses([this.choices.containerInner.element], dirty, hasError, hasMessages, element);
- }
- else {
- super.setErrorClasses([this.refs.selectContainer], dirty, hasError, hasMessages, element);
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/Select.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/select/Select.unit.js
deleted file mode 100644
index 82cd7a7e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/Select.unit.js
+++ /dev/null
@@ -1,1215 +0,0 @@
-/* eslint-disable max-statements */
-import assert from 'power-assert';
-import cloneDeep from 'lodash/cloneDeep';
-import sinon from 'sinon';
-import Harness from '../../../test/harness';
-import SelectComponent from './Select';
-import { expect } from 'chai';
-import NativePromise from 'native-promise-only';
-import Formio from './../../Formio';
-import _ from 'lodash';
-
-import {
- comp1,
- comp2,
- multiSelect,
- multiSelectOptions,
- comp4,
- comp5,
- comp6,
- comp7,
- comp8,
- comp9,
- comp10,
- comp11,
- comp12,
- comp13,
- comp14,
- comp15,
- comp16,
- comp17,
- comp18,
- comp19,
- comp20,
- comp21,
-} from './fixtures';
-
-describe('Select Component', () => {
- it('should not stringify select option value', function(done) {
- Harness.testCreate(SelectComponent, comp6).then((component) => {
- component.setValue({ value:'a', label:'A' });
- setTimeout(()=> {
- assert.equal(component.choices._currentState.items[0].value.value, 'a');
- assert.equal(typeof component.choices._currentState.items[0].value , 'object');
- assert.equal(component.dataValue.value, 'a');
- assert.equal(typeof component.dataValue , 'object');
- done();
- }, 300);
- });
- });
-
- it('should return string value for different value types', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const stringValue = component.asString(true);
- const stringValue1 = component.asString(11);
- const stringValue2 = component.asString('test');
- const stringValue3 = component.asString(12);
- assert.equal(stringValue, 'true ');
- assert.equal(stringValue1, '11 ');
- assert.equal(stringValue2, 'test ');
- assert.equal(stringValue3, '1.2 ');
- done();
- });
- });
-
- it('Should return plain text when csv option is provided', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- assert.equal(component.getView('red', { csv:true }), 'Red');
- });
- });
-
- it('should correctly determine storage type when dataType is auto', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const value = component.normalizeSingleValue('true');
- const value1 = component.normalizeSingleValue('11');
- const value2 = component.normalizeSingleValue('test');
- const value3 = component.normalizeSingleValue('11test11test');
- const value4 = component.normalizeSingleValue('test11');
- const value5 = component.normalizeSingleValue('0');
- const value6 = component.normalizeSingleValue('');
- assert.equal(typeof value, 'boolean');
- assert.equal(typeof value1, 'number');
- assert.equal(typeof value2, 'string');
- assert.equal(typeof value3, 'string');
- assert.equal(typeof value4, 'string');
- assert.equal(typeof value5, 'number');
- assert.equal(typeof value6, 'string');
- done();
- });
- });
-
- it('should not stringify default empty values', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const value = component.normalizeSingleValue({});
- const value1 = component.normalizeSingleValue([]);
- assert.equal(typeof value, 'object');
- assert.equal(typeof value1, 'object');
- done();
- });
- });
-
- it('should not change value letter case', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const value = component.normalizeSingleValue('data.textArea');
- const value1 = component.normalizeSingleValue('ECMAScript');
- const value2 = component.normalizeSingleValue('JS');
- assert.equal(value, 'data.textArea');
- assert.equal(value1, 'ECMAScript');
- assert.equal(value2, 'JS');
- done();
- });
- });
-
- it('should define boolean value', function(done) {
- Harness.testCreate(SelectComponent, comp4).then((component) => {
- const value = component.normalizeSingleValue('TRUE');
- const value1 = component.normalizeSingleValue('False');
- const value2 = component.normalizeSingleValue('true');
- assert.equal(value, true);
- assert.equal(value1, false);
- assert.equal(value2, true);
- done();
- });
- });
-
- it('1/2 should not display empty choice options if property value is not defined', function(done) {
- Harness.testCreate(SelectComponent, comp5).then((component) => {
- component.setItems([{
- 'label': '111',
- 'value': '111'
- }, {
- 'label': '222',
- 'value': '222'
- }, {
- 'label': '333',
- 'value': '333'
- }], false);
- assert.equal(component.selectOptions.length, 0);
- done();
- });
- });
-
- it('2/2 should display choice option if property value is set', function(done) {
- comp5.template = '{{ item.label }} ';
- Harness.testCreate(SelectComponent, comp5).then((component) => {
- component.setItems([{
- 'label': '111',
- 'value': '111'
- }, {
- 'label': '222',
- 'value': '222'
- }, {
- 'label': '333',
- 'value': '333'
- }], false);
- assert.equal(component.selectOptions.length, 3);
- done();
- });
- });
-
- it('should have only unique dropdown options', function(done) {
- comp5.template = '{{ item.label }} ';
- comp5.uniqueOptions = true;
- Harness.testCreate(SelectComponent, comp5).then((component) => {
- component.setItems([{
- 'label': 'Label 1',
- 'value': 'value1'
- }, {
- 'label': 'Label 2',
- 'value': 'value2'
- }, {
- 'label': 'Label 3',
- 'value': 'value3'
- }, {
- 'label': 'Label 4',
- 'value': 'value3'
- }], false);
-
- assert.equal(component.selectOptions.length, 3);
- done();
- });
- });
-
- it('should format unlisted values', function(done) {
- comp5.template = '{{ item.label }} ';
- Harness.testCreate(SelectComponent, comp5).then((component) => {
- const formattedValue1 = component.getView('Unlisted value');
- const formattedValue2 = component.getView(0);
-
- assert.equal(formattedValue1, 'Unlisted value ');
- assert.equal(formattedValue2, '0 ');
- done();
- });
- });
-
- it('should set multiple selected values not repeating them', function(done) {
- Harness.testCreate(SelectComponent, multiSelect).then((component) => {
- component.setItems(multiSelectOptions, false);
- component.setChoicesValue(['Cheers']);
- component.setChoicesValue(['Cheers', 'Cyberdyne Systems'], 1);
- component.setChoicesValue(['Cheers', 'Cyberdyne Systems', 'Massive Dynamic'], 2);
- const choices = component.element.querySelector('.choices__list--multiple').children;
- assert.equal(choices.length, 3);
- done();
- });
- });
-
- it('should not show selected values in dropdown when searching', function(done) {
- Harness.testCreate(SelectComponent, multiSelect).then((component) => {
- component.setItems(multiSelectOptions, false);
- component.setChoicesValue(['Cheers']);
- component.setChoicesValue(['Cheers', 'Cyberdyne Systems'], 1);
- component.setItems([], true);
- const itemsInDropdown = component.element.querySelectorAll('.choices__item--choice');
- const choices = component.element.querySelector('.choices__list--multiple').children;
- assert.equal(choices.length, 2);
- assert.equal(itemsInDropdown.length, 1);
- done();
- });
- });
-
- it('Should build a Select component', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- Harness.testElements(component, 'select', 1);
- });
- });
-
- it('Should preserve the tabindex', () => {
- return Harness.testCreate(SelectComponent, comp2).then((component) => {
- const element = component.element.getElementsByClassName('choices__list choices__list--single')[0];
- Harness.testElementAttribute(element, 'tabindex', '10');
- });
- });
-
- it('Should default to 0 when tabindex is not specified', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- const element = component.element.getElementsByClassName('choices__list choices__list--single')[0];
- Harness.testElementAttribute(element, 'tabindex', '0');
- });
- });
-
- it('Should allow to override threshold option of fuzzy search', () => {
- try {
- const c1 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.2 });
- const c2 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.4 });
- const c3 = Object.assign(cloneDeep(comp1), { selectThreshold: 0.8 });
- const comps = [
- Harness.testCreate(SelectComponent, c1),
- Harness.testCreate(SelectComponent, c2),
- Harness.testCreate(SelectComponent, c3),
- ];
-
- return NativePromise
- .all(comps)
- .then(([a, b, c]) => {
- expect(a.choices.config.fuseOptions.threshold).to.equal(0.2);
- expect(b.choices.config.fuseOptions.threshold).to.equal(0.4);
- expect(c.choices.config.fuseOptions.threshold).to.equal(0.8);
- });
- }
- catch (error) {
- return NativePromise.reject(error);
- }
- });
-
- it('should set component value', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- assert.deepEqual(component.dataValue, '');
- component.setValue('red');
- assert.equal(component.dataValue, 'red');
- });
- });
-
- it('should remove selected item', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- assert.deepEqual(component.dataValue, '');
- component.setValue('red');
- assert.equal(component.dataValue, 'red');
-
- const element = component.element.getElementsByClassName('choices__button')[0];
- component.choices._handleButtonAction(component.choices._store.activeItems, element);
-
- assert.equal(component.dataValue, '');
- });
- });
-
- it('should open dropdown after item has been removed', () => {
- global.requestAnimationFrame = cb => cb();
- window.matchMedia = window.matchMedia || function() {
- return {
- matches : false,
- addListener : function() {},
- removeListener: function() {}
- };
- };
-
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- component.setValue('red');
-
- const element = component.element.getElementsByClassName('choices__button')[0];
- component.choices._handleButtonAction(component.choices._store.activeItems, element);
-
- component.choices.showDropdown(true);
-
- assert.equal(component.choices.dropdown.isActive, true);
- });
- });
-
- it('should keep dropdown closed after item has been removed by keypress', () => {
- return Harness.testCreate(SelectComponent, comp1).then((component) => {
- component.setValue('red');
-
- const element = component.element.querySelector('.choices__button');
- const ke = new KeyboardEvent('keydown', {
- bubbles: true, cancelable: true, keyCode: 13
- });
-
- element.dispatchEvent(ke);
-
- assert.equal(component.dataValue, '');
- assert.equal(component.choices.dropdown.isActive, false);
- });
- });
-
- it('Should render and set values in selects with different widget types', (done) => {
- const form = _.cloneDeep(comp7);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const selectHTML = form.getComponent('selectHtml');
- const selectChoices = form.getComponent('selectChoices');
- assert.equal(!!selectHTML.choices, false);
- assert.equal(!!selectChoices.choices, true);
-
- setTimeout(() => {
- assert.equal(selectChoices.element.querySelectorAll('.choices__item--choice').length, 3);
- const value = 'b';
- selectHTML.setValue(value);
- selectChoices.setValue(value);
-
- setTimeout(() => {
- assert.equal(selectHTML.dataValue, value);
- assert.equal(selectChoices.dataValue, value);
- assert.equal(selectHTML.getValue(), value);
- assert.equal(selectChoices.getValue(), value);
-
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should clear select value when "clear value on refresh options" and "refresh options on" is enable and number component is changed ', (done) => {
- const form = _.cloneDeep(comp8);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const numberComp = form.getComponent('number');
- const value = 'b';
- select.setValue(value);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- assert.equal(select.getValue(), value);
- const numberInput = numberComp.refs.input[0];
- const numberValue = 5;
- const inputEvent = new Event('input');
- numberInput.value = numberValue;
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(numberComp.dataValue, numberValue);
- assert.equal(numberComp.getValue(), numberValue);
- assert.equal(select.dataValue, '');
- assert.equal(select.getValue(), '');
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
-
- it('Should update select items when "refresh options on" is enable and number component is changed', (done) => {
- const form = _.cloneDeep(comp9);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function(formio, type, url) {
- return new Promise(resolve => {
- let values =[{ name: 'Ivan' }, { name: 'Mike' }];
-
- if (url.endsWith('5')) {
- values = [{ name: 'Kate' }, { name: 'Ann' }, { name: 'Lana' }];
- }
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const numberComp = form.getComponent('number');
- setTimeout(() => {
- assert.equal(select.selectOptions.length, 2);
- assert.deepEqual(select.selectOptions[0].value, { name: 'Ivan' });
-
- const numberValue = 5;
- const inputEvent = new Event('input');
- const numberInput = numberComp.refs.input[0];
-
- numberInput.value = numberValue;
- numberInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(numberComp.dataValue, numberValue);
- assert.equal(numberComp.getValue(), numberValue);
- assert.equal(select.selectOptions.length, 3);
- assert.deepEqual(select.selectOptions[0].value, { name: 'Kate' });
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 500);
- }, 200);
- }).catch(done);
- });
-
- it('Should update select items when "refresh options on blur" is enable and number component is changed', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].refreshOnBlur = 'number';
-
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function(formio, type, url) {
- return new Promise(resolve => {
- let values =[{ name: 'Ivan' }, { name: 'Mike' }];
-
- if (url.endsWith('5')) {
- values = [{ name: 'Kate' }, { name: 'Ann' }, { name: 'Lana' }];
- }
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const numberComp = form.getComponent('number');
- setTimeout(() => {
- assert.equal(select.selectOptions.length, 2);
- assert.deepEqual(select.selectOptions[0].value, { name: 'Ivan' });
-
- const numberValue = 5;
- const inputEvent = new Event('input');
- const focusEvent = new Event('focus');
- const blurEvent = new Event('blur');
- const numberInput = numberComp.refs.input[0];
- numberInput.dispatchEvent(focusEvent);
- numberInput.value = numberValue;
- numberInput.dispatchEvent(inputEvent);
- numberInput.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(numberComp.dataValue, numberValue);
- assert.equal(numberComp.getValue(), numberValue);
- assert.equal(select.selectOptions.length, 3);
- assert.deepEqual(select.selectOptions[0].value, { name: 'Kate' });
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 500);
- }, 200);
- }).catch(done);
- });
-
- it('Should be able to search if static search is enable', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
-
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- const focusEvent = new Event('focus');
- searchField.dispatchEvent(focusEvent);
-
- setTimeout(() => {
- assert.equal(select.choices.dropdown.isActive, true);
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 5);
-
- const keyupEvent = new Event('keyup');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- searchField.value = 'par';
- searchField.dispatchEvent(keyupEvent);
-
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 1);
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
-
- it('Should not be able to search if static search is disable', (done) => {
- const form = _.cloneDeep(comp10);
- form.components[0].searchEnabled = false;
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- assert.equal(searchField, null);
-
- done();
- }).catch(done);
- });
-
- it('Should save correct value if value property and item template property are different', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].valueProperty = 'age';
- form.components[1].lazyLoad = true;
-
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values =[{ name: 'Ivan', age: 35 }, { name: 'Mike', age: 41 }];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- assert.equal(select.selectOptions.length, 0);
- select.choices.showDropdown();
-
- setTimeout(() => {
- assert.equal(select.selectOptions.length, 2);
- assert.deepEqual(select.selectOptions[0].value, 35);
- assert.deepEqual(select.selectOptions[0].label, 'Ivan ');
-
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 2);
- assert.equal(items[0].textContent.trim(), 'Ivan');
-
- select.setValue(41);
-
- setTimeout(() => {
- assert.equal(select.getValue(), 41);
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Mike');
-
- Formio.makeRequest = originalMakeRequest;
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
-
- it('Should set custom header when sending request in select url', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].lazyLoad = true;
- form.components[1].data.headers = [{ key:'testHeader', value:'test' }];
-
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function(formio, type, url, method, data, opts) {
- assert.equal(opts.header.get('testHeader'), 'test');
- return new Promise(resolve => {
- const values = [{ name: 'Ivan', age: 35 }, { name: 'Mike', age: 41 }];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- assert.equal(select.selectOptions.length, 0);
- select.choices.showDropdown();
-
- setTimeout(() => {
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should set value in select url with lazy load option', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].lazyLoad = true;
-
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [{ name: 'Ivan' }, { name: 'Mike' }];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setValue({ name: 'Ivan' });
- setTimeout(() => {
- assert.deepEqual(select.getValue(), { name: 'Ivan' });
- assert.deepEqual(select.dataValue, { name: 'Ivan' });
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
-
- Formio.makeRequest = originalMakeRequest;
-
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should set value in select url with lazy load option when value property is defined', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].refreshOn = null;
- form.components[1].lazyLoad = true;
- form.components[1].valueProperty = 'name';
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [{ name: 'Ivan' }, { name: 'Mike' }];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setValue('Ivan');
- setTimeout(() => {
- assert.equal(select.getValue(), 'Ivan');
- assert.equal(select.dataValue, 'Ivan');
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
-
- Formio.makeRequest = originalMakeRequest;
-
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should be able to search if static search is enable', (done) => {
- const form = _.cloneDeep(comp10);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
-
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- const focusEvent = new Event('focus');
- searchField.dispatchEvent(focusEvent);
-
- setTimeout(() => {
- assert.equal(select.choices.dropdown.isActive, true);
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 5);
-
- const keyupEvent = new Event('keyup');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- searchField.value = 'par';
- searchField.dispatchEvent(keyupEvent);
-
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 1);
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
-
- it('Server side search is debounced with the correct timeout', (done) => {
- const form = _.cloneDeep(comp9);
- form.components[1].lazyLoad = false;
- form.components[1].searchDebounce = 0.7;
- form.components[1].disableLimit = false;
- form.components[1].searchField = 'name';
- const element = document.createElement('div');
-
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- resolve([]);
- });
- };
-
- var searchHasBeenDebounced = false;
- var originalDebounce = _.debounce;
- _.debounce = (fn, timeout, opts) => {
- searchHasBeenDebounced = timeout === 700;
- return originalDebounce(fn, 0, opts);
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- const focusEvent = new Event('focus');
- searchField.dispatchEvent(focusEvent);
-
- setTimeout(() => {
- const keyupEvent = new Event('keyup');
- searchField.value = 'the_name';
- searchField.dispatchEvent(keyupEvent);
-
- setTimeout(() => {
- _.debounce = originalDebounce;
- Formio.makeRequest = originalMakeRequest;
-
- assert.equal(searchHasBeenDebounced, true);
- done();
- }, 50);
- }, 200);
- }).catch(done);
- });
-
- it('Should provide "Allow only available values" validation', (done) => {
- const form = _.cloneDeep(comp10);
- form.components[0].validate.onlyAvailableItems = true;
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const value = 'Dallas';
- select.setValue(value);
-
- setTimeout(() => {
- assert.equal(select.getValue(), value);
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(form.errors.length, 1);
- assert.equal(select.error.message, 'Select is an invalid value.');
- document.innerHTML = '';
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
-
- it('Should render and set value in select json', (done) => {
- const formObj = _.cloneDeep(comp11);
- const element = document.createElement('div');
-
- Formio.createForm(element, formObj).then(form => {
- const select = form.getComponent('select');
- assert.equal(select.choices.containerInner.element.children[1].children[0].dataset.value, formObj.components[0].placeholder);
- select.choices.showDropdown();
-
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 4);
-
- const value = { value: 'a', label:'A' };
- select.setValue(value);
-
- setTimeout(() => {
- assert.deepEqual(select.getValue(), value);
- assert.deepEqual(select.dataValue, value);
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'A');
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
-
- it('Should load and set items in select resource and set value', (done) => {
- const form = _.cloneDeep(comp12);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function(formio, type, url) {
- return new Promise(resolve => {
- let values = [{ data: { name: 'Ivan' } }, { data: { name: 'Mike' } }];
-
- if (url.endsWith('Ivan')) {
- assert.equal(url.endsWith('/form/60114dd32cab36ad94ac4f94/submission?limit=100&skip=0&data.name__regex=Ivan'), true);
- values = [{ data: { name: 'Ivan' } }];
- }
- else {
- assert.equal(url.endsWith('/form/60114dd32cab36ad94ac4f94/submission?limit=100&skip=0'), true);
- }
-
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 1);
- select.setValue('Ivan');
-
- setTimeout(() => {
- assert.equal(select.getValue(), 'Ivan');
- assert.equal(select.dataValue, 'Ivan');
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'Ivan');
- select.choices.showDropdown();
-
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
-
- assert.equal(items.length, 2);
- assert.equal(items[0].textContent, 'Ivan');
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
-
- it('Should not have "limit" and "skip" query params when "Disable limit" option checked', (done) => {
- const form = _.cloneDeep(comp9);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
- Formio.makeRequest = (_, __, url) => {
- assert.equal(url, 'https://test.com/');
- return Promise.resolve({});
- };
-
- Formio.createForm(element, form).then(() => {
- setTimeout(() => {
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 200);
- }).catch(done);
- });
-
- it('The empty option in html5 shouldn\'t have the [Object Object] value', () => {
- return Harness.testCreate(SelectComponent, comp13).then((component) => {
- const emptyOption = component.element.querySelectorAll('option')[0];
- assert.notEqual(emptyOption.value, '[object Object]');
- assert.equal(emptyOption.value, '');
- });
- });
-
- it('Should not have default values in schema', (done) => {
- const form = _.cloneDeep(comp14);
- const element = document.createElement('div');
-
- const requiredSchema = {
- label: 'Select',
- tableView: true,
- key: 'select',
- type: 'select',
- input: true
- };
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- assert.deepEqual(requiredSchema, select.schema);
- done();
- }).catch(done);
- });
-
- it('Should show async custom values and be able to set submission', (done) => {
- const formObj = _.cloneDeep(comp16);
- const element = document.createElement('div');
-
- Formio.createForm(element, formObj).then(form => {
- const select = form.getComponent('select');
- select.choices.showDropdown();
-
- setTimeout(() => {
- const items = select.choices.choiceList.element.children;
- assert.equal(items.length, 3);
- const value = 'bb';
- form.submission = { data: { select: value } };
-
- setTimeout(() => {
- assert.deepEqual(select.getValue(), value);
- assert.deepEqual(select.dataValue, value);
- assert.equal(select.choices.containerInner.element.children[1].children[0].children[0].textContent, 'B');
-
- done();
- }, 400);
- }, 200);
- }).catch(done);
- });
-
- it('Should provide metadata.selectData for Select component pointed to a resource where value property is set to a field', (done) => {
- const form = _.cloneDeep(comp17);
- const testItems = [
- { textField: 'John' },
- { textField: 'Mary' },
- { textField: 'Sally' }
- ];
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setItems(testItems.map(item => ({ data: item })));
- const value = 'John';
- select.setValue(value);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(_.isEqual(form.submission.metadata.selectData.select.data, testItems[0]), true);
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should provide correct metadata.selectData for multiple Select', (done) => {
- const form = _.cloneDeep(comp20);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const values = ['apple', 'orange'];
- select.setValue(values);
-
- setTimeout(()=> {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const metadata = form.submission.metadata.selectData.select;
- assert.equal(_.keys(metadata).length, 2);
- values.forEach((value) => {
- assert.equal(_.find(select.component.data.values, { value }).label, metadata[value].label);
- });
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should provide correct metadata.selectData for HTML5 Select', (done) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, comp21).then(form => {
- const select = form.getComponent('animals');
- const checkbox = form.getComponent('checkbox');
- const value = 'dog';
- select.setValue(value);
-
- setTimeout(()=> {
- checkbox.setValue(true);
- setTimeout(() => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- const metadata = form.submission.metadata.selectData.animals2;
- assert.equal(metadata.label, 'Dog');
- done();
- }, 200);
- }, 300);
- }, 200);
- }).catch(done);
- });
-
- it('OnBlur validation should work properly with Select component', function(done) {
- this.timeout(0);
- const element = document.createElement('div');
-
- Formio.createForm(element, comp19).then(form => {
- const select = form.components[0];
- select.setValue('banana');
- select.focusableElement.focus();
- select.pristine = false;
-
- setTimeout(() => {
- assert(!select.error, 'Select should be valid while changing');
- select.focusableElement.dispatchEvent(new Event('blur'));
-
- setTimeout(() => {
- assert(select.error, 'Should set error after Select component was blurred');
- done();
- }, 500);
- }, 200);
- }).catch(done);
- });
-
- it('Should escape special characters in regex search field', done => {
- const form = _.cloneDeep(comp17);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const searchField = select.element.querySelector('.choices__input.choices__input--cloned');
- const focusEvent = new Event('focus');
- searchField.dispatchEvent(focusEvent);
-
- setTimeout(() => {
- const keyupEvent = new Event('keyup');
- searchField.value = '^$.*+?()[]{}|';
- searchField.dispatchEvent(keyupEvent);
-
- const spy = sinon.spy(Formio, 'makeRequest');
-
- setTimeout(() => {
- assert.equal(spy.callCount, 1);
-
- const urlArg = spy.args[0][2];
-
- assert.ok(urlArg && typeof urlArg === 'string' && urlArg.startsWith('http'), 'A URL should be passed as the third argument to "Formio.makeRequest()"');
-
- assert.ok(urlArg.includes('__regex=%5C%5E%5C%24%5C.%5C*%5C%2B%5C%3F%5C(%5C)%5C%5B%5C%5D%5C%7B%5C%7D%5C%7C'), 'The URL should contain escaped and encoded search value regex');
-
- done();
- }, 500);
- }, 200);
- }).catch(done);
- });
-
- // it('should reset input value when called with empty value', () => {
- // const comp = Object.assign({}, comp1);
- // delete comp.placeholder;
- //
- // return Harness.testCreate(SelectComponent, comp).then((component) => {
- // assert.deepEqual(component.dataValue, '');
- // assert.equal(component.refs.input[0].value, '');
- // component.setValue('red');
- // assert.equal(component.dataValue, 'red');
- // assert.equal(component.refs.input[0].value, 'red');
- // component.setValue('');
- // assert.equal(component.dataValue, '');
- // assert.equal(component.refs.input[0].value, '');
- // });
- // });
-});
-
-describe('Select Component', () => {
- it('Select Component should work correctly with the values in the form of an array', (done) => {
- const form = _.cloneDeep(comp18);
- const testItems = [
- { textField: ['one','two'] },
- { textField: ['three','four'] },
- { textField: ['five','six'] },
- ];
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setItems(testItems.map(item => ({ data: item })));
- const value = ['three','four'];
- select.setValue(value);
- assert.equal(select.selectOptions.length, 3);
- setTimeout(() => {
- assert.deepEqual(select.getValue(), value);
- assert.deepEqual(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-});
-
-describe('Select Component with Entire Object Value Property', () => {
- it('Should provide correct value', (done) => {
- const form = _.cloneDeep(comp15);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const value = { 'textField':'rgd','submit':true,'number':11 };
- select.setValue(value);
-
- setTimeout(() => {
- assert.equal(select.getValue(), value);
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should provide correct items for Resource DataSrc Type and Entire Object Value Property', (done) => {
- const form = _.cloneDeep(comp15);
- const testItems = [
- { textField: 'Jone', number: 1 },
- { textField: 'Mary', number: 2 },
- { textField: 'Sally', number: 3 }
- ];
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setItems(testItems.map(item => ({ data: item })));
- const value = { textField: 'Jone', number: 1 };
- select.setValue(value);
- assert.equal(select.selectOptions.length, 3);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(typeof select.dataValue, 'object');
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should provide correct html value for Resource DataSrc Type and Entire Object Value Property', (done) => {
- const form = _.cloneDeep(comp15);
- const testItems = [
- { textField: 'Jone', number: 1 },
- { textField: 'Mary', number: 2 },
- { textField: 'Sally', number: 3 }
- ];
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- select.setItems(testItems.map(item => ({ data: item })));
- const selectContainer = element.querySelector('[ref="selectContainer"]');
- assert.notEqual(selectContainer, null);
- const options = selectContainer.childNodes;
- assert.equal(options.length, 4);
- options.forEach((option) => {
- assert.notEqual(option.value, '[object Object]');
- });
- const value = { textField: 'Jone', number: 1 };
- select.setValue(value);
- assert.equal(select.selectOptions.length, 3);
-
- setTimeout(() => {
- assert.equal(select.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(typeof select.dataValue, 'object');
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should set submission value for Resource DataSrc Type and Entire Object Value Property', (done) => {
- const form = _.cloneDeep(comp15);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const select = form.getComponent('select');
- const value = { textField: 'Jone', nubmer: 1 };
- form.submission = {
- data: {
- select: value
- }
- };
-
- setTimeout(() => {
- assert.equal(typeof select.dataValue, 'object');
- const selectContainer = element.querySelector('[ref="selectContainer"]');
- assert.notEqual(selectContainer, null);
- assert.notEqual(selectContainer.value, '');
- const options = selectContainer.childNodes;
- assert.equal(options.length, 2);
- done();
- }, 1000);
- }).catch(done);
- });
-
- it('Should get string representation of value for Resource DataSrc Type and Entire Object Value Property', (done) => {
- Harness.testCreate(SelectComponent, comp15.components[0]).then((component) => {
- const entireObject = {
- a: '1',
- b: '2',
- };
- const formattedValue = component.getView(entireObject);
- assert.equal(formattedValue, JSON.stringify(entireObject));
- done();
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.data.js
deleted file mode 100644
index df6ad3e1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.data.js
+++ /dev/null
@@ -1,629 +0,0 @@
-import { eachComponent } from '../../../utils/utils';
-
-export default [
- {
- key: 'dataSrc',
- data: {
- values: [
- { label: 'Values', value: 'values' },
- { label: 'URL', value: 'url' },
- { label: 'Resource', value: 'resource' },
- { label: 'Custom', value: 'custom' },
- { label: 'Raw JSON', value: 'json' },
- ],
- },
- },
- {
- type: 'textfield',
- weight: 10,
- input: true,
- key: 'indexeddb.database',
- label: 'Database name',
- tooltip: 'The name of the indexeddb database.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'indexeddb'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'indexeddb.table',
- label: 'Table name',
- weight: 16,
- tooltip: 'The name of table in the indexeddb database.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'indexeddb'] },
- }
- },
- {
- type: 'textarea',
- as: 'json',
- editor: 'ace',
- weight: 18,
- input: true,
- key: 'indexeddb.filter',
- label: 'Row Filter',
- tooltip: 'Filter table items that match the object.',
- defaultValue: {},
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'indexeddb'] },
- },
- },
- {
- type: 'textarea',
- as: 'json',
- editor: 'ace',
- weight: 10,
- input: true,
- key: 'data.json',
- label: 'Data Source Raw JSON',
- tooltip: 'A valid JSON array to use as a data source.',
- description: 'Example:
["apple", "banana", "orange"]. Example 2:
[{"name": "John", "email": "john.doe@test.com"}, {"name": "Jane", "email": "jane.doe@test.com"}]. ',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'json'] },
- },
- },
- {
- type: 'checkbox',
- input: true,
- label: 'Lazy Load Data',
- key: 'lazyLoad',
- tooltip: 'When set, this will not fire off the request to the URL until this control is within focus. This can improve performance if you have many Select dropdowns on your form where the API\'s will only fire when the control is activated.',
- weight: 11,
- conditional: {
- json: {
- and: [
- {
- in: [
- { var: 'data.dataSrc' },
- [
- 'resource',
- 'url',
- ],
- ],
- },
- {
- '!==': [
- { var: 'data.widget' },
- 'html5'
- ]
- }
- ]
- },
- },
- },
- {
- type: 'datagrid',
- input: true,
- label: 'Data Source Values',
- key: 'data.values',
- tooltip: 'Values to use as the data source. Labels are shown in the select field. Values are the corresponding values saved with the submission.',
- weight: 10,
- reorder: true,
- defaultValue: [{ label: '', value: '' }],
- components: [
- {
- label: 'Label',
- key: 'label',
- input: true,
- type: 'textfield',
- },
- {
- label: 'Value',
- key: 'value',
- input: true,
- type: 'textfield',
- allowCalculateOverride: true,
- calculateValue: 'value = _.camelCase(row.label);',
- },
- ],
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'values'] },
- },
- },
- {
- type: 'select',
- input: true,
- dataSrc: 'url',
- data: {
- url: '/form?type=resource&limit=1000000&select=_id,title',
- },
- authenticate: true,
- template: '{{ item.title }} ',
- valueProperty: '_id',
- clearOnHide: false,
- label: 'Resource',
- key: 'data.resource',
- lazyLoad: false,
- weight: 10,
- tooltip: 'The resource to be used with this field.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- label: 'Data Path',
- key: 'selectValues',
- weight: 12,
- description: 'The object path to the iterable items.',
- tooltip: 'The property within the source data, where iterable items reside. For example: results.items or results[0].items',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'url'] },
- },
- },
- {
- type: 'select',
- input: true,
- label: 'Value Property',
- key: 'valueProperty',
- skipMerge: true,
- clearOnHide: true,
- tooltip: 'The field to use as the value.',
- weight: 11,
- refreshOn: 'data.resource',
- template: '{{ item.label }} ',
- valueProperty: 'key',
- dataSrc: 'url',
- lazyLoad: false,
- onSetItems(component, form) {
- const newItems = form.type === 'resource'
- ? [{
- label: '{Entire Object}',
- key: 'data',
- }]
- : [];
-
- eachComponent(form.components, (component, path) => {
- if (component.input) {
- newItems.push({
- label: component.label || component.key,
- key: `data.${path}`
- });
- }
- });
- return newItems;
- },
- onChange(context) {
- if (context && context.flags && context.flags.modified) {
- const valueProp = context.instance.data.valueProperty;
- const templateProp = valueProp ? valueProp : 'data';
- const template = `{{ item.${templateProp} }} `;
- const searchField = valueProp ? `${valueProp}__regex` : '';
- context.instance.root.getComponent('template').setValue(template);
- context.instance.root.getComponent('searchField').setValue(searchField);
- }
- },
- data: {
- url: '/form/{{ data.data.resource }}',
- },
- conditional: {
- json: {
- and: [
- { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- { '!==': [{ var: 'data.reference' }, true] },
- { var: 'data.data.resource' },
- ],
- },
- },
- },
- {
- type: 'select',
- input: true,
- label: 'Storage Type',
- key: 'dataType',
- clearOnHide: true,
- tooltip: 'The type to store the data. If you select something other than autotype, it will force it to that type.',
- weight: 12,
- template: '{{ item.label }} ',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Autotype', value: 'auto' },
- { label: 'String', value: 'string' },
- { label: 'Number', value: 'number' },
- { label: 'Boolean', value: 'boolean' },
- { label: 'Object', value: 'object' },
- ],
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'idPath',
- weight: 12,
- label: 'ID Path',
- placeholder: 'id',
- tooltip: 'Path to the select option id.'
- },
- {
- type: 'textfield',
- input: true,
- label: 'Select Fields',
- key: 'selectFields',
- tooltip: 'The properties on the resource to return as part of the options. Separate property names by commas. If left blank, all properties will be returned.',
- placeholder: 'Comma separated list of fields to select.',
- weight: 14,
- conditional: {
- json: {
- and: [
- { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- { '===': [{ var: 'data.valueProperty' }, ''] },
- ],
- },
- },
- },
- {
- type: 'checkbox',
- input: true,
- key: 'disableLimit',
- label: 'Disable limiting response',
- tooltip: 'When enabled the request will not include the limit and skip options in the query string',
- weight: 15,
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'url'] },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'searchField',
- label: 'Search Query Name',
- weight: 16,
- description: 'Name of URL query parameter',
- tooltip: 'The name of the search querystring parameter used when sending a request to filter results with. The server at the URL must handle this query parameter.',
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource',
- ],
- ],
- },
- },
- },
- {
- type: 'number',
- input: true,
- key: 'searchDebounce',
- label: 'Search request delay',
- weight: 16,
- description: 'The delay (in seconds) before the search request is sent.',
- tooltip: 'The delay in seconds before the search request is sent, measured from the last character input in the search field.',
- validate: {
- min: 0,
- customMessage: '',
- json: '',
- max: 1,
- },
- delimiter: false,
- requireDecimal: false,
- encrypted: false,
- defaultValue: 0.3,
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource',
- ],
- ],
- },
- },
- },
- {
- type: 'number',
- input: true,
- key: 'minSearch',
- weight: 17,
- label: 'Minimum Search Length',
- tooltip: 'The minimum amount of characters they must type before a search is made.',
- defaultValue: 0,
- conditional: {
- json: {
- and: [
- { '===': [{ var: 'data.dataSrc' }, 'url'] },
- { '!=': [{ var: 'data.searchField' }, ''] },
- ],
- },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'filter',
- label: 'Filter Query',
- weight: 18,
- description: 'The filter query for results.',
- tooltip: 'Use this to provide additional filtering using query parameters.',
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource',
- ],
- ],
- },
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'sort',
- label: 'Sort Query',
- weight: 18,
- description: 'The sort query for results',
- tooltip: 'Use this to provide additional sorting using query parameters',
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource',
- ],
- ],
- },
- },
- },
- {
- type: 'number',
- input: true,
- key: 'limit',
- label: 'Limit',
- weight: 18,
- description: 'Maximum number of items to view per page of results.',
- tooltip: 'Use this to limit the number of items to request or view.',
- clearOnHide: false,
- conditional: {
- json: {
- and: [
- { in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource'
- ],
- ] },
- { '!==': [{ var: 'data.disableLimit' }, true] }
- ]
- },
- },
- },
- {
- type: 'textarea',
- input: true,
- key: 'data.custom',
- label: 'Custom Values',
- editor: 'ace',
- rows: 10,
- weight: 14,
- placeholder: "values = data['mykey'] or values = Promise.resolve(['myValue'])",
- tooltip: 'Write custom code to return the value options or a promise with value options. The form data object is available.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'custom'] },
- },
- },
- {
- type: 'select',
- input: true,
- key: 'refreshOn',
- label: 'Refresh Options On',
- weight: 19,
- tooltip: 'Refresh data when another field changes.',
- dataSrc: 'custom',
- valueProperty: 'value',
- data: {
- custom(context) {
- var values = [];
- values.push({ label: 'Any Change', value: 'data' });
- context.utils.eachComponent(context.instance.options.editForm.components, function(component, path) {
- if (component.key !== context.data.key) {
- values.push({
- label: component.label || component.key,
- value: path
- });
- }
- });
- return values;
- }
- },
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource',
- 'values',
- 'custom'
- ],
- ],
- },
- },
- },
- {
- type: 'select',
- input: true,
- key: 'refreshOnBlur',
- label: 'Refresh Options On Blur',
- weight: 19,
- tooltip: 'Refresh data when another field is blured.',
- dataSrc: 'custom',
- valueProperty: 'value',
- data: {
- custom(context) {
- var values = [];
- values.push({ label: 'Any Change', value: 'data' });
- context.utils.eachComponent(context.instance.options.editForm.components, function(component, path) {
- if (component.key !== context.data.key) {
- values.push({
- label: component.label || component.key,
- value: path
- });
- }
- });
- return values;
- }
- },
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource',
- 'values'
- ],
- ],
- },
- },
- },
- {
- type: 'checkbox',
- input: true,
- weight: 20,
- key: 'clearOnRefresh',
- label: 'Clear Value On Refresh Options',
- defaultValue: false,
- tooltip: 'When the Refresh On field is changed, clear this components value.',
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource',
- 'values',
- 'custom'
- ],
- ],
- },
- },
- },
- {
- type: 'checkbox',
- input: true,
- weight: 21,
- key: 'searchEnabled',
- label: 'Enable Static Search',
- defaultValue: true,
- tooltip: 'When checked, the select dropdown will allow for searching within the static list of items provided.',
- },
- {
- type: 'checkbox',
- input: true,
- weight: 21,
- key: 'noRefreshOnScroll',
- label: 'Disable Options Refresh When Scrolling',
- defaultValue: false,
- tooltip: 'When checked, the select with search input won\'t perform new api requests when scrolling through the list of options.',
- conditional: {
- json: {
- and: [
- { in: [
- { var: 'data.dataSrc' },
- [
- 'url',
- 'resource'
- ],
- ] },
- { '===': [{ var: 'data.searchEnabled' }, true] }
- ]
- },
- },
- },
- {
- label: 'Search Threshold',
- mask: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'number',
- input: true,
- key: 'selectThreshold',
- validate: {
- min: 0,
- customMessage: '',
- json: '',
- max: 1,
- },
- delimiter: false,
- requireDecimal: false,
- encrypted: false,
- defaultValue: 0.3,
- weight: 22,
- tooltip: 'At what point does the match algorithm give up. A threshold of 0.0 requires a perfect match, a threshold of 1.0 would match anything.',
- },
- {
- type: 'checkbox',
- input: true,
- weight: 23,
- key: 'addResource',
- label: 'Add Resource',
- tooltip: 'Allows to create a new resource while entering a submission.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- },
- },
- {
- type: 'textfield',
- label: 'Add Resource Label',
- key: 'addResourceLabel',
- tooltip: 'Set the text of the Add Resource button.',
- placeholder: 'Add Resource',
- weight: 24,
- input: true,
- conditional: {
- json: {
- and: [
- { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- { '!!': { var: 'data.addResource' } },
- ],
- },
- },
- },
- {
- type: 'checkbox',
- input: true,
- weight: 25,
- key: 'reference',
- label: 'Save as reference',
- tooltip: 'Using this option will save this field as a reference and link its value to the value of the origin record.',
- conditional: {
- json: { '===': [{ var: 'data.dataSrc' }, 'resource'] },
- },
- },
- {
- type: 'checkbox',
- input: true,
- weight: 27,
- key: 'readOnlyValue',
- label: 'Read Only Value',
- tooltip: 'Check this if you would like to show just the value when in Read Only mode.',
- },
- {
- type: 'textarea',
- as: 'json',
- editor: 'ace',
- weight: 28,
- input: true,
- key: 'customOptions',
- label: 'Choices.js options',
- tooltip: 'A raw JSON object to use as options for the Select component (Choices JS).',
- defaultValue: {},
- },
- {
- type: 'checkbox',
- input: true,
- weight: 29,
- key: 'useExactSearch',
- label: 'Use exact search',
- tooltip: 'Disables search algorithm threshold.',
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.display.js
deleted file mode 100644
index cd6e222f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.display.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default [
- {
- type: 'select',
- input: true,
- weight: 20,
- tooltip: 'Select the type of widget you\'d like to use.',
- key: 'widget',
- defaultValue: 'choicesjs',
- label: 'Widget Type',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'ChoicesJS', value: 'choicesjs' },
- { label: 'HTML 5', value: 'html5' },
- ],
- },
- },
- {
- weight: 1230,
- type: 'checkbox',
- label: 'Unique Options',
- tooltip: 'Display only unique dropdown options.',
- key: 'uniqueOptions',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.validation.js
deleted file mode 100644
index 704fd144..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/editForm/Select.edit.validation.js
+++ /dev/null
@@ -1,33 +0,0 @@
-export default [
- {
- weight: 50,
- type: 'checkbox',
- label: 'Perform server validation of remote value',
- tooltip: 'Check this if you would like for the server to perform a validation check to ensure the selected value is an available option. This requires a Search query to ensure a record is found.',
- key: 'validate.select',
- input: true,
- conditional: {
- json: { var: 'data.searchField' }
- }
- },
- {
- weight: 52,
- type: 'checkbox',
- label: 'Allow only available values',
- tooltip: 'Check this if you would like to perform a validation check to ensure the selected value is an available option (only for synchronous values).',
- key: 'validate.onlyAvailableItems',
- input: true,
- conditional: {
- json: {
- in: [
- { var: 'data.dataSrc' },
- [
- 'values',
- 'json',
- 'custom'
- ],
- ],
- },
- },
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp1.js
deleted file mode 100644
index 325f174a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp1.js
+++ /dev/null
@@ -1,64 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [],
- 'type': 'select',
- 'validate': {
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'multiple': false,
- 'template': '{{ item.label }} ',
- 'authenticate': false,
- 'filter': '',
- 'refreshOn': '',
- 'defaultValue': '',
- 'valueProperty': '',
- 'dataSrc': 'values',
- 'data': {
- 'custom': '',
- 'resource': '',
- 'url': '',
- 'json': '',
- 'values': [
- {
- 'label': 'Red',
- 'value': 'red'
- },
- {
- 'label': 'Blue',
- 'value': 'blue'
- },
- {
- 'label': 'Green',
- 'value': 'green'
- },
- {
- 'label': 'Yellow',
- 'value': 'yellow'
- },
- {
- 'label': 'Purple',
- 'value': 'purple'
- },
- {
- 'label': 'Orange',
- 'value': 'orange'
- },
- {
- 'label': 'Black',
- 'value': 'black'
- }
- ]
- },
- 'placeholder': 'Enter your favorite color',
- 'key': 'favoriteColor',
- 'label': 'Favorite Color',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp10.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp10.js
deleted file mode 100644
index 3af21848..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp10.js
+++ /dev/null
@@ -1,30 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Select',
- tableView: true,
- data: {
- values: [
- { label: 'Paris', value: 'paris' },
- { label: 'London', value: 'london' },
- { label: 'Madrid', value: 'madrid' },
- { label: 'Berlin', value: 'berlin' },
- { label: 'Kiev', value: 'kiev' }
- ]
- },
- selectThreshold: 0.3,
- validate: { onlyAvailableItems: false },
- key: 'select',
- type: 'select',
- indexeddb: { filter: {} },
- input: true
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: true, input: true, tableView: false }
- ],
- title: 'test',
- display: 'form',
- name: 'testCheckbox',
- path: 'testcheckbox',
- project: '5ebcf8938bdebc4c58a949a3',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp11.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp11.js
deleted file mode 100644
index 13830e1c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp11.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export default {
- components: [
- {
- type: 'select',
- label: 'Select JSON',
- key: 'select',
- placeholder: 'Select one',
- data: {
- json: `[
- {"value":"a","label":"A"},
- {"value":"b","label":"B"},
- {"value":"c","label":"C"},
- {"value":"d","label":"D"}
- ]`
- },
- dataSrc: 'json',
- template: '{{ item.label }} ',
- input: true
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: false, input: true, tableView: false }
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp12.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp12.js
deleted file mode 100644
index f92e14b1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp12.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Select',
- tableView: true,
- dataSrc: 'resource',
- data: { values: [{ label: '', value: '' }], resource: '60114dd32cab36ad94ac4f94' },
- valueProperty: 'data.name',
- template: '{{ item.data.name }} ',
- selectThreshold: 0.3,
- validate: { onlyAvailableItems: false },
- key: 'select',
- type: 'select',
- indexeddb: { filter: {} },
- searchField: 'data.name__regex',
- input: true,
- addResource: false,
- reference: false
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: true, input: true, tableView: false }
- ],
- title: 'test',
- display: 'form',
- name: 'test',
- path: 'test',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp13.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp13.js
deleted file mode 100644
index 2af63a66..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp13.js
+++ /dev/null
@@ -1,30 +0,0 @@
-export default {
- label: 'Location',
- widget: 'html5',
- tableView: true,
- dataSrc: 'custom',
- data: {
- values: [
- {
- label: '',
- value: '',
- },
- ],
- custom:
- 'values = [\r\n{\r\n "label" : "Test 1",\r\n "value" : "test1"\r\n },\r\n{\r\n "label" : "Test 2",\r\n "value" : "test2"\r\n }\r\n];\r\n',
- },
- refreshOn: 'district',
- clearOnRefresh: true,
- selectThreshold: 0.3,
- calculateServer: true,
- validate: {
- onlyAvailableItems: false,
- },
- key: 'location',
- type: 'select',
- indexeddb: {
- filter: {},
- },
- input: true,
- hideOnChildrenHidden: false,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp14.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp14.js
deleted file mode 100644
index 8d796772..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp14.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Select',
- tableView: true,
- data: {
- values: [
- { label: '', value: '' }
- ]
- },
- selectThreshold: 0.3,
- validate: { onlyAvailableItems: false },
- key: 'select',
- type: 'select',
- indexeddb: { filter: {} },
- input: true
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: true, input: true, tableView: false }
- ],
- title: 'test',
- display: 'form',
- name: 'selectform',
- path: 'selectform',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp15.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp15.js
deleted file mode 100644
index d1ab01b1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp15.js
+++ /dev/null
@@ -1,39 +0,0 @@
-export default {
- _id: '6110fab8ca845631779c2bc5',
- type: 'form',
- components: [
- {
- label: 'Select',
- widget: 'html5',
- tableView: true,
- dataSrc: 'resource',
- data: {
- resource: '6110fa7961e298191332514d',
- project: 'gjrwbdsqkpxesha',
- },
- dataType: 'object',
- valueProperty: 'data',
- template: '{{ item.data }} ',
- validate: { select: false },
- key: 'select',
- type: 'select',
- searchField: 'data__regex',
- input: true,
- addResource: false,
- reference: false,
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- },
- ],
- title: 'FIO-3011',
- display: 'form',
- name: 'fio3011',
- path: 'fio3011',
- project: '6108d710d447e01ac3d81b8f',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp16.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp16.js
deleted file mode 100644
index 4106d67a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp16.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- _id: '60ec032f86daf81238ab4e37',
- type: 'form',
- components: [
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- dataSrc: 'custom',
- valueProperty:'value',
- data: {
- custom:"values = Promise.resolve([\n {label: 'A', value: 'aa'}, \n {label: 'B', value: 'bb'}, \n {label: 'C', value: 'cc'}\n]);",
- },
- key: 'select',
- type: 'select',
- input: true
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
- title: 'custom async',
- display: 'form',
- name: 'customAsync',
- path: 'customasync',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp17.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp17.js
deleted file mode 100644
index 9960c0b7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp17.js
+++ /dev/null
@@ -1,41 +0,0 @@
-export default {
- _id: '6110fab8ca845631779c2bc5',
- type: 'form',
- components: [
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- dataSrc: 'resource',
- data: {
- resource: '63f8a8d04890866e84b9540c'
- },
- dataType: 'string',
- valueProperty: 'data.textField',
- template: '{{ item.data.textField }} ',
- validate: {
- select: false
- },
- key: 'select',
- type: 'select',
- searchField: 'data.textField__regex',
- noRefreshOnScroll: false,
- addResource: false,
- reference: false,
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- },
- ],
- title: 'FIO-3011',
- display: 'form',
- name: 'fio3011',
- path: 'fio3011',
- project: '6108d710d447e01ac3d81b8f',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp18.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp18.js
deleted file mode 100644
index 63b7b568..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp18.js
+++ /dev/null
@@ -1,40 +0,0 @@
-export default {
- _id: '6450b301441fa8778d1ca28e',
- type: 'form',
- components: [
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- dataSrc: 'resource',
- data: {
- resource: '6450b4bb441fa8778d1ca69e'
- },
- valueProperty: 'data.textField',
- template: '{{ item.data.textField }} ',
- validate: {
- select: false
- },
- key: 'select',
- type: 'select',
- searchField: 'data.textField__regex',
- noRefreshOnScroll: false,
- addResource: false,
- reference: false,
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true,
- },
- ],
- title: 'FIO-6760-Select Component',
- display: 'form',
- name: 'fio6760SelectComponent',
- path: 'fio6760selectcomponent',
- project: '6406eec64f70ff1b445c6f44',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp19.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp19.js
deleted file mode 100644
index 5e7707c0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp19.js
+++ /dev/null
@@ -1,34 +0,0 @@
-export default {
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- data: {
- values: [
- {
- label: 'Banana',
- value: 'banana'
- },
- {
- label: 'Apple',
- value: 'apple'
- },
- {
- label: 'Pineapple',
- value: 'pineapple'
- }
- ]
- },
- validateOn: 'blur',
- validate: {
- custom: "valid = data.select == 'apple' ? true : 'You must select an apple';"
- },
- key: 'select',
- type: 'select',
- input: true
- },
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp2.js
deleted file mode 100644
index 7405df5c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp2.js
+++ /dev/null
@@ -1,65 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [],
- 'type': 'select',
- 'validate': {
- 'required': false
- },
- 'tabindex': '10',
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'multiple': false,
- 'template': '{{ item.label }} ',
- 'authenticate': false,
- 'filter': '',
- 'refreshOn': '',
- 'defaultValue': '',
- 'valueProperty': '',
- 'dataSrc': 'values',
- 'data': {
- 'custom': '',
- 'resource': '',
- 'url': '',
- 'json': '',
- 'values': [
- {
- 'label': 'Red',
- 'value': 'red'
- },
- {
- 'label': 'Blue',
- 'value': 'blue'
- },
- {
- 'label': 'Green',
- 'value': 'green'
- },
- {
- 'label': 'Yellow',
- 'value': 'yellow'
- },
- {
- 'label': 'Purple',
- 'value': 'purple'
- },
- {
- 'label': 'Orange',
- 'value': 'orange'
- },
- {
- 'label': 'Black',
- 'value': 'black'
- }
- ]
- },
- 'placeholder': 'Enter your favorite color',
- 'key': 'favoriteColor',
- 'label': 'Favorite Color',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp20.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp20.js
deleted file mode 100644
index 69ff024e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp20.js
+++ /dev/null
@@ -1,45 +0,0 @@
-export default {
- _id: '659fa81f4a40147c0ffb949b',
- title: '7724',
- name: '7724',
- path: '7724',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Select',
- widget: 'choicesjs',
- tableView: true,
- multiple: true,
- data:
- {
- values: [
- {
- label: 'Apple',
- value: 'apple'
- },
- {
- label: 'Orange',
- value: 'orange'
- },
- {
- label: 'Pear',
- value: 'pear'
- }
- ]
- },
- key: 'select',
- type: 'select',
- input: true
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
- project: '63cead09be0090345b109e22'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp21.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp21.js
deleted file mode 100644
index 198eb718..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp21.js
+++ /dev/null
@@ -1,104 +0,0 @@
-export default {
- title: 'FIO-7632',
- name: 'fio7632',
- path: 'fio7632',
- type: 'form',
- display: 'form',
- components: [
- {
- collapsible: false,
- key: 'panel',
- type: 'panel',
- label: 'Panel',
- input: false,
- tableView: false,
- components: [
- {
- label: 'Animals',
- widget: 'html5',
- tableView: true,
- data: {
- values: [
- {
- label: 'Dog',
- value: 'dog',
- },
- {
- label: 'Cat',
- value: 'cat',
- },
- {
- label: 'Horse',
- value: 'horse',
- },
- ],
- },
- key: 'animals',
- type: 'select',
- input: true,
- },
- {
- label: 'Checkbox',
- tableView: false,
- key: 'checkbox',
- type: 'checkbox',
- input: true,
- },
- {
- label: 'Animals2',
- widget: 'html5',
- tableView: true,
- data: {
- values: [
- {
- label: 'Dog',
- value: 'dog',
- },
- {
- label: 'Cat',
- value: 'cat',
- },
- {
- label: 'Horse',
- value: 'horse',
- },
- ],
- },
- calculateValue: 'if (data.checkbox === true) {\n value = data.animals;\n}',
- key: 'animals2',
- logic: [
- {
- name: 'disable',
- trigger: {
- type: 'javascript',
- javascript: 'result = row.checkbox === true;',
- },
- actions: [
- {
- name: 'disable',
- type: 'property',
- property: {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean',
- },
- state: true,
- },
- ],
- },
- ],
- type: 'select',
- input: true,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- },
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp3.js
deleted file mode 100644
index dad067d2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp3.js
+++ /dev/null
@@ -1,208 +0,0 @@
-export const multiSelect = {
- type: 'select',
- label: 'Companies',
- key: 'companies',
- placeholder: 'Select a company',
- dataSrc: 'url',
- data: {
- url: 'https://example.form.io/company/submission?limit={{ limit }}&skip={{ skip }}'
- },
- valueProperty: 'data.name',
- searchField: 'data.name__regex',
- template: '{{ item.data.name }} ',
- multiple: true,
- input: true
-};
-
-export const multiSelectOptions = [{
- '_id': '5c5f1901a590ab507db886b1',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Cheers',
- 'email': 'cheers@example.com',
- 'phoneNumber': '(982) 143-9839',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:16:33.636Z',
- 'modified': '2019-02-09T18:16:33.637Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f18f1a590ab874fb886b0',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Cyberdyne Systems',
- 'email': 'cyberdyne@example.com',
- 'phoneNumber': '(982) 382-9039',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:16:17.956Z',
- 'modified': '2019-02-09T18:16:17.956Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f18e1d809c48f4abd1496',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Wayne Enterprises',
- 'email': 'we@example.com',
- 'phoneNumber': '(982) 338-9432',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:16:01.388Z',
- 'modified': '2019-02-09T18:16:01.389Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f18d1a590ab5693b886ae',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Gekko & Co',
- 'email': 'gekko@example.com',
- 'phoneNumber': '(982) 982-3989',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:15:45.716Z',
- 'modified': '2019-02-09T18:15:45.716Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f18c4ce9978f8e6ab91fe',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Ollivander`s Wand Shop',
- 'email': 'ows@example.com',
- 'phoneNumber': '(987) 190-2398',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:15:32.390Z',
- 'modified': '2019-02-09T18:15:32.391Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f18b5c6782092f6379b43',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Stark Industries',
- 'email': 'stark@example.com',
- 'phoneNumber': '(897) 239-8723',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:15:17.861Z',
- 'modified': '2019-02-09T18:15:17.863Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f189ea590ab5c90b886aa',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Massive Dynamic',
- 'email': 'md@example.com',
- 'phoneNumber': '(872) 939-8439',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:14:54.203Z',
- 'modified': '2019-02-09T18:14:54.204Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f188ece997855cfab91fb',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Vehement Capital Partners',
- 'email': 'Vehement@example.com',
- 'phoneNumber': '(982) 720-9289',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:14:38.059Z',
- 'modified': '2019-02-09T18:14:38.060Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f187b9163aee074c7da29',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Hooli',
- 'email': 'Hooli@example.com',
- 'phoneNumber': '(987) 239-8239',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:14:19.714Z',
- 'modified': '2019-02-09T18:14:19.714Z',
- 'project': '58b78b87f5609a0070f3f456'
-}, {
- '_id': '5c5f186dce9978dc6cab91f8',
- 'owner': '553dbfc08d22d5cb1a7024f2',
- 'roles': [],
- '_vid': 0,
- '_fvid': 0,
- 'state': 'submitted',
- 'data': {
- 'name': 'Umbrella Corporation',
- 'email': 'umbrella@example.com',
- 'phoneNumber': '(982) 782-3762',
- 'submit': true
- },
- 'access': [],
- 'form': '5b8c1017edc1a6c05601af8e',
- 'externalIds': [],
- 'created': '2019-02-09T18:14:05.353Z',
- 'modified': '2019-02-09T18:14:05.354Z',
- 'project': '58b78b87f5609a0070f3f456'
-}];
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp4.js
deleted file mode 100644
index bc04d0e4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp4.js
+++ /dev/null
@@ -1,104 +0,0 @@
-export default {
- 'label': 'Select',
- 'labelPosition': 'top',
- 'widget': 'choicesjs',
- 'tableView': true,
- 'modalEdit': false,
- 'multiple': false,
- 'dataSrc': 'values',
- 'data': {
- 'values': [{
- 'label': 'true',
- 'value': 'true'
- }, {
- 'label': '1.2',
- 'value': '12'
- }, {
- 'label': '11',
- 'value': '11'
- }, {
- 'label': 'test',
- 'value': 'test'
- }],
- 'resource': '',
- 'json': '',
- 'url': '',
- 'custom': ''
- },
- 'valueProperty': '',
- 'dataType': 'auto',
- 'template': '{{ item.label }} ',
- 'searchEnabled': true,
- 'selectThreshold': 0.3,
- 'readOnlyValue': false,
- 'customOptions': {},
- 'persistent': true,
- 'protected': false,
- 'dbIndex': false,
- 'encrypted': false,
- 'clearOnHide': true,
- 'customDefaultValue': '',
- 'calculateValue': '',
- 'calculateServer': false,
- 'allowCalculateOverride': false,
- 'validateOn': 'change',
- 'validate': {
- 'required': false,
- 'customMessage': '',
- 'custom': '',
- 'customPrivate': false,
- 'json': '',
- 'strictDateValidation': false,
- 'multiple': false,
- 'unique': false
- },
- 'unique': false,
- 'errorLabel': '',
- 'key': 'select1',
- 'tags': [],
- 'properties': {},
- 'conditional': {
- 'show': null,
- 'when': null,
- 'eq': '',
- 'json': ''
- },
- 'customConditional': '',
- 'logic': [],
- 'attributes': {},
- 'overlay': {
- 'style': '',
- 'page': '',
- 'left': '',
- 'top': '',
- 'width': '',
- 'height': ''
- },
- 'type': 'select',
- 'indexeddb': {
- 'filter': {}
- },
- 'selectFields': '',
- 'searchField': '',
- 'minSearch': 0,
- 'filter': '',
- 'limit': 100,
- 'refreshOn': '',
- 'redrawOn': '',
- 'input': true,
- 'prefix': '',
- 'suffix': '',
- 'showCharCount': false,
- 'showWordCount': false,
- 'allowMultipleMasks': false,
- 'clearOnRefresh': false,
- 'lazyLoad': true,
- 'authenticate': false,
- 'searchThreshold': 0.3,
- 'fuseOptions': {
- 'include': 'score',
- 'threshold': 0.3
- },
- 'id': 'ef6o05a',
- 'defaultValue': ''
- };
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp5.js
deleted file mode 100644
index 87398318..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp5.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default {
- 'label': 'Select',
- 'widget': 'choicesjs',
- 'tableView': true,
- 'data': {
- 'values': [{
- 'label': '111',
- 'value': '111'
- }, {
- 'label': '222',
- 'value': '222'
- }, {
- 'label': '333',
- 'value': '333'
- }]
- },
- 'template': ' ',
- 'selectThreshold': 0.3,
- 'calculateServer': false,
- 'key': 'select2',
- 'type': 'select',
- 'indexeddb': {
- 'filter': {}
- },
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp6.js
deleted file mode 100644
index 436e61db..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp6.js
+++ /dev/null
@@ -1,28 +0,0 @@
-export default {
- 'label': 'Select',
- 'widget': 'choicesjs',
- 'tableView': true,
- 'dataSrc': 'json',
- 'data': {
- 'json': [{
- 'value': 'a',
- 'label': 'A'
- }, {
- 'value': 'b',
- 'label': 'B'
- }, {
- 'value': 'c',
- 'label': 'C'
- }, {
- 'value': 'd',
- 'label': 'D'
- }]
- },
- 'selectThreshold': 0.3,
- 'key': 'select',
- 'type': 'select',
- 'indexeddb': {
- 'filter': {}
- },
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp7.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp7.js
deleted file mode 100644
index 2ffb54c6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp7.js
+++ /dev/null
@@ -1,44 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Select Choices',
- tableView: true,
- data: {
- values: [{ label: 'a', value: 'a' }, { label: 'b', value: 'b' }, { label: 'c', value: 'c' }]
- },
- selectThreshold: 0.3,
- validate: { onlyAvailableItems: false },
- key: 'selectChoices',
- type: 'select',
- indexeddb: { filter: {} },
- input: true
- },
- {
- label: 'Select HTML',
- widget: 'html5',
- tableView: true,
- data: {
- values: [{ label: 'a', value: 'a' }, { label: 'b', value: 'b' }, { label: 'c', value: 'c' }]
- },
- selectThreshold: 0.3,
- validate: { onlyAvailableItems: false },
- key: 'selectHtml',
- type: 'select',
- indexeddb: { filter: {} },
- input: true
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
- title: 'test checkbox',
- display: 'form',
- name: 'testCheckbox',
- path: 'testcheckbox',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp8.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp8.js
deleted file mode 100644
index a07ad0f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp8.js
+++ /dev/null
@@ -1,35 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'number',
- type: 'number',
- input: true
- },
- {
- label: 'Select',
- tableView: true,
- data: { values: [{ label: 'a', value: 'a' }, { label: 'b', value: 'b' }, { label: 'c', value: 'c' }] },
- refreshOn: 'number',
- clearOnRefresh: true,
- selectThreshold: 0.3,
- validate: { onlyAvailableItems: false },
- key: 'select',
- type: 'select',
- indexeddb: { filter: {} },
- input: true
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: true, input: true, tableView: false }
- ],
- title: 'test',
- display: 'form',
- name: 'test',
- path: 'test',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp9.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp9.js
deleted file mode 100644
index 5e667dbc..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/comp9.js
+++ /dev/null
@@ -1,65 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Number',
- mask: false,
- spellcheck: true,
- tableView: false,
- delimiter: false,
- requireDecimal: false,
- inputFormat: 'plain',
- key: 'number',
- type: 'number',
- input: true
- },
- {
- label: 'Select',
- tableView: true,
- dataSrc: 'url',
- data: {
- values: [
- {
- label: '',
- value: ''
- }
- ],
- url: 'https://test.com/{{ data.number }}',
- headers: [
- {
- key: '',
- value: ''
- }
- ]
- },
- template: '{{ item.name }} ',
- refreshOn: 'number',
- lazyLoad: false,
- selectThreshold: 0.3,
- validate: {
- onlyAvailableItems: false
- },
- key: 'select',
- type: 'select',
- indexeddb: {
- filter: {}
- },
- input: true,
- disableLimit: true
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
- title: 'test checkbox',
- display: 'form',
- name: 'testCheckbox',
- path: 'testcheckbox',
- project: '5ebcf8938bdebc4c58a949a3',
- machineName: 'cjksbatcpbhyfbs:testCheckbox'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/index.js
deleted file mode 100644
index 1567d054..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export { multiSelect, multiSelectOptions } from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
-export comp6 from './comp6';
-export comp7 from './comp7';
-export comp8 from './comp8';
-export comp9 from './comp9';
-export comp10 from './comp10';
-export comp11 from './comp11';
-export comp12 from './comp12';
-export comp13 from './comp13';
-export comp14 from './comp14';
-export comp15 from './comp15';
-export comp16 from './comp16';
-export comp17 from './comp17';
-export comp18 from './comp18';
-export comp19 from './comp19';
-export comp20 from './comp20';
-export comp21 from './comp21';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/values.js
deleted file mode 100644
index c7e1e657..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/select/fixtures/values.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default [
- 'one',
- 'two',
- false,
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.form.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.form.js
deleted file mode 100644
index 7d7300fc..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.form.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import radioEditForm from '../radio/Radio.form';
-import SelectBoxesEditValidation from './editForm/SelectBoxes.edit.validation';
-
-export default function(...extend) {
- return radioEditForm([
- {
- key: 'data',
- components: [
- {
- key: 'dataType',
- ignore: true,
- }
- ]
- },
- {
- key: 'validation',
- components: SelectBoxesEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.js
deleted file mode 100644
index 945f2256..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.js
+++ /dev/null
@@ -1,286 +0,0 @@
-import _ from 'lodash';
-import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-import RadioComponent from '../radio/Radio';
-
-export default class SelectBoxesComponent extends RadioComponent {
- static schema(...extend) {
- return RadioComponent.schema({
- type: 'selectboxes',
- label: 'Select Boxes',
- key: 'selectBoxes',
- inline: false
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Select Boxes',
- group: 'basic',
- icon: 'plus-square',
- weight: 60,
- documentation: '/userguide/form-building/form-components#select-box',
- schema: SelectBoxesComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return SelectBoxesComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- valueComponent(classComp) {
- return {
- type: 'select',
- dataSrc: 'custom',
- valueProperty: 'value',
- valueType: 'string',
- data: {
- custom: `values = ${classComp && classComp.values ? JSON.stringify(classComp.values) : []}`
- },
- };
- }
- };
- }
-
- static savedValueTypes(schema) {
- return getComponentSavedTypes(schema) || [componentValueTypes.object];
- }
-
- constructor(...args) {
- super(...args);
- this.validators = this.validators.concat('minSelectedCount', 'maxSelectedCount', 'availableValueProperty');
- }
-
- init() {
- super.init();
- this.component.inputType = 'checkbox';
- }
-
- get defaultSchema() {
- return SelectBoxesComponent.schema();
- }
-
- get inputInfo() {
- const info = super.elementInfo();
- info.attr.name += '[]';
- info.attr.type = 'checkbox';
- info.attr.class = 'form-check-input';
- return info;
- }
-
- get emptyValue() {
- return this.component.values.reduce((prev, value) => {
- if (value.value) {
- prev[value.value] = false;
- }
- return prev;
- }, {});
- }
-
- get defaultValue() {
- let defaultValue = this.emptyValue;
-
- if (!_.isEmpty(this.component.defaultValue)) {
- defaultValue = this.component.defaultValue;
- }
- if (this.component.customDefaultValue && !this.options.preview) {
- defaultValue = this.evaluate(
- this.component.customDefaultValue,
- { value: '' },
- 'value'
- );
- }
-
- return defaultValue;
- }
-
- /**
- * Only empty if the values are all false.
- *
- * @param value
- * @return {boolean}
- */
- isEmpty(value = this.dataValue) {
- let empty = true;
- for (const key in value) {
- if (value.hasOwnProperty(key) && value[key]) {
- empty = false;
- break;
- }
- }
-
- return empty;
- }
-
- getValue() {
- if (this.viewOnly || !this.refs.input || !this.refs.input.length) {
- return this.dataValue;
- }
- const value = {};
- _.each(this.refs.input, (input) => {
- value[input.value] = !!input.checked;
- });
- return value;
- }
-
- /**
- * Normalize values coming into updateValue.
- *
- * @param value
- * @return {*}
- */
- normalizeValue(value) {
- value = value || {};
- if (typeof value !== 'object') {
- if (typeof value === 'string') {
- value = {
- [value]: true
- };
- }
- else {
- value = {};
- }
- }
- if (Array.isArray(value)) {
- _.each(value, (val) => {
- value[val] = true;
- });
- }
-
- const checkedValues = _.keys(_.pickBy(value, (val) => val));
- if (this.isSelectURL && this.templateData && _.every(checkedValues, (val) => this.templateData[val])) {
- const submission = this.root.submission;
- if (!submission.metadata.selectData) {
- submission.metadata.selectData = {};
- }
- const selectData = [];
- checkedValues.forEach((value) => selectData.push(this.templateData[value]));
- _.set(submission.metadata.selectData, this.path, selectData);
- }
-
- return value;
- }
-
- /**
- * Set the value of this component.
- *
- * @param value
- * @param flags
- */
- setValue(value, flags = {}) {
- const changed = this.updateValue(value, flags);
- value = this.dataValue;
-
- if (this.isHtmlRenderMode()) {
- if (changed) {
- this.redraw();
- }
- }
- else {
- _.each(this.refs.input, (input) => {
- if (_.isUndefined(value[input.value])) {
- value[input.value] = false;
- }
- input.checked = !!value[input.value];
- });
- }
-
- return changed;
- }
-
- getValueAsString(value) {
- if (!value) {
- return '';
- }
-
- if (this.isSelectURL) {
- return _(value).pickBy((val) => val).keys().join(', ');
- }
- return _(this.component.values || [])
- .filter((v) => value[v.value])
- .map('label')
- .join(', ');
- }
-
- setSelectedClasses() {
- if (this.refs.wrapper) {
- //add/remove selected option class
- const value = this.dataValue;
- const valuesKeys = Object.keys(value);
-
- this.refs.wrapper.forEach((wrapper, index) => {
- let key = valuesKeys[index];
- const input = this.refs.input[index];
- if (input?.value.toString() !== key) {
- key = valuesKeys.find((k) => input?.value.toString() === k);
- }
- const isChecked = value[key];
- if ((isChecked && key) || (this.isSelectURL && !this.shouldLoad && this.listData && _.findIndex(this.selectData, this.listData[index]) !== -1)) {
- //add class to container when selected
- this.addClass(wrapper, this.optionSelectedClass);
- //change "checked" attribute
- input.setAttribute('checked', 'true');
- }
- else if (!isChecked && key) {
- this.removeClass(wrapper, this.optionSelectedClass);
- input.removeAttribute('checked');
- }
- });
- }
- }
-
- setInputsDisabled(value, onlyUnchecked) {
- if (this.refs.input) {
- this.refs.input.forEach(item => {
- if (onlyUnchecked && !item.checked || !onlyUnchecked) {
- item.disabled = value;
- }
- });
- }
- }
-
- checkComponentValidity(data, dirty, rowData, options) {
- const minCount = this.component.validate.minSelectedCount;
- const maxCount = this.component.validate.maxSelectedCount;
- const isValid = this.isValid(data, dirty);
-
- if ((maxCount || minCount) && !this.shouldSkipValidation(data, dirty, rowData)) {
- const count = Object.keys(this.validationValue).reduce((total, key) => {
- if (this.validationValue[key]) {
- total++;
- }
- return total;
- }, 0);
-
- // Disable the rest of inputs if the max amount is already checked
- if (maxCount && count >= maxCount) {
- this.setInputsDisabled(true, true);
- }
- else if (maxCount && !this.shouldDisabled) {
- this.setInputsDisabled(false);
- }
-
- if (!isValid && maxCount && count > maxCount) {
- const message = this.t(
- this.component.maxSelectedCountMessage || 'You can only select up to {{maxCount}} items.',
- { maxCount }
- );
- this.setCustomValidity(message, dirty);
- return false;
- }
- else if (!isValid && minCount && count < minCount) {
- this.setInputsDisabled(false);
- const message = this.t(
- this.component.minSelectedCountMessage || 'You must select at least {{minCount}} items.',
- { minCount }
- );
- this.setCustomValidity(message, dirty);
- return false;
- }
- }
-
- return super.checkComponentValidity(data, dirty, rowData, options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.unit.js
deleted file mode 100644
index 557f230d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/SelectBoxes.unit.js
+++ /dev/null
@@ -1,363 +0,0 @@
-import assert from 'power-assert';
-import Harness from '../../../test/harness';
-import _ from 'lodash';
-import SelectBoxesComponent from './SelectBoxes';
-import Formio from './../../Formio';
-
-import {
- comp1,
- comp3,
- comp4,
- comp5,
- comp6
-} from './fixtures';
-import wizardWithSelectBoxes from '../../../test/forms/wizardWithSelectBoxes';
-
-describe('SelectBoxes Component', () => {
- it('Should build a SelectBoxes component', () => {
- return Harness.testCreate(SelectBoxesComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="checkbox"]', 8);
- });
- });
-
- it('Should build a SelectBoxes component with URL DataSrc', (done) => {
- const form = _.cloneDeep(comp5);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [
- { name : 'Alabama', abbreviation : 'AL' },
- { name : 'Alaska', abbreviation: 'AK' },
- { name: 'American Samoa', abbreviation: 'AS' }
- ];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const selectBoxes = form.getComponent('selectBoxes');
-
- setTimeout(()=>{
- assert.equal(selectBoxes.loadedOptions.length, 3);
-
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should display values in DataTab', function(done) {
- Harness.testCreate(SelectBoxesComponent, comp6).then((component) => {
- const value1 = component.getView({ Alabama: false, Alaska: true });
- const value2 = component.getView({ Alabama: true, Alaska: true });
- assert.equal(value1, 'Alaska');
- assert.equal(value2, 'Alabama, Alaska');
- done();
- });
- });
-
- it('Should provide metadata.selectData for SelectBoxes component with URL DataSrc', (done) => {
- const form = _.cloneDeep(comp5);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [
- { name : 'Alabama', abbreviation : 'AL' },
- { name : 'Alaska', abbreviation: 'AK' },
- { name: 'American Samoa', abbreviation: 'AS' }
- ];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(form => {
- const selectBoxes = form.getComponent('selectBoxes');
-
- setTimeout(()=>{
- const value = { AL: false, AK: true, AS: true };
- selectBoxes.setValue(value);
- setTimeout(() => {
- assert.equal(selectBoxes.dataValue, value);
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
- setTimeout(() => {
- assert.equal(_.isEqual(form.submission.metadata.selectData.selectBoxes, [{ name : 'Alaska' }, { name : 'American Samoa' }]), true);
- assert.equal(form.submission.metadata.listData.selectBoxes.length, 3);
- Formio.makeRequest = originalMakeRequest;
- done();
- },200);
- },200);
- }, 200);
- }).catch(done);
- });
-
- describe('error messages', () => {
- it('Should have a minSelectedCount validation message', () => {
- const formJson = {
- components: [
- {
- type: 'selectboxes',
- key: 'options',
- values: [
- { label: 'Option 1', value: '1' },
- { label: 'Option 2', value: '2' },
- { label: 'Option 3', value: '3' },
- { label: 'Option 4', value: '4' }
- ],
- validate: {
- minSelectedCount: 2
- }
- }
- ]
- };
- const element = document.createElement('div');
- return Formio.createForm(element, formJson)
- .then(async form => {
- form.submission = {
- data: {
- options: { 1: true }
- }
- };
- const comp = form.getComponent('options');
- setTimeout(() => {
- const { messageContainer } = comp.refs;
- assert.equal(
- messageContainer.textContent.trim(),
- 'You must select at least 2 items.'
- );
- }, 300);
- });
- });
-
- it('Should use the minSelectedCountMessage if provided', () => {
- const formJson = {
- components: [
- {
- type: 'selectboxes',
- key: 'options',
- values: [
- { label: 'Option 1', value: '1' },
- { label: 'Option 2', value: '2' },
- { label: 'Option 3', value: '3' },
- { label: 'Option 4', value: '4' }
- ],
- validate: {
- minSelectedCount: 2,
- },
- minSelectedCountMessage: 'Please select at least {{minCount}} items.'
- }
- ]
- };
- const element = document.createElement('div');
- return Formio.createForm(element, formJson)
- .then(async form => {
- form.submission = {
- data: {
- options: { 1: true }
- }
- };
- const comp = form.getComponent('options');
- setTimeout(() => {
- const { messageContainer } = comp.refs;
- assert.equal(
- messageContainer.textContent.trim(),
- 'Please select at least 2 items.'
- );
- }, 300);
- });
- });
-
- it('Hidden SelectBoxes validation should not prevent submission', (done) => {
- const element = document.createElement('div');
- Formio.createForm(element, comp4)
- .then(async form => {
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
- setTimeout(() => {
- assert.equal(form.submission.state, 'submitted');
- assert.equal(form.errors.length, 0);
- done();
- }, 500);
- })
- .catch(done);
- });
-
- it('Should have a maxSelectedCount validation message', () => {
- const formJson = {
- components: [
- {
- type: 'selectboxes',
- key: 'options',
- values: [
- { label: 'Option 1', value: '1' },
- { label: 'Option 2', value: '2' },
- { label: 'Option 3', value: '3' },
- { label: 'Option 4', value: '4' }
- ],
- validate: {
- maxSelectedCount: 2
- }
- }
- ]
- };
- const element = document.createElement('div');
- return Formio.createForm(element, formJson)
- .then(async form => {
- form.submission = {
- data: {
- options: { 1: true, 2: true, 3: true }
- }
- };
- const comp = form.getComponent('options');
- setTimeout(() => {
- const { messageContainer } = comp.refs;
- assert.equal(
- messageContainer.textContent.trim(),
- 'You can only select up to 2 items.'
- );
- }, 300);
- });
- });
-
- it('Should use the maxSelectedCountMessage if provided', () => {
- const formJson = {
- components: [
- {
- type: 'selectboxes',
- key: 'options',
- values: [
- { label: 'Option 1', value: '1' },
- { label: 'Option 2', value: '2' },
- { label: 'Option 3', value: '3' },
- { label: 'Option 4', value: '4' }
- ],
- validate: {
- maxSelectedCount: 2,
- },
- maxSelectedCountMessage: 'Please select {{maxCount}} items at most.'
- }
- ]
- };
- const element = document.createElement('div');
- return Formio.createForm(element, formJson)
- .then(async form => {
- form.submission = {
- data: {
- options: { 1: true, 2: true, 3: true }
- }
- };
- const comp = form.getComponent('options');
- setTimeout(() => {
- const { messageContainer } = comp.refs;
- assert.equal(
- messageContainer.textContent.trim(),
- 'Please select 2 items at most.'
- );
- }, 300);
- });
- });
-
- it('Should provide validation for ValueProperty', (done) => {
- const form = _.cloneDeep(comp5);
- const element = document.createElement('div');
- const originalMakeRequest = Formio.makeRequest;
-
- Formio.makeRequest = function() {
- return new Promise(resolve => {
- const values = [
- { name : 'Alabama', abbreviation : 'AL' },
- { name : 'Alaska', abbreviation: { a:2, b: 'c' } },
- { name : 'American Samoa', abbreviation: true }
- ];
- resolve(values);
- });
- };
-
- Formio.createForm(element, form).then(async form => {
- const selectBoxes = form.getComponent('selectBoxes');
-
- setTimeout(()=>{
- const inputs = selectBoxes.element.querySelectorAll('input');
- inputs[1].checked = true;
- inputs[2].checked = true;
-
- setTimeout(()=>{
- const submit = form.getComponent('submit');
- const clickEvent = new Event('click');
- const submitBtn = submit.refs.button;
- submitBtn.dispatchEvent(clickEvent);
-
- setTimeout(()=>{
- assert.equal(form.errors.length, 1);
- assert.equal(selectBoxes.error.message, 'Invalid Value Property');
- selectBoxes.setValue({ 'AL': true });
-
- setTimeout(()=>{
- assert.equal(form.errors.length, 0);
- assert.equal(!!selectBoxes.error, false);
- document.innerHTML = '';
- Formio.makeRequest = originalMakeRequest;
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 200);
- }).catch(done);
- });
- });
-
- it('Should set "checked" attribute correctly when value is changed', (done) => {
- Formio.createForm(document.createElement('div'), wizardWithSelectBoxes).then((form) => {
- const selectBoxes = form.getComponent(['selectBoxes']);
- const value = {
- five: false,
- four: false,
- one: true,
- three: false,
- two: true,
- };
-
- selectBoxes.setValue(value);
-
- const checkInputs = (values) => {
- Object.entries(values).forEach(([key, value]) => {
- const input = selectBoxes.element.querySelector(`input[value="${key}"]`);
- assert.equal(input.checked, value, 'Should be checked');
- });
- };
-
- setTimeout(() => {
- checkInputs(value);
- form.setPage(1);
-
- setTimeout(() => {
- form.setPage(0);
-
- setTimeout(() => {
- checkInputs(value);
- done();
- });
- }, 200);
- }, 200);
- }).catch(done);
- });
-});
-
-describe('SelectBoxes Component', () => {
- it('should have red asterisk left hand side to the options labels if component is required and label is hidden', () => {
- return Harness.testCreate(SelectBoxesComponent, comp3).then(component => {
- const options = component.element.querySelectorAll('.form-check-label');
- options.forEach(i => {
- assert.deepEqual(!!getComputedStyle(i, ':before'), true);
- });
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/editForm/SelectBoxes.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/editForm/SelectBoxes.edit.validation.js
deleted file mode 100644
index 5e0ac2ce..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/editForm/SelectBoxes.edit.validation.js
+++ /dev/null
@@ -1,34 +0,0 @@
-export default [
- {
- type: 'number',
- input: true,
- key: 'validate.minSelectedCount',
- label: 'Minimum checked number',
- tooltip: 'Minimum checkboxes required before form can be submitted.',
- weight: 250
- },
- {
- type: 'number',
- input: true,
- key: 'validate.maxSelectedCount',
- label: 'Maximum checked number',
- tooltip: 'Maximum checkboxes possible before form can be submitted.',
- weight: 250
- },
- {
- type: 'textfield',
- input: true,
- key: 'minSelectedCountMessage',
- label: 'Minimum checked error message',
- tooltip: 'Error message displayed if minimum number of items not checked.',
- weight: 250
- },
- {
- type: 'textfield',
- input: true,
- key: 'maxSelectedCountMessage',
- label: 'Maximum checked error message',
- tooltip: 'Error message displayed if maximum number of items checked.',
- weight: 250
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp1.js
deleted file mode 100644
index 0350d97a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp1.js
+++ /dev/null
@@ -1,52 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'type': 'selectboxes',
- 'validate': {
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'inline': false,
- 'values': [
- {
- 'label': 'Red',
- 'value': 'red'
- },
- {
- 'label': 'Blue',
- 'value': 'blue'
- },
- {
- 'label': 'Green',
- 'value': 'green'
- },
- {
- 'label': 'Orange',
- 'value': 'orange'
- },
- {
- 'label': 'Yellow',
- 'value': 'yellow'
- },
- {
- 'label': 'Purple',
- 'value': 'purple'
- },
- {
- 'label': 'Black',
- 'value': 'black'
- },
- {
- 'label': 'White',
- 'value': 'white'
- }
- ],
- 'key': 'favoriteColors',
- 'label': 'Favorite Colors',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp2.js
deleted file mode 100644
index feb46ec1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp2.js
+++ /dev/null
@@ -1,52 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'type': 'selectboxes',
- 'validate': {
- 'required': true
- },
- 'persistent': true,
- 'protected': false,
- 'inline': false,
- 'values': [
- {
- 'label': 'Red',
- 'value': 'red'
- },
- {
- 'label': 'Blue',
- 'value': 'blue'
- },
- {
- 'label': 'Green',
- 'value': 'green'
- },
- {
- 'label': 'Orange',
- 'value': 'orange'
- },
- {
- 'label': 'Yellow',
- 'value': 'yellow'
- },
- {
- 'label': 'Purple',
- 'value': 'purple'
- },
- {
- 'label': 'Black',
- 'value': 'black'
- },
- {
- 'label': 'White',
- 'value': 'white'
- }
- ],
- 'key': 'favoriteColors',
- 'label': 'Favorite Colors',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp3.js
deleted file mode 100644
index 78b78f01..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp3.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default {
- _id: '61135ec3e4188f021c7ad390',
- label: 'Select Boxes',
- optionsLabelPosition: 'right',
- hideLabel: true,
- tableView: false,
- values: [
- { label: '55', value: '55', shortcut: '' },
- { label: '77', value: '77', shortcut: '' },
- ],
- validate: { required: true },
- key: 'selectBoxes',
- type: 'selectboxes',
- input: true,
- inputType: 'checkbox',
- title: 'FIO-2959',
- name: 'fio2959',
- path: 'fio2959',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp4.js
deleted file mode 100644
index 155305e5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp4.js
+++ /dev/null
@@ -1,65 +0,0 @@
-export default {
- _id: '638743c823671dec2ace618b',
- title: '5685',
- name: '5685',
- path: '5685',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Checkbox',
- tableView: false,
- key: 'checkbox',
- type: 'checkbox',
- input: true
- },
- {
- label: 'Select Boxes',
- optionsLabelPosition: 'right',
- tableView: false,
- defaultValue:
- {
- '1': false,
- '2': false,
- '3': false
- },
- values: [
- {
- label: '1',
- value: '1',
- shortcut: ''
- },
- {
- label: '2',
- value: '2',
- shortcut: ''
- },
- {
- label: '3',
- value: '3',
- shortcut: ''
- }],
- validate:
- {
- minSelectedCount: 1
- },
- key: 'selectBoxes1',
- conditional:
- {
- show: true,
- when: 'checkbox',
- eq: true
- },
- type: 'selectboxes',
- input: true,
- inputType: 'checkbox'
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp5.js
deleted file mode 100644
index fc76a9e0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp5.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Select Boxes',
- dataSrc: 'url',
- data: {
- url: 'https://cdn.rawgit.com/mshafrir/2646763/raw/states_titlecase.json'
- },
- valueProperty: 'abbreviation',
- template: '{{ item.name }} ',
- key: 'selectBoxes',
- type: 'selectboxes',
- input: true,
- inputType: 'checkbox',
- },
- {
- label: 'Submit',
- showValidations: false,
- alwaysEnabled: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'test selectBoxes Url',
- display: 'form',
- name: 'testSelectBoxesUrl',
- path: 'testSelectBoxesUrl',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp6.js
deleted file mode 100644
index 38756d5e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/comp6.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default {
- label: 'Select Boxes',
- dataSrc: 'url',
- data: {
- url: 'https://cdn.rawgit.com/mshafrir/2646763/raw/states_titlecase.json'
- },
- valueProperty: 'abbreviation',
- template: '{{ item.name }} ',
- key: 'selectBoxes',
- type: 'selectboxes',
- input: true,
- inputType: 'checkbox',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/index.js
deleted file mode 100644
index c964f29f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
-export comp6 from './comp6';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/values.js
deleted file mode 100644
index d99cad79..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/selectboxes/fixtures/values.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export default [
- {
- one: true,
- two: true,
- three: true,
- },
- {
- one: false,
- two: false,
- three: false,
- },
- {
- one: true,
- two: false,
- three: true,
- },
- {
- one: false,
- two: true,
- three: false,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.form.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.form.js
deleted file mode 100644
index d7db9e4f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.form.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import Components from '../Components';
-import SignatureEditData from './editForm/Signature.edit.data';
-import SignatureEditDisplay from './editForm/Signature.edit.display';
-import SignatureEditValidation from './editForm/Signature.edit.validation';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: SignatureEditDisplay
- },
- {
- key: 'data',
- components: SignatureEditData
- },
- {
- key: 'validation',
- components: SignatureEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.js
deleted file mode 100644
index 6015ce46..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.js
+++ /dev/null
@@ -1,298 +0,0 @@
-import SignaturePad from 'signature_pad';
-import _ResizeObserver from 'resize-observer-polyfill';
-import Input from '../_classes/input/Input';
-import _ from 'lodash';
-import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-
-export default class SignatureComponent extends Input {
- static schema(...extend) {
- return Input.schema({
- type: 'signature',
- label: 'Signature',
- key: 'signature',
- footer: 'Sign above',
- width: '100%',
- height: '150px',
- penColor: 'black',
- backgroundColor: 'rgb(245,245,235)',
- minWidth: '0.5',
- maxWidth: '2.5',
- keepOverlayRatio: true,
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Signature',
- group: 'advanced',
- icon: 'pencil',
- weight: 120,
- documentation: '/developers/integrations/esign/esign-integrations#signature-component',
- schema: SignatureComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return SignatureComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: ['isEmpty', 'isNotEmpty'],
- };
- }
-
- static savedValueTypes(schema) {
- schema = schema || {};
- return getComponentSavedTypes(schema) || [componentValueTypes.string];
- }
-
- init() {
- super.init();
- this.currentWidth = 0;
- this.scale = 1;
-
- if (!this.component.width) {
- this.component.width = '100%';
- }
- if (!this.component.height) {
- this.component.height = '200px';
- }
-
- if (
- this.component.keepOverlayRatio
- && this.options?.display === 'pdf'
- && this.component.overlay?.width
- && this.component.overlay?.height
- ) {
- this.ratio = this.component.overlay?.width / this.component.overlay?.height;
- this.component.width = '100%';
- this.component.height = 'auto';
- }
- }
-
- get emptyValue() {
- return '';
- }
-
- get defaultSchema() {
- return SignatureComponent.schema();
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- info.type = 'input';
- info.attr.type = 'hidden';
- return info;
- }
-
- get className() {
- return `${super.className} signature-pad`;
- }
-
- labelIsHidden() {
- return this.component.hideLabel;
- }
-
- setValue(value, flags = {}) {
- const changed = super.setValue(value, flags);
- if (this.refs.signatureImage && (this.options.readOnly || this.disabled)) {
- this.refs.signatureImage.setAttribute('src', value);
- this.showCanvas(false);
- }
- if (this.signaturePad) {
- if (!value) {
- this.signaturePad.clear();
- }
- else if (changed) {
- this.triggerChange();
- }
- }
-
- if (this.signaturePad && this.dataValue && this.signaturePad.isEmpty()) {
- this.setDataToSigaturePad();
- }
-
- return changed;
- }
-
- showCanvas(show) {
- if (show) {
- if (this.refs.canvas) {
- this.refs.canvas.style.display = 'inherit';
- }
- if (this.refs.signatureImage) {
- this.refs.signatureImage.style.display = 'none';
- }
- }
- else {
- if (this.refs.canvas) {
- this.refs.canvas.style.display = 'none';
- }
- if (this.refs.signatureImage) {
- this.refs.signatureImage.style.display = 'inherit';
- this.refs.signatureImage.style.maxHeight = '100%';
- }
- }
- }
-
- onDisabled() {
- this.showCanvas(!super.disabled);
- if (this.signaturePad) {
- if (super.disabled) {
- this.signaturePad.off();
- if (this.refs.refresh) {
- this.refs.refresh.classList.add('disabled');
- }
- if (this.refs.signatureImage && this.dataValue) {
- this.refs.signatureImage.setAttribute('src', this.dataValue);
- }
- }
- else {
- this.signaturePad.on();
- if (this.refs.refresh) {
- this.refs.refresh.classList.remove('disabled');
- }
- }
- }
- }
-
- checkSize(force, scale) {
- if (this.refs.padBody && (force || this.refs.padBody && this.refs.padBody.offsetWidth !== this.currentWidth)) {
- this.scale = force ? scale : this.scale;
- this.currentWidth = this.refs.padBody.offsetWidth;
- const width = this.currentWidth * this.scale;
- const height = this.ratio ? width / this.ratio : this.refs.padBody.offsetHeight * this.scale;
- const maxHeight = this.ratio ? height : this.refs.padBody.offsetHeight * this.scale;
-
- this.refs.canvas.width = width;
- this.refs.canvas.height = height > maxHeight ? maxHeight : height;
- this.refs.canvas.style.maxWidth = `${this.currentWidth * this.scale}px`;
- this.refs.canvas.style.maxHeight = `${maxHeight}px`;
- const ctx = this.refs.canvas.getContext('2d');
- ctx.setTransform(1, 0, 0, 1, 0, 0);
- ctx.scale((1 / this.scale), (1 / this.scale));
- ctx.fillStyle = this.signaturePad.backgroundColor;
- ctx.fillRect(0, 0, this.refs.canvas.width, this.refs.canvas.height);
- this.signaturePad.clear();
-
- if (this.dataValue) {
- this.setDataToSigaturePad();
- }
-
- this.showCanvas(true);
- }
- }
-
- renderElement(value, index) {
- return this.renderTemplate('signature', {
- element: super.renderElement(value, index),
- required: _.get(this.component, 'validate.required', false),
- });
- }
-
- get hasModalSaveButton() {
- return false;
- }
-
- getModalPreviewTemplate() {
- return this.renderTemplate('modalPreview', {
- previewText: this.dataValue ?
- ` ` :
- this.t('Click to Sign')
- });
- }
-
- attach(element) {
- this.loadRefs(element, { canvas: 'single', refresh: 'single', padBody: 'single', signatureImage: 'single' });
- const superAttach = super.attach(element);
-
- if (this.refs.refresh && this.options.readOnly) {
- this.refs.refresh.classList.add('disabled');
- }
-
- // Create the signature pad.
- if (this.refs.canvas) {
- this.signaturePad = new SignaturePad(this.refs.canvas, {
- minWidth: this.component.minWidth,
- maxWidth: this.component.maxWidth,
- penColor: this.component.penColor,
- backgroundColor: this.component.backgroundColor
- });
-
- this.signaturePad.addEventListener('endStroke', () => this.setValue(this.signaturePad.toDataURL()));
- this.refs.signatureImage.setAttribute('src', this.signaturePad.toDataURL());
-
- this.onDisabled();
-
- // Ensure the signature is always the size of its container.
- if (this.refs.padBody) {
- if (!this.refs.padBody.style.maxWidth) {
- this.refs.padBody.style.maxWidth = '100%';
- }
-
- if (!this.builderMode && !this.options.preview) {
- this.observer = new _ResizeObserver(() => {
- this.checkSize();
- });
-
- this.observer.observe(this.refs.padBody);
- }
-
- this.addEventListener(window, 'resize', _.debounce(() => this.checkSize(), 10));
-
- setTimeout(function checkWidth() {
- if (this.refs.padBody && this.refs.padBody.offsetWidth) {
- this.checkSize();
- }
- else {
- setTimeout(checkWidth.bind(this), 20);
- }
- }.bind(this), 20);
- }
- }
- this.addEventListener(this.refs.refresh, 'click', (event) => {
- event.preventDefault();
- this.showCanvas(true);
- this.signaturePad.clear();
- this.setValue(this.defaultValue);
- });
- this.setValue(this.dataValue);
- return superAttach;
- }
- /* eslint-enable max-statements */
-
- detach() {
- if (this.observer) {
- this.observer.disconnect();
- this.observer = null;
- }
-
- if (this.signaturePad) {
- this.signaturePad.off();
- }
- this.signaturePad = null;
- this.currentWidth = 0;
- super.detach();
- }
-
- getValueAsString(value) {
- if (_.isUndefined(value) && this.inDataTable) {
- return '';
- }
- return value ? 'Yes' : 'No';
- }
-
- focus() {
- this.refs.padBody.focus();
- }
-
- setDataToSigaturePad() {
- this.signaturePad.fromDataURL(this.dataValue, {
- ratio: 1,
- width: this.refs.canvas.width,
- height: this.refs.canvas.height,
- });
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.unit.js
deleted file mode 100644
index 8b137891..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/Signature.unit.js
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.data.js
deleted file mode 100644
index 8cb587f6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.data.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true,
- },
- {
- key: 'defaultValue',
- ignore: true,
- },
- {
- key: 'dbIndex',
- ignore: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.display.js
deleted file mode 100644
index 9a2d296f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.display.js
+++ /dev/null
@@ -1,69 +0,0 @@
-export default [
- {
- type: 'textfield',
- input: true,
- key: 'footer',
- label: 'Footer Label',
- tooltip: 'The footer text that appears below the signature area.',
- placeholder: 'Footer Label',
- weight: 10
- },
- {
- type: 'textfield',
- input: true,
- key: 'width',
- label: 'Width',
- tooltip: 'The width of the signature area.',
- placeholder: 'Width',
- conditional: {
- json: { '!' : [{ var: 'data.keepOverlayRatio' }] },
- },
- weight: 50
- },
- {
- type: 'textfield',
- input: true,
- key: 'height',
- label: 'Height',
- tooltip: 'The height of the signature area.',
- placeholder: 'Height', conditional: {
- json: { '!' : [{ var: 'data.keepOverlayRatio' }] },
- },
- weight: 51
- },
- {
- weight: 52,
- type: 'checkbox',
- label: 'Keep Overlay Aspect Ratio',
- tooltip: 'If checked, the field will have the same aspect ratio as its preview.',
- key: 'keepOverlayRatio',
- customConditional: ({ options }) => (options?.editForm?.display === 'pdf'),
- input: true
- },
- {
- type: 'textfield',
- input: true,
- key: 'backgroundColor',
- label: 'Background Color',
- tooltip: 'The background color of the signature area.',
- placeholder: 'Background Color',
- weight: 52
- },
- {
- type: 'textfield',
- input: true,
- key: 'penColor',
- label: 'Pen Color',
- tooltip: 'The ink color for the signature area.',
- placeholder: 'Pen Color',
- weight: 53
- },
- {
- key: 'placeholder',
- ignore: true,
- },
- {
- key: 'autofocus',
- ignore: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.validation.js
deleted file mode 100644
index a025ede8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/editForm/Signature.edit.validation.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default [
- {
- key: 'unique',
- ignore: true,
- },
- {
- key: 'validateOn',
- ignore: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/comp1.js
deleted file mode 100644
index 5c5a1187..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/comp1.js
+++ /dev/null
@@ -1,28 +0,0 @@
-export default {
- 'lockKey': true,
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [],
- 'hideLabel': true,
- 'type': 'signature',
- 'validate': {
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'maxWidth': '2.5',
- 'minWidth': '0.5',
- 'backgroundColor': 'rgb(245,245,235)',
- 'penColor': 'black',
- 'height': '150px',
- 'width': '100%',
- 'footer': 'Sign above',
- 'placeholder': '',
- 'key': 'signature1',
- 'label': 'Signature',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/values.js
deleted file mode 100644
index 1f2c6609..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/signature/fixtures/values.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default [
- 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABgIAAACWCAYAAAAc9JMyAAATVUlEQVR4Xu3dPWvVZxzH4TuCD1AzJEOdjEurIDgU6dKKuBUXqSL4brr4IjrVxRchdJRuQqVvQOpTl8QpEbVpmnKOdXMQ4cs33OdyCUbz+537uv9TPnDO2uvX24fDHwIECBAgQIAAAQIECBAgQIAAAQIECBAgQGBKgTUhYMp7dSgCBAgQIECAAAECBAgQIECAAAECBAgQILAUEAI8CAQIECBAgAABAgQIECBAgAABAgQIECBAYGIBIWDiy3U0AgQIECBAgAABAgQIECBAgAABAgQIECAgBHgGCBAgQIAAAQIECBAgQIAAAQIECBAgQIDAxAJCwMSX62gECBAgQIAAAQIECBAgQIAAAQIECBAgQEAI8AwQIECAAAECBAgQIECAAAECBAgQIECAAIGJBYSAiS/X0QgQIECAAAECBAgQIECAAAECBAgQIECAgBDgGSBAgAABAgQIECBAgAABAgQIECBAgAABAhMLCAETX66jESBAgAABAgQIECBAgAABAgQIECBAgAABIcAzQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEJhYQAia+XEcjQIAAAQIECBAgQIAAAQIECBAgQIAAAQJCgGeAAAECBAgQIECAAAECBAgQIECAAAECBAhMLCAETHy5jkaAAAECBAgQIECAAAECBAgQIECAAAECBIQAzwABAgQIECBAgAABAgQIECBAgAABAgQIEJhYQAiY+HIdjQABAgQIECBAgAABAgQIECBAgAABAgQICAGeAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMLGAEDDx5ToaAQIECBAgQIAAAQIECBAgQIAAAQIECBAQAjwDBAgQIECAAAECBAgQIECAAAECBAgQIEBgYgEhYOLLdTQCBAgQIECAAAECBAgQIECAAAECBAgQICAEeAYIECBAgAABAgQIECBAgAABAgQIECBAgMDEAkLAxJfraAQIECBAgAABAgQIECBAgAABAgQIECBAQAjwDBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgYkFhICJL9fRCBAgQIAAAQIECBAgQIAAAQIECBAgQICAEOAZIECAAAECBAgQIECAAAECBAgQIECAAAECEwsIARNfrqMRIECAAAECBAgQIECAAAECBAgQIECAAAEhwDNAgAABAgQIECBAgAABAgQIECBAgAABAgQmFhACJr5cRyNAgAABAgQIECBAgAABAgQIECBAgAABAkKAZ4AAAQIECBAgQIAAAQIECBAgQIAAAQIECEwsIARMfLmORoAAAQIECBAgQIAAAQIECBAgQIAAAQIEhADPAAECBAgQIECAAAECBAgQIECAAAECBAgQmFhACJj4ch2NAAECBAgQIECAAAECBAgQIECAAAECBAgIAZ4BAgQIECBAgAABAgQIECBAgAABAgQIECAwscDKhoCXL/8ap06dHNvbr8bOzs7yik+fPr38ure3t/x65cp3E1+9oxEgQIAAAQIECBAgQIAAAQIECBAgQIDAKgisZAi4fv3mePjwt4/e79ra2jg8PFz+2/r66XHs2LGxvr4+3r37exkMzp07OzY3N/8PB1+M/f1/xoULX4+Dg4Pl906cODGeP38xdnf3lt/f3d1dxobFz21tnR2PH/8x9vZeL/9++fI34/btH8fGxsYqPGvOSIAAAQIECBAgQIAAAQIECBAgQIAAAQIFgZULAU+e/DkuXfq2QP3xlffu/Tzu3Ll9ZF6PF0KAAAECBAgQIECAAAECBAgQIECAAAECcwmsXAh4+vTZuHjx8pG5xfv3fxm3bt04Mq/HCyFAgAABAgQIECBAgAABAgQIECBAgACBuQRWLgQsru/atR/Go0e/f9JNHj9+fJw58+V4+/bt2Nl5tXx7n83NjbF4C6HFZwrs7++P8+e/GgcH/y7nnTx5Yjx79mL5OQOL7y/eImjxlkJbW1vLtwN6/9ZAe+PFi5fj5s0b4+7dnz7pdfhPBAgQIECAAAECBAgQIECAAAECBAgQIEDgcwRWMgQsoB48+HW8ebP45f7O2N5+/2HBV69+v/zl/ocPC/7wy/vPgfUzBAgQIECAAAECBAgQIECAAAECBAgQIEDgKAisbAg4CvheAwECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLSAEpIXNJ0CAAAECBAgQIECAAAECBAgQIECAAAECRQEhoIhvNQECBAgQIECAAAECBAgQIECAAAECBAgQSAsIAWlh8wkQIECAAAECBAgQIECAAAECBAgQIECAQFFACCjiW02AAAECBAgQIECAAAECBAgQIECAAAECBNICQkBa2HwCBAgQIECAAAECBAgQIECAAAECBAgQIFAUEAKK+FYTIECAAAECBAgQIECAAAECBAgQIECAAIG0gBCQFjafAAECBAgQIECAAAECBAgQIECAAAECBAgUBYSAIr7VBAgQIECAAAECBAgQIECAAAECBAgQIEAgLfAfpsyz7fPE9GYAAAAASUVORK5CYII=',
- 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABgQAAACWCAYAAAAR6uN1AAARFElEQVR4Xu3ZQQ0AMAwDsZU/6E4ajJ3LIE5/md3d4wgQIECAAAECBAgQIECAAAECBAgQIECAAIGvBcYg8HW/whEgQIAAAQIECBAgQIAAAQIECBAgQIAAgSdgEPAIBAgQIECAAAECBAgQIECAAAECBAgQIEAgIGAQCJQsIgECBAgQIECAAAECBAgQIECAAAECBAgQMAj4AQIECBAgQIAAAQIECBAgQIAAAQIECBAgEBAwCARKFpEAAQIECBAgQIAAAQIECBAgQIAAAQIECBgE/AABAgQIECBAgAABAgQIECBAgAABAgQIEAgIGAQCJYtIgAABAgQIECBAgAABAgQIECBAgAABAgQMAn6AAAECBAgQIECAAAECBAgQIECAAAECBAgEBAwCgZJFJECAAAECBAgQIECAAAECBAgQIECAAAECBgE/QIAAAQIECBAgQIAAAQIECBAgQIAAAQIEAgIGgUDJIhIgQIAAAQIECBAgQIAAAQIECBAgQIAAAYOAHyBAgAABAgQIECBAgAABAgQIECBAgAABAgEBg0CgZBEJECBAgAABAgQIECBAgAABAgQIECBAgIBBwA8QIECAAAECBAgQIECAAAECBAgQIECAAIGAgEEgULKIBAgQIECAAAECBAgQIECAAAECBAgQIEDAIOAHCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAQMAgEChZRAIECBAgQIAAAQIECBAgQIAAAQIECBAgYBDwAwQIECBAgAABAgQIECBAgAABAgQIECBAICBgEAiULCIBAgQIECBAgAABAgQIECBAgAABAgQIEDAI+AECBAgQIECAAAECBAgQIECAAAECBAgQIBAQMAgEShaRAAECBAgQIECAAAECBAgQIECAAAECBAgYBPwAAQIECBAgQIAAAQIECBAgQIAAAQIECBAICBgEAiWLSIAAAQIECBAgQIAAAQIECBAgQIAAAQIEDAJ+gAABAgQIECBAgAABAgQIECBAgAABAgQIBAQMAoGSRSRAgAABAgQIECBAgAABAgQIECBAgAABAgYBP0CAAAECBAgQIECAAAECBAgQIECAAAECBAICBoFAySISIECAAAECBAgQIECAAAECBAgQIECAAAGDgB8gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIBAYNAoGQRCRAgQIAAAQIECBAgQIAAAQIECBAgQICAQcAPECBAgAABAgQIECBAgAABAgQIECBAgACBgIBBIFCyiAQIECBAgAABAgQIECBAgAABAgQIECBAwCDgBwgQIECAAAECBAgQIECAAAECBAgQIECAQEDAIBAoWUQCBAgQIECAAAECBAgQIECAAAECBAgQIGAQ8AMECBAgQIAAAQIECBAgQIAAAQIECBAgQCAgYBAIlCwiAQIECBAgQIAAAQIECBAgQIAAAQIECBAwCPgBAgQIECBAgAABAgQIECBAgAABAgQIECAQEDAIBEoWkQABAgQIECBAgAABAgQIECBAgAABAgQIGAT8AAECBAgQIECAAAECBAgQIECAAAECBAgQCAgYBAIli0iAAAECBAgQIECAAAECBAgQIECAAAECBAwCfoAAAQIECBAgQIAAAQIECBAgQIAAAQIECAQEDAKBkkUkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIGAT9AgAABAgQIECBAgAABAgQIECBAgAABAgQCAgaBQMkiEiBAgAABAgQIECBAgAABAgQIECBAgAABg4AfIECAAAECBAgQIECAAAECBAgQIECAAAECAQGDQKBkEQkQIECAAAECBAgQIECAAAECBAgQIECAgEHADxAgQIAAAQIECBAgQIAAAQIECBAgQIAAgYCAQSBQsogECBAgQIAAAQIECBAgQIAAAQIECBAgQMAg4AcIECBAgAABAgQIECBAgAABAgQIECBAgEBAwCAQKFlEAgQIECBAgAABAgQIECBAgAABAgQIECBgEPADBAgQIECAAAECBAgQIECAAAECBAgQIEAgIGAQCJQsIgECBAgQIECAAAECBAgQIECAAAECBAgQMAj4AQIECBAgQIAAAQIECBAgQIAAAQIECBAgEBAwCARKFpEAAQIECBAgQIAAAQIECBAgQIAAAQIECBgE/AABAgQIECBAgAABAgQIECBAgAABAgQIEAgIGAQCJYtIgAABAgQIECBAgAABAgQIECBAgAABAgQMAn6AAAECBAgQIECAAAECBAgQIECAAAECBAgEBAwCgZJFJECAAAECBAgQIECAAAECBAgQIECAAAECBgE/QIAAAQIECBAgQIAAAQIECBAgQIAAAQIEAgIGgUDJIhIgQIAAAQIECBAgQIAAAQIECBAgQIAAAYOAHyBAgAABAgQIECBAgAABAgQIECBAgAABAgEBg0CgZBEJECBAgAABAgQIECBAgAABAgQIECBAgIBBwA8QIECAAAECBAgQIECAAAECBAgQIECAAIGAgEEgULKIBAgQIECAAAECBAgQIECAAAECBAgQIEDAIOAHCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAQMAgEChZRAIECBAgQIAAAQIECBAgQIAAAQIECBAgYBDwAwQIECBAgAABAgQIECBAgAABAgQIECBAICBgEAiULCIBAgQIECBAgAABAgQIECBAgAABAgQIEDAI+AECBAgQIECAAAECBAgQIECAAAECBAgQIBAQMAgEShaRAAECBAgQIECAAAECBAgQIECAAAECBAgYBPwAAQIECBAgQIAAAQIECBAgQIAAAQIECBAICBgEAiWLSIAAAQIECBAgQIAAAQIECBAgQIAAAQIEDAJ+gAABAgQIECBAgAABAgQIECBAgAABAgQIBAQMAoGSRSRAgAABAgQIECBAgAABAgQIECBAgAABAgYBP0CAAAECBAgQIECAAAECBAgQIECAAAECBAICBoFAySISIECAAAECBAgQIECAAAECBAgQIECAAAGDgB8gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIBAYNAoGQRCRAgQIAAAQIECBAgQIAAAQIECBAgQICAQcAPECBAgAABAgQIECBAgAABAgQIECBAgACBgIBBIFCyiAQIECBAgAABAgQIECBAgAABAgQIECBAwCDgBwgQIECAAAECBAgQIECAAAECBAgQIECAQEDAIBAoWUQCBAgQIECAAAECBAgQIECAAAECBAgQIGAQ8AMECBAgQIAAAQIECBAgQIAAAQIECBAgQCAgYBAIlCwiAQIECBAgQIAAAQIECBAgQIAAAQIECBAwCPgBAgQIECBAgAABAgQIECBAgAABAgQIECAQEDAIBEoWkQABAgQIECBAgAABAgQIECBAgAABAgQIGAT8AAECBAgQIECAAAECBAgQIECAAAECBAgQCAgYBAIli0iAAAECBAgQIECAAAECBAgQIECAAAECBAwCfoAAAQIECBAgQIAAAQIECBAgQIAAAQIECAQEDAKBkkUkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIGAT9AgAABAgQIECBAgAABAgQIECBAgAABAgQCAgaBQMkiEiBAgAABAgQIECBAgAABAgQIECBAgAABg4AfIECAAAECBAgQIECAAAECBAgQIECAAAECAQGDQKBkEQkQIECAAAECBAgQIECAAAECBAgQIECAgEHADxAgQIAAAQIECBAgQIAAAQIECBAgQIAAgYCAQSBQsogECBAgQIAAAQIECBAgQIAAAQIECBAgQMAg4AcIECBAgAABAgQIECBAgAABAgQIECBAgEBAwCAQKFlEAgQIECBAgAABAgQIECBAgAABAgQIECBgEPADBAgQIECAAAECBAgQIECAAAECBAgQIEAgIGAQCJQsIgECBAgQIECAAAECBAgQIECAAAECBAgQMAj4AQIECBAgQIAAAQIECBAgQIAAAQIECBAgEBAwCARKFpEAAQIECBAgQIAAAQIECBAgQIAAAQIECBgE/AABAgQIECBAgAABAgQIECBAgAABAgQIEAgIGAQCJYtIgAABAgQIECBAgAABAgQIECBAgAABAgQMAn6AAAECBAgQIECAAAECBAgQIECAAAECBAgEBAwCgZJFJECAAAECBAgQIECAAAECBAgQIECAAAECBgE/QIAAAQIECBAgQIAAAQIECBAgQIAAAQIEAgIGgUDJIhIgQIAAAQIECBAgQIAAAQIECBAgQIAAAYOAHyBAgAABAgQIECBAgAABAgQIECBAgAABAgEBg0CgZBEJECBAgAABAgQIECBAgAABAgQIECBAgIBBwA8QIECAAAECBAgQIECAAAECBAgQIECAAIGAgEEgULKIBAgQIECAAAECBAgQIECAAAECBAgQIEDAIOAHCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAQMAgEChZRAIECBAgQIAAAQIECBAgQIAAAQIECBAgYBDwAwQIECBAgAABAgQIECBAgAABAgQIECBAICBgEAiULCIBAgQIECBAgAABAgQIECBAgAABAgQIEDAI+AECBAgQIECAAAECBAgQIECAAAECBAgQIBAQMAgEShaRAAECBAgQIECAAAECBAgQIECAAAECBAgYBPwAAQIECBAgQIAAAQIECBAgQIAAAQIECBAICBgEAiWLSIAAAQIECBAgQIAAAQIECBAgQIAAAQIEDAJ+gAABAgQIECBAgAABAgQIECBAgAABAgQIBAQMAoGSRSRAgAABAgQIECBAgAABAgQIECBAgAABAgYBP0CAAAECBAgQIECAAAECBAgQIECAAAECBAICBoFAySISIECAAAECBAgQIECAAAECBAgQIECAAAGDgB8gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIBAYNAoGQRCRAgQIAAAQIECBAgQIAAAQIECBAgQICAQcAPECBAgAABAgQIECBAgAABAgQIECBAgACBgIBBIFCyiAQIECBAgAABAgQIECBAgAABAgQIECBAwCDgBwgQIECAAAECBAgQIECAAAECBAgQIECAQEDAIBAoWUQCBAgQIECAAAECBAgQIECAAAECBAgQIGAQ8AMECBAgQIAAAQIECBAgQIAAAQIECBAgQCAgYBAIlCwiAQIECBAgQIAAAQIECBAgQIAAAQIECBAwCPgBAgQIECBAgAABAgQIECBAgAABAgQIECAQEDAIBEoWkQABAgQIECBAgAABAgQIECBAgAABAgQIGAT8AAECBAgQIECAAAECBAgQIECAAAECBAgQCAgYBAIli0iAAAECBAgQIECAAAECBAgQIECAAAECBAwCfoAAAQIECBAgQIAAAQIECBAgQIAAAQIECAQEDAKBkkUkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIGAT9AgAABAgQIECBAgAABAgQIECBAgAABAgQCAgaBQMkiEiBAgAABAgQIECBAgAABAgQIECBAgAABg4AfIECAAAECBAgQIECAAAECBAgQIECAAAECAQGDQKBkEQkQIECAAAECBAgQIECAAAECBAgQIECAgEHADxAgQIAAAQIECBAgQIAAAQIECBAgQIAAgYCAQSBQsogECBAgQIAAAQIECBAgQIAAAQIECBAgQMAg4AcIECBAgAABAgQIECBAgAABAgQIECBAgEBAwCAQKFlEAgQIECBAgAABAgQIECBAgAABAgQIECBgEPADBAgQIECAAAECBAgQIECAAAECBAgQIEAgIGAQCJQsIgECBAgQIECAAAECBAgQIECAAAECBAgQMAj4AQIECBAgQIAAAQIECBAgQIAAAQIECBAgEBAwCARKFpEAAQIECBAgQIAAAQIECBAgQIAAAQIECFxa9FZdos1aNQAAAABJRU5ErkJggg==',
- 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABgYAAACWCAYAAAAVHzNIAAATUUlEQVR4Xu3dMU+WZxQG4IdCkQ9DCKUxhdHJRQcNc2Pj5OS/8If4b9x0btKxCybyB1hq1JhUoi2lxdY279dASpM2mJyE3JzrmyC8HM5z3c92Jy8Lu7u7fw4fAgQIECBAgAABAgQIECBAgAABAgQIECBAoIXAgmKgRc4OSYAAAQIECBAgQIAAAQIECBAgQIAAAQIE5gKKAReBAAECBAgQIECAAAECBAgQIECAAAECBAg0ElAMNArbUQkQIECAAAECBAgQIECAAAECBAgQIECAgGLAHSBAgAABAgQIECBAgAABAgQIECBAgAABAo0EFAONwnZUAgQIECBAgAABAgQIECBAgAABAgQIECCgGHAHCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAIwHFQKOwHZUAAQIECBAgQIAAAQIECBAgQIAAAQIECCgG3AECBAgQIECAAAECBAgQIECAAAECBAgQINBIQDHQKGxHJUCAAAECBAgQIECAAAECBAgQIECAAAECigF3gAABAgQIECBAgAABAgQIECBAgAABAgQINBJQDDQK21EJECBAgAABAgQIECBAgAABAgQIECBAgIBiwB0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQKNBBQDjcJ2VAIECBAgQIAAAQIECBAgQIAAAQIECBAgoBhwBwgQIECAAAECBAgQIECAAAECBAgQIECAQCMBxUCjsB2VAAECBAgQIECAAAECBAgQIECAAAECBAgoBtwBAgQIECBAgAABAgQIECBAgAABAgQIECDQSEAx0ChsRyVAgAABAgQIECBAgAABAgQIECBAgAABAooBd4AAAQIECBAgQIAAAQIECBAgQIAAAQIECDQSUAw0CttRCRAgQIAAAQIECBAgQIAAAQIECBAgQICAYsAdIECAAAECBAgQIECAAAECBAgQIECAAAECjQQUA43CdlQCBAgQIECAAAECBAgQIECAAAECBAgQIKAYcAcIECBAgAABAgQIECBAgAABAgQIECBAgEAjAcVAo7AdlQABAgQIECBAgAABAgQIECBAgAABAgQIKAbcAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0EhAMdAobEclQIAAAQIECBAgQIAAAQIECBAgQIAAAQKKAXeAAAECBAgQIECAAAECBAgQIECAAAECBAg0ElAMNArbUQkQIECAAAECBAgQIECAAAECBAgQIECAgGLAHSBAgAABAgQIECBAgAABAgQIECBAgAABAo0EFAONwnZUAgQIECBAgAABAgQIECBAgAABAgQIECCgGHAHCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAIwHFQKOwHZUAAQIECBAgQIAAAQIECBAgQIAAAQIECCgG3AECBAgQIECAAAECBAgQIECAAAECBAgQINBIQDHQKGxHJUCAAAECBAgQIECAAAECBAgQIECAAAECigF3gAABAgQIECBAgAABAgQIECBAgAABAgQINBJQDDQK21EJECBAgAABAgQIECBAgAABAgQIECBAgIBiwB0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQKNBBQDjcJ2VAIECBAgQIAAAQIECBAgQIAAAQIECBAgoBhwBwgQIECAAAECBAgQIECAAAECBAgQIECAQCMBxUCjsB2VAAECBAgQIECAAAECBAgQIECAAAECBAgoBtwBAgQIECBAgAABAgQIECBAgAABAgQIECDQSEAx0ChsRyVAgAABAgQIECBAgAABAgQIECBAgAABAooBd4AAAQIECBAgQIAAAQIECBAgQIAAAQIECDQSUAw0CttRCRAgQIAAAQIECBAgQIAAAQIECBAgQICAYsAdIECAAAECBAgQIECAAAECBAgQIECAAAECjQQUA43CdlQCBAgQIECAAAECBAgQIECAAAECBAgQIKAYcAcIECBAgAABAgQIECBAgAABAgQIECBAgEAjAcVAo7AdlQABAgQIECBAgAABAgQIECBAgAABAgQIKAbcAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0EhAMTDG+PDxwzj8/XDs/7R/JvrVpdVxY/3GeHf8bqwvrze6Fo5KgAABAgQIECBAgAABAgQIECBAgAABApdVoH0x8Gjv0Xjyw5P/zHdhLJz52Z3NO/Pvd77cGTc3bo69t3tj48rGWFlcOX3u1S+vxtbq1tiebY9nPz6bf33ymS3OxsbyxpgtzcbWbGscHB+Mg98Oxsujl/Ny4v3x+/mj0+9cXbo67n5197LePeciQIAAAQIECBAgQIAAAQIECBAgQIAAgQsQaF0MvPn1zbj/7f0LYD/fn9xe3R5Pv3l6voc9RYAAAQIECBAgQIAAAQIECBAgQIAAAQIEziHQuhh4cfhiPPjuwTmYLuaR62vXx+OvH1/MH/dXCRAgQIAAAQIECBAgQIAAAQIECBAgQOBSCrQuBqZEH37/cP66n0/53N68PXY2d8atL26N52+f//1qoMXZ6YjptUDTa4Sm1wFNs6evTz5HfxzNXx90b+ve/PfmrxI6Pjh9fnoN0fT708/WPl8b11aufcpqniVAgAABAgQIECBAgAABAgQIECBAgAABAv8r0L4YmHReH70ey58tj/2fz/7z4elnJ/9T4J+K//6/A+4YAQIECBAgQIAAAQIECBAgQIAAAQIECBBIEVAMpCRlTwIECBAgQIAAAQIECBAgQIAAAQIECBAgUCCgGChANIIAAQIECBAgQIAAAQIECBAgQIAAAQIECKQIKAZSkrInAQIECBAgQIAAAQIECBAgQIAAAQIECBAoEFAMFCAaQYAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgQUAylJ2ZMAAQIECBAgQIAAAQIECBAgQIAAAQIECBQIKAYKEI0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAoqBlKTsSYAAAQIECBAgQIAAAQIECBAgQIAAAQIECgQUAwWIRhAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRQBxUBKUvYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIFAoqBAkQjCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAioBiICUpexIgQIAAAQIECBAgQIAAAQIECBAgQIAAgQIBxUABohEECBAgQIAAAQIECBAgQIAAAQIECBAgQCBFQDGQkpQ9CRAgQIAAAQIECBAgQIAAAQIECBAgQIBAgYBioADRCAIECBAgQIAAAQIECBAgQIAAAQIECBAgkCKgGEhJyp4ECBAgQIAAAQIECBAgQIAAAQIECBAgQKBAQDFQgGgEAQIECBAgQIAAAQIECBAgQIAAAQIECBBIEVAMpCRlTwIECBAgQIAAAQIECBAgQIAAAQIECBAgUCCgGChANIIAAQIECBAgQIAAAQIECBAgQIAAAQIECKQIKAZSkrInAQIECBAgQIAAAQIECBAgQIAAAQIECBAoEFAMFCAaQYAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgQUAylJ2ZMAAQIECBAgQIAAAQIECBAgQIAAAQIECBQIKAYKEI0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAoqBlKTsSYAAAQIECBAgQIAAAQIECBAgQIAAAQIECgQUAwWIRhAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRQBxUBKUvYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIFAoqBAkQjCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAioBiICUpexIgQIAAAQIECBAgQIAAAQIECBAgQIAAgQIBxUABohEECBAgQIAAAQIECBAgQIAAAQIECBAgQCBFQDGQkpQ9CRAgQIAAAQIECBAgQIAAAQIECBAgQIBAgYBioADRCAIECBAgQIAAAQIECBAgQIAAAQIECBAgkCKgGEhJyp4ECBAgQIAAAQIECBAgQIAAAQIECBAgQKBAQDFQgGgEAQIECBAgQIAAAQIECBAgQIAAAQIECBBIEVAMpCRlTwIECBAgQIAAAQIECBAgQIAAAQIECBAgUCCgGChANIIAAQIECBAgQIAAAQIECBAgQIAAAQIECKQIKAZSkrInAQIECBAgQIAAAQIECBAgQIAAAQIECBAoEFAMFCAaQYAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgQUAylJ2ZMAAQIECBAgQIAAAQIECBAgQIAAAQIECBQIKAYKEI0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAoqBlKTsSYAAAQIECBAgQIAAAQIECBAgQIAAAQIECgQUAwWIRhAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRQBxUBKUvYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIFAoqBAkQjCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAioBiICUpexIgQIAAAQIECBAgQIAAAQIECBAgQIAAgQIBxUABohEECBAgQIAAAQIECBAgQIAAAQIECBAgQCBFQDGQkpQ9CRAgQIAAAQIECBAgQIAAAQIECBAgQIBAgYBioADRCAIECBAgQIAAAQIECBAgQIAAAQIECBAgkCKgGEhJyp4ECBAgQIAAAQIECBAgQIAAAQIECBAgQKBAQDFQgGgEAQIECBAgQIAAAQIECBAgQIAAAQIECBBIEVAMpCRlTwIECBAgQIAAAQIECBAgQIAAAQIECBAgUCCgGChANIIAAQIECBAgQIAAAQIECBAgQIAAAQIECKQIKAZSkrInAQIECBAgQIAAAQIECBAgQIAAAQIECBAoEFAMFCAaQYAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgQUAylJ2ZMAAQIECBAgQIAAAQIECBAgQIAAAQIECBQIKAYKEI0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAoqBlKTsSYAAAQIECBAgQIAAAQIECBAgQIAAAQIECgQUAwWIRhAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRQBxUBKUvYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIFAoqBAkQjCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAioBiICUpexIgQIAAAQIECBAgQIAAAQIECBAgQIAAgQIBxUABohEECBAgQIAAAQIECBAgQIAAAQIECBAgQCBFQDGQkpQ9CRAgQIAAAQIECBAgQIAAAQIECBAgQIBAgYBioADRCAIECBAgQIAAAQIECBAgQIAAAQIECBAgkCKgGEhJyp4ECBAgQIAAAQIECBAgQIAAAQIECBAgQKBAQDFQgGgEAQIECBAgQIAAAQIECBAgQIAAAQIECBBIEVAMpCRlTwIECBAgQIAAAQIECBAgQIAAAQIECBAgUCCgGChANIIAAQIECBAgQIAAAQIECBAgQIAAAQIECKQIKAZSkrInAQIECBAgQIAAAQIECBAgQIAAAQIECBAoEFAMFCAaQYAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgQUAylJ2ZMAAQIECBAgQIAAAQIECBAgQIAAAQIECBQIKAYKEI0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAoqBlKTsSYAAAQIECBAgQIAAAQIECBAgQIAAAQIECgQUAwWIRhAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRQBxUBKUvYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIFAoqBAkQjCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAioBiICUpexIgQIAAAQIECBAgQIAAAQIECBAgQIAAgQIBxUABohEECBAgQIAAAQIECBAgQIAAAQIECBAgQCBFQDGQkpQ9CRAgQIAAAQIECBAgQIAAAQIECBAgQIBAgYBioADRCAIECBAgQIAAAQIECBAgQIAAAQIECBAgkCKgGEhJyp4ECBAgQIAAAQIECBAgQIAAAQIECBAgQKBAQDFQgGgEAQIECBAgQIAAAQIECBAgQIAAAQIECBBIEVAMpCRlTwIECBAgQIAAAQIECBAgQIAAAQIECBAgUCCgGChANIIAAQIECBAgQIAAAQIECBAgQIAAAQIECKQIKAZSkrInAQIECBAgQIAAAQIECBAgQIAAAQIECBAoEFAMFCAaQYAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgQUAylJ2ZMAAQIECBAgQIAAAQIECBAgQIAAAQIECBQIKAYKEI0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAoqBlKTsSYAAAQIECBAgQIAAAQIECBAgQIAAAQIECgQUAwWIRhAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRQBxUBKUvYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIFAoqBAkQjCBAgQIAAAQIECBAgQIAAAQIECBAgQIBAioBiICUpexIgQIAAAQIECBAgQIAAAQIECBAgQIAAgQIBxUABohEECBAgQIAAAQIECBAgQIAAAQIECBAgQCBFQDGQkpQ9CRAgQIAAAQIECBAgQIAAAQIECBAgQIBAgYBioADRCAIECBAgQIAAAQIECBAgQIAAAQIECBAgkCKgGEhJyp4ECBAgQIAAAQIECBAgQIAAAQIECBAgQKBA4C+R01m3EQ6wBwAAAABJRU5ErkJggg==',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.form.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.form.js
deleted file mode 100644
index 0db2c40a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.form.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import Components from '../Components';
-import SurveyEditData from './editForm/Survey.edit.data';
-import SurveyEditDisplay from './editForm/Survey.edit.display';
-import SurveyEditValidation from './editForm/Survey.edit.validation';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: SurveyEditDisplay
- },
- {
- key: 'data',
- components: SurveyEditData
- },
- {
- key: 'validation',
- components: SurveyEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.js
deleted file mode 100644
index db2274bc..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.js
+++ /dev/null
@@ -1,195 +0,0 @@
-import _ from 'lodash';
-import Field from '../_classes/field/Field';
-import { boolValue, componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-
-export default class SurveyComponent extends Field {
- static schema(...extend) {
- return Field.schema({
- type: 'survey',
- label: 'Survey',
- key: 'survey',
- questions: [],
- values: []
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Survey',
- group: 'advanced',
- icon: 'list',
- weight: 110,
- documentation: '/userguide/form-building/advanced-components#survey',
- schema: SurveyComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return SurveyComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: ['isEmpty', 'isNotEmpty'],
- };
- }
-
- static savedValueTypes(schema) {
- return getComponentSavedTypes(schema) || [componentValueTypes.object];
- }
-
- get defaultSchema() {
- return SurveyComponent.schema();
- }
-
- render() {
- return super.render(this.renderTemplate('survey'));
- }
-
- attach(element) {
- this.loadRefs(element, { input: 'multiple' });
- const superAttach = super.attach(element);
- this.refs.input.forEach((input) => {
- if (this.disabled) {
- input.setAttribute('disabled', 'disabled');
- }
- else {
- this.addEventListener(input, 'change', () => this.updateValue(null, {
- modified: true
- }));
- }
- });
- this.setValue(this.dataValue);
- return superAttach;
- }
-
- setValue(value, flags = {}) {
- if (!value) {
- return false;
- }
-
- _.each(this.component.questions, (question) => {
- _.each(this.refs.input, (input) => {
- if (input.name === this.getInputName(question)) {
- input.checked = (input.value === value[question.value]);
- }
- });
- });
-
- const changed = this.updateValue(value, flags);
-
- if (changed && this.isHtmlRenderMode()) {
- this.redraw();
- }
-
- return changed;
- }
-
- get emptyValue() {
- return {};
- }
-
- get defaultValue() {
- const defaultValue = super.defaultValue;
- //support for default values created in old formio.js versions
- if (defaultValue && !_.isObject(defaultValue) && this.component.values.some(value => value.value === defaultValue)) {
- const adoptedDefaultValue = {};
-
- this.component.questions.forEach(question => {
- adoptedDefaultValue[question.value] = defaultValue;
- });
-
- return adoptedDefaultValue;
- }
-
- return defaultValue;
- }
-
- getValue() {
- if (this.viewOnly || !this.refs.input || !this.refs.input.length) {
- return this.dataValue;
- }
- const value = {};
- _.each(this.component.questions, (question) => {
- _.each(this.refs.input, (input) => {
- if (input.checked && (input.name === this.getInputName(question))) {
- value[question.value] = input.value;
- return false;
- }
- });
- });
- return value;
- }
-
- set disabled(disabled) {
- super.disabled = disabled;
- _.each(this.refs.input, (input) => {
- input.disabled = true;
- });
- }
-
- get disabled() {
- return super.disabled;
- }
-
- validateRequired(setting, value) {
- if (!boolValue(setting)) {
- return true;
- }
- return this.component.questions.reduce((result, question) =>
- result && Boolean(value[question.value]), true);
- }
-
- getInputName(question) {
- return `${this.options.name}[${question.value}]`;
- }
-
- getValueAsString(value, options) {
- if (options?.email) {
- let result = (`
-
-
-
- Question
- Value
-
-
-
- `);
-
- _.forIn(value, (value, key) => {
- const question = _.find(this.component.questions, ['value', key]);
- const answer = _.find(this.component.values, ['value', value]);
-
- if (!question || !answer) {
- return;
- }
-
- result += (`
-
- ${question.label}
- ${answer.label}
-
- `);
- });
-
- result += '
';
-
- return result;
- }
-
- if (_.isPlainObject(value)) {
- const { values = [], questions = [] } = this.component;
- return _.isEmpty(value)
- ? ''
- : _.map(value,(v, q) => {
- const valueLabel = _.get(_.find(values, val => _.isEqual(val.value, v)), 'label', v);
- const questionLabel = _.get(_.find(questions, quest => _.isEqual(quest.value, q)), 'label', q);
- return `${questionLabel}: ${valueLabel}`;
- }).join('; ');
- }
-
- return super.getValueAsString(value, options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.unit.js
deleted file mode 100644
index 0a356d48..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/Survey.unit.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import assert from 'power-assert';
-
-import Harness from '../../../test/harness';
-import SurveyComponent from './Survey';
-
-import {
- comp1,
- comp2
-} from './fixtures';
-
-describe('Survey Component', () => {
- it('Should build a survey component', () => {
- return Harness.testCreate(SurveyComponent, comp1).then((component) => {
- const inputs = Harness.testElements(component, 'input[type="radio"]', 10);
- inputs.forEach((input, index) => {
- if (index < 5) {
- // Service
- assert.equal(input.name, 'data[surveyQuestions][service]');
- assert.equal(input.id, `${component.key}-service-${comp1.values[index].value}`);
- }
- else {
- // How do you like our service?
- assert.equal(input.name, 'data[surveyQuestions][howWouldYouRateTheTechnology]');
- assert.equal(input.id, `${component.key}-howWouldYouRateTheTechnology-${comp1.values[index - 5].value}`);
- }
- });
- });
- });
-
- it('Should set the value of surveys.', () => {
- return Harness.testCreate(SurveyComponent, comp1).then((component) => {
- Harness.testSetGet(component, { service: 'bad', howWouldYouRateTheTechnology: 'good' });
- const inputs = Harness.testElements(component, 'input[type="radio"]', 10);
- for (const input of inputs) {
- if (
- (input.id === `${component.key}-service-bad`) ||
- (input.id === `${component.key}-howWouldYouRateTheTechnology-good`)
- ) {
- assert.equal(input.checked, true);
- }
- else {
- assert.equal(input.checked, false);
- }
- }
- });
- });
-
- it('Should require all questions for required Survey', (done) => {
- Harness.testCreate(SurveyComponent, comp2).then((component) => {
- Harness.testSetGet(component, { service: 'bad' });
- component.on('componentChange', () => {
- done();
- });
- // assert(component.element)
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.data.js
deleted file mode 100644
index ffb60b36..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.data.js
+++ /dev/null
@@ -1,70 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true
- },
- {
- type: 'datagrid',
- input: true,
- label: 'Questions',
- key: 'questions',
- tooltip: 'The questions you would like to ask in this survey question.',
- weight: 0,
- reorder: true,
- defaultValue: [{ label: '', value: '' }],
- components: [
- {
- label: 'Label',
- key: 'label',
- input: true,
- type: 'textfield'
- },
- {
- label: 'Value',
- key: 'value',
- input: true,
- type: 'textfield',
- allowCalculateOverride: true,
- calculateValue: { _camelCase: [{ var: 'row.label' }] }
- },
- {
- label: 'Tooltip',
- key: 'tooltip',
- input: true,
- type: 'textfield',
- },
- ]
- },
- {
- type: 'datagrid',
- input: true,
- label: 'Values',
- key: 'values',
- tooltip: 'The values that can be selected per question. Example: \'Satisfied\', \'Very Satisfied\', etc.',
- weight: 1,
- reorder: true,
- defaultValue: [{ label: '', value: '' }],
- components: [
- {
- label: 'Label',
- key: 'label',
- input: true,
- type: 'textfield'
- },
- {
- label: 'Value',
- key: 'value',
- input: true,
- type: 'textfield',
- allowCalculateOverride: true,
- calculateValue: { _camelCase: [{ var: 'row.label' }] }
- },
- {
- label: 'Tooltip',
- key: 'tooltip',
- input: true,
- type: 'textfield',
- },
- ]
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.display.js
deleted file mode 100644
index 2e7810dd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.display.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- {
- key: 'placeholder',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.validation.js
deleted file mode 100644
index bbb7e134..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/editForm/Survey.edit.validation.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- {
- key: 'validateOn',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/comp1.js
deleted file mode 100644
index f80510ab..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/comp1.js
+++ /dev/null
@@ -1,53 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [],
- 'type': 'survey',
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'required': false
- },
- 'persistent': true,
- 'protected': false,
- 'defaultValue': '',
- 'values': [
- {
- 'label': 'Excellent',
- 'value': 'excellent'
- },
- {
- 'label': 'Good',
- 'value': 'good'
- },
- {
- 'label': 'Average',
- 'value': 'average'
- },
- {
- 'label': 'Inadequate',
- 'value': 'inadequate'
- },
- {
- 'label': 'Bad',
- 'value': 'bad'
- }
- ],
- 'questions': [
- {
- 'label': 'How do you like our service?',
- 'value': 'service'
- },
- {
- 'label': 'How would you rate the technology?',
- 'value': 'howWouldYouRateTheTechnology'
- }
- ],
- 'key': 'surveyQuestions',
- 'label': 'Survey Questions',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/comp2.js
deleted file mode 100644
index fa05acdb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/comp2.js
+++ /dev/null
@@ -1,53 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [],
- 'type': 'survey',
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'required': true
- },
- 'persistent': true,
- 'protected': false,
- 'defaultValue': '',
- 'values': [
- {
- 'label': 'Excellent',
- 'value': 'excellent'
- },
- {
- 'label': 'Good',
- 'value': 'good'
- },
- {
- 'label': 'Average',
- 'value': 'average'
- },
- {
- 'label': 'Inadequate',
- 'value': 'inadequate'
- },
- {
- 'label': 'Bad',
- 'value': 'bad'
- }
- ],
- 'questions': [
- {
- 'label': 'How do you like our service?',
- 'value': 'service'
- },
- {
- 'label': 'How would you rate the technology?',
- 'value': 'howWouldYouRateTheTechnology'
- }
- ],
- 'key': 'surveyQuestions',
- 'label': 'Survey Questions',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/index.js
deleted file mode 100644
index 63468958..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/values.js
deleted file mode 100644
index bc0622b3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/survey/fixtures/values.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default [
- {
- one: 'a',
- two: 'b',
- },
- {
- one: 'b',
- two: 'a',
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/table/Table.form.js b/web-client/core/themes/italia/static/formio/css/src/components/table/Table.form.js
deleted file mode 100644
index a0e1155f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/table/Table.form.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import nestedComponentForm from '../_classes/nested/NestedComponent.form';
-
-import TableEditDisplay from './editForm/Table.edit.display';
-
-export default function(...extend) {
- return nestedComponentForm([
- {
- key: 'display',
- components: TableEditDisplay
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/table/Table.js b/web-client/core/themes/italia/static/formio/css/src/components/table/Table.js
deleted file mode 100644
index 090cae91..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/table/Table.js
+++ /dev/null
@@ -1,191 +0,0 @@
-import _ from 'lodash';
-import BuilderUtils from '../../utils/builder';
-import NestedComponent from '../_classes/nested/NestedComponent';
-
-export default class TableComponent extends NestedComponent {
- static emptyTable(numRows, numCols) {
- const rows = [];
- for (let i = 0; i < numRows; i++) {
- const cols = [];
- for (let j = 0; j < numCols; j++) {
- cols.push({ components: [] });
- }
- rows.push(cols);
- }
- return rows;
- }
-
- static schema(...extend) {
- return NestedComponent.schema({
- label: 'Table',
- type: 'table',
- input: false,
- key: 'table',
- numRows: 3,
- numCols: 3,
- rows: TableComponent.emptyTable(3, 3),
- header: [],
- caption: '',
- cloneRows: false,
- striped: false,
- bordered: false,
- hover: false,
- condensed: false,
- persistent: false
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Table',
- group: 'layout',
- icon: 'table',
- weight: 40,
- documentation: '/userguide/form-building/layout-components#table',
- showPreview: false,
- schema: TableComponent.schema()
- };
- }
-
- static savedValueTypes() {
- return [];
- }
-
- get defaultSchema() {
- return TableComponent.schema();
- }
-
- get schema() {
- const schema = _.omit(super.schema, 'components');
- schema.rows = [];
- this.eachComponent((component) => {
- if (!schema.rows || !schema.rows.length) {
- schema.rows = TableComponent.emptyTable(this.component.numRows, this.component.numCols);
- }
- if (!schema.rows[component.tableRow]) {
- schema.rows[component.tableRow] = [];
- }
- if (!schema.rows[component.tableRow][component.tableColumn]) {
- schema.rows[component.tableRow][component.column] = { components: [] };
- }
- schema.rows[component.tableRow][component.tableColumn].components.push(component.schema);
- });
- if (!schema.rows.length) {
- schema.rows = TableComponent.emptyTable(this.component.numRows, this.component.numCols);
- }
- return schema;
- }
-
- get className() {
- let name = `table-responsive ${super.className}`;
- if (!this.component.bordered) {
- name += ' no-top-border-table';
- }
- return name;
- }
-
- get cellClassName() {
- let name = '';
- if (this.component.cellAlignment) {
- name = `cell-align-${this.component.cellAlignment}`;
- }
- return name;
- }
-
- get tableKey() {
- return `table-${this.key}`;
- }
-
- get colWidth() {
- const { numCols } = this.component;
- if (!numCols || typeof numCols !== 'number') {
- return '';
- }
- return Math.floor(12 / numCols).toString();
- }
-
- constructor(...args) {
- super(...args);
- this.noField = true;
- }
-
- init() {
- super.init();
- // Ensure component.rows has the correct number of rows and columns.
- for (let rowIndex = 0; rowIndex < this.component.numRows; rowIndex++) {
- this.component.rows[rowIndex] = this.component.rows[rowIndex] || [];
- for (let colIndex = 0; colIndex < this.component.numCols; colIndex++) {
- this.component.rows[rowIndex][colIndex] = this.component.rows[rowIndex][colIndex] || { components: [] };
- }
- this.component.rows[rowIndex] = this.component.rows[rowIndex].slice(0, this.component.numCols);
- }
- this.component.rows = this.component.rows.slice(0, this.component.numRows);
-
- const lastNonEmptyRow = [];
- this.table = [];
- _.each(this.component.rows, (row, rowIndex) => {
- this.table[rowIndex] = [];
- _.each(row, (column, colIndex) => {
- this.table[rowIndex][colIndex] = [];
- if (this.component.cloneRows) {
- if (column.components.length) {
- lastNonEmptyRow[colIndex] = column;
- }
- else if (lastNonEmptyRow[colIndex]) {
- column.components = _.cloneDeep(lastNonEmptyRow[colIndex].components);
- BuilderUtils.uniquify(this.root._form.components, column);
- }
- }
- _.each(column.components, (comp) => {
- let columnComponent;
-
- if (this.builderMode) {
- comp.id = comp.id + rowIndex;
- columnComponent = comp;
- }
- else {
- columnComponent = { ...comp, id: (comp.id + rowIndex) };
- }
-
- const component = this.createComponent(columnComponent);
- component.tableRow = rowIndex;
- component.tableColumn = colIndex;
- this.table[rowIndex][colIndex].push(component);
- });
- });
- });
- }
-
- render() {
- return super.render(this.renderTemplate('table', {
- cellClassName: this.cellClassName,
- tableKey: this.tableKey,
- colWidth: this.colWidth,
- tableComponents: this.table.map(row =>
- row.map(column =>
- this.renderComponents(column)
- )
- )
- }));
- }
-
- attach(element) {
- const keys = this.table.reduce((prev, row, rowIndex) => {
- prev[`${this.tableKey}-${rowIndex}`] = 'multiple';
- return prev;
- }, {});
- this.loadRefs(element, keys);
- const superAttach = super.attach(element);
- this.table.forEach((row, rowIndex) => {
- row.forEach((column, columnIndex) => {
- this.attachComponents(this.refs[`${this.tableKey}-${rowIndex}`][columnIndex], this.table[rowIndex][columnIndex], this.component.rows[rowIndex][columnIndex].components);
- });
- });
- return superAttach;
- }
-
- destroy(all) {
- super.destroy(all);
- delete this.table;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/table/Table.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/table/Table.unit.js
deleted file mode 100644
index 4ae4e7ed..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/table/Table.unit.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import Harness from '../../../test/harness';
-import TableComponent from './Table';
-
-import {
- comp1
-} from './fixtures';
-
-describe('Table Component', () => {
- it('Should build a Table component', () => {
- return Harness.testCreate(TableComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 6);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/table/editForm/Table.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/table/editForm/Table.edit.display.js
deleted file mode 100644
index b1e2b18a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/table/editForm/Table.edit.display.js
+++ /dev/null
@@ -1,109 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- key: 'disabled',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
- {
- type: 'number',
- label: 'Number of Rows',
- key: 'numRows',
- input: true,
- weight: 1,
- placeholder: 'Number of Rows',
- tooltip: 'Enter the number or rows that should be displayed by this table.'
- },
- {
- type: 'number',
- label: 'Number of Columns',
- key: 'numCols',
- input: true,
- weight: 2,
- placeholder: 'Number of Columns',
- tooltip: 'Enter the number or columns that should be displayed by this table.'
- },
- {
- type: 'checkbox',
- label: 'Clone Row Components',
- key: 'cloneRows',
- input: true,
- weight: 3,
- tooltip: 'Check this if you would like to \'clone\' the first row of components to all additional empty rows of the table.'
- },
- {
- type: 'select',
- label: 'Cell Alignment',
- key: 'cellAlignment',
- input: true,
- tooltip: 'Horizontal alignment for cells of the table.',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Left', value: 'left' },
- { label: 'Center', value: 'center' },
- { label: 'Right', value: 'right' }
- ]
- },
- defaultValue: 'left',
- weight: 3
- },
- {
- type: 'checkbox',
- label: 'Striped',
- key: 'striped',
- tooltip: 'This will stripe the table if checked.',
- input: true,
- weight: 701
- },
- {
- type: 'checkbox',
- label: 'Bordered',
- key: 'bordered',
- input: true,
- tooltip: 'This will border the table if checked.',
- weight: 702
- },
- {
- type: 'checkbox',
- label: 'Hover',
- key: 'hover',
- input: true,
- tooltip: 'Highlight a row on hover.',
- weight: 703
- },
- {
- type: 'checkbox',
- label: 'Condensed',
- key: 'condensed',
- input: true,
- tooltip: 'Condense the size of the table.',
- weight: 704
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/table/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/table/fixtures/comp1.js
deleted file mode 100644
index 3a402679..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/table/fixtures/comp1.js
+++ /dev/null
@@ -1,251 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'table',
- 'condensed': false,
- 'hover': false,
- 'bordered': false,
- 'striped': false,
- 'caption': '',
- 'header': [
-
- ],
- 'rows': [
- [
- {
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'a',
- 'label': 'a',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ]
- },
- {
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'b',
- 'label': 'b',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ]
- },
- {
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'c',
- 'label': 'c',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ]
- }
- ],
- [
- {
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'd',
- 'label': 'd',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ]
- },
- {
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'e',
- 'label': 'e',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ]
- },
- {
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'f',
- 'label': 'f',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ]
- }
- ]
- ],
- 'numCols': 3,
- 'numRows': 2,
- 'key': 'table1',
- 'input': false
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/table/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/table/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/table/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.form.js b/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.form.js
deleted file mode 100644
index 2a02192a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.form.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import nestedComponentForm from '../_classes/nested/NestedComponent.form';
-
-import TabsEditDisplay from './editForm/Tabs.edit.display';
-
-export default function(...extend) {
- return nestedComponentForm([
- {
- key: 'display',
- components: TabsEditDisplay
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.js b/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.js
deleted file mode 100644
index db16f9d1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.js
+++ /dev/null
@@ -1,237 +0,0 @@
-import _ from 'lodash';
-import NestedComponent from '../_classes/nested/NestedComponent';
-
-export default class TabsComponent extends NestedComponent {
- static schema(...extend) {
- return NestedComponent.schema({
- label: 'Tabs',
- type: 'tabs',
- input: false,
- key: 'tabs',
- persistent: false,
- tableView: false,
- components: [
- {
- label: 'Tab 1',
- key: 'tab1',
- components: [],
- },
- ],
- verticalLayout: false,
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Tabs',
- group: 'layout',
- icon: 'folder-o',
- weight: 50,
- documentation: '/userguide/form-building/layout-components#tabs',
- showPreview: false,
- schema: TabsComponent.schema(),
- };
- }
-
- static savedValueTypes() {
- return [];
- }
-
- get defaultSchema() {
- return TabsComponent.schema();
- }
-
- get schema() {
- const schema = super.schema;
- // We need to clone this because the builder uses the "components" reference and this would reset that reference.
- const components = _.cloneDeep(this.component.components);
- schema.components = components.map((tab, index) => {
- tab.components = this.tabs[index].map((component) => component.schema);
- return tab;
- });
-
- return schema;
- }
-
- get tabKey() {
- return `tab-${this.key}`;
- }
-
- get tabLikey() {
- return `tabLi-${this.key}`;
- }
-
- get tabLinkKey() {
- return `tabLink-${this.key}`;
- }
-
- constructor(...args) {
- super(...args);
- this.currentTab = 0;
- this.noField = true;
- }
-
- init() {
- this.components = [];
- this.tabs = [];
- _.each(this.component.components, (tab, index) => {
- this.tabs[index] = [];
- // Initialize empty tabs.
- tab.components = tab.components || [];
- _.each(tab.components, (comp) => {
- const component = this.createComponent(comp);
- component.tab = index;
- this.tabs[index].push(component);
- });
- });
- }
-
- render() {
- return super.render(this.renderTemplate(
- 'tab',
- {
- tabKey: this.tabKey,
- tabLikey: this.tabLikey,
- tabLinkKey: this.tabLinkKey,
- currentTab: this.currentTab,
- tabComponents: this.tabs.map(tab => this.renderComponents(tab)),
- },
- (
- this.options.flatten || this.options.pdf ? 'flat' : null
- ),
- ));
- }
-
- attach(element) {
- this.loadRefs(
- element,
- {
- [this.tabLinkKey]: 'multiple',
- [this.tabKey]: 'multiple',
- [this.tabLikey]: 'multiple',
- },
- );
- ['change', 'error'].forEach(event => this.on(event, this.handleTabsValidation.bind(this)));
- const superAttach = super.attach(element);
- this.refs[this.tabLinkKey].forEach((tabLink, index) => {
- this.addEventListener(tabLink, 'click', (event) => {
- event.preventDefault();
- this.setTab(index);
- });
- });
- this.refs[this.tabKey].forEach((tab, index) => {
- this.attachComponents(tab, this.tabs[index], this.component.components[index].components);
- });
- return superAttach;
- }
-
- detach(all) {
- super.detach(all);
- }
-
- /**
- * Set the current tab.
- *
- * @param index
- */
- setTab(index) {
- if (!this.tabs || !this.tabs[index] || !this.refs[this.tabKey] || !this.refs[this.tabKey][index]) {
- return;
- }
-
- this.currentTab = index;
-
- _.each(this.refs[this.tabKey], (tab) => {
- this.removeClass(tab, 'formio-tab-panel-active');
- tab.style.display = 'none';
- });
- this.addClass(this.refs[this.tabKey][index], 'formio-tab-panel-active');
- this.refs[this.tabKey][index].style.display = 'block';
-
- _.each(this.refs[this.tabLinkKey], (tabLink, tabIndex) => {
- if (this.refs[this.tabLinkKey][tabIndex]) {
- this.removeClass(tabLink, 'formio-tab-link-active');
- }
- if (this.refs[this.tabLikey][tabIndex]) {
- this.removeClass(this.refs[this.tabLikey][tabIndex], 'formio-tab-link-container-active');
- }
- });
- if (this.refs[this.tabLikey][index]) {
- this.addClass(this.refs[this.tabLikey][index], 'formio-tab-link-container-active');
- }
- if (this.refs[this.tabLinkKey][index]) {
- this.addClass(this.refs[this.tabLinkKey][index], 'formio-tab-link-active');
- }
- this.triggerChange();
- }
-
- beforeFocus(component) {
- if ('beforeFocus' in this.parent) {
- this.parent.beforeFocus(this);
- }
- const tabIndex = this.tabs.findIndex((tab) => {
- return tab.some((comp) => comp === component);
- });
- if (tabIndex !== -1 && this.currentTab !== tabIndex) {
- this.setTab(tabIndex);
- }
- }
-
- setErrorClasses(elements, dirty, hasErrors, hasMessages, element = this.element) {
- if (this.component.modalEdit) {
- super.setErrorClasses(elements, dirty, hasErrors, hasMessages, element);
- }
-
- elements.forEach((element) => {
- this.addClass(element, 'is-invalid');
-
- if (element.getAttribute('ref') !== 'openModal') {
- if (this.options.highlightErrors) {
- this.addClass(element, 'tab-error');
- }
- else {
- this.addClass(element, 'has-error');
- }
- }
- });
- }
-
- clearErrorClasses(elements) {
- if (this.options.server || !this.rendered) {
- return;
- }
-
- if (this.component.modalEdit) {
- const element = Array.isArray(elements) || elements instanceof NodeList ? this.element : elements;
- super.clearErrorClasses(element);
- }
-
- elements = Array.isArray(elements) || elements instanceof NodeList ? elements : [elements];
-
- elements.forEach((element) => {
- this.removeClass(element, 'is-invalid');
- this.removeClass(element, 'tab-error');
- this.removeClass(element, 'has-error');
- });
- }
-
- handleTabsValidation() {
- if (!this.refs[this.tabLinkKey] || !this.refs[this.tabLinkKey].length || !this.tabs.length) {
- return;
- }
-
- this.clearErrorClasses(this.refs[this.tabLinkKey]);
-
- const invalidTabsIndexes = this.tabs.reduce((invalidTabs, tab, tabIndex) => {
- const hasComponentWithError = tab.some(comp => !!comp.error);
- return hasComponentWithError ? [...invalidTabs, tabIndex] : invalidTabs;
- }, []);
-
- if (!invalidTabsIndexes.length) {
- return;
- }
-
- const invalidTabs = [...this.refs[this.tabLinkKey]].filter((_, tabIndex) => invalidTabsIndexes.includes(tabIndex));
- this.setErrorClasses(invalidTabs);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.unit.js
deleted file mode 100644
index d395fb87..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tabs/Tabs.unit.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import assert from 'power-assert';
-import Formio from '../../Formio';
-import { comp1 } from './fixtures';
-
-describe('Tabs Component', () => {
- it('Test setting error classes when set to modalEdit', (done) => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, { display: 'form', type: 'form', components: [comp1] }).then((form) => {
- const comp = form.components[0];
-
- const data = {
- textField: '',
- };
-
- form.checkValidity(data, true, data);
-
- setTimeout(() => {
- const openModalWrapper = form.element.querySelector('[ref="openModalWrapper"]');
- assert(openModalWrapper.className.includes('formio-error-wrapper'), 'Should have error class');
- assert(openModalWrapper.className.includes('has-message'), 'Should have class indicating that the component has a message');
-
- const openModalButton = comp.element.querySelector('[ref="openModal"]');
-
- assert(!openModalButton.className.includes('tab-error'), 'Open modal element should not have a tab-error class');
-
- const validData = {
- textField: 'Text',
- };
-
- form.setSubmission({ data: validData });
-
- setTimeout(() => {
- const openModalWrapper = form.element.querySelector('[ref="openModalWrapper"]');
- assert(!openModalWrapper.className.includes('formio-error-wrapper'), 'Should not have error class');
- assert(!openModalWrapper.className.includes('has-message'), 'Should not have class indicating that the component has a message');
-
- done();
- }, 250);
- }, 200);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tabs/editForm/Tabs.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/tabs/editForm/Tabs.edit.display.js
deleted file mode 100644
index 5328daf9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tabs/editForm/Tabs.edit.display.js
+++ /dev/null
@@ -1,66 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- key: 'disabled',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
- {
- key: 'components',
- type: 'datagrid',
- input: true,
- label: 'Tabs',
- weight: 50,
- reorder: true,
- components: [
- {
- type: 'textfield',
- input: true,
- key: 'label',
- label: 'Label'
- },
- {
- type: 'textfield',
- input: true,
- key: 'key',
- label: 'Key',
- allowCalculateOverride: true,
- calculateValue: { _camelCase: [{ var: 'row.label' }] }
- }
- ]
- },
- {
- weight: 1100,
- type: 'checkbox',
- label: 'Vertical Layout',
- tooltip: 'Make this field display in vertical orientation.',
- key: 'verticalLayout',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tabs/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/tabs/fixtures/comp1.js
deleted file mode 100644
index f1b0a431..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tabs/fixtures/comp1.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- label: 'Tabs',
- components: [
- {
- label: 'Tab 1',
- key: 'tab1',
- components: []
- },
- {
- label: 'Tab 2',
- key: 'tab2',
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true
- },
- key: 'textField',
- type: 'textfield',
- input: true
- }
- ]
- }
- ],
- key: 'tabs',
- type: 'tabs',
- input: false,
- tableView: false,
- modalEdit: true,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tabs/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/tabs/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tabs/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.form.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.form.js
deleted file mode 100644
index 40fb75a3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.form.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import Components from '../Components';
-
-import TagsEditData from './editForm/Tags.edit.data';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'data',
- components: TagsEditData
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.js
deleted file mode 100644
index edbbafd6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.js
+++ /dev/null
@@ -1,196 +0,0 @@
-import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
-import Input from '../_classes/input/Input';
-
-let Choices;
-if (typeof window !== 'undefined') {
- Choices = require('@formio/choices.js');
-}
-
-export default class TagsComponent extends Input {
- static schema(...extend) {
- return Input.schema({
- type: 'tags',
- label: 'Tags',
- key: 'tags',
- delimeter: ',',
- storeas: 'string',
- maxTags: 0
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Tags',
- icon: 'tags',
- group: 'advanced',
- documentation: '/userguide/form-building/advanced-components#tags',
- weight: 30,
- schema: TagsComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return TagsComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: [...super.conditionOperatorsSettings.operators, 'includes', 'notIncludes'],
- };
- }
-
- static savedValueTypes(schema) {
- schema = schema || {};
-
- return getComponentSavedTypes(schema) ||[componentValueTypes[schema.storeas] || componentValueTypes.string];
- }
-
- init() {
- super.init();
- }
-
- get emptyValue() {
- return (this.component.storeas === 'string') ? '' : [];
- }
-
- get defaultSchema() {
- return TagsComponent.schema();
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- info.type = 'input';
- info.attr.type = 'text';
- info.changeEvent = 'change';
- return info;
- }
-
- get delimiter() {
- return this.component.delimeter || ',';
- }
-
- attachElement(element, index) {
- super.attachElement(element, index);
- if (!element) {
- return;
- }
- element.setAttribute('dir', this.i18next.dir());
- if (this.choices) {
- this.choices.destroy();
- }
-
- if (!Choices) {
- return;
- }
-
- const hasPlaceholder = !!this.component.placeholder;
-
- this.choices = new Choices(element, {
- delimiter: this.delimiter,
- editItems: true,
- allowHTML: true,
- maxItemCount: this.component.maxTags,
- removeItemButton: true,
- duplicateItemsAllowed: false,
- shadowRoot: this.root ? this.root.shadowRoot : null,
- placeholder: hasPlaceholder,
- placeholderValue: hasPlaceholder ? this.t(this.component.placeholder, { _userInput: true }) : null,
- });
- this.choices.itemList.element.tabIndex = element.tabIndex;
- this.addEventListener(this.choices.input.element, 'blur', () => {
- const value = this.choices.input.value;
- const maxTagsNumber = this.component.maxTags;
- const valuesCount = this.choices.getValue(true).length;
- const isRepeatedValue = this.choices.getValue(true).some(existingValue => existingValue.trim() === value.trim());
-
- if (value) {
- if (maxTagsNumber && valuesCount === maxTagsNumber) {
- this.choices.addItems = false;
- this.choices.clearInput();
- }
- else if (isRepeatedValue) {
- this.choices.clearInput();
- }
- else {
- this.choices.setValue([value]);
- this.choices.clearInput();
- this.choices.hideDropdown(true);
- this.updateValue(null, {
- modified: true
- });
- }
- }
- });
- }
-
- detach() {
- super.detach();
- if (this.choices) {
- this.choices.destroy();
- this.choices = null;
- }
- }
-
- normalizeValue(value) {
- if (this.component.storeas === 'string' && Array.isArray(value)) {
- return value.join(this.delimiter);
- }
- else if (this.component.storeas === 'array' && typeof value === 'string') {
- return value.split(this.delimiter).filter(result => result);
- }
- return value;
- }
-
- setValue(value, flags = {}) {
- const changed = super.setValue(value, flags);
- if (this.choices) {
- let dataValue = this.dataValue;
- this.choices.removeActiveItems();
- if (dataValue) {
- if (typeof dataValue === 'string') {
- dataValue = dataValue.split(this.delimiter).filter(result => result);
- }
- const value = Array.isArray(dataValue) ? dataValue : [dataValue];
- this.choices.setValue(value.map((val) => this.sanitize(val, this.shouldSanitizeValue)));
- }
- }
- return changed;
- }
-
- set disabled(disabled) {
- super.disabled = disabled;
- if (!this.choices) {
- return;
- }
- if (disabled) {
- this.choices.disable();
- }
- else {
- this.choices.enable();
- }
- }
-
- get disabled() {
- return super.disabled;
- }
-
- focus() {
- if (this.refs.input && this.refs.input.length) {
- this.refs.input[0].parentNode.lastChild.focus();
- }
- }
-
- getValueAsString(value) {
- if (!value) {
- return '';
- }
-
- if (Array.isArray(value)) {
- return value.join(`${this.delimiter || ','} `);
- }
-
- const stringValue = value.toString();
- return this.sanitize(stringValue, this.shouldSanitizeValue);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.unit.js
deleted file mode 100644
index 2b7f60ec..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/Tags.unit.js
+++ /dev/null
@@ -1,134 +0,0 @@
-import Harness from '../../../test/harness';
-import TagsComponent from './Tags';
-import assert from 'power-assert';
-import modalTagsComponent from '../../../test/formtest/modalTagsComponent';
-import _ from 'lodash';
-
-import {
- comp1,
- comp2,
- comp3,
- comp4,
- comp5,
-} from './fixtures';
-import Formio from '../../Formio';
-
-describe('Tags Component', function() {
- it('Should build a tags component', function() {
- return Harness.testCreate(TagsComponent, comp1);
- });
-
- it('Should set placeholder', function(done) {
- Harness.testCreate(TagsComponent, comp4).then((component) => {
- assert.equal(component.choices.config.placeholder, true);
- assert.equal(component.choices.config.placeholderValue, component.component.placeholder);
- assert.equal(component.choices.input.element.attributes.placeholder.value, component.component.placeholder);
- done();
- }).catch(done);
- });
-
- it('Should not allow to add non-unique tags on blur', function(done) {
- Harness.testCreate(TagsComponent, comp2).then((component) => {
- const values = ['test', 'test1', 'test'];
- Harness.setTagsValue(values, component);
- assert.equal(component.choices.getValue(true).length, 2);
- done();
- }).catch(done);
- });
-
- it('Should not exceed maxTags limit', function(done) {
- Harness.testCreate(TagsComponent, comp2).then((component) => {
- const values = ['1', '2', '3', '4', '5'];
- Harness.setTagsValue(values, component);
-
- assert.equal(component.choices.getValue(true).length, 4);
- done();
- }).catch(done);
- });
-
- it('Check getValueAsString', (done) => {
- const element = document.createElement('div');
- Formio.createForm(element, modalTagsComponent)
- .then(form => {
- const component = form.getComponent(['tags']);
- const modalWindow = component.componentModal.refs.modalContents;
-
- Harness.setTagsValue(['test', 'test1', 'test2'], component);
- Harness.dispatchEvent('click', modalWindow, '[ref="modalSave"]');
-
- setTimeout(() => {
- const modalPreview = component.element.querySelector('[ref="openModal"]');
- assert.equal(modalPreview.textContent.trim(), 'test, test1, test2', 'All tags should be rendered inside Modal Preview');
- form.destroy();
- done();
- }, 150);
- })
- .catch(done);
- });
-
- it('Should use correct delimiter for value', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].delimeter = '-';
-
- Formio.createForm(element, form).then(form => {
- const tags = form.getComponent('tags');
- const value = ['tag1','tag2', 'tag3'];
-
- tags.setValue(value);
-
- setTimeout(() => {
- assert.equal(tags.getValue(), value.join('-'));
- assert.equal(tags.dataValue, value.join('-'));
- assert.equal(form.submission.data.tags, value.join('-'));
-
- document.innerHTML = '';
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should use store value as array', (done) => {
- const form = _.cloneDeep(comp3);
- const element = document.createElement('div');
- form.components[0].storeas = 'array';
-
- Formio.createForm(element, form).then(form => {
- const tags = form.getComponent('tags');
- const value = ['tag1','tag2', 'tag3'];
-
- tags.setValue(value);
-
- setTimeout(() => {
- assert.deepEqual(tags.getValue(), value.join(','));
- assert.deepEqual(form.submission.data.tags, value);
- assert.equal(tags.dataValue, value);
-
- document.innerHTML = '';
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should show the specified delimiter when get value as string', (done) => {
- const form = _.cloneDeep(comp5);
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const tags = form.getComponent('tags');
- const value = ['tag1', 'tag2', 'tag3'];
-
- tags.setValue(value);
-
- setTimeout(() => {
- assert.deepEqual(tags.getValue(), value.join(tags.component.delimeter));
- assert.deepEqual(form.submission.data.tags, value);
- assert.equal(tags.dataValue, value);
- assert.equal(tags.getValueAsString(value), value.join(`${tags.component.delimeter} `));
-
- document.innerHTML = '';
- done();
- }, 200);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/editForm/Tags.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/editForm/Tags.edit.data.js
deleted file mode 100644
index 0f3fb73f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/editForm/Tags.edit.data.js
+++ /dev/null
@@ -1,37 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true
- },
- {
- weight: 20,
- type: 'textfield',
- input: true,
- key: 'delimeter',
- label: 'Delimiter',
- tooltip: 'What is used to separate the tags.'
- },
- {
- weight: 22,
- type: 'number',
- input: true,
- key: 'maxTags',
- label: 'Max Tags',
- defaultValue: 0,
- tooltip: 'The maximum amount of tags that can be added. 0 for infinity.'
- },
- {
- weight: 24,
- type: 'select',
- input: true,
- key: 'storeas',
- label: 'Store As',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'String (CSV)', value: 'string' },
- { label: 'Array of Tags', value: 'array' }
- ]
- }
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp1.js
deleted file mode 100644
index f339187e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp1.js
+++ /dev/null
@@ -1,20 +0,0 @@
-export default {
- 'input': true,
- 'tableView': false,
- 'label': 'Tags',
- 'key': 'tags',
- 'placeholder': '',
- 'prefix': '',
- 'suffix': '',
- 'protected': true,
- 'persistent': true,
- 'type': 'tags',
- 'tags': [
-
- ],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp2.js
deleted file mode 100644
index b98c3e63..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp2.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default {
- 'label': 'Tags',
- 'tableView': false,
- 'maxTags': 4,
- 'calculateServer': false,
- 'key': 'tags',
- 'type': 'tags',
- 'input': true
-};
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp3.js
deleted file mode 100644
index 4c72da46..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp3.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default {
- type: 'form',
- components: [
- { label: 'Tags', tableView: false, key: 'tags', type: 'tags', input: true },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'test11',
- display: 'form',
- name: 'test11',
- path: 'test11',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp4.js
deleted file mode 100644
index f85c9d1e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp4.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
- label: 'Tags',
- placeholder: 'some text',
- tableView: false,
- key: 'tags',
- type: 'tags',
- input: true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp5.js
deleted file mode 100644
index 0bd18656..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/comp5.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export default {
- 'type': 'form',
- 'display': 'form',
- 'components': [
- {
- 'label': 'Tags',
- 'tableView': true,
- 'delimeter': ';',
- 'storeas': 'array',
- 'key': 'tags',
- 'type': 'tags',
- 'input': true,
- }, {
- 'type': 'button',
- 'label': 'Submit',
- 'key': 'submit',
- 'disableOnInvalid': true,
- 'input': true,
- 'tableView': false,
- },
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/index.js
deleted file mode 100644
index e9a9dd95..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/values.js
deleted file mode 100644
index 1518fab4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tags/fixtures/values.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- 'a, b, c',
- ['a', 'b', 'c'],
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.form.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.form.js
deleted file mode 100644
index b8cf874c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.form.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import textEditForm from '../textfield/TextField.form';
-import TextAreaEditDisplay from './editForm/TextArea.edit.display';
-import TextAreaEditValidation from './editForm/TextArea.edit.validation';
-
-export default function(...extend) {
- return textEditForm([
- {
- key: 'display',
- components: TextAreaEditDisplay
- },
- {
- key: 'validation',
- components: TextAreaEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.js
deleted file mode 100644
index adcb4f33..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.js
+++ /dev/null
@@ -1,615 +0,0 @@
-/* global Quill */
-import TextFieldComponent from '../textfield/TextField';
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-import { uniqueName, getBrowserInfo } from '../../utils/utils';
-
-export default class TextAreaComponent extends TextFieldComponent {
- static schema(...extend) {
- return TextFieldComponent.schema({
- type: 'textarea',
- label: 'Text Area',
- key: 'textArea',
- rows: 3,
- wysiwyg: false,
- editor: '',
- fixedSize: true,
- inputFormat: 'html',
- validate: {
- minWords: '',
- maxWords: ''
- }
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Text Area',
- group: 'basic',
- icon: 'font',
- documentation: '/userguide/form-building/form-components#text-area',
- weight: 20,
- schema: TextAreaComponent.schema()
- };
- }
-
- init() {
- super.init();
- this.editors = [];
- this.editorsReady = [];
- this.updateSizes = [];
-
- // Never submit on enter for text areas.
- this.options.submitOnEnter = false;
- }
-
- get defaultSchema() {
- return TextAreaComponent.schema();
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- info.type = this.component.wysiwyg ? 'div' : 'textarea';
- if (this.component.rows) {
- info.attr.rows = this.component.rows;
- }
- return info;
- }
-
- validateMultiple() {
- return !this.isJsonValue;
- }
-
- renderElement(value, index) {
- const info = this.inputInfo;
- info.attr = info.attr || {};
- info.content = value;
- if ((this.options.readOnly || this.disabled) && !this.isHtmlRenderMode()) {
- const elementStyle = this.info.attr.style || '';
- const children = `
`;
-
- return this.renderTemplate('well', {
- children,
- nestedKey: this.key,
- value
- });
- }
-
- return this.renderTemplate('input', {
- prefix: this.prefix,
- suffix: this.suffix,
- input: info,
- value,
- index
- });
- }
-
- get autoExpand() {
- return this.component.autoExpand;
- }
-
- /**
- * Updates the editor value.
- *
- * @param newValue
- */
- updateEditorValue(index, newValue) {
- newValue = this.getConvertedValue(this.trimBlanks(newValue));
- const dataValue = this.dataValue;
- if (this.component.multiple && Array.isArray(dataValue)) {
- const newArray = _.clone(dataValue);
- newArray[index] = newValue;
- newValue = newArray;
- }
-
- if ((!_.isEqual(newValue, dataValue)) && (!_.isEmpty(newValue) || !_.isEmpty(dataValue))) {
- this.updateValue(newValue, {
- modified: !this.autoModified
- }, index);
- }
- this.autoModified = false;
- }
-
- attachElement(element, index) {
- if (this.autoExpand && (this.isPlain || this.options.readOnly || this.options.htmlView)) {
- if (element.nodeName === 'TEXTAREA') {
- this.addAutoExpanding(element, index);
- }
- }
-
- if (this.options.readOnly) {
- return element;
- }
-
- if (this.component.wysiwyg && !this.component.editor) {
- this.component.editor = 'ckeditor';
- }
-
- let settings = _.isEmpty(this.component.wysiwyg) ?
- this.wysiwygDefault[this.component.editor] || this.wysiwygDefault.default
- : this.component.wysiwyg;
-
- // Keep track of when this editor is ready.
- this.editorsReady[index] = new NativePromise((editorReady) => {
- // Attempt to add a wysiwyg editor. In order to add one, it must be included on the global scope.
- switch (this.component.editor) {
- case 'ace':
- if (!settings) {
- settings = {};
- }
- settings.mode = this.component.as ? `ace/mode/${this.component.as}` : 'ace/mode/javascript';
- this.addAce(element, settings, (newValue) => this.updateEditorValue(index, newValue)).then((ace) => {
- this.editors[index] = ace;
- let dataValue = this.dataValue;
- dataValue = (this.component.multiple && Array.isArray(dataValue)) ? dataValue[index] : dataValue;
- ace.setValue(this.setConvertedValue(dataValue, index));
- editorReady(ace);
- return ace;
- }).catch(err => console.warn(err));
- break;
- case 'quill':
- // Normalize the configurations for quill.
- if (settings.hasOwnProperty('toolbarGroups') || settings.hasOwnProperty('toolbar')) {
- console.warn('The WYSIWYG settings are configured for CKEditor. For this renderer, you will need to use configurations for the Quill Editor. See https://quilljs.com/docs/configuration for more information.');
- settings = this.wysiwygDefault.quill;
- }
-
- // Add the quill editor.
- this.addQuill(
- element,
- settings, () => this.updateEditorValue(index, this.editors[index].root.innerHTML)
- ).then((quill) => {
- this.editors[index] = quill;
- if (this.component.isUploadEnabled) {
- const _this = this;
- quill.getModule('uploader').options.handler = function(...args) {
- //we need initial 'this' because quill calls this method with its own context and we need some inner quill methods exposed in it
- //we also need current component instance as we use some fields and methods from it as well
- _this.imageHandler.call(_this, this, ...args);
- };
- }
- quill.root.spellcheck = this.component.spellcheck;
- if (this.options.readOnly || this.disabled) {
- quill.disable();
- }
-
- let dataValue = this.dataValue;
- dataValue = (this.component.multiple && Array.isArray(dataValue)) ? dataValue[index] : dataValue;
- quill.setContents(quill.clipboard.convert({ html: this.setConvertedValue(dataValue, index) }));
- editorReady(quill);
- return quill;
- }).catch(err => console.warn(err));
- break;
- case 'ckeditor':
- settings = settings || {};
- settings.rows = this.component.rows;
- this.addCKE(element, settings, (newValue) => this.updateEditorValue(index, newValue))
- .then((editor) => {
- this.editors[index] = editor;
- let dataValue = this.dataValue;
- dataValue = (this.component.multiple && Array.isArray(dataValue)) ? dataValue[index] : dataValue;
- const value = this.setConvertedValue(dataValue, index);
- const isReadOnly = this.options.readOnly || this.disabled;
- // Use ckeditor 4 in IE browser
- if (getBrowserInfo().ie) {
- editor.on('instanceReady', () => {
- editor.setReadOnly(isReadOnly);
- editor.setData(value);
- });
- }
- else {
- const numRows = parseInt(this.component.rows, 10);
-
- if (_.isFinite(numRows) && _.has(editor, 'ui.view.editable.editableElement')) {
- // Default height is 21px with 10px margin + a 14px top margin.
- const editorHeight = (numRows * 31) + 14;
- editor.ui.view.editable.editableElement.style.height = `${(editorHeight)}px`;
- }
- editor.isReadOnly = isReadOnly;
- editor.data.set(value);
- }
-
- editorReady(editor);
- return editor;
- });
- break;
- default:
- super.attachElement(element, index);
- break;
- }
- });
-
- return element;
- }
-
- attach(element) {
- const attached = super.attach(element);
- // Make sure we restore the value after attaching since wysiwygs and readonly texts need an additional set.
- this.restoreValue();
- return attached;
- }
-
- imageHandler(moduleInstance, range, files) {
- const quillInstance = moduleInstance.quill;
-
- if (!files || !files.length) {
- console.warn('No files selected');
- return;
- }
-
- quillInstance.enable(false);
- const { uploadStorage, uploadUrl, uploadOptions, uploadDir, fileKey } = this.component;
- let requestData;
- this.fileService
- .uploadFile(
- uploadStorage,
- files[0],
- uniqueName(files[0].name),
- uploadDir || '', //should pass empty string if undefined
- null,
- uploadUrl,
- uploadOptions,
- fileKey
- )
- .then(result => {
- requestData = result;
- return this.fileService.downloadFile(result);
- })
- .then(result => {
- quillInstance.enable(true);
- const Delta = Quill.import('delta');
- quillInstance.updateContents(new Delta()
- .retain(range.index)
- .delete(range.length)
- .insert(
- {
- image: result.url
- },
- {
- alt: JSON.stringify(requestData),
- })
- , Quill.sources.USER);
- }).catch(error => {
- console.warn('Quill image upload failed');
- console.warn(error);
- quillInstance.enable(true);
- });
- }
-
- get isPlain() {
- return (!this.component.wysiwyg && !this.component.editor);
- }
-
- get htmlView() {
- return this.options.readOnly && (this.component.editor || this.component.wysiwyg);
- }
-
- setValueAt(index, value, flags = {}) {
- super.setValueAt(index, value, flags);
-
- if (this.editorsReady[index]) {
- const setEditorsValue = (flags) => (editor) => {
- if (!flags.skipWysiwyg) {
- this.autoModified = true;
- switch (this.component.editor) {
- case 'ace':
- editor.setValue(this.setConvertedValue(value, index));
- break;
- case 'quill':
- if (this.component.isUploadEnabled) {
- this.setAsyncConvertedValue(value)
- .then(result => {
- const content = editor.clipboard.convert({ html: result });
- editor.setContents(content);
- });
- }
- else {
- const convertedValue = this.setConvertedValue(value, index);
- const content = editor.clipboard.convert({ html: convertedValue });
- editor.setContents(content);
- }
- break;
- case 'ckeditor':
- editor.data.set(this.setConvertedValue(value, index));
- break;
- }
- }
- };
-
- this.editorsReady[index].then(setEditorsValue(_.clone(flags)));
- }
- }
-
- setValue(value, flags = {}) {
- if (this.isPlain || this.options.readOnly || this.disabled) {
- value = (this.component.multiple && Array.isArray(value)) ?
- value.map((val, index) => this.setConvertedValue(val, index)) :
- this.setConvertedValue(value);
- return super.setValue(value, flags);
- }
- flags.skipWysiwyg = value === '' && flags.resetValue ? false : _.isEqual(value, this.getValue());
- return super.setValue(value, flags);
- }
-
- setContent(element, content, forceSanitize) {
- super.setContent(element, content, forceSanitize, {
- addAttr: ['allow', 'allowfullscreen', 'frameborder', 'scrolling'],
- addTags: ['iframe'],
- });
- }
-
- setReadOnlyValue(value, index) {
- index = index || 0;
- if (this.options.readOnly || this.disabled) {
- if (this.refs.input && this.refs.input[index]) {
- if (this.component.inputFormat === 'plain') {
- this.refs.input[index].innerText = this.isPlain ? value : this.interpolate(value, {}, { noeval: true });
- }
- else {
- this.setContent(this.refs.input[index], this.isPlain ? value : this.interpolate(value, {}, { noeval: true }), this.shouldSanitizeValue);
- }
- }
- }
- }
-
- get isJsonValue() {
- return this.component.as && this.component.as === 'json';
- }
-
- setConvertedValue(value, index) {
- if (this.isJsonValue && !_.isNil(value)) {
- try {
- value = JSON.stringify(value, null, 2);
- }
- catch (err) {
- console.warn(err);
- }
- }
-
- if (!_.isString(value)) {
- value = '';
- }
-
- this.setReadOnlyValue(value, index);
- return value;
- }
-
- setAsyncConvertedValue(value) {
- if (this.isJsonValue && value) {
- try {
- value = JSON.stringify(value, null, 2);
- }
- catch (err) {
- console.warn(err);
- }
- }
-
- if (!_.isString(value)) {
- value = '';
- }
-
- const htmlDoc = new DOMParser().parseFromString(value,'text/html');
- const images = htmlDoc.getElementsByTagName('img');
- if (images.length) {
- return this.setImagesUrl(images)
- .then( () => {
- value = htmlDoc.getElementsByTagName('body')[0].innerHTML;
- return value;
- });
- }
- else {
- return NativePromise.resolve(value);
- }
- }
-
- setImagesUrl(images) {
- return NativePromise.all(_.map(images, image => {
- let requestData;
- try {
- requestData = JSON.parse(image.getAttribute('alt'));
- }
- catch (error) {
- console.warn(error);
- }
-
- return this.fileService.downloadFile(requestData)
- .then((result) => {
- image.setAttribute('src', result.url);
- });
- }));
- }
-
- addAutoExpanding(textarea, index) {
- let heightOffset = null;
- let previousHeight = null;
-
- const changeOverflow = (value) => {
- const width = textarea.style.width;
-
- textarea.style.width = '0px';
- textarea.offsetWidth;
- textarea.style.width = width;
-
- textarea.style.overflowY = value;
- };
-
- const preventParentScroll = (element, changeSize) => {
- const nodeScrolls = [];
-
- while (element && element.parentNode && element.parentNode instanceof Element) {
- if (element.parentNode.scrollTop) {
- nodeScrolls.push({
- node: element.parentNode,
- scrollTop: element.parentNode.scrollTop,
- });
- }
- element = element.parentNode;
- }
-
- changeSize();
-
- nodeScrolls.forEach((nodeScroll) => {
- nodeScroll.node.scrollTop = nodeScroll.scrollTop;
- });
- };
-
- const resize = () => {
- if (textarea.scrollHeight === 0) {
- return;
- }
-
- preventParentScroll(textarea, () => {
- textarea.style.height = '';
- textarea.style.height = `${textarea.scrollHeight + heightOffset}px`;
- });
- };
-
- const update = _.debounce(() => {
- resize();
- const styleHeight = Math.round(parseFloat(textarea.style.height));
- const computed = window.getComputedStyle(textarea, null);
- let currentHeight = textarea.offsetHeight;
- if (currentHeight < styleHeight && computed.overflowY === 'hidden') {
- changeOverflow('scroll');
- }
- else if (computed.overflowY !== 'hidden') {
- changeOverflow('hidden');
- }
-
- resize();
- currentHeight = textarea.offsetHeight;
- if (previousHeight !== currentHeight) {
- previousHeight = currentHeight;
- update();
- }
- }, 200);
- const computedStyle = window.getComputedStyle(textarea, null);
-
- textarea.style.resize = 'none';
- heightOffset = parseFloat(computedStyle.borderTopWidth) + parseFloat(computedStyle.borderBottomWidth) || 0;
-
- if (window) {
- this.addEventListener(window, 'resize', update);
- }
-
- this.addEventListener(textarea, 'input', update);
- this.on('initialized', update);
- this.updateSizes[index] = update;
- update();
- }
-
- trimBlanks(value) {
- if (!value || this.isPlain) {
- return value;
- }
-
- const trimBlanks = (value) => {
- const nbsp = '
';
- const br = '
';
- const brNbsp = '
';
- const regExp = new RegExp(`^${nbsp}|${nbsp}$|^${br}|${br}$|^${brNbsp}|${brNbsp}$`, 'g');
- return typeof value === 'string' ? value.replace(regExp, '') : value;
- };
-
- if (Array.isArray(value)) {
- value.forEach((input, index) => {
- value[index] = trimBlanks(input);
- });
- }
- else {
- value = trimBlanks(value);
- }
- return value;
- }
-
- onChange(flags, fromRoot) {
- const changed = super.onChange(flags, fromRoot);
- this.updateSizes.forEach(updateSize => updateSize());
- return changed;
- }
-
- hasChanged(newValue, oldValue) {
- return super.hasChanged(this.trimBlanks(newValue), this.trimBlanks(oldValue));
- }
-
- isEmpty(value = this.dataValue) {
- return super.isEmpty(this.trimBlanks(value));
- }
-
- get defaultValue() {
- let defaultValue = super.defaultValue;
- if (this.component.editor === 'quill' && !defaultValue) {
- defaultValue = '
';
- }
- return defaultValue;
- }
-
- getConvertedValue(value) {
- if (this.isJsonValue && value) {
- try {
- value = JSON.parse(value);
- }
- catch (err) {
- // console.warn(err);
- }
- }
- return value;
- }
-
- detach() {
- // Destroy all editors.
- this.editors.forEach(editor => {
- if (editor.destroy) {
- editor.destroy();
- }
- });
- this.editors = [];
- this.editorsReady = [];
- this.updateSizes.forEach(updateSize => this.removeEventListener(window, 'resize', updateSize));
- this.updateSizes = [];
- super.detach();
- }
-
- getValue() {
- if (this.isPlain) {
- return this.getConvertedValue(super.getValue());
- }
-
- return this.dataValue;
- }
-
- focus() {
- super.focus();
- switch (this.component.editor) {
- case 'ckeditor': {
- // Wait for the editor to be ready.
- this.editorsReady[0]?.then(() => {
- if (this.editors[0].editing?.view?.focus) {
- this.editors[0].editing.view.focus();
- }
- this.element.scrollIntoView();
- }).catch((err) => {
- console.warn('An editor did not initialize properly when trying to focus:', err);
- });
- break;
- }
- case 'ace': {
- this.editorsReady[0]?.then(() => {
- this.editors[0].focus();
- this.element.scrollIntoView();
- }).catch((err) => {
- console.warn('An editor did not initialize properly when trying to focus:', err);
- });
- break;
- }
- case 'quill': {
- this.editorsReady[0]?.then(() => {
- this.editors[0].focus();
- }).catch((err) => {
- console.warn('An editor did not initialize properly when trying to focus:', err);
- });
- break;
- }
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.unit.js
deleted file mode 100644
index 51ee4407..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/TextArea.unit.js
+++ /dev/null
@@ -1,532 +0,0 @@
-import { expect } from 'chai';
-import _ from 'lodash';
-import assert from 'power-assert';
-import sinon from 'sinon';
-import formWithCKEditor from '../../../test/forms/formWithCKEditor';
-import formWithRichTextAreas from '../../../test/forms/formWithRichTextAreas';
-import Harness from '../../../test/harness';
-import Formio from '../../Formio';
-import { comp1, comp2, comp3, comp4 } from './fixtures';
-import TextAreaComponent from './TextArea';
-import 'ace-builds';
-
-describe('TextArea Component', () => {
- it('Should build a TextArea component', () => {
- return Harness.testCreate(TextAreaComponent, comp1).then((component) => {
- Harness.testElements(component, 'textarea', 1);
- });
- });
-
- it('setValue should be called only once', () => {
- return Harness.testCreate(TextAreaComponent, comp2).then((component) => {
- const valueToSet = [
- {
- firstName: 'Bobby',
- lastName: 'Lynch'
- },
- {
- firstName: 'Harold',
- lastName: 'Freeman'
- },
- ];
- const emit = sinon.spy(component, 'setValue');
- component.setValue(valueToSet);
- expect(component.getValue()).to.deep.equal([
- {
- firstName: 'Bobby',
- lastName: 'Lynch'
- },
- {
- firstName: 'Harold',
- lastName: 'Freeman'
- }
- ]);
- expect(emit.callCount).to.equal(1);
- });
- });
-
- it('Should provide min/max length validation', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].validate = { minLength: 5, maxLength: 10 };
-
- const validValues = [
- '',
- 'te_st',
- 'test value',
- ' ',
- 'What?',
- 'test: ',
- 't ',
- ' t '
- ];
-
- const invalidMin = [
- 't',
- 'tt',
- 'ttt',
- 'tttt',
- ' t ',
- ' t',
- '_4_'
- ];
-
- const invalidMax = [
- 'test__value',
- 'test value ',
- ' test value',
- 'test: value',
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textArea');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidMin, false, 'Text Area must have at least 5 characters.');
- testValidity(invalidMax, false, 'Text Area must have no more than 10 characters.', invalidMax[invalidMax.length-1]);
- });
-
- it('Should provide min/max words validation', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].validate = { minWords: 2, maxWords: 5 };
-
- const validValues = [
- '',
- 'test value',
- 'some, test value',
- 'some - test - value',
- ' value value value value value ',
- ' What ?',
- '" test "',
- ];
-
- const invalidMin = [
- ' t ',
- '? ',
- 'e',
- '_test ',
- ' 9',
- 't ',
- 'What?',
- '"4"'
- ];
-
- const invalidMax = [
- 'te st __ va lue ""',
- '" te st va lue "',
- '11 - 22 - 33 - 44',
- 'te st : va lue :',
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textArea');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidMin, false, 'Text Area must have at least 2 words.');
- testValidity(invalidMax, false, 'Text Area must have no more than 5 words.', invalidMax[invalidMax.length-1]);
- });
-
- it('Should provide pattern validation', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].validate = { pattern: '\\D+' };
-
- const validValues = [
- '',
- ' ',
- 'test value',
- '& "" (test) _ ,.*',
- ' some - test - value ',
- ];
-
- const invalidValues = [
- 'test(2)',
- '123',
- '0 waste',
- '"9"',
- ' 9',
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textArea');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message.trim(), error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues,
- false,
- 'Text Area does not match the pattern \\D+',
- invalidValues[invalidValues.length-1]
- );
- });
-
- it('Should set custom number of rows', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].rows = 5;
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textArea');
- assert.equal(component.refs.input[0].rows, component.component.rows, 'Should set custom number of rows');
-
- done();
- }).catch(done);
- });
-
- it('Should render HTML', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].inputFormat = 'html';
- const element = document.createElement('div');
-
- Formio.createForm(element, form, {
- readOnly: true
- }).then(form => {
- form.setSubmission({
- data: {
- textArea: 'HTML! '
- }
- });
- setTimeout(() => {
- const textArea = form.getComponent('textArea');
- assert.equal(textArea.refs.input[0].innerHTML, 'HTML! ');
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should render plain text', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].inputFormat = 'plain';
- const element = document.createElement('div');
-
- Formio.createForm(element, form, {
- readOnly: true
- }).then(form => {
- form.setSubmission({
- data: {
- textArea: 'Plain text! '
- }
- });
- setTimeout(() => {
- const textArea = form.getComponent('textArea');
- assert.equal(textArea.refs.input[0].innerText, 'Plain text! ');
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should correctly count characters if character counter is enabled', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].showCharCount = true;
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textArea');
- const inputValue = (value) => {
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value;
- input.dispatchEvent(inputEvent);
- };
-
- const checkValue = (value) => {
- assert.equal(component.dataValue, value, 'Should set value');
- assert.equal(parseInt(component.refs.charcount[0].textContent), value.length, 'Should show correct chars number');
- assert.equal(component.refs.charcount[0].textContent, `${value.length} characters`, 'Should show correct message');
- };
-
- let value = 'test Value (@#!-"]) _ 23.,5}/*&&';
- inputValue(value);
- setTimeout(() => {
- checkValue(value);
- value = '';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value);
- value = ' ';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value);
-
- done();
- }, 200);
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should correctly count words if word counter is enabled', (done) => {
- const form = _.cloneDeep(comp3);
- form.components[0].showWordCount = true;
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textArea');
- const inputValue = (value) => {
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value;
- input.dispatchEvent(inputEvent);
- };
-
- const checkValue = (value, expected) => {
- assert.equal(component.dataValue, value, 'Should set value');
- assert.equal(parseInt(component.refs.wordcount[0].textContent), expected, 'Should show correct words number');
- assert.equal(component.refs.wordcount[0].textContent, `${expected} words`, 'Should show correct message');
- };
-
- let value = 'test , test_test 11 - "so me"';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value, 7);
- value = ' test ';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value, 1);
- value = ' . . ';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value, 2);
-
- done();
- }, 200);
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- describe('Rich text editors', () => {
- describe('CKEditor', () => {
- it('Should allow to insert media fiels and show the in them read-only mode', (done) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, formWithCKEditor, { readOnly: true }).then(form => {
- form.submission = {
- data: {
- textArea: `
-
-
-
-
-
- `,
- },
- state: 'submitted',
- };
-
- setTimeout(() => {
- const mediaA = form.element.querySelector('iframe[src="https://www.youtube.com/embed/GsLRrmnJXF8"]');
- const mediaB = form.element.querySelector('iframe[src="https://www.youtube.com/embed/FmA6U5rXl38"]');
- assert(mediaA, 'Should not remove embedded media');
- assert(mediaB, 'Should not remove embedded media');
-
- done();
- }, 300);
- }).catch(done);
- });
- });
-
- it('Should clear value in the editor on Reset', (done) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, formWithRichTextAreas).then(form => {
- form.setValue({
- data: {
- textArea: 'Test',
- textAreaAce: 'Test',
- },
- });
-
- setTimeout(() => {
- const plainTextArea = form.getComponent(['textArea']);
- const aceTextArea = form.getComponent(['textAreaAce']);
-
- const textAreaElement = plainTextArea.element.querySelector('textarea');
- console.log(aceTextArea.editors);
- const aceEditor = aceTextArea.editors[0];
-
- // Make sure value is set to the components
- assert.equal(plainTextArea.dataValue, 'Test');
- assert.equal(aceTextArea.dataValue, 'Test');
-
- // Make sure value is set to the editors/elements
- assert.equal(textAreaElement.value, 'Test');
- assert.equal(aceEditor.getValue(), 'Test');
-
- form.resetValue();
-
- setTimeout(() => {
- // Make sure value is cleared on the components
- assert.equal(plainTextArea.dataValue, '');
- assert.equal(aceTextArea.dataValue, '');
-
- // Make sure value is cleared in the editors/elements
- assert.equal(textAreaElement.value, '');
- assert.equal(aceEditor.getValue(), '');
- done();
- }, 300);
- }, 500);
- }).catch(done);
- });
-
- it('Should set empty value properly when save as JSON', (done) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, comp4).then(form => {
- const aceTextArea = form.getComponent(['jsonTextarea']);
- assert.equal(aceTextArea.data.jsonTextarea, '', 'The value should be empty');
- done();
- }).catch(done);
- });
-
- it('Should not autofocus until the editor is ready', (done) => {
- const element = document.createElement('div');
- const testComponents = [
- {
- type: 'textarea',
- autofocus: true,
- editor: 'ckeditor',
- key: 'textArea',
- label: 'Text Area',
- input: true,
- }
- ];
- const testForm = { ...formWithCKEditor, components: testComponents };
-
- Formio.createForm(element, testForm).then(form => {
- const textArea = form.getComponent('textArea');
- // since prior to this fix the focus function will throw, we'll make sure it doesn't
- expect(textArea.focus.bind(textArea)).to.not.throw();
-
- done();
- }).catch(done);
- });
-
- it('Should not autofocus if the form is readOnly', (done) => {
- const element = document.createElement('div');
- const testComponents = [
- {
- type: 'textarea',
- autofocus: true,
- editor: 'ckeditor',
- key: 'textArea',
- label: 'Text Area',
- input: true,
- }
- ];
- const testForm = { ...formWithCKEditor, components: testComponents };
-
- Formio.createForm(element, testForm, { readOnly: true }).then(form => {
- const textArea = form.getComponent('textArea');
- // since prior to this fix the focus function will throw if readOnly, we'll make sure it doesn't
- expect(textArea.focus.bind(textArea)).to.not.throw();
-
- done();
- }).catch(done);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/editForm/TextArea.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/editForm/TextArea.edit.display.js
deleted file mode 100644
index a24ac111..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/editForm/TextArea.edit.display.js
+++ /dev/null
@@ -1,259 +0,0 @@
-import _ from 'lodash';
-import { GlobalFormio as Formio } from '../../../Formio';
-
-export default [
- {
- key: 'inputMask',
- ignore: true
- },
- {
- key: 'allowMultipleMasks',
- ignore: true
- },
- {
- key: 'mask',
- ignore: true
- },
- {
- type: 'number',
- input: true,
- key: 'rows',
- label: 'Rows',
- weight: 210,
- tooltip: 'This allows control over how many rows are visible in the text area.',
- placeholder: 'Enter the amount of rows'
- },
- {
- weight: 1350,
- type: 'checkbox',
- input: true,
- key: 'spellcheck',
- defaultValue: true,
- label: 'Allow Spellcheck'
- },
- {
- type: 'select',
- input: true,
- key: 'editor',
- label: 'Editor',
- tooltip: 'Select the type of WYSIWYG editor to use for this text area.',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'None', value: '' },
- { label: 'ACE', value: 'ace' },
- { label: 'CKEditor', value: 'ckeditor' },
- { label: 'Quill', value: 'quill' },
- ]
- },
- weight: 415
- },
- {
- type: 'checkbox',
- input: true,
- key: 'autoExpand',
- label: 'Auto Expand',
- tooltip: 'This will make the TextArea auto expand it\'s height as the user is typing into the area.',
- weight: 415,
- conditional: {
- json: {
- '==': [
- { var: 'data.editor' },
- ''
- ]
- }
- }
- },
- {
- type: 'checkbox',
- input: true,
- key: 'isUploadEnabled',
- label: 'Enable Image Upload',
- weight: 415.1,
- conditional: {
- json: {
- or: [
- {
- '===': [
- { var: 'data.editor' },
- 'quill'
- ],
- },
- {
- '===': [
- { var: 'data.editor' },
- 'ckeditor'
- ],
- }
- ]
- }
- }
- },
- {
- type: 'select',
- input: true,
- key: 'uploadStorage',
- label: 'Image Upload Storage',
- placeholder: 'Select your file storage provider',
- weight: 415.2,
- tooltip: 'Which storage to save the files in.',
- valueProperty: 'value',
- dataSrc: 'custom',
- data: {
- custom() {
- return _.map(Formio.Providers.getProviders('storage'), (storage, key) => ({
- label: storage.title,
- value: key
- }));
- }
- },
- conditional: {
- json: {
- '===': [
- { var: 'data.isUploadEnabled' },
- true
- ]
- }
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'uploadUrl',
- label: 'Image Upload Url',
- weight: 415.3,
- placeholder: 'Enter the url to post the files to.',
- tooltip: 'See https://github.com/danialfarid/ng-file-upload#server-side for how to set up the server.',
- conditional: {
- json: { '===': [{ var: 'data.uploadStorage' }, 'url'] }
- }
- },
- {
- type: 'textarea',
- key: 'uploadOptions',
- label: 'Image Upload Custom request options',
- tooltip: 'Pass your custom xhr options(optional)',
- rows: 5,
- editor: 'ace',
- input: true,
- weight: 415.4,
- placeholder: `{
- "withCredentials": true
- }`,
- conditional: {
- json: {
- '===': [{
- var: 'data.uploadStorage'
- }, 'url']
- }
- }
- },
- {
- type: 'textfield',
- input: true,
- key: 'uploadDir',
- label: 'Image Upload Directory',
- placeholder: '(optional) Enter a directory for the files',
- tooltip: 'This will place all the files uploaded in this field in the directory',
- weight: 415.5,
- conditional: {
- json: {
- '===': [
- { var: 'data.isUploadEnabled' },
- true
- ]
- }
- }
- },
- {
- type: 'textfield',
- key: 'fileKey',
- input: true,
- label: 'File form-data Key',
- tooltip: 'Key name that you would like to modify for the file while calling API request.',
- rows: 5,
- weight: 415.6,
- placeholder: 'Enter the key name of a file for form data.',
- conditional: {
- json: {
- and: [
- { '===': [
- { var: 'data.editor' },
- 'quill'
- ] },
- { '===': [
- { var: 'data.isUploadEnabled' },
- true
- ] },
- { '===': [
- { var: 'data.uploadStorage' },
- 'url'
- ] },
- ]
- }
- }
- },
- {
- type: 'select',
- input: true,
- key: 'as',
- label: 'Save As',
- dataSrc: 'values',
- tooltip: 'This setting determines how the value should be entered and stored in the database.',
- clearOnHide: true,
- data: {
- values: [
- { label: 'String', value: 'string' },
- { label: 'JSON', value: 'json' },
- { label: 'HTML', value: 'html' }
- ]
- },
- conditional: {
- json: {
- or: [
- { '===': [
- { var: 'data.editor' },
- 'quill'
- ] },
- { '===': [
- { var: 'data.editor' },
- 'ace'
- ] }
- ]
- }
- },
- weight: 416
- },
- {
- type: 'textarea',
- input: true,
- editor: 'ace',
- rows: 10,
- as: 'json',
- label: 'Editor Settings',
- tooltip: 'Enter the WYSIWYG editor JSON configuration.',
- key: 'wysiwyg',
- customDefaultValue(value, component, row, data, instance) {
- return instance ? instance.wysiwygDefault : '';
- },
- conditional: {
- json: {
- or: [
- { '===': [
- { var: 'data.editor' },
- 'ace'
- ] },
- { '===': [
- { var: 'data.editor' },
- 'ckeditor'
- ] },
- { '===': [
- { var: 'data.editor' },
- 'quill'
- ] },
- ]
- }
- },
- weight: 417
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/editForm/TextArea.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/editForm/TextArea.edit.validation.js
deleted file mode 100644
index 9261c911..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/editForm/TextArea.edit.validation.js
+++ /dev/null
@@ -1,20 +0,0 @@
-export default [
- {
- weight: 125,
- key: 'validate.minWords',
- label: 'Minimum Word Length',
- placeholder: 'Minimum Word Length',
- type: 'number',
- tooltip: 'The minimum amount of words that can be added to this field.',
- input: true
- },
- {
- weight: 126,
- key: 'validate.maxWords',
- label: 'Maximum Word Length',
- placeholder: 'Maximum Word Length',
- type: 'number',
- tooltip: 'The maximum amount of words that can be added to this field.',
- input: true
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp1.js
deleted file mode 100644
index 9c903885..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp1.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'textarea',
- 'validate': {
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'wysiwyg': false,
- 'persistent': true,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'rows': 3,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': 'Enter your message here',
- 'key': 'message',
- 'label': 'Message',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp2.js
deleted file mode 100644
index 7a66bef9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp2.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default {
- 'tags': [],
- 'type': 'textarea',
- 'validate': {
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'wysiwyg': false,
- 'persistent': true,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'rows': 3,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'textArea',
- 'label': 'Text Area',
- 'editor': 'ace',
- 'as': 'json',
- 'tableView': true,
- 'spellcheck': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp3.js
deleted file mode 100644
index 51da8fa9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp3.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Text Area',
- autoExpand: false,
- tableView: true,
- key: 'textArea',
- type: 'textarea',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- revisions: '',
- _vid: 0,
- title: 'text area tests',
- display: 'form',
- name: 'textAriaTests',
- path: 'textAriaTests',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp4.js
deleted file mode 100644
index 35df665c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/comp4.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- type: 'textarea',
- key: 'jsonTextarea',
- rows: 5,
- editor: 'ace',
- hideLabel: true,
- as: 'json',
- input: true
- },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'text area tests',
- display: 'form',
- name: 'textAriaTests',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/index.js
deleted file mode 100644
index 6664cb89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/values.js
deleted file mode 100644
index bd7aa8d2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textarea/fixtures/values.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default [
- 'asdf
',
- 'foobar
',
-];
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.builder.spec.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.builder.spec.js
deleted file mode 100644
index 757b40db..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.builder.spec.js
+++ /dev/null
@@ -1,147 +0,0 @@
-import Harness from '../../../test/harness';
-import EventEmitter from '../../EventEmitter';
-import assert from 'power-assert';
-
-describe('TextField Builder', () => {
- let builder = null;
-
- before((done) => {
- // Incrise Events limit for this tests set
- Harness.builderBefore(done, {
- editForm: {
- events: new EventEmitter()
- }
- });
- });
- after(() => {
- Harness.builderAfter();
- });
-
- it('Should create a new textfield component', () => {
- builder = Harness.buildComponent('textfield');
- return builder.editForm.formReady.then(() => {
- // Make sure default preview is correct.
- const preview = builder.componentPreview.innerHTML;
- assert(preview.indexOf('formio-component formio-component-textfield formio-component-textField') !== -1, 'Must have correct classes');
- assert(preview.indexOf('Text Field ') !== -1, 'Must have a label');
- assert(preview.indexOf(' {
- Harness.setComponentProperty('label', 'Text Field', 'First Name', (preview) => {
- assert(preview.match(/label.*input/), 'Label must be on top.');
- assert(preview.indexOf('First Name ') !== -1, 'Must have a label');
- done();
- });
- });
-
- it('Should allow you to hide/show the label', (done) => {
- Harness.setComponentProperty('hideLabel', false, true, (preview) => {
- assert(preview.indexOf(' {
- assert(preview.indexOf(' {
- Harness.setComponentProperty('labelPosition', 'top', 'bottom', (preview) => {
- assert(preview.match(/input.*label/), 'Label must be on bottom.');
- Harness.setComponentProperty('labelPosition', 'bottom', 'left-left', (preview) => {
- assert(preview.match(/label.*style=".*float: left; width: 30%; margin-right: 3%;.*input/), 'Label must be positioned on the left floated left');
- Harness.setComponentProperty('labelPosition', 'left-left', 'left-right', (preview) => {
- assert(preview.match(/label.*style=".*float: left; width: 30%; margin-right: 3%; text-align: right;.*input/), 'Label must be positioned on the left floated right');
- Harness.setComponentProperty('labelPosition', 'left-right', 'right-left', (preview) => {
- assert(preview.match(/label.*style=".*float: right; width: 30%; margin-left: 3%;.*input/), 'Label must be positioned on the right floated left');
- Harness.setComponentProperty('labelPosition', 'right-left', 'right-right', (preview) => {
- assert(preview.match(/label.*style=".*float: right; width: 30%; margin-left: 3%; text-align: right;.*input/), 'Label must be positioned on the right floated right');
- done();
- });
- });
- });
- });
- });
- });
-
- it('Should allow you to change the label width and margin', (done) => {
- Harness.setComponentProperty('labelPosition', 'right-right', 'top', () => {
- Harness.testVisibility(builder.editForm, '.formio-component-labelWidth', false);
- Harness.testVisibility(builder.editForm, '.formio-component-labelMargin', false);
- Harness.setComponentProperty('labelPosition', 'top', 'left-left', () => {
- Harness.testVisibility(builder.editForm, '.formio-component-labelWidth', true);
- Harness.testVisibility(builder.editForm, '.formio-component-labelMargin', true);
- Harness.setComponentProperty('labelWidth', 30, 20, () => {
- Harness.setComponentProperty('labelMargin', 3, 5, (preview) => {
- assert(preview.match(/label.*style=".*float: left; width: 20%; margin-right: 5%;.*input/), 'Label must be positioned on the left floated left');
- Harness.setComponentProperty('labelPosition', 'left-left', 'right-right', (preview) => {
- assert(preview.match(/label.*style=".*float: right; width: 20%; margin-left: 5%; text-align: right;.*input/), 'Label must be positioned on the right floated right');
- Harness.testVisibility(builder.editForm, '.formio-component-labelWidth', true);
- Harness.testVisibility(builder.editForm, '.formio-component-labelMargin', true);
- done();
- });
- });
- });
- });
- });
- });
-
- it('Should allow you to set the input mask', (done) => {
- Harness.testBuilderProperty('inputMask', '', '(999) 999-9999', null, () => {
- assert.equal(builder.preview.inputs[0].placeholder, '(___) ___-____');
- builder.preview.setValue('1234567890');
- assert.equal(builder.preview.inputs[0].value, '(123) 456-7890');
- assert.equal(builder.preview.getValue(), '(123) 456-7890');
- done();
- });
- });
-
- it('Should set the placeholder of the input', (done) => {
- Harness.setComponentProperty('labelPosition', 'right-right', 'top', () => {
- Harness.testBuilderProperty('placeholder', '', 'Enter something here', /input.*name="data\[firstName\].*placeholder="Enter something here"/, done);
- });
- });
-
- it('Should set the description of the input', (done) => {
- Harness.testBuilderProperty('description', '', 'This is a description', /input.*div.*class="help-block">This is a description<\/div>/, done);
- });
-
- it('Should set the tooltip of the input', (done) => {
- Harness.testBuilderProperty('tooltip', '', 'This is something you should fill out.', /label.*i.*class="glyphicon glyphicon-question-sign text-muted.*<\/label>/, () => {
- assert(builder.preview.tooltip, 'There should be a tooltip instance');
- builder.preview.tooltip.show();
- const toolTipText = builder.preview.element.querySelector('.tooltip-inner');
- assert.equal(toolTipText.innerHTML, 'This is something you should fill out.');
- done();
- });
- });
-
- it('Should set the prefix of the input', (done) => {
- Harness.testBuilderProperty('prefix', '', '$', /div class="input-group">.*\$<\/div>.*input/, done);
- });
-
- it('Should set the suffix of the input', (done) => {
- Harness.testBuilderProperty('suffix', '', 'USD', /div class="input-group">.*input.*
USD<\/div>/, done);
- });
-
- it('Should set the custom css class of the input', (done) => {
- Harness.testBuilderProperty('customClass', '', 'custom-text-field', null, () => {
- assert(builder.preview.hasClass(builder.preview.element, 'custom-text-field'), 'Preview should have this custom class');
- done();
- });
- });
-
- it('Should set the tab index of the input element', (done) => {
- Harness.testBuilderProperty('tabindex', '', 10, null, () => {
- assert.equal(builder.preview.inputs[0].tabIndex, 10);
- done();
- });
- });
-
- it('Should allow you to set the multiple flag', (done) => {
- Harness.testBuilderProperty('multiple', false, true, null, () => {
- done();
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.form.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.form.js
deleted file mode 100644
index 50c8c473..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.form.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import Components from '../Components';
-
-import TextFieldEditData from './editForm/TextField.edit.data';
-import TextFieldEditDisplay from './editForm/TextField.edit.display';
-import TextFieldEditValidation from './editForm/TextField.edit.validation';
-
-export default function(...extend) {
- return Components.baseEditForm([
- {
- key: 'display',
- components: TextFieldEditDisplay
- },
- {
- key: 'data',
- components: TextFieldEditData
- },
- {
- key: 'validation',
- components: TextFieldEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.js
deleted file mode 100644
index 5bdac587..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.js
+++ /dev/null
@@ -1,279 +0,0 @@
-import Input from '../_classes/input/Input';
-import { conformToMask } from '@formio/vanilla-text-mask';
-import * as FormioUtils from '../../utils/utils';
-import NativePromise from 'native-promise-only';
-import _ from 'lodash';
-
-export default class TextFieldComponent extends Input {
- static schema(...extend) {
- return Input.schema({
- label: 'Text Field',
- key: 'textField',
- type: 'textfield',
- mask: false,
- inputType: 'text',
- inputFormat: 'plain',
- inputMask: '',
- displayMask: '',
- tableView: true,
- spellcheck: true,
- truncateMultipleSpaces: false,
- validate: {
- minLength: '',
- maxLength: '',
- pattern: ''
- }
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Text Field',
- icon: 'terminal',
- group: 'basic',
- documentation: '/userguide/form-building/form-components#text-field',
- weight: 0,
- schema: TextFieldComponent.schema()
- };
- }
-
- static get serverConditionSettings() {
- return TextFieldComponent.conditionOperatorsSettings;
- }
-
- static get conditionOperatorsSettings() {
- return {
- ...super.conditionOperatorsSettings,
- operators: [...super.conditionOperatorsSettings.operators, 'includes', 'notIncludes', 'endsWith', 'startsWith'],
- };
- }
-
- static savedValueTypes(schema) {
- return FormioUtils.getComponentSavedTypes(schema) || [FormioUtils.componentValueTypes.string];
- }
-
- get defaultSchema() {
- return TextFieldComponent.schema();
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- info.type = 'input';
-
- if (this.component.hasOwnProperty('spellcheck')) {
- info.attr.spellcheck = this.component.spellcheck;
- }
-
- if (this.component.mask) {
- info.attr.type = 'password';
- }
- else {
- info.attr.type = (this.component.inputType === 'password') ? 'password' : 'text';
- }
- info.changeEvent = (this.component.applyMaskOn === 'blur') ? 'blur' : 'input';
- return info;
- }
-
- get emptyValue() {
- return '';
- }
-
- constructor(component, options, data) {
- super(component, options, data);
-
- const timezone = (this.component.widget?.timezone || this.options.timezone);
- const displayInTimezone = (this.component.widget?.displayInTimezone || 'viewer');
-
- if (this.component.widget?.type === 'calendar') {
- this.component.widget = {
- ...this.component.widget,
- readOnly: this.options.readOnly,
- timezone,
- displayInTimezone,
- locale: this.component.widget.locale || this.options.language,
- saveAs: 'text'
- };
- }
- }
-
- attach(element) {
- this.loadRefs(element, {
- valueMaskInput: 'single',
- });
- return super.attach(element);
- }
-
- /**
- * Returns the mask value object.
- *
- * @param value
- * @param flags
- * @return {*}
- */
- maskValue(value, flags = {}) {
- // Convert it into the correct format.
- if (!value || (typeof value !== 'object')) {
- value = {
- value,
- maskName: this.component.inputMasks[0].label
- };
- }
-
- // If no value is provided, then set the defaultValue.
- if (!value.value) {
- const defaultValue = flags.noDefault ? this.emptyValue : this.defaultValue;
- value.value = Array.isArray(defaultValue) ? defaultValue[0] : defaultValue;
- }
-
- return value;
- }
-
- /**
- * Normalize the value set in the data object.
- *
- * @param value
- * @param flags
- * @return {*}
- */
- normalizeValue(value, flags = {}) {
- if (!this.isMultipleMasksField) {
- return super.normalizeValue(value);
- }
- if (Array.isArray(value)) {
- return super.normalizeValue(value.map((val) => this.maskValue(val, flags)));
- }
- return super.normalizeValue(this.maskValue(value, flags));
- }
-
- /**
- * Sets the value at this index.
- *
- * @param index
- * @param value
- * @param flags
- */
- setValueAt(index, value, flags = {}) {
- if (!this.isMultipleMasksField) {
- return super.setValueAt(index, value, flags);
- }
- value = this.maskValue(value, flags);
- const textValue = value.value || '';
- const textInput = this.refs.mask ? this.refs.mask[index] : null;
- const maskInput = this.refs.select ? this.refs.select[index]: null;
- const mask = this.getMaskPattern(value.maskName);
- if (textInput && maskInput && mask) {
- const placeholderChar = this.placeholderChar;
- textInput.value = conformToMask(textValue, FormioUtils.getInputMask(mask), { placeholderChar }).conformedValue;
- maskInput.value = value.maskName;
- }
- else {
- return super.setValueAt(index, textValue, flags);
- }
- }
-
- unmaskValue(value, format = this.component.displayMask) {
- const mask = FormioUtils.getInputMask(format, this.placeholderChar);
-
- return FormioUtils.unmaskValue(value, mask, this.placeholderChar);
- }
-
- /**
- * Returns the value at this index.
- *
- * @param index
- * @return {*}
- */
- getValueAt(index) {
- if (!this.isMultipleMasksField) {
- const value = super.getValueAt(index);
- const valueMask = this.component.inputMask;
- const displayMask = this.component.displayMask;
-
- // If the input has only the valueMask or the displayMask is the same as the valueMask,
- // just return the value which is already formatted
- if (valueMask && !displayMask || displayMask === valueMask) {
- return value;
- }
-
- // If there is only the displayMask, return the raw (unmasked) value
- if (displayMask && !valueMask) {
- return this.unmaskValue(value, displayMask);
- }
-
- if (this.refs.valueMaskInput?.mask) {
- this.refs.valueMaskInput.mask.textMaskInputElement.update(value);
- return this.refs.valueMaskInput?.value;
- }
-
- return value;
- }
- const textInput = this.refs.mask ? this.refs.mask[index] : null;
- const maskInput = this.refs.select ? this.refs.select[index]: null;
- return {
- value: textInput ? textInput.value : undefined,
- maskName: maskInput ? maskInput.value : undefined
- };
- }
-
- isHtmlRenderMode() {
- return super.isHtmlRenderMode() ||
- ((this.options.readOnly || this.disabled) &&
- this.component.inputFormat === 'html' &&
- this.type === 'textfield');
- }
-
- isEmpty(value = this.dataValue) {
- if (!this.isMultipleMasksField) {
- return super.isEmpty((value || '').toString().trim());
- }
- return super.isEmpty(value) || (this.component.multiple ? value.length === 0 : (!value.maskName || !value.value));
- }
-
- truncateMultipleSpaces(value) {
- if (value) {
- return value.trim().replace(/\s{2,}/g, ' ');
- }
- return value;
- }
-
- get validationValue() {
- const value = super.validationValue;
- if (value && this.component.truncateMultipleSpaces) {
- return this.truncateMultipleSpaces(value);
- }
- return value;
- }
-
- beforeSubmit() {
- let value = this.dataValue;
-
- if (!this.component.truncateMultipleSpaces || !value) {
- return NativePromise.resolve(value);
- }
- value = this.truncateMultipleSpaces(value);
- this.dataValue = value;
- return NativePromise.resolve(value).then(() => super.beforeSubmit());
- }
-
- getValueAsString(value, options) {
- if (options?.email && this.visible && !this.skipInEmail && _.isObject(value)) {
- const result = (`
-
-
-
- ${value.maskName}
- ${value.value}
-
-
-
- `);
-
- return result;
- }
-
- if (value && this.component.inputFormat === 'plain' && /<[^<>]+>/g.test(value)) {
- value = value.replaceAll('<','<').replaceAll('>', '>');
- }
- return super.getValueAsString(value, options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.unit.js
deleted file mode 100644
index 1e8bf643..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/TextField.unit.js
+++ /dev/null
@@ -1,1411 +0,0 @@
-import assert from 'power-assert';
-import _ from 'lodash';
-import Harness from '../../../test/harness';
-import TextFieldComponent from './TextField';
-import Formio from './../../Formio';
-import 'flatpickr';
-
-import {
- comp1,
- comp2,
- comp4,
- comp5,
- comp6,
- withDisplayAndInputMasks,
- comp7,
-} from './fixtures';
-
-describe('TextField Component', () => {
- it('Should create a new TextField', () => {
- const textField = new TextFieldComponent({
- label: 'First Name',
- key: 'firstName',
- input: true,
- type: 'textfield'
- });
-
- assert.equal(textField.component.key, 'firstName');
- });
-
- it('Should build a TextField component', () => {
- return Harness.testCreate(TextFieldComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 1);
- });
- });
-
- it('Should disable multiple mask selector if component is disabled', (done) => {
- Harness.testCreate(TextFieldComponent, comp4).then((component) => {
- Harness.testElements(component, '[disabled]', 2);
- done();
- });
- });
-
- it('Should check mask and value in the textfield component in the email template', (done) => {
- const formJson = {
- components: [{
- label: 'Text Field',
- tableView: true,
- allowMultipleMasks: true,
- inputMasks: [{
- label: 'mask1',
- mask: 'mask1'
- }],
- key: 'textField',
- type: 'textfield',
- input: true
- }]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson)
- .then(form => {
- form.setSubmission({
- data: {
- textField: {
- value: 'mask1',
- maskName: 'mask2'
- }
- },
- });
-
- const textField = form.getComponent('textField');
-
- setTimeout(() => {
- assert.equal(textField.dataValue.value, 'mask1', 'Should check value');
- assert.equal(textField.dataValue.maskName, 'mask2', 'Should check maskName');
- const toString = textField.getValueAsString(textField.dataValue, { email: true });
- assert.ok(toString.includes('table'), 'Email template should render html table');
- assert.ok(toString.includes(textField.dataValue.maskName), 'Email template should have Text Field mackName');
- assert.ok(toString.includes(textField.dataValue.value), 'Email template should have Text Field value');
- done();
- }, 300);
- })
- .catch(done);
- });
-
- it('Should provide required validation', () => {
- return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
- validate: { required: true }
- })).then((component) => {
- return Harness.testInvalid(component, '', 'firstName', 'First Name is required').then(() => component);
- }).then((component) => {
- return Harness.testValid(component, 'te').then(() => component);
- });
- });
-
- it('Should provide minWords validation', () => {
- return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
- validate: { minWords: 2 }
- })).then((component) => {
- return Harness.testInvalid(component, 'test', 'firstName', 'First Name must have at least 2 words.').then(() => component);
- }).then((component) => {
- return Harness.testValid(component, 'te st').then(() => component);
- });
- });
-
- it('Should correctly calculate remaining words', (done) => {
- Harness.testCreate(TextFieldComponent, comp5).then((component) => {
- const inputEvent = new Event('input', { bubbles: true, cancelable: true });
- const element = component.refs.input[0];
-
- element.value = 'paper format A4';
- element.dispatchEvent(inputEvent);
-
- setTimeout(()=>{
- assert.equal(component.refs.wordcount[0].textContent, '2 words remaining.');
-
- element.value = 'Hey, guys! We are here!!';
- element.dispatchEvent(inputEvent);
-
- setTimeout(()=>{
- assert.equal(component.refs.wordcount[0].textContent, '0 words remaining.');
-
- element.value = ' Some test text 111 ';
- element.dispatchEvent(inputEvent);
-
- setTimeout(()=>{
- assert.equal(component.refs.wordcount[0].textContent, '1 words remaining.');
-
- done();
- }, 300);
- }, 275);
- }, 250);
- });
- });
-
- it('Should provide maxWords validation', () => {
- return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
- validate: { maxWords: 2 }
- })).then((component) => {
- return Harness.testInvalid(component, 'test test test', 'firstName', 'First Name must have no more than 2 words.').then(() => component);
- }).then((component) => {
- return Harness.testValid(component, 'te st').then(() => component);
- });
- });
-
- it('Should provide minLength validation', () => {
- return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
- validate: { minLength: 2 }
- })).then((component) => {
- return Harness.testInvalid(component, 't', 'firstName', 'First Name must have at least 2 characters.').then(() => component);
- }).then((component) => {
- return Harness.testValid(component, 'te').then(() => component);
- });
- });
-
- it('Should provide maxLength validation', () => {
- return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
- validate: { maxLength: 5 }
- })).then(component => {
- return Harness.testInvalid(component, 'testte', 'firstName', 'First Name must have no more than 5 characters.').then(() => component);
- }).then((component) => {
- return Harness.testValid(component, 'te').then(() => component);
- });
- });
-
- it('Should provide custom validation', () => {
- return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
- validate: {
- custom: 'valid = (input !== "Joe") ? true : "You cannot be Joe"'
- }
- })).then((component) => {
- return Harness.testInvalid(component, 'Joe', 'firstName', 'You cannot be Joe').then(() => component);
- }).then((component) => {
- return Harness.testValid(component, 'Tom').then(() => component);
- });
- });
-
- it('Should provide one custom error message', (done) => {
- const formJson = {
- components: [{
- label: 'Text Field',
- tableView: true,
- validate: {
- pattern: '^[0-9]*$]',
- customMessage: 'Custom Error Message',
- minWords: 10
- },
- key: 'textField',
- type: 'textfield',
- input: true
- }]
- };
- const element = document.createElement('div');
- Formio.createForm(element, formJson)
- .then(form => {
- form.submission = {
- data: {
- textField: 'textField'
- }
- };
- const textField = form.getComponent('textField');
- setTimeout(() => {
- assert.equal(textField.refs.messageContainer.children.length, 1);
- assert.equal(textField.refs.messageContainer.children[0].innerHTML, 'Custom Error Message');
- done();
- }, 300);
- })
- .catch(done);
- });
-
- it('Should provide json validation', () => {
- return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
- validate: {
- json: {
- 'if': [
- {
- '===': [
- { var: 'data.firstName' },
- 'Joe'
- ]
- },
- true,
- 'You must be Joe'
- ]
- }
- }
- })).then((component) => {
- return Harness.testInvalid(component, 'Tom', 'firstName', 'You must be Joe').then(() => component);
- }).then((component) => {
- return Harness.testValid(component, 'Joe').then(() => component);
- });
- });
-
- it('Should provide number input mask only after blur event if applyMaskOn setting on blur', (done) => {
- const form = _.cloneDeep(comp7);
- const element = document.createElement('div');
- form.components[0].inputMask = '99-99';
- const value = 999;
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- const changed = component.setValue(value);
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- assert.equal(component.getValue(), value);
- }
-
- setTimeout(() => {
- const textFieldInput = component.element.querySelector('.form-control');
- const event = new Event('blur');
- textFieldInput.dispatchEvent(event);
-
- setTimeout(() => {
- assert.equal(component.getValue(), '99-9_');
- done();
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should provide validation of number input mask only after blur event if applyMaskOn setting on blur', (done) => {
- const form = _.cloneDeep(comp7);
- const element = document.createElement('div');
- form.components[0].inputMask = '99-99';
- let value = 999;
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- let changed = component.setValue(value);
- const error = 'Text Field does not match the mask.';
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- assert.equal(!!component.error, false, 'Should not contain error');
-
- const textFieldInput = component.element.querySelector('.form-control');
- const event = new Event('blur');
- textFieldInput.dispatchEvent(event);
-
- setTimeout(() => {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
-
- value = 9999;
- changed = component.setValue(value);
-
- setTimeout(() => {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
-
- textFieldInput.dispatchEvent(event);
-
- setTimeout(() => {
- assert.equal(!!component.error, false, 'Should not contain error');
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should provide validation of number input mask after setting value', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = '99/99-99.99:99,99';
-
- const validValues = [
- '',
- '99/99-99.99:99,99',
- ];
-
- const invalidValues = [
- '99/99-99.99:99,,99',
- '99/99-99.99:99,9',
- '9999-99.99:99,,99',
- '99/99-99.99:9(9,9)9',
- '99999999#999999999',
- 'fffffff()f99/99-99.99:99,99',
- '77ff7777ff7777ff7777',
- '9/99-99.99999,99',
- '9/99-9/9.9/9:99,9/9',
- '99/99-a9.99:99,99',
- '99/99---.99:99,99',
- 'ddddddddddddddd',
- '9/99-9/9.9/9:99,9/9ddd',
- '9/99-99.99999,fffffff',
- '99/_9-99.9f9:99,9g9',
- 'A8/99-99.99:99,99',
- ];
-
- const testValidity = (values, valid, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const changed = component.setValue(value);
- const error = 'Text Field does not match the mask.';
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues, false, invalidValues[invalidValues.length-1]);
- });
-
- it('Should allow inputing only numbers and format input according to input mask', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = '99/99-99.99:99,99';
-
- const values = [
- '99/99-99.99:99,,99',
- '9999-99.99:999,,99',
- '99/99-99.99:9(9,9)9',
- '99999999999999999',
- 'ffffffff99/99-99.99:99,99',
- '99ff999999ff999ff9',
- '9/99-99.99999,999',
- '9/99-9/9.9/9:999,9/9',
- '99.99-a9.99:999,99',
- '99/99---.99:9999,99',
- '999999999999',
- '99999-9/9.9/9:99,9/9ddd',
- '9----99999-99.99999,fffffff',
- '999-9kkkk9.99999f9:99,9g9',
- 'A9/99-99.999:99,99',
- ];
-
- const testFormatting = (values, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value;
- input.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(!!component.error, false, 'Should not contain error');
- assert.equal(component.getValue(), '99/99-99.99:99,99', 'Should set and format value');
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testFormatting(values, values[values.length-1]);
- });
-
- it('Should provide validation for alphabetic input mask after setting value', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = 'a/A/a-a:a.a,aa';
-
- const validValues = [
- '',
- 'b/V/r-y:d.d,as',
- 'b/b/r-y:d.d,as',
- ];
-
- const invalidValues = [
- 'b/b/r-y:d.d',
- 'b/v/r-yCC:d.d,as',
- 'rD/F/R-y:d.d,DE',
- 'bv/Sr-y:d.d,as',
- '555555555555555',
- 'ssssEsssssssssssss',
- 'b/v/Rr-y:d$.d,a',
- '3/3/#r-y:d.d,as',
- '3/3/6-6&&:d...d,as',
- '5/5/5ee-55.5,5'
- ];
-
- const testValidity = (values, valid, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const changed = component.setValue(value);
- const error = 'Text Field does not match the mask.';
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues, false, invalidValues[invalidValues.length-1]);
- });
-
- it('Should allow inputing only letters and format input according to input mask', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = 'a/a/a-a:a.a,aa';
-
- const values = [
- 'ssssSSSSSSS/sss-ss.s,ss',
- 'ss/sSss-sSSs.s,ss',
- 'ssSssssssSSSssssss',
- 's/sS/sss-s5555:sss.--s,s',
- '3/s3/Ss-s:ss.s,ssSsss',
- 'ssSs3/3s/s6-s6:s...s,s',
- 's5/5sSS/5s-5:sS---5.s5,s5sss'
- ];
-
- const testFormatting = (values, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value;
- input.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(!!component.error, false, 'Should not contain error');
- assert.equal(component.getValue(), 's/s/s-s:s.s,ss', 'Should set and format value');
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testFormatting(values, values[values.length-1]);
- });
-
- it('Should provide validation for alphanumeric input mask after setting value', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = '**/***.*-*,**';
-
- const validValues = [
- '',
- 'f4/D34.3-S,dd',
- 'gg/ggg.g-g,gg',
- 'DD/DDD.D-D,DD',
- '55/555.5-5,55',
- ];
-
- const invalidValues = [
- 'er432ff',
- 'rD5/F/R-y:d',
- '_=+dsds4',
- 'sFFFFF--------2',
- 'sd',
- 'sf__df',
- 'gg/ggg.g-g',
- ];
-
- const testValidity = (values, valid, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const changed = component.setValue(value);
- const error = 'Text Field does not match the mask.';
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues, false, invalidValues[invalidValues.length-1]);
- });
-
- it('Should allow inputing only letters and digits and format input according to input mask', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = '**/***.*-*,**';
-
- const values = [
- { value:'ssssSSSSSSS/sss-ss.s,ss', expected: 'ss/ssS.S-S,SS' },
- { value:'ss/sSss-sSSs.s,ss', expected: 'ss/sSs.s-s,SS' },
- { value:'ssS666ssssssSSSssssss', expected: 'ss/S66.6-s,ss' },
- { value:'s/sS/sss-s5555:sss.--s,s', expected: 'ss/Sss.s-s,55' },
- { value:'3/s3/Ss-s:ss.s,ssSsss', expected: '3s/3Ss.s-s,ss' },
- { value:'ssSs3/3s/s6-s6:s...s,s', expected: 'ss/Ss3.3-s,s6' },
- { value:'s5/5sSS/5s-5:sS---5.s5,s5sss', expected: 's5/5sS.S-5,s5' },
- ];
-
- const testFormatting = (values, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value.value;
- input.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(!!component.error, false, 'Should not contain error');
- assert.equal(component.getValue(), value.expected, 'Should set and format value');
-
- if (_.isEqual(value.value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testFormatting(values, values[values.length-1].value);
- });
-
- it('Should provide validation for mixed input mask after setting value', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = '**/99-aa';
-
- const validValues = [
- '',
- '4r/34-fg',
- '46/34-yy',
- 'ye/56-op',
- 'We/56-op',
- ];
-
- const invalidValues = [
- 'te/56-Dp',
- 'te/E6-pp',
- 'tdddde/E6-pp',
- 'te/E6',
- 'te/E6-p',
- 'gdfgdfgdf',
- '43543',
- 'W'
- ];
-
- const testValidity = (values, valid, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const changed = component.setValue(value);
- const error = 'Text Field does not match the mask.';
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues, false, invalidValues[invalidValues.length-1]);
- });
-
- it('Should allow inputing only letters and digits and format input according to mixed input mask', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = '**/99-aa';
-
- const values = [
- { value:'S67gf-+f34cfd', expected: 'S6/73-cf' },
- { value:'56DDDfdsf23,DDdsf', expected: '56/23-ds' },
- { value:'--fs344d.g234df', expected: 'fs/34-dg' },
- { value:'000000000g234df', expected: '00/00-gd' },
- ];
-
- const testFormatting = (values, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value.value;
- input.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(!!component.error, false, 'Should not contain error');
- assert.equal(component.getValue(), value.expected, 'Should set and format value');
-
- if (_.isEqual(value.value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testFormatting(values, values[values.length-1].value);
- });
-
- it('Should allow multiple masks', (done) => {
- const form = _.cloneDeep(comp6);
- const tf = form.components[0];
- tf.allowMultipleMasks = true;
- tf.inputMasks = [
- { label: 'number', mask: '99-99' },
- { label: 'letter', mask: 'aa.aa' },
- { label: 'any', mask: '**/**' }
- ];
-
- const masks = [
- { index: 0, mask: 'number', valueValid:['33-33'], valueInvalid: ['Bd'] },
- { index: 1, mask: 'letter', valueValid:['rr.dd'], valueInvalid: ['Nr-22'] },
- { index: 2, mask: 'any', valueValid:['Dv/33'], valueInvalid: ['4/4'] },
- ];
-
- const testMask = (mask, valid, lastValue) => {
- const values = valid ? mask.valueValid : mask.valueInvalid;
-
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
- const component = form.getComponent('textField');
- const changed = component.setValue({ value: value, maskName: mask.mask });
- const error = 'Text Field does not match the mask.';
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- assert.equal(component.refs.select[0].options[mask.index].selected, true, 'Should select correct mask');
- assert.equal(component.getValue().maskName, mask.mask, 'Should apply correct mask');
-
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- _.each(masks, (mask, index) => {
- testMask(mask, true);
- testMask(mask, false, (index === masks.length - 1) ? mask.valueInvalid[mask.valueInvalid.length-1] : undefined);
- });
- });
-
- it('Should provide validation of number input mask with low dash and placeholder char after setting value', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = '99_99/99';
- form.components[0].inputMaskPlaceholderChar = '.';
-
- const validValues = [
- '',
- '55_44/88',
- ];
-
- const invalidValues = [
- '99 99 99',
- '44_44_55',
- '55555555',
- ];
-
- const testValidity = (values, valid, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const input = component.refs.input[0];
-
- assert.equal(input.placeholder, '.._../..', 'Should set placeholder using the char setting');
-
- const changed = component.setValue(value);
- const error = 'Text Field does not match the mask.';
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues, false, invalidValues[invalidValues.length-1]);
- });
-
- it('Should format input according to input mask with low dash when placeholder char is set', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputMask = '99_99/99';
- form.components[0].inputMaskPlaceholderChar = '.';
-
- const values = [
- { value:'4444444', expected: '44_44/44' },
- ];
-
- const testFormatting = (values, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('textField');
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value.value;
- input.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(!!component.error, false, 'Should not contain error');
- assert.equal(component.getValue(), value.expected, 'Should set and format value');
-
- if (_.isEqual(value.value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testFormatting(values, values[values.length-1].value);
- });
-
- it('Should correctly count characters if character counter is enabled', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].showCharCount = true;
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- const inputValue = (value) => {
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value;
- input.dispatchEvent(inputEvent);
- };
-
- const checkValue = (value) => {
- assert.equal(component.dataValue, value, 'Should set value');
- assert.equal(parseInt(component.refs.charcount[0].textContent), value.length, 'Should show correct chars number');
- assert.equal(component.refs.charcount[0].textContent, `${value.length} characters`, 'Should show correct message');
- };
-
- let value = 'test Value (@#!-"]) _ 23.,5}/*&&';
- inputValue(value);
- setTimeout(() => {
- checkValue(value);
- value = '';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value);
- value = ' ';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value);
-
- done();
- }, 200);
- }, 200);
- }, 200);
- }).catch(done);
- });
-
- it('Should format value to uppercase', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].case = 'uppercase';
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- const inputValue = (value) => {
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value;
- input.dispatchEvent(inputEvent);
- };
-
- const checkValue = (value) => {
- assert.equal(component.dataValue, value.toUpperCase(), 'Should format value to uppercase');
- assert.equal(component.getValue(), value.toUpperCase(), 'Should format value to uppercase');
- };
-
- let value = 'SoMe Value';
- inputValue(value);
- setTimeout(() => {
- checkValue(value);
- value = 'test 1 value 1';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value);
- value = '';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value);
-
- done();
- }, 100);
- }, 100);
- }, 100);
- }).catch(done);
- });
-
- it('Should format value to lowercase', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].case = 'lowercase';
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- const inputValue = (value) => {
- const input = component.refs.input[0];
- const inputEvent = new Event('input');
- input.value = value;
- input.dispatchEvent(inputEvent);
- };
-
- const checkValue = (value) => {
- assert.equal(component.dataValue, value.toLowerCase(), 'Should format value to lowercase (1)');
- assert.equal(component.getValue(), value.toLowerCase(), 'Should format value to lowercase (2)');
- };
-
- let value = 'SoMe Value';
- inputValue(value);
- setTimeout(() => {
- checkValue(value);
- value = 'TEST 1 VALUE (1)';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value);
- value = '';
- inputValue(value);
-
- setTimeout(() => {
- checkValue(value);
-
- done();
- }, 100);
- }, 100);
- }, 100);
- }).catch(done);
- });
-
- it('Should render and open/close calendar on click', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].widget = {
- allowInput: true,
- altInput: true,
- clickOpens: true,
- dateFormat: 'dd-MM-yyyy',
- enableDate: true,
- enableTime: true,
- format: 'dd-MM-yyyy',
- hourIncrement: 1,
- minuteIncrement: 5,
- mode: 'single',
- noCalendar: false,
- saveAs: 'date',
- 'time_24hr': false,
- type: 'calendar',
- useLocaleSettings: false,
- };
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- const clickElem = (path) => {
- const elem = _.get(component, path);
- const clickEvent = new Event('click');
- elem.dispatchEvent(clickEvent);
- };
- const checkCalendarState = (open) => {
- const calendar = document.querySelector('.flatpickr-calendar');
- assert.equal(calendar.classList.contains('open'), open, `${open ? 'Should open calendar' : 'Should close calendar'}`);
- };
-
- assert.equal(component.widget.settings.type, 'calendar', 'Should create calendar widget');
- clickElem('refs.suffix[0]');
-
- setTimeout(() => {
- checkCalendarState(true);
- clickElem('refs.suffix[0]');
-
- setTimeout(() => {
- checkCalendarState(false);
- clickElem('element.children[1].children[0].children[1]');
-
- setTimeout(() => {
- checkCalendarState(true);
- clickElem('refs.suffix[0]');
-
- setTimeout(() => {
- checkCalendarState(false);
- document.body.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should set value into calendar', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].widget = {
- allowInput: true,
- altInput: true,
- clickOpens: true,
- dateFormat: 'dd-MM-yyyy',
- enableDate: true,
- enableTime: true,
- format: 'dd-MM-yyyy',
- hourIncrement: 1,
- minuteIncrement: 5,
- mode: 'single',
- noCalendar: false,
- saveAs: 'date',
- 'time_24hr': false,
- type: 'calendar',
- useLocaleSettings: false,
- };
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- const clickElem = (path) => {
- const elem = _.get(component, path);
- const clickEvent = new Event('click');
- elem.dispatchEvent(clickEvent);
- };
- const checkCalendarState = (open, selectedDay) => {
- const calendar = document.querySelector('.flatpickr-calendar');
- assert.equal(calendar.classList.contains('open'), open, `${open ? 'Should open calendar' : 'Should close calendar'}`);
- if (selectedDay) {
- const day = calendar.querySelector('.flatpickr-day.selected').textContent;
- assert.equal(day, selectedDay, 'Should select correct day');
- }
- };
-
- const date = '16-03-2031';
-
- component.setValue(date);
-
- setTimeout(() => {
- checkCalendarState(false);
- const widget = component.element.querySelector('.flatpickr-input').widget;
-
- assert.equal(component.getValue(), date, 'Should set text field value');
- assert.equal(widget.calendar.input.value, date, 'Should set flatpickr value');
- assert.equal(widget.calendar.currentMonth, 2, 'Should set correct month');
- assert.equal(widget.calendar.currentYear, 2031, 'Should set correct year');
-
- clickElem('refs.suffix[0]');
-
- setTimeout(() => {
- checkCalendarState(true);
- clickElem('refs.suffix[0]');
-
- setTimeout(() => {
- checkCalendarState(false);
- document.body.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should allow manual input and set value on blur if calendar widget is enabled with allowed input', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].widget = {
- allowInput: true,
- altInput: true,
- clickOpens: true,
- dateFormat: 'dd-MM-yyyy',
- enableDate: true,
- enableTime: true,
- format: 'dd-MM-yyyy',
- hourIncrement: 1,
- minuteIncrement: 5,
- mode: 'single',
- noCalendar: false,
- saveAs: 'date',
- 'time_24hr': false,
- type: 'calendar',
- useLocaleSettings: false,
- };
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- const clickElem = (path, element) => {
- const elem = element || _.get(component, path);
- const clickEvent = new Event('click');
- elem.dispatchEvent(clickEvent);
- };
- const checkCalendarState = (open, selectedDay) => {
- const calendar = document.querySelector('.flatpickr-calendar');
- assert.equal(calendar.classList.contains('open'), open, `${open ? 'Should open calendar' : 'Should close calendar'}`);
- if (selectedDay) {
- const day = calendar.querySelector('.flatpickr-day.selected').textContent;
- assert.equal(day, selectedDay, 'Should select correct day');
- }
- };
-
- const triggerDateInputEvent = (eventName, value) => {
- const dateInput = component.element.querySelector('.form-control.input');
- const event = new Event(eventName);
- if (eventName === 'input') {
- dateInput.value = value;
- }
- dateInput.dispatchEvent(event);
- };
-
- triggerDateInputEvent('focus');
-
- setTimeout(() => {
- const date = '21-01-2001';
- checkCalendarState(true);
- triggerDateInputEvent('input', date);
-
- setTimeout(() => {
- checkCalendarState(true);
- triggerDateInputEvent('blur');
-
- setTimeout(() => {
- checkCalendarState(true, 21);
-
- assert.equal(component.getValue(), date, 'Should set text field value');
- const widget = component.element.querySelector('.flatpickr-input').widget;
- assert.equal(widget.calendar.input.value, date, 'Should set flatpickr value');
- assert.equal(widget.calendar.currentMonth, 0, 'Should set correct month');
- assert.equal(widget.calendar.currentYear, 2001, 'Should set correct year');
-
- clickElem('refs.suffix[0]');
-
- setTimeout(() => {
- checkCalendarState(false);
- assert.equal(component.getValue(), date, 'Should save text field value');
-
- document.body.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should allow removing date value if calendar widget is enabled with allowed input', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].widget = {
- allowInput: true,
- altInput: true,
- clickOpens: true,
- dateFormat: 'dd-MM-yyyy',
- enableDate: true,
- enableTime: true,
- format: 'dd-MM-yyyy',
- hourIncrement: 1,
- minuteIncrement: 5,
- mode: 'single',
- noCalendar: false,
- saveAs: 'date',
- 'time_24hr': false,
- type: 'calendar',
- useLocaleSettings: false,
- };
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- const component = form.getComponent('textField');
- const clickElem = (path, element) => {
- const elem = element || _.get(component, path);
- const clickEvent = new Event('click');
- elem.dispatchEvent(clickEvent);
- };
-
- const checkCalendarState = (open, selectedDay, noSelectedDay) => {
- const calendar = document.querySelector('.flatpickr-calendar');
- assert.equal(calendar.classList.contains('open'), open, `${open ? 'Should open calendar' : 'Should close calendar'}`);
- if (selectedDay) {
- const day = calendar.querySelector('.flatpickr-day.selected').textContent;
- assert.equal(day, selectedDay, 'Should select correct day');
- }
- if (noSelectedDay) {
- const day = calendar.querySelector('.flatpickr-day.selected');
- assert.equal(!!day, false, 'Should not contain selected day');
- }
- };
-
- const triggerDateInputEvent = (eventName, value) => {
- const dateInput = component.element.querySelector('.form-control.input');
- const event = new Event(eventName);
- if (eventName === 'input') {
- dateInput.value = value;
- }
- dateInput.dispatchEvent(event);
- };
-
- let date = '12-03-2009';
- component.setValue(date);
- triggerDateInputEvent('focus');
-
- setTimeout(() => {
- assert.equal(component.getValue(), date, 'Should set text field value');
- date = '';
- checkCalendarState(true);
- triggerDateInputEvent('input', date);
-
- setTimeout(() => {
- checkCalendarState(true);
- triggerDateInputEvent('blur');
-
- setTimeout(() => {
- checkCalendarState(true, '', true);
-
- assert.equal(component.getValue(), date, 'Should set text field value');
- const widget = component.element.querySelector('.flatpickr-input').widget;
- assert.equal(widget.calendar.input.value, date, 'Should set flatpickr value');
-
- clickElem('refs.suffix[0]');
-
- setTimeout(() => {
- checkCalendarState(false);
- assert.equal(component.getValue(), date, 'Should save text field value');
- document.body.innerHTML = '';
- done();
- }, 300);
- }, 300);
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Test Display mask', (done) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, withDisplayAndInputMasks).then(form => {
- const textField = form.getComponent(['textField']);
- const textFieldDisplayMask = form.getComponent(['textFieldDisplayMask']);
- const textFieldDisplayAndInputMasks = form.getComponent(['textFieldDisplayAndInputMasks']);
- const textFieldDisplayAndInputMasksReverse = form.getComponent(['textFieldDisplayAndInputMasksReverse']);
-
- Harness.dispatchEvent(
- 'input',
- form.element,
- '[name="data[textField]"',
- (input) => input.value = '123123',
- );
- Harness.dispatchEvent(
- 'input',
- form.element,
- '[name="data[textFieldDisplayMask]"',
- (input) => input.value = '123123',
- );
- Harness.dispatchEvent(
- 'input',
- form.element,
- '[name="data[textFieldDisplayAndInputMasks]"',
- (input) => input.value = '123123',
- );
- Harness.dispatchEvent(
- 'input',
- form.element,
- '[name="data[textFieldDisplayAndInputMasksReverse]"',
- (input) => input.value = '123123',
- );
-
- setTimeout(() => {
- Harness.getInputValue(textField, 'data[textField]', '123-123');
- Harness.getInputValue(textFieldDisplayMask, 'data[textFieldDisplayMask]', '123-123');
- Harness.getInputValue(textFieldDisplayAndInputMasks, 'data[textFieldDisplayAndInputMasks]', '+1(23)-123');
- Harness.getInputValue(textFieldDisplayAndInputMasksReverse, 'data[textFieldDisplayAndInputMasksReverse]', '123-123');
-
- assert.equal(
- textField.dataValue,
- '123-123',
- 'If only Input mask is set, it should affect both value and view',
- );
- assert.equal(
- textFieldDisplayMask.dataValue,
- '123123',
- 'If only Display mask is set, it should affect only view',
- );
- assert.equal(
- textFieldDisplayAndInputMasks.dataValue,
- '123-123',
- 'If both Input and Display masks are set, the Input mask should be applied to value',
- );
- assert.equal(
- textFieldDisplayAndInputMasksReverse.dataValue,
- '+1(23)-123',
- 'If both Input and Display masks are set, the Input mask should be applied to value',
- );
- done();
- }, 200);
- }).catch(done);
- });
-
- it('Should render HTML', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputFormat = 'html';
- const element = document.createElement('div');
-
- Formio.createForm(element, form, {
- readOnly: true
- }).then(form => {
- form.setSubmission({
- data: {
- textField: '
HTML! '
- }
- });
- setTimeout(() => {
- const textField = form.getComponent('textField');
- textField.loadRefs(element, {
- value: 'multiple'
- });
- assert.equal(textField.refs.value[0].innerHTML, '
HTML! ');
- done();
- }, 300);
- }).catch(done);
- });
-
- it('Should render plain text', (done) => {
- const form = _.cloneDeep(comp6);
- form.components[0].inputFormat = 'plain';
- const element = document.createElement('div');
-
- Formio.createForm(element, form, {
- readOnly: true
- }).then(form => {
- form.setSubmission({
- data: {
- textField: '
Plain! '
- }
- });
- setTimeout(() => {
- const textField = form.getComponent('textField');
- assert.equal(textField.refs.input[0].value, '
Plain! ');
- done();
- }, 300);
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.data.js
deleted file mode 100644
index 9ed4427a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.data.js
+++ /dev/null
@@ -1,56 +0,0 @@
-export default [
- {
- type: 'select',
- label: 'Input Format',
- key: 'inputFormat',
- weight: 105,
- placeholder: 'Input Format',
- tooltip: 'Force the output of this field to be sanitized in a specific format.',
- template: '
{{ item.label }} ',
- data: {
- values: [
- {
- value: 'plain',
- label: 'Plain'
- },
- {
- value: 'html',
- label: 'HTML'
- },{
- value: 'raw',
- label: 'Raw (Insecure)'
- }
- ]
- },
- defaultValue: 'plain',
- input: true
- },
- {
- weight: 200,
- type: 'radio',
- label: 'Text Case',
- key: 'case',
- tooltip: 'When data is entered, you can change the case of the value.',
- input: true,
- values: [
- {
- value: 'mixed',
- label: 'Mixed (Allow upper and lower case)'
- },
- {
- value: 'uppercase',
- label: 'Uppercase'
- },{
- value: 'lowercase',
- label: 'Lowercase'
- }
- ]
- },
- {
- weight: 205,
- type: 'checkbox',
- input: true,
- key: 'truncateMultipleSpaces',
- label: 'Truncate Multiple Spaces',
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.display.js
deleted file mode 100644
index 98041138..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.display.js
+++ /dev/null
@@ -1,207 +0,0 @@
-import Widgets from '../../../widgets';
-import _ from 'lodash';
-export default [
- {
- weight: 400,
- type: 'select',
- input: true,
- key: 'widget.type',
- label: 'Widget',
- placeholder: 'Select a widget',
- tooltip: 'The widget is the display UI used to input the value of the field.',
- defaultValue: 'input',
- onChange: (context) => {
- context.data.widget = _.pick(context.data.widget, 'type');
- },
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Input Field', value: 'input' },
- { label: 'Calendar Picker', value: 'calendar' },
- ]
- },
- conditional: {
- json: { '===': [{ var: 'data.type' }, 'textfield'] }
- }
- },
- {
- weight: 405,
- type: 'textarea',
- key: 'widget',
- label: 'Widget Settings',
- refreshOn: 'wiget.type',
- clearOnHide: false,
- // Deleted clearOnHide and refreshOn to make possible to change exist widget settings.
- calculateValue: (context) => {
- const { calculatedValue } = context.instance;
- const { type } = context.data.widget;
-
- if (
- _.isEmpty(_.omit(context.data.widget, 'type')) ||
- _.isEmpty(_.omit(calculatedValue, 'type'))
- ) {
- if (calculatedValue && !calculatedValue.type) {
- return context.data.widget;
- }
-
- const existWidget = context.instance._currentForm.options.editComponent.widget;
- if (existWidget && !_.isEmpty(_.omit(existWidget, 'type')) && type === existWidget.type) {
- return _.omit(existWidget, 'language');
- }
- else if (type) {
- return _.omit(Widgets[type].defaultSettings, 'language');
- }
- }
- return context.data.widget;
- },
- input: true,
- rows: 5,
- editor: 'ace',
- as: 'json',
- conditional: {
- json: { '!==': [{ var: 'data.widget.type' }, 'input'] }
- }
- },
- {
- weight: 410,
- type: 'textfield',
- input: true,
- key: 'inputMask',
- label: 'Input Mask',
- tooltip: 'An input mask helps the user with input by ensuring a predefined format.
9: numeric
a: alphabetical
*: alphanumeric
Example telephone mask: (999) 999-9999
See the
jquery.inputmask documentation for more information.',
- customConditional(context) {
- return !context.data.allowMultipleMasks;
- },
- },
- {
- weight: 410,
- type: 'textfield',
- input: true,
- key: 'displayMask',
- label: 'Display Mask',
- tooltip: 'A display mask helps to display the input in a readable way, this won\'t affect the value which will be saved (to affect both view and saved value, delete Display Mask and use Input Mask).
9: numeric
a: alphabetical
*: alphanumeric
Example telephone mask: (999) 999-9999
See the
jquery.inputmask documentation for more information.',
- customConditional(context) {
- return !context.data.allowMultipleMasks;
- },
- },
- {
- weight: 410,
- type: 'select',
- input: true,
- key: 'applyMaskOn',
- label: 'Apply Mask On',
- tooltip: 'Select the type of applying mask.',
- defaultValue: 'change',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'Change', value: 'change' },
- { label: 'Blur', value: 'blur' },
- ],
- },
- customConditional(context) {
- return !context.data.allowMultipleMasks;
- },
- },
- {
- weight: 411,
- type: 'textfield',
- input: true,
- key: 'inputMaskPlaceholderChar',
- label: 'Input Mask Placeholder Char',
- tooltip: 'You can specify a char which will be used as a placeholder in the field.
E.g., \u02cd
Make note that placeholder char will be replaced by a space if it is used inside the mask',
- validation: {
- maxLength: 1
- },
- customConditional(context) {
- return context.data.inputMask || context.data.displayMask;
- }
- },
- {
- weight: 413,
- type: 'checkbox',
- input: true,
- key: 'allowMultipleMasks',
- label: 'Allow Multiple Masks'
- },
- {
- weight: 1350,
- type: 'checkbox',
- input: true,
- key: 'spellcheck',
- defaultValue: true,
- label: 'Allow Spellcheck'
- },
- {
- weight: 417,
- type: 'datagrid',
- input: true,
- key: 'inputMasks',
- label: 'Input Masks',
- customConditional(context) {
- return context.data.allowMultipleMasks === true;
- },
- reorder: true,
- components: [
- {
- type: 'textfield',
- key: 'label',
- label: 'Label',
- input: true
- },
- {
- type: 'textfield',
- key: 'mask',
- label: 'Mask',
- input: true
- }
- ]
- },
- {
- weight: 320,
- type: 'textfield',
- input: true,
- key: 'prefix',
- label: 'Prefix'
- },
- {
- weight: 330,
- type: 'textfield',
- input: true,
- key: 'suffix',
- label: 'Suffix'
- },
- {
- weight: 700,
- type: 'textfield',
- input: true,
- key: 'autocomplete',
- label: 'Autocomplete',
- placeholder: 'on',
- tooltip: 'Indicates whether input elements can by default have their values automatically completed by the browser. See the
MDN documentation on autocomplete for more information.'
- },
- {
- weight: 1300,
- type: 'checkbox',
- label: 'Hide Input',
- tooltip: 'Hide the input in the browser. This does not encrypt on the server. Do not use for passwords.',
- key: 'mask',
- input: true
- },
- {
- weight: 1200,
- type: 'checkbox',
- label: 'Show Word Counter',
- tooltip: 'Show a live count of the number of words.',
- key: 'showWordCount',
- input: true
- },
- {
- weight: 1201,
- type: 'checkbox',
- label: 'Show Character Counter',
- tooltip: 'Show a live count of the number of characters.',
- key: 'showCharCount',
- input: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.validation.js
deleted file mode 100644
index b9926d5a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/editForm/TextField.edit.validation.js
+++ /dev/null
@@ -1,47 +0,0 @@
-export default [
- {
- weight: 110,
- key: 'validate.minLength',
- label: 'Minimum Length',
- placeholder: 'Minimum Length',
- type: 'number',
- tooltip: 'The minimum length requirement this field must meet.',
- input: true
- },
- {
- weight: 120,
- key: 'validate.maxLength',
- label: 'Maximum Length',
- placeholder: 'Maximum Length',
- type: 'number',
- tooltip: 'The maximum length requirement this field must meet.',
- input: true
- },
- {
- weight: 125,
- key: 'validate.minWords',
- label: 'Minimum Word Length',
- placeholder: 'Minimum Word Length',
- type: 'number',
- tooltip: 'The minimum amount of words that can be added to this field.',
- input: true
- },
- {
- weight: 126,
- key: 'validate.maxWords',
- label: 'Maximum Word Length',
- placeholder: 'Maximum Word Length',
- type: 'number',
- tooltip: 'The maximum amount of words that can be added to this field.',
- input: true
- },
- {
- weight: 130,
- key: 'validate.pattern',
- label: 'Regular Expression Pattern',
- placeholder: 'Regular Expression Pattern',
- type: 'textfield',
- tooltip: 'The regular expression pattern test that the field value must pass before the form can be submitted.',
- input: true
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp-with-display-and-value-masks.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp-with-display-and-value-masks.js
deleted file mode 100644
index 4880fdf5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp-with-display-and-value-masks.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Text Field with Input Mask',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- inputMask: '999-999',
- input: true
- },
- {
- label: 'Text Field with Display Mask',
- tableView: true,
- key: 'textFieldDisplayMask',
- type: 'textfield',
- displayMask: '999-999',
- input: true
- },
- {
- label: 'Text Field with Display and Input Masks',
- tableView: true,
- key: 'textFieldDisplayAndInputMasks',
- type: 'textfield',
- displayMask: '+9(99)-999',
- inputMask: '999-999',
- input: true
- },
- {
- label: 'Text Field with Display and Input Masks',
- tableView: true,
- key: 'textFieldDisplayAndInputMasksReverse',
- type: 'textfield',
- displayMask: '999-999',
- inputMask: '+9(99)-999',
- input: true
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: true, input: true, tableView: false }
- ],
- revisions: '',
- _vid: 0,
- title: 'Value And Display Masks',
- display: 'form',
- name: 'valueAndDisplayMasks',
- path: 'valueanddisplaymasks',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp1.js
deleted file mode 100644
index 3d9ac129..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp1.js
+++ /dev/null
@@ -1,33 +0,0 @@
-export default {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': 'Enter your first name',
- 'key': 'firstName',
- 'label': 'First Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp2.js
deleted file mode 100644
index d2031b1b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp2.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- 'tags': [],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': 0,
- 'minLength': 0,
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'firstName',
- 'label': 'First Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp3.js
deleted file mode 100644
index dc0c5d3f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp3.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export default {
- 'tags': [],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': 0,
- 'minLength': 0,
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': true,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'names',
- 'label': 'Names',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp4.js
deleted file mode 100644
index 4340b347..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp4.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- 'label': 'Text Field',
- 'allowMultipleMasks': true,
- 'spellcheck': true,
- 'tableView': true,
- 'calculateServer': false,
- 'key': 'textField1',
- 'type': 'textfield',
- 'data': {
- 'textField1': {
- 'value': '555',
- 'maskName': 'mask1'
- },
- 'submit': true,
- },
- 'inputMasks': [{
- 'label': 'mask1',
- 'mask': '999'
- }, {
- 'label': 'mask2',
- 'mask': 'aaa'
- }],
- 'input': true,
- 'disabled': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp5.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp5.js
deleted file mode 100644
index e15b5eff..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp5.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default {
- 'label': 'Text Field',
- 'showWordCount': true,
- 'tableView': true,
- 'validate': {
- 'maxWords': 5
- },
- 'key': 'textField',
- 'type': 'textfield',
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp6.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp6.js
deleted file mode 100644
index ee148f25..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp6.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default {
- type: 'form',
- components: [
- {
- label: 'Text Field',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true
- },
- { type: 'button', label: 'Submit', key: 'submit', disableOnInvalid: true, input: true, tableView: false }
- ],
- revisions: '',
- _vid: 0,
- title: 'input mask',
- display: 'form',
- name: 'inputMask',
- path: 'inputmask',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp7.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp7.js
deleted file mode 100644
index 6011ff10..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/comp7.js
+++ /dev/null
@@ -1,36 +0,0 @@
-export default {
- _id: '62fa6dfa619cf2405b7d01d6',
- title: '5376',
- name: '5376',
- path: '5376',
- type: 'form',
- display: 'form',
- components: [
- {
- label: 'Text Field',
- inputMask: '99-99',
- applyMaskOn: 'blur',
- tableView: true,
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
- settings: {},
- properties: {},
- project: '61029d3b4c9d4e24e774bb15',
- controller: '',
- revisions: '',
- submissionRevisions: '',
- created: '2022-08-15T16:02:02.668Z',
- modified: '2022-11-04T10:20:50.111Z',
- machineName: 'dev-pvbwkiwgifflcai:5376',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/index.js
deleted file mode 100644
index 9cfd5997..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
-export comp5 from './comp5';
-export comp6 from './comp6';
-export withDisplayAndInputMasks from './comp-with-display-and-value-masks';
-export comp7 from './comp7';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/values.js
deleted file mode 100644
index d1ca10ed..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/textfield/fixtures/values.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default [
- 'do',
- 're',
- 'me',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/Time.form.js b/web-client/core/themes/italia/static/formio/css/src/components/time/Time.form.js
deleted file mode 100644
index b21d70c3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/Time.form.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import baseEditForm from '../_classes/component/Component.form';
-
-import TimeEditData from './editForm/Time.edit.data';
-import TimeEditDisplay from './editForm/Time.edit.display';
-
-export default function(...extend) {
- return baseEditForm([
- {
- key: 'data',
- components: TimeEditData,
- },
- {
- key: 'display',
- components: TimeEditDisplay,
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/Time.js b/web-client/core/themes/italia/static/formio/css/src/components/time/Time.js
deleted file mode 100644
index ac8f4e85..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/Time.js
+++ /dev/null
@@ -1,180 +0,0 @@
-import moment from 'moment';
-import TextFieldComponent from '../textfield/TextField';
-import { getBrowserInfo } from '../../utils/utils';
-
-const defaultDataFormat = 'HH:mm:ss';
-
-export default class TimeComponent extends TextFieldComponent {
- static schema(...extend) {
- return TextFieldComponent.schema({
- type: 'time',
- label: 'Time',
- key: 'time',
- inputType: 'time',
- format: 'HH:mm',
- dataFormat: defaultDataFormat,
- }, ...extend);
- }
-
- static get serverConditionSettings() {
- return {
- ...super.serverConditionSettings,
- valueComponent(classComp) {
- return {
- ...classComp,
- type: 'time',
- };
- },
- };
- }
-
- constructor(component, options, data) {
- super(component, options, data);
- const { edge: isEdgeBrowser, version: edgeVersion } = getBrowserInfo();
- this.component.inputMask = this.getInputMaskFromFormat(this.component.format);
- this.component.inputType = isEdgeBrowser && edgeVersion <= 18
- ? 'text'
- : (this.component.inputType || 'time');
- this.rawData = this.component.multiple ? [] : this.emptyValue;
- }
-
- init() {
- super.init();
- if (this.component.inputType === 'text') {
- this.validators.push('time');
- }
- }
-
- static get builderInfo() {
- return {
- title: 'Time',
- icon: 'clock-o',
- group: 'advanced',
- documentation: '/userguide/form-building/advanced-components#time-1',
- weight: 55,
- schema: TimeComponent.schema(),
- };
- }
-
- get dataFormat() {
- return this.component.dataFormat || defaultDataFormat;
- }
-
- get defaultSchema() {
- return TimeComponent.schema();
- }
-
- get defaultValue() {
- let value = super.defaultValue;
- if (this.component.multiple && Array.isArray(value)) {
- value = value.map(item => item ? this.getStringAsValue(item) : item);
- }
- else {
- if (value) {
- value = this.getStringAsValue(value);
- }
- }
- return value;
- }
-
- get validationValue() {
- if (Array.isArray(this.rawData) && !this.rawData.length || !this.rawData) {
- return this.dataValue;
- }
- return this.rawData;
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- info.attr.type = this.component.inputType;
- return info;
- }
-
- get skipMaskValidation() {
- return true;
- }
-
- isNotCompleteInput(value) {
- return value.includes('_');
- }
-
- removeValue(index) {
- this.rawData = Array.isArray(this.rawData) ? [...this.rawData.slice(0, index), ...this.rawData.slice(index + 1)] : this.emptyValue;
- super.removeValue(index);
- }
-
- resetRawData(index) {
- if (index) {
- this.setRawValue(this.emptyValue, index);
- }
- else {
- this.rawData = [];
- }
- }
-
- setRawValue(value, index) {
- if (Array.isArray(this.rawData)) {
- this.rawData[index] = value;
- }
- else {
- this.rawData = value;
- }
- }
-
- getRawValue(index) {
- if (index && Array.isArray(this.rawData)) {
- return this.rawData[index] || this.emptyValue;
- }
- else {
- return this.rawData;
- }
- }
-
- getValueAt(index) {
- if (!this.refs.input.length || !this.refs.input[index]) {
- return this.emptyValue;
- }
-
- const { value } = this.refs.input[index];
-
- if (!value) {
- this.resetRawData(index);
- return this.emptyValue;
- }
-
- this.setRawValue(value, index);
- return this.getStringAsValue(value);
- }
-
- setValueAt(index, value) {
- this.setRawValue(value ? this.getValueAsString(value) : value, index);
- this.refs.input[index].value = this.getRawValue(index);
- }
-
- getStringAsValue(view) {
- return view ? moment(view, this.component.format).format(this.component.dataFormat) : view;
- }
-
- getValueAsString(value) {
- return (value ? moment(value, this.component.dataFormat).format(this.component.format) : value) || '';
- }
-
- getInputMaskFromFormat(format) {
- if (format === 'LT') {
- return '99:99 AA';
- }
- if (format === 'LTS') {
- return '99:99:99 AA';
- }
- return format.replace(/[hHmMsSk]/g, '9')
- .replace(/[aA]/, 'AA');
- }
-
- addFocusBlurEvents(element) {
- super.addFocusBlurEvents(element);
-
- this.addEventListener(element, 'blur', () => {
- element.value = this.getValueAsString(element.value);
- });
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/Time.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/time/Time.unit.js
deleted file mode 100644
index e42bc70d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/Time.unit.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import Harness from '../../../test/harness';
-import assert from 'power-assert';
-import TimeComponent from './Time';
-import {
- comp1,
- comp2,
- comp3,
- timeForm2,
- timeForm,
-} from './fixtures';
-import Webform from '../../Webform';
-
-describe('Time Component', () => {
- it('Should build a time component', () => {
- return Harness.testCreate(TimeComponent, comp1);
- });
-
- it('Should format value on blur', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(timeForm).then(() => {
- const component = form.components[0];
- const inputEvent = new Event('input', { bubbles: true, cancelable: true });
- const blurEvent = new Event('blur');
- const timeInput = component.element.querySelector('input[name="data[time]"]');
-
- timeInput.value = '10:0_ __';
- timeInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- assert.equal(timeInput.value, '10:0_ __');
- assert.equal(component.dataValue, '10:00:00');
- timeInput.dispatchEvent(blurEvent);
-
- setTimeout(() => {
- assert.equal(timeInput.value, '10:00 AM');
- done();
- }, 500);
- }, 250);
- })
- .catch(done);
- });
-
- it('Should not show error if value corresponds to the mask', (done) => {
- Harness.testCreate(TimeComponent, comp2).then((component) => {
- const inputEvent = new Event('input', { bubbles: true, cancelable: true });
- const timeInput = component.element.querySelector('input[name="data[time]"]');
- timeInput.value = '12:0_';
- timeInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- timeInput.value = '12:00';
- timeInput.dispatchEvent(inputEvent);
-
- setTimeout(() => {
- component.checkData(component.data);
-
- setTimeout(() => {
- assert.equal(component.errors.length, 0);
- done();
- }, 700);
- }, 600);
- }, 500);
- });
- });
-
- it('Should be invalid if time is not real', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(timeForm2).then(() => {
- const component = form.components[0];
- Harness.setInputValue(component, 'data[time]', '89:19');
- setTimeout(() => {
- assert.equal(component.error.message, 'Invalid time', 'Should have an error');
- done();
- }, 650);
- }).catch(done);
- });
-
- it('Should build a time component', (done) => {
- Harness.testCreate(TimeComponent, comp3).then((time) => {
- assert.deepEqual(time.dataValue, ['10:00:00', '11:00:00'], 'Should be set to default value');
- done();
- }).catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/editForm/Time.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/time/editForm/Time.edit.data.js
deleted file mode 100644
index 82853055..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/editForm/Time.edit.data.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default [
- {
- type: 'textfield',
- input: true,
- key: 'dataFormat',
- label: 'Data Format',
- placeholder: 'HH:mm:ss',
- tooltip: 'The moment.js format for saving the value of this field.',
- weight: 25,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/editForm/Time.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/time/editForm/Time.edit.display.js
deleted file mode 100644
index 4a622866..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/editForm/Time.edit.display.js
+++ /dev/null
@@ -1,40 +0,0 @@
-export default [
- {
- type: 'select',
- input: true,
- weight: 40,
- tooltip: 'Select the type of widget you\'d like to use.',
- key: 'inputType',
- defaultValue: 'time',
- label: 'Input Type',
- dataSrc: 'values',
- data: {
- values: [
- { label: 'HTML5 Time Input', value: 'time' },
- { label: 'Text Input with Mask', value: 'text' },
- ],
- },
- },
- {
- type: 'textfield',
- input: true,
- key: 'format',
- label: 'Format',
- placeholder: 'Format',
- tooltip: 'The moment.js format for showing the value of this field.',
- weight: 50,
- defaultValue: 'HH:mm',
- conditional: {
- json: {
- '===': [
- { var: 'data.inputType' },
- 'text',
- ],
- },
- },
- },
- {
- key: 'placeholder',
- ignore: true,
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp1.js
deleted file mode 100644
index 6a8db141..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp1.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'time',
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'format': 'HH:mm',
- 'defaultValue': '',
- 'suffix': '',
- 'prefix': '',
- 'placeholder': 'Enter a time',
- 'key': 'time',
- 'label': 'Time',
- 'inputType': 'time',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp2.js
deleted file mode 100644
index 2ca2669c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp2.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export default {
- label: 'Time',
- inputType: 'text',
- tableView: true,
- key: 'time',
- type: 'time',
- input: true,
- inputMask: '99:99',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp3.js
deleted file mode 100644
index 43865c36..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/comp3.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export default {
- label: 'Time',
- tableView: true,
- multiple: true,
- validate: {
- multiple: true
- },
- key: 'time',
- type: 'time',
- input: true,
- inputMask: '99:99',
- defaultValue: [
- '10:00:00',
- '11:00:00'
- ]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/index.js
deleted file mode 100644
index 11d2e0e0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export timeForm from './timeForm';
-export timeForm2 from './timeForm2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/timeForm.js b/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/timeForm.js
deleted file mode 100644
index 5d009893..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/timeForm.js
+++ /dev/null
@@ -1,50 +0,0 @@
-export default {
- _id: '5ec5107f54969741745be8c2',
- type: 'form',
- tags: [],
- owner: '5e05a6b7549cdc2ece30c6b0',
- components: [
- {
- label: 'Time',
- inputType: 'text',
- tableView: true,
- validate: {
- required: true
- },
- key: 'time',
- type: 'time',
- format: 'HH:mm A',
- input: true,
- inputMask: '99:99 AA'
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false
- }
- ],
- controller: '',
- revisions: '',
- _vid: 0,
- title: 'time',
- display: 'form',
- access: [
- {
- roles: [
- '5e96e79ee1c3ad3178454100',
- '5e96e79ee1c3ad3178454101',
- '5e96e79ee1c3ad3178454102'
- ],
- type: 'read_all'
- }
- ],
- submissionAccess: [],
- settings: {},
- properties: {},
- name: 'time',
- path: 'time',
- project: '5e96e79ee1c3ad31784540ff'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/timeForm2.js b/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/timeForm2.js
deleted file mode 100644
index 99410235..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/timeForm2.js
+++ /dev/null
@@ -1,42 +0,0 @@
-export default {
- '_id': '5ee08571a177ce44348f53e4',
- 'type': 'form',
- 'owner': '5e05a6b7549cdc2ece30c6b0',
- 'components': [
- {
- 'label': 'Time',
- 'inputType': 'text',
- 'tableView': true,
- 'key': 'time',
- 'type': 'time',
- 'input': true,
- 'inputMask': '99:99'
- },
- {
- 'label': 'Submit',
- 'showValidations': false,
- 'disableOnInvalid': true,
- 'tableView': false,
- 'key': 'submit',
- 'type': 'button',
- 'input': true
- }
- ],
- 'controller': '',
- 'revisions': '',
- '_vid': 0,
- 'title': 'timeInputMaskValidation',
- 'display': 'form',
- 'access': [
- {
- 'roles': [
- '5e96e79ee1c3ad3178454100',
- '5e96e79ee1c3ad3178454101',
- '5e96e79ee1c3ad3178454102'
- ],
- 'type': 'read_all'
- }
- ],
- 'name': 'timeInputMaskValidation',
- 'path': 'timeinputmaskvalidation'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/values.js
deleted file mode 100644
index e6142e6f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/time/fixtures/values.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default [
- '01:01:00',
- '13:14:00',
- '23:59:00',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/Node.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/Node.js
deleted file mode 100644
index 58db7167..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/Node.js
+++ /dev/null
@@ -1,227 +0,0 @@
-import _ from 'lodash';
-
-export default class Node {
- constructor(
- parent,
- {
- data = {},
- children = [],
- } = {},
- {
- checkNode,
- createComponents,
- isNew = true,
- removeComponents,
- parentPath = ''
- } = {},
- ) {
- this.parent = parent;
- this.previousData = {};
- this.persistentData = _.cloneDeep(data);
- this.new = isNew;
- this.createComponents = createComponents;
- this.checkNode = checkNode;
- this.removeComponents = removeComponents;
- this.revertAvailable = false;
- this.editing = false;
- this.collapsed = false;
- this.components = [];
- this.children = [];
- this.parentPath = parentPath;
-
- this.resetData();
- this.children = children.map((child, index) => new Node(this, child, {
- checkNode,
- createComponents,
- isNew: false,
- removeComponents,
- parentPath: this.getChildrenPath(index),
- }));
-}
-
- get value() {
- return this.new
- ? null // Check the special case for empty root node.
- : {
- data: _.cloneDeep(this.persistentData),
- children: this.children.filter((child) => !child.new).map((child) => child.value),
- };
- }
-
- get isRoot() {
- return this.parent === null;
- }
-
- get changing() {
- return this.new || this.editing;
- }
-
- get hasChangingChildren() {
- return this.changin || this.children.some((child) => child.hasChangingChildren);
- }
-
- get hasData() {
- return !_.isEmpty(this.persistentData);
- }
-
- get hasChildren() {
- return Array.isArray(this.children) && this.children.length > 0;
- }
-
- getChildrenPath(index) {
- return this.parentPath ? `${this.parentPath}.children[${index}]` : '';
- }
-
- eachChild(iteratee) {
- iteratee(this);
- this.children.forEach((child) => child.eachChild(iteratee));
- return this;
- }
-
- getComponents() {
- return this.children.reduce(
- (components, child) => components.concat(child.getComponents()),
- this.components,
- );
- }
-
- validateNode() {
- let valid = true;
- this.getComponents().forEach(comp => {
- comp.setPristine(false);
- valid &= comp.checkValidity(null, false, this.persistentData);
- });
- return valid;
- }
-
- addChild() {
- if (this.new) {
- return null;
- }
-
- const child = new Node(this, {}, {
- checkNode: this.checkNode,
- createComponents: this.createComponents,
- isNew: true,
- removeComponents: this.removeComponents,
- parentPath: this.getChildrenPath(this.children.length),
- });
- this.children = this.children.concat(child);
- return child;
- }
-
- removeChild(childToRemove) {
- if (!this.new) {
- this.children = this.children.filter((child) => child !== childToRemove);
- }
-
- return this;
- }
-
- edit() {
- if (this.new) {
- return this;
- }
-
- this.editing = true;
- return this.resetData();
- }
-
- save() {
- const isValid = this.validateNode();
- if (this.changing && isValid) {
- if (this.new) {
- this.new = false;
- }
- else {
- this.editing = false;
- this.revertAvailable = true;
- }
- this.commitData();
- }
-
- return isValid;
- }
-
- cancel() {
- if (this.new) {
- this.remove();
- }
- else if (this.editing) {
- this.editing = false;
- this.resetData();
- }
-
- return this;
- }
-
- remove() {
- this.parent.removeChild(this);
- this.parent = null;
- this.clearComponents();
- return this;
- }
-
- revert() {
- if (!this.revertAvailable) {
- return this;
- }
-
- this.data = this.previousData;
- return this.commitData();
- }
-
- commitData() {
- this.previousData = this.persistentData;
- this.persistentData = _.cloneDeep(this.data);
- this.clearComponents();
- return this;
- }
-
- resetData() {
- this.data = _.cloneDeep(this.persistentData);
- this.updateComponentsContext();
- return this;
- }
-
- updateComponentsContext() {
- if (this.changing) {
- this.instantiateComponents();
- }
- else {
- this.clearComponents();
- }
-
- return this;
- }
-
- instantiateComponents() {
- this.components = this.createComponents(this.data, this);
- this.components.forEach((component) => {
- if (this.parentPath) {
- const path = this.calculateComponentPath(component);
- component.path = path;
- }
- });
- this.checkNode(this);
- }
-
- clearComponents() {
- this.removeComponents(this.components);
- this.components = [];
- }
-
- /**
- * Return a path of component's value.
- *
- * @param {Object} component - The component instance.
- * @return {string} - The component's value path.
- */
- calculateComponentPath(component) {
- let path = '';
- if (component.component.key) {
- path = `${this.parentPath}.data.${component.component.key}`;
- }
- return path;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.form.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.form.js
deleted file mode 100644
index 2fe5c9a1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.form.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import componentEditForm from '../_classes/component/Component.form';
-import TreeEditData from './editForm/Tree.edit.data';
-import TreeDisplayData from './editForm/Tree.edit.display';
-export default function(...extend) {
- return componentEditForm([
- {
- key: 'display',
- components: TreeDisplayData,
- },
- {
- key: 'data',
- components: TreeEditData,
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.js
deleted file mode 100644
index 1cbd9aff..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.js
+++ /dev/null
@@ -1,522 +0,0 @@
-import _ from 'lodash';
-import Component from '../_classes/component/Component';
-import Components from '../Components';
-import NestedDataComponent from '../_classes/nesteddata/NestedDataComponent';
-import Node from './Node';
-import NativePromise from 'native-promise-only';
-
-export default class TreeComponent extends NestedDataComponent {
- static schema(...extend) {
- return NestedDataComponent.schema({
- label: 'Tree',
- key: 'tree',
- type: 'tree',
- clearOnHide: true,
- input: true,
- tree: true,
- components: [],
- multiple: false,
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Tree',
- icon: 'indent',
- weight: 40,
- documentation: '/userguide/form-building/data-components#tree',
- showPreview: false,
- schema: TreeComponent.schema(),
- };
- }
-
- constructor(...args) {
- super(...args);
- this.type = 'tree';
- }
-
- get emptyValue() {
- return {};
- }
-
- get viewComponents() {
- if (!this.viewComponentsInstantiated) {
- this.viewComponentsInstantiated = true;
- this._viewComponents = this.createComponents({});
- }
-
- return this._viewComponents;
- }
-
- init() {
- if (this.builderMode) {
- return super.init();
- }
-
- this.components = [];
- this.componentOptions = {
- ...this.options,
- parent: this,
- root: this.root || this,
- };
- this.disabled = this.shouldDisabled;
- this.setRoot();
- this.viewComponentsInstantiated = false;
- this._viewComponents = [];
- }
-
- get disabled() {
- return super.disabled;
- }
-
- set disabled(disabled) {
- super.disabled = disabled;
- this.viewComponents.forEach((component) => component.parentDisabled = disabled);
- }
-
- get isDefaultValueComponent() {
- return !!this.options.editComponent && !!this.options.editForm && this.component.key === 'defaultValue';
- }
-
- destroy() {
- super.destroy();
-
- if (!this.builderMode) {
- this.removeComponents(this._viewComponents);
- }
- }
-
- createComponents(data, node) {
- const components = this.componentComponents.map(
- (component) => {
- const componentInstance = Components.create(component, this.componentOptions, data);
- componentInstance.init();
- componentInstance.parentDisabled = this.disabled;
- return componentInstance;
- },
- );
-
- if (node) {
- this.checkNode(this.data, node);
- }
-
- return components;
- }
-
- removeComponents(components) {
- return components.map((component) => component.destroy());
- }
-
- render() {
- if (this.builderMode) {
- return super.render();
- }
-
- return super.render(this.renderTree(this.treeRoot));
- }
-
- renderTree(node = {}, odd = true) {
- const childNodes = (node.hasChildren && !node.collapsed)
- ? this.renderChildNodes(node.children, !odd)
- : [];
- const content = node.changing
- ? this.renderEdit(node)
- : this.renderView(node);
-
- return this.renderTemplate('tree', {
- odd,
- childNodes,
- content,
- node,
- });
- }
-
- renderChildNodes(nodes = [], odd) {
- return nodes.map((node) => this.renderTree(node, odd));
- }
-
- renderEdit(node = {}) {
- return this.renderTemplate('treeEdit', {
- children: this.renderComponents(node.components),
- node,
- });
- }
-
- renderView(node = {}) {
- return this.renderTemplate('treeView', {
- values: this.viewComponents.map((component) => {
- component.data = node.data;
- component.checkComponentConditions(node.data);
- return component.getView(component.dataValue);
- }),
- nodeData: node.data,
- node,
- });
- }
-
- attach(element) {
- if (this.builderMode) {
- return super.attach(element);
- }
-
- this.loadRefs(element, {
- root: 'single',
- });
-
- return NativePromise.all([
- super.attach(element),
- this.attachNode(this.refs.root, this.treeRoot),
- ]);
- }
-
- attachNode(element, node) {
- if (!element) {
- return NativePromise.resolve();
- }
-
- let componentsPromise = NativePromise.resolve();
- let childrenPromise = NativePromise.resolve();
-
- node.refs = _.reduce(
- element.children,
- (refs, child) => (
- child.hasAttribute('ref')
- ? {
- ...refs,
- [child.getAttribute('ref')]: child,
- }
- : refs
- ),
- {},
- );
-
- if (node.refs.content) {
- this.attachActions(node);
- componentsPromise = this.attachComponents(node);
- }
-
- if (node.refs.childNodes) {
- childrenPromise = this.attachChildren(node);
- }
-
- return NativePromise.all([
- componentsPromise,
- childrenPromise,
- ]);
- }
-
- attachActions(node) {
- if (!node.editing) {
- this.loadRefs.call(node, node.refs.content, {
- addChild: 'single',
- editNode: 'single',
- removeNode: 'single',
- revertNode: 'single',
- toggleNode: 'single',
- });
- }
-
- //load refs correctly (if there is nested tree)
- this.loadRefs.call(node, node.refs.content.children[0]?.children[1] || node.refs.content, {
- cancelNode: 'single',
- saveNode: 'single',
- });
-
- if (node.refs.addChild) {
- this.addEventListener(node.refs.addChild, 'click', () => {
- this.addChild(node);
- });
- }
-
- if (node.refs.cancelNode) {
- this.addEventListener(node.refs.cancelNode, 'click', () => {
- this.cancelNode(node);
- });
- }
-
- if (node.refs.editNode) {
- this.addEventListener(node.refs.editNode, 'click', () => {
- this.editNode(node);
- });
- }
-
- if (node.refs.removeNode) {
- this.addEventListener(node.refs.removeNode, 'click', () => {
- this.removeNode(node);
- });
- }
-
- if (node.refs.revertNode) {
- this.addEventListener(node.refs.revertNode, 'click', () => {
- this.revertNode(node);
- });
- }
-
- if (node.refs.saveNode) {
- this.addEventListener(node.refs.saveNode, 'click', () => {
- this.saveNode(node);
- });
- }
-
- if (node.refs.toggleNode) {
- this.addEventListener(node.refs.toggleNode, 'click', () => {
- this.toggleNode(node);
- });
- }
- }
-
- attachComponents(node, ...args) {
- if (this.builderMode) {
- return super.attachComponents.call(this, node, ...args);
- }
-
- this.loadRefs.call(node, node.refs.content, {
- nodeEdit: 'single',
- });
-
- return node.refs.nodeEdit
- ? super.attachComponents(node.refs.nodeEdit, node.components)
- : NativePromise.resolve();
- }
-
- attachChildren(node) {
- const childElements = node.refs.childNodes.children;
-
- return NativePromise.all(
- _.map(
- childElements,
- (childElement, index) => this.attachNode(childElement, node.children[index]),
- ),
- );
- }
-
- setValue(value, flags = {}) {
- const changed = this.updateValue(value, flags);
- this.setRoot();
- return changed;
- }
-
- addChild(parent) {
- if (this.options.readOnly || parent.new) {
- return;
- }
-
- this.hook('tree.addChild', {
- parent,
- component: this,
- }, () => {
- const child = parent.addChild();
- this.redraw();
-
- return child;
- });
- }
-
- cancelNode(node) {
- if (this.options.readOnly) {
- return;
- }
-
- this.hook('tree.cancelNode', {
- node,
- component: this,
- }, () => {
- if (node.isRoot) {
- if (node.persistentData && !_.isEmpty(node.persistentData)) {
- node.cancel();
- this.redraw();
- }
- else {
- this.removeRoot();
- }
- }
- else {
- node.cancel();
- this.redraw();
- }
-
- return node;
- });
- }
-
- editNode(node) {
- if (this.options.readOnly || node.new) {
- return;
- }
-
- this.hook('tree.editNode', {
- node,
- component: this,
- }, () => {
- node.edit();
- this.redraw();
-
- return node;
- });
- }
-
- removeNode(node) {
- if (this.options.readOnly || node.new) {
- return;
- }
-
- this.hook('tree.removeNode', {
- node,
- component: this,
- }, () => {
- if (node.isRoot) {
- this.removeRoot();
- }
- else {
- node.remove();
- this.updateTree();
- }
-
- return node;
- });
- }
-
- revertNode(node) {
- if (this.options.readOnly || !node.revertAvailable) {
- return;
- }
-
- this.hook('tree.revertNode', {
- node,
- component: this,
- }, () => {
- node.revert();
- this.updateTree();
-
- return node;
- });
- }
-
- saveNode(node) {
- if (this.options.readOnly) {
- return;
- }
-
- this.hook('tree.saveNode', {
- node,
- component: this,
- }, () => {
- const isSaved = node.save();
- if (isSaved) {
- this.updateTree();
- }
-
- return node;
- });
- }
-
- toggleNode(node) {
- this.hook('tree.toggleNode', {
- node,
- component: this,
- }, () => {
- node.collapsed = !node.collapsed;
- this.redraw();
-
- return node;
- });
- }
-
- removeRoot() {
- if (this.options.readOnly) {
- return;
- }
-
- this.dataValue = this.defaultValue;
- this.setRoot();
- this.redraw();
- }
-
- setRoot() {
- const value = this.getValue();
- this.treeRoot = new Node(null, value, {
- isNew: this.builderMode ? true : !value.data,
- createComponents: this.createComponents.bind(this),
- checkNode: this.checkNode.bind(this, this.data),
- removeComponents: this.removeComponents,
- parentPath: this.isDefaultValueComponent ? (this.path || this.component.key) : null,
- });
- this.hook('tree.setRoot', {
- root: this.treeRoot,
- component: this,
- });
- this.redraw();
- }
-
- getValue() {
- return this.dataValue || {};
- }
-
- updateTree() {
- this.updateValue(this.treeRoot.value);
- this.redraw();
- }
-
- checkData(data, flags, row) {
- return this.checkNode(data, this.treeRoot, flags, row);
- }
-
- checkNode(data, node, flags, row) {
- return node.children.reduce(
- (result, child) => this.checkNode(data, child, flags, row) && result,
- super.checkData(data, flags, node.data, node.components) && !node.editing && !node.new,
- );
- }
-
- getComponents() {
- return this.treeRoot && (this.isDefaultValueComponent || (!this.isDefaultValueComponent && !this.builderMode))
- ? this.treeRoot.getComponents()
- : super.getComponents();
- }
-
- getValueAsString(value, options) {
- const getChildAsString = (value) => {
- let result = (`
-
-
- `);
- result += `
-
- `;
- result += Object.keys(value.data).map((k) => (`
- ${k}
-
- ${value.data[k]}
-
- `));
-
- if (value.children?.length !== 0) {
- value.children?.forEach((v) => {
- result += getChildAsString(v);
- });
- }
-
- result += `
-
-
- `;
-
- result += (`
-
-
- `);
-
- return result;
- };
-
- if (options?.email) {
- let result = '';
- result += getChildAsString(value);
- return result;
- }
-
- return super.getValueAsString(value, options);
- }
-}
-
-TreeComponent.prototype.hasChanged = Component.prototype.hasChanged;
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.unit.js
deleted file mode 100644
index 5ea98fd2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/Tree.unit.js
+++ /dev/null
@@ -1,207 +0,0 @@
-import assert from 'power-assert';
-import Harness from '../../../test/harness';
-import TreeComponent from './Tree';
-import {
- comp1,
- comp2,
- comp3,
- comp4
-} from './fixtures';
-import Webform from '../../Webform';
-import _ from 'lodash';
-import Formio from '../../Formio';
-
-describe('Tree Component', () => {
- it('Should set and render values in readOnly mode', function(done) {
- Harness.testCreate(TreeComponent, comp1).then((component) => {
- component.setValue({
- data: {
- number: 111,
- },
- children: [{
- data: {
- number: 222,
- },
- children: [{
- data: {
- number: 333,
- },
- children: []
- }]
- }]
- });
-
- assert.equal(component.element.querySelectorAll('.tree__node-content').length, 3);
- assert.equal(component.element.querySelectorAll('.editNode').length, 3);
-
- component.options.readOnly = true;
- component.redraw();
-
- const valueContainers = component.element.querySelectorAll('.col-sm-2');
-
- assert.equal(component.element.querySelectorAll('.tree__node-content').length, 3);
- assert.equal(component.element.querySelectorAll('.editNode').length, 0);
- assert.equal(valueContainers[0].innerHTML.trim(), '111');
- assert.equal(valueContainers[1].innerHTML.trim(), '222');
- assert.equal(valueContainers[2].innerHTML.trim(), '333');
-
- done();
- });
- });
- it('Should render tree and allow to save node with basic, layout and data component inside', function(done) {
- Harness.testCreate(TreeComponent, comp2).then((component) => {
- assert.equal(!!component.treeRoot.refs.content, true);
- assert.equal(!!component.treeRoot.refs.cancelNode, true);
- assert.equal(!!component.treeRoot.refs.saveNode, true);
- assert.equal(!!component.treeRoot.refs.addChild, false);
- assert.equal(!!component.treeRoot.refs.editNode, false);
- assert.equal(!!component.treeRoot.refs.removeNode, false);
-
- const value = {
- data: {
- dataGrid: [{ textField: 'data grid 1st row text' }],
- number: 3333,
- select: '',
- textArea: 'text area text',
- },
- children: []
- };
-
- const inputFields = {
- 'data[tree][dataGrid][0][textField]': value.data.dataGrid[0].textField,
- 'data[tree][number]':value.data.number,
- 'data[tree][textArea]': value.data.textArea
- };
-
- const inputEvent = new Event('input');
- _.each(inputFields, (value, fieldName)=> {
- const input = component.element.querySelector(`[name="${fieldName}"]`);
- input.value = value;
- input.dispatchEvent(inputEvent);
- });
-
- setTimeout(() => {
- const clickEvent = new Event('click');
- component.treeRoot.refs.saveNode.dispatchEvent(clickEvent);
- setTimeout(() => {
- assert.equal(!!component.treeRoot.refs.content, true);
- assert.equal(!!component.treeRoot.refs.cancelNode, false);
- assert.equal(!!component.treeRoot.refs.saveNode, false);
- assert.equal(!!component.treeRoot.refs.addChild, true);
- assert.equal(!!component.treeRoot.refs.editNode, true);
- assert.equal(!!component.treeRoot.refs.removeNode, true);
- assert.deepEqual(component.getValue(), value, 'setvalue');
-
- done();
- });
- });
- });
- });
- it('Should keep the node of parent tree opened when saving the node of a child tree', function(done) {
- Harness.testCreate(TreeComponent, comp3).then((component) => {
- assert.equal(!!component.treeRoot.refs.cancelNode, true);
- assert.equal(!!component.treeRoot.refs.saveNode, true);
- assert.equal(!!component.treeRoot.refs.editNode, false);
-
- const clickEvent = new Event('click');
- const childSaveNodeBtn = component.element.querySelector('.formio-component-tree1').querySelector('[ref="saveNode"]');
-
- childSaveNodeBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!component.treeRoot.refs.cancelNode, true);
- assert.equal(!!component.treeRoot.refs.saveNode, true);
- assert.equal(!!component.treeRoot.refs.editNode, false);
-
- const childTree = component.element.querySelector('.formio-component-tree1');
- const saveBtn = childTree.querySelector('[ref="saveNode"]');
- const editBtn = childTree.querySelector('[ref="editNode"]');
-
- assert.equal(!!saveBtn, false);
- assert.equal(!!editBtn, true);
-
- done();
- });
- });
- });
- it('Should allow to open node of a child tree for editing after opening parent tree node', function(done) {
- Harness.testCreate(TreeComponent, comp3).then((component) => {
- assert.equal(!!component.treeRoot.refs.cancelNode, true, 'Should show cancel btn for parent tree');
- assert.equal(!!component.treeRoot.refs.saveNode, true, 'Should show save btn for parent tree');
- assert.equal(!!component.treeRoot.refs.editNode, false, 'Should not show edit btn for parent node in editing tree');
-
- assert.equal(!!component.treeRoot.components[0].treeRoot.refs.cancelNode, true, 'Should show cancel btn for child tree');
- assert.equal(!!component.treeRoot.components[0].treeRoot.refs.saveNode, true, 'Should show save btn for child tree');
- assert.equal(!!component.treeRoot.components[0].treeRoot.refs.editNode, false, 'Should not show edit btn for child tree in editing tree');
-
- const clickEvent = new Event('click');
- const childSaveNodeBtn = component.treeRoot.components[0].treeRoot.refs.saveNode;
- const parentSaveNodeBtn = component.treeRoot.refs.saveNode;
- childSaveNodeBtn.dispatchEvent(clickEvent);
- parentSaveNodeBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!component.treeRoot.refs.cancelNode, false, 'Should not show cancel btn for parent tree');
- assert.equal(!!component.treeRoot.refs.saveNode, false, 'Should not show save btn for parent tree');
- assert.equal(!!component.treeRoot.refs.editNode, true, 'Should show edit btn for parent tree');
-
- const parentEditNodeBtn = component.treeRoot.refs.editNode;
-
- parentEditNodeBtn.dispatchEvent(clickEvent);
-
- setTimeout(() => {
- assert.equal(!!component.treeRoot.components[0].treeRoot.refs.saveNode, false, 'Should not show save btn for child tree');
- assert.equal(!!component.treeRoot.components[0].treeRoot.refs.editNode, true, 'Should show edit btn for child tree');
-
- const childEditNodeBtn = component.treeRoot.components[0].treeRoot.refs.editNode;
-
- childEditNodeBtn.dispatchEvent(clickEvent);
-
- assert.equal(component.treeRoot.components[0].treeRoot.editing, true, 'Should set editing mode for child tree');
- assert.equal(!!component.treeRoot.components[0].treeRoot.refs.saveNode, true, 'Should show save btn for child tree');
-
- done();
- });
- });
- });
- });
-
- it('Should stop the submission if component didn\'t saved and has required fields', (done) => {
- const formElement = document.createElement('div');
- const form = new Webform(formElement);
- form.setForm(comp4).then(() => {
- const submitButton = form.getComponent(['submit']);
- assert.equal(submitButton.disabled, true, 'Submit button should being disabled');
- const tree = form.getComponent(['tree']);
- const textField = tree.getComponents()[0].getComponent(['textField']);
- textField.setValue('123');
-
- setTimeout(() => {
- assert.equal(submitButton.disabled, true, 'Submit button should being disabled');
- tree.saveNode(tree.treeRoot);
-
- setTimeout(() => {
- assert.equal(submitButton.disabled, false, 'Submit button should being disabled');
- done();
- }, 300);
- }, 300);
- }).catch(done);
- });
-
- it('Should work with empty data and no defaults', (done) => {
- const formElement = document.createElement('div');
- Formio.createForm(formElement, {
- type: 'form',
- components: [comp1],
- display: 'form',
- }, { noDefaults: true })
- .then((form) => {
- setTimeout(() => {
- const tree = form.getComponent(['tree']);
- assert.equal(tree.treeRoot.new, true);
- done();
- }, 300);
- })
- .catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/editForm/Tree.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/editForm/Tree.edit.data.js
deleted file mode 100644
index 296b37f4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/editForm/Tree.edit.data.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default [
- {
- key: 'multiple',
- ignore: true
- },
-];
-/* eslint-enable max-len */
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/editForm/Tree.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/editForm/Tree.edit.display.js
deleted file mode 100644
index 5c563e98..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/editForm/Tree.edit.display.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default [
- {
- key: 'treeInfo',
- weight: -10,
- type: 'htmlelement',
- tag: 'div',
- className: 'alert alert-danger',
- content: 'This component has been deprecated and will be removed in a future version of Formio.js.',
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp1.js
deleted file mode 100644
index 9e698b57..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp1.js
+++ /dev/null
@@ -1,23 +0,0 @@
-export default {
- 'label': 'Tree',
- 'tableView': true,
- 'calculateServer': false,
- 'key': 'tree',
- 'type': 'tree',
- 'input': true,
- 'tree': true,
- 'components': [{
- 'label': 'Number',
- 'mask': false,
- 'spellcheck': true,
- 'tableView': false,
- 'delimiter': false,
- 'requireDecimal': false,
- 'inputFormat': 'plain',
- 'calculateServer': false,
- 'key': 'number',
- 'type': 'number',
- 'input': true
- }]
-};
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp2.js
deleted file mode 100644
index d7b1f9b3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp2.js
+++ /dev/null
@@ -1,80 +0,0 @@
-export default {
- 'label': 'Tree',
- 'tableView': false,
- 'key': 'tree',
- 'type': 'tree',
- 'input': true,
- 'tree': true,
- 'components': [{
- 'label': 'Text Area',
- 'autoExpand': false,
- 'tableView': true,
- 'key': 'textArea',
- 'type': 'textarea',
- 'input': true
- }, {
- 'label': 'Select',
- 'widget': 'choicesjs',
- 'tableView': true,
- 'data': {
- 'values': [{
- 'label': 'a',
- 'value': 'a'
- }, {
- 'label': 'b',
- 'value': 'b'
- }, {
- 'label': 'c',
- 'value': 'c'
- }]
- },
- 'selectThreshold': 0.3,
- 'validate': {
- 'onlyAvailableItems': false
- },
- 'key': 'select',
- 'type': 'select',
- 'indexeddb': {
- 'filter': {}
- },
- 'input': true
- }, {
- 'collapsible': false,
- 'key': 'panel',
- 'type': 'panel',
- 'label': 'Panel',
- 'input': false,
- 'tableView': false,
- 'components': [{
- 'label': 'Number',
- 'mask': false,
- 'spellcheck': true,
- 'tableView': false,
- 'delimiter': false,
- 'requireDecimal': false,
- 'inputFormat': 'plain',
- 'key': 'number',
- 'type': 'number',
- 'input': true
- }]
- }, {
- 'label': 'Data Grid',
- 'reorder': false,
- 'addAnotherPosition': 'bottom',
- 'layoutFixed': false,
- 'enableRowGroups': false,
- 'initEmpty': false,
- 'tableView': false,
- 'defaultValue': [{}],
- 'key': 'dataGrid',
- 'type': 'datagrid',
- 'input': true,
- 'components': [{
- 'label': 'Text Field',
- 'tableView': true,
- 'key': 'textField',
- 'type': 'textfield',
- 'input': true
- }]
- }]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp3.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp3.js
deleted file mode 100644
index 922cdb45..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp3.js
+++ /dev/null
@@ -1,23 +0,0 @@
-export default {
- 'label': 'Tree',
- 'tableView': false,
- 'key': 'tree',
- 'type': 'tree',
- 'input': true,
- 'tree': true,
- 'components': [{
- 'label': 'Tree',
- 'tableView': false,
- 'key': 'tree1',
- 'type': 'tree',
- 'input': true,
- 'tree': true,
- 'components': [{
- 'label': 'Text Field',
- 'tableView': true,
- 'key': 'textField',
- 'type': 'textfield',
- 'input': true
- }]
- }]
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp4.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp4.js
deleted file mode 100644
index 46ad419c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/comp4.js
+++ /dev/null
@@ -1,45 +0,0 @@
-export default {
- type: 'form',
- owner: null,
- components: [
- {
- label: 'Tree',
- tableView: false,
- key: 'tree',
- type: 'tree',
- input: true,
- tree: true,
- components: [
- {
- title: 'Required validation',
- collapsible: false,
- key: 'panel',
- type: 'panel',
- label: 'Panel',
- input: false,
- tableView: false,
- components: [
- {
- label: 'Text Field',
- tableView: true,
- validate: {
- required: true,
- },
- key: 'textField',
- type: 'textfield',
- input: true,
- },
- ],
- },
- ],
- },
- {
- type: 'button',
- label: 'Submit',
- key: 'submit',
- disableOnInvalid: true,
- input: true,
- tableView: false,
- },
- ],
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/index.js
deleted file mode 100644
index 6664cb89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/tree/fixtures/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
-export comp3 from './comp3';
-export comp4 from './comp4';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.form.js b/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.form.js
deleted file mode 100644
index d111ace1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.form.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import UnknownEditDisplay from './editForm/Unknown.edit.display';
-export default function() {
- return {
- components: [
- {
- type: 'tabs',
- key: 'tabs',
- components: [
- {
- label: 'Custom',
- key: 'display',
- weight: 0,
- components: UnknownEditDisplay
- }
- ]
- }
- ]
- };
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.js b/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.js
deleted file mode 100644
index 4c8ec12f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import Component from '../_classes/component/Component';
-
-export default class UnknownComponent extends Component {
- static schema() {
- return {
- type: 'custom',
- key: 'custom',
- protected: false,
- persistent: true
- };
- }
-
- static get builderInfo() {
- return {
- title: 'Custom',
- icon: 'cubes',
- group: 'premium',
- documentation: '/userguide/form-building/premium-components#custom',
- weight: 120,
- schema: UnknownComponent.schema()
- };
- }
-
- get defaultSchema() {
- return UnknownComponent.schema();
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.unit.js
deleted file mode 100644
index 6c29a3d1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/unknown/Unknown.unit.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import UnknownComponent from './Unknown';
-
-import {
- comp1
-} from './fixtures';
-
-describe('Custom Component', () => {
- it('Should build a Custom component in builder mode', (done) => {
- new UnknownComponent(comp1, {
- builder: true
- });
- done();
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/unknown/editForm/Unknown.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/unknown/editForm/Unknown.edit.display.js
deleted file mode 100644
index e6042d03..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/unknown/editForm/Unknown.edit.display.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default [
- {
- key: 'customComponentDescription',
- label: 'Custom component description',
- input: false,
- tag: 'p',
- content: 'Custom components can be used to render special fields or widgets inside your app. ' +
- 'For information on how to display in an app, see ' +
- '
' +
- 'custom component documentation' +
- ' .',
- type: 'htmlelement',
- weight: 5
- },
- {
- type: 'textarea',
- as: 'json',
- editor: 'ace',
- weight: 10,
- input: true,
- key: 'componentJson',
- label: 'Custom Element JSON',
- tooltip: 'Enter the JSON for this custom element.'
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/unknown/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/unknown/fixtures/comp1.js
deleted file mode 100644
index 7224bd04..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/unknown/fixtures/comp1.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
- 'label': 'My Own Custom Component',
- 'type': 'myOwnCustomType',
- 'input': true,
- 'key': 'custom2'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/unknown/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/unknown/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/unknown/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/Url.form.js b/web-client/core/themes/italia/static/formio/css/src/components/url/Url.form.js
deleted file mode 100644
index 4b772ba6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/Url.form.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import textEditForm from '../textfield/TextField.form';
-
-import UrlEditDisplay from './editForm/Url.edit.display';
-import UrlEditData from './editForm/Url.edit.data';
-import UrlEditValidation from './editForm/Url.edit.validation';
-
-export default function(...extend) {
- return textEditForm([
- {
- key: 'display',
- components: UrlEditDisplay
- },
- {
- key: 'data',
- components: UrlEditData
- },
- {
- key: 'validation',
- components: UrlEditValidation
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/Url.js b/web-client/core/themes/italia/static/formio/css/src/components/url/Url.js
deleted file mode 100644
index 56a4908e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/Url.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import TextFieldComponent from '../textfield/TextField';
-
-export default class UrlComponent extends TextFieldComponent {
- static schema(...extend) {
- return TextFieldComponent.schema({
- type: 'url',
- label: 'Url',
- key: 'url',
- inputType: 'url'
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Url',
- group: 'advanced',
- icon: 'link',
- documentation: '/userguide/form-building/advanced-components#url',
- weight: 20,
- schema: UrlComponent.schema()
- };
- }
-
- constructor(component, options, data) {
- super(component, options, data);
- this.validators.push('url');
- }
-
- get defaultSchema() {
- return UrlComponent.schema();
- }
-
- elementInfo() {
- const info = super.elementInfo();
- info.attr.type = this.component.mask ? 'password' : 'url';
- return info;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/Url.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/url/Url.unit.js
deleted file mode 100644
index 2391c486..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/Url.unit.js
+++ /dev/null
@@ -1,226 +0,0 @@
-import Harness from '../../../test/harness';
-import UrlComponent from './Url';
-import Formio from './../../Formio';
-import assert from 'power-assert';
-import _ from 'lodash';
-
-import {
- comp1,
- comp2
-} from './fixtures';
-
-describe('Url Component', () => {
- it('Should build a url component', (done) => {
- Harness.testCreate(UrlComponent, comp1).then(() => {
- done();
- });
- });
-
- it('Should provide min/max length validation', (done) => {
- const form = _.cloneDeep(comp2);
- form.components[0].validate = { minLength: 6, maxLength: 10 };
-
- const validValues = [
- '',
- 'www.hhh.by',
- 'uuu.by',
- 'TE2-t.est',
- 'te2-t.est'
- ];
-
- const invalidMin = [
- 'hh.jj',
- 'w.by'
- ];
-
- const invalidMax = [
- 'Test-t.Test',
- 'test.test.test',
- 't-t-t-t-t.tt'
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('url');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message, error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidMin, false, 'Url must have at least 6 characters.');
- testValidity(invalidMax, false, 'Url must have no more than 10 characters.', invalidMax[invalidMax.length-1]);
- });
-
- it('Should provide pattern validation', (done) => {
- const form = _.cloneDeep(comp2);
- form.components[0].validate = { pattern: '^(https?):\\/\\/(-\\.)?([^\\s\\/?\\.#-]+\\.?)+(\\/[^\\s]*)?$' };
-
- const validValues = [
- 'https://someTest.com',
- 'http://test.com',
- 'http://userid@example.com:8080',
- ''
- ];
-
- const invalidValues = [
- 'www.test.com',
- 'test.hh',
- 'http://at--er.b.co'
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('url');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message.trim(), error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues,
- false,
- 'Url does not match the pattern ^(https?):\\/\\/(-\\.)?([^\\s\\/?\\.#-]+\\.?)+(\\/[^\\s]*)?$',
- invalidValues[invalidValues.length-1]
- );
- });
-
- it('Should provide url validation', (done) => {
- const form = _.cloneDeep(comp2);
-
- const validValues = [
- '',
- 'www.test.test',
- 'https://www.test.test',
- 'http://www.test.test',
- 'email://test1111@test.to',
- 'email://t-e-s-t@te-st.to',
- 'te.S-T.test',
- 'www.1111111.test'
- ];
-
- const invalidValues = [
- ' ',
- 'e.S-T.test.',
- 'someText',
- '.www.test.to',
- 'htthhhhhps://www.test.test',
- '://www.test.test',
- ' www.test.test',
- 'www.test.test ',
- 'www.te st.test',
- 'www.1111111.33',
- 'www.rrrrrr.66h',
- 'email://test111test.to',
- 'http://',
- 'http://.',
- 'http://..',
- 'http://../',
- 'http://?',
- 'http://??',
- 'http://??/',
- 'http://#',
- 'http://##',
- 'http://##/',
- 'http://foo.bar?q=Spaces should be encoded',
- '//',
- '//a',
- '///a',
- '///',
- 'http:///a'
- ];
-
- const testValidity = (values, valid, message, lastValue) => {
- _.each(values, (value) => {
- const element = document.createElement('div');
-
- Formio.createForm(element, form).then(form => {
- form.setPristine(false);
-
- const component = form.getComponent('url');
- const changed = component.setValue(value);
- const error = message;
-
- if (value) {
- assert.equal(changed, true, 'Should set value');
- }
-
- setTimeout(() => {
- if (valid) {
- assert.equal(!!component.error, false, 'Should not contain error');
- }
- else {
- assert.equal(!!component.error, true, 'Should contain error');
- assert.equal(component.error.message.trim(), error, 'Should contain error message');
- assert.equal(component.element.classList.contains('has-error'), true, 'Should contain error class');
- assert.equal(component.refs.messageContainer.textContent.trim(), error, 'Should show error');
- }
-
- if (_.isEqual(value, lastValue)) {
- done();
- }
- }, 300);
- }).catch(done);
- });
- };
-
- testValidity(validValues, true);
- testValidity(invalidValues,
- false,
- 'Url must be a valid url.',
- invalidValues[invalidValues.length-1]
- );
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.data.js b/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.data.js
deleted file mode 100644
index 17004a3a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.data.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default [
- {
- key: 'case',
- ignore: true,
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.display.js
deleted file mode 100644
index 3310b2ac..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.display.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default [
- {
- key: 'inputMask',
- ignore: true
- },
- {
- key: 'allowMultipleMasks',
- ignore: true
- },
- {
- key: 'showWordCount',
- ignore: true,
- },
- {
- key: 'showCharCount',
- ignore: true,
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.validation.js b/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.validation.js
deleted file mode 100644
index 27ef9e7c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/editForm/Url.edit.validation.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default [
- {
- key: 'validate.minWords',
- ignore: true,
- },
- {
- key: 'validate.maxWords',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/comp1.js
deleted file mode 100644
index 7cc2b18f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/comp1.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [
-
- ],
- 'type': 'url',
- 'kickbox': {
- 'enabled': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'suffix': '',
- 'prefix': '',
- 'placeholder': 'Enter a URL',
- 'key': 'url',
- 'label': 'Url',
- 'inputType': 'url',
- 'tableView': true,
- 'input': true
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/comp2.js b/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/comp2.js
deleted file mode 100644
index 6d79d29c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/comp2.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export default {
- type: 'form',
- components: [
- { label: 'Url', tableView: true, key: 'url', type: 'url', input: true },
- {
- label: 'Submit',
- showValidations: false,
- tableView: false,
- key: 'submit',
- type: 'button',
- input: true
- }
- ],
- title: 'test11',
- display: 'form',
- controller: '',
- properties: {},
- settings: {},
- name: 'test11',
- path: 'test11',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/index.js
deleted file mode 100644
index 63468958..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export comp1 from './comp1';
-export comp2 from './comp2';
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/values.js b/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/values.js
deleted file mode 100644
index ebaa3c3d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/url/fixtures/values.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default [
- 'https://www.google.com',
- 'https://www.apple.com',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/well/Well.form.js b/web-client/core/themes/italia/static/formio/css/src/components/well/Well.form.js
deleted file mode 100644
index 1c7f8764..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/well/Well.form.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import nestedComponentForm from '../_classes/nested/NestedComponent.form';
-
-import WellEditDisplay from './editForm/Well.edit.display';
-
-export default function(...extend) {
- return nestedComponentForm([
- {
- key: 'display',
- components: WellEditDisplay
- },
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/well/Well.js b/web-client/core/themes/italia/static/formio/css/src/components/well/Well.js
deleted file mode 100644
index c9819959..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/well/Well.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import NestedComponent from '../_classes/nested/NestedComponent';
-
-export default class WellComponent extends NestedComponent {
- static schema(...extend) {
- return NestedComponent.schema({
- type: 'well',
- key: 'well',
- input: false,
- persistent: false,
- components: []
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Well',
- icon: 'square-o',
- group: 'layout',
- documentation: '/userguide/form-building/layout-components#well',
- showPreview: false,
- weight: 60,
- schema: WellComponent.schema()
- };
- }
-
- static savedValueTypes() {
- return [];
- }
-
- get defaultSchema() {
- return WellComponent.schema();
- }
-
- get className() {
- return `${this.component.customClass}`;
- }
-
- get templateName() {
- return 'well';
- }
-
- constructor(...args) {
- super(...args);
- this.noField = true;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/well/Well.unit.js b/web-client/core/themes/italia/static/formio/css/src/components/well/Well.unit.js
deleted file mode 100644
index a296cff4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/well/Well.unit.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import Harness from '../../../test/harness';
-import WellComponent from './Well';
-
-import {
- comp1
-} from './fixtures';
-import { expect } from 'chai';
-
-describe('Well Component', () => {
- it('Should build a Well component', () => {
- return Harness.testCreate(WellComponent, comp1).then((component) => {
- Harness.testElements(component, 'input[type="text"]', 2);
- });
- });
-
- it('Should skip validation on non-input nested components', done => {
- Harness.testCreate(WellComponent, comp1)
- .then(cmp => {
- expect(cmp.shouldSkipValidation()).to.be.true;
- done();
- }, done)
- .catch(done);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/well/editForm/Well.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/components/well/editForm/Well.edit.display.js
deleted file mode 100644
index 61d3e0aa..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/well/editForm/Well.edit.display.js
+++ /dev/null
@@ -1,30 +0,0 @@
-export default [
- {
- key: 'labelPosition',
- ignore: true
- },
- {
- key: 'placeholder',
- ignore: true
- },
- {
- key: 'description',
- ignore: true
- },
- {
- key: 'autofocus',
- ignore: true
- },
- {
- key: 'tooltip',
- ignore: true
- },
- {
- key: 'tabindex',
- ignore: true
- },
- {
- key: 'tableView',
- ignore: true
- },
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/well/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/components/well/fixtures/comp1.js
deleted file mode 100644
index bc6a9c22..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/well/fixtures/comp1.js
+++ /dev/null
@@ -1,79 +0,0 @@
-export default {
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'tags': [],
- 'type': 'well',
- 'components': [
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'firstName',
- 'label': 'First Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- },
- {
- 'tags': [
-
- ],
- 'type': 'textfield',
- 'conditional': {
- 'eq': '',
- 'when': null,
- 'show': ''
- },
- 'validate': {
- 'customPrivate': false,
- 'custom': '',
- 'pattern': '',
- 'maxLength': '',
- 'minLength': '',
- 'required': false
- },
- 'persistent': true,
- 'unique': false,
- 'protected': false,
- 'defaultValue': '',
- 'multiple': false,
- 'suffix': '',
- 'prefix': '',
- 'placeholder': '',
- 'key': 'lastName',
- 'label': 'Last Name',
- 'inputMask': '',
- 'inputType': 'text',
- 'tableView': true,
- 'input': true
- }
- ],
- 'input': false,
- 'key': 'well1'
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/components/well/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/components/well/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/components/well/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.form.js b/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.form.js
deleted file mode 100644
index 2f12ae24..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.form.js
+++ /dev/null
@@ -1,77 +0,0 @@
-import baseEditForm from '../../components/_classes/component/Component.form';
-import EditTableEditDisplay from './editForm/EditTable.edit.display';
-
-export default function(...extend) {
- return baseEditForm([
- {
- key: 'display',
- components: EditTableEditDisplay,
- },
- {
- key: 'data',
- components: [{
- key: 'defaultValue',
- ignore: true
- }, {
- label: '',
- mask: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'hidden',
- input: true,
- key: 'disableAddingRemovingRows',
- calculateValue(context) {
- return context.instance.data.enableRowGroups;
- },
- encrypted: false
- }, {
- key: 'enableRowGroups',
- type: 'checkbox',
- label: 'Enable Row Groups',
- weight: 50,
- }, {
- label: 'Groups',
- disableAddingRemovingRows: false,
- defaultOpen: false,
- addAnother: '',
- addAnotherPosition: 'bottom',
- mask: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'datagrid',
- input: true,
- key: 'rowGroups',
- reorder: true,
- components: [
- {
- label: 'Label',
- allowMultipleMasks: false,
- showWordCount: false,
- showCharCount: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'textfield',
- input: true,
- key: 'label',
- widget: {
- type: ''
- },
- row: '0-0'
- },
- {
- label: 'Number of Rows',
- mask: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'number',
- input: true,
- key: 'numberOfRows',
- row: '0-1'
- }
- ],
- weight: 51,
- conditional: { json: { var: 'data.enableRowGroups' } }
- }],
- }
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.js b/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.js
deleted file mode 100644
index 99174ee5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.js
+++ /dev/null
@@ -1,284 +0,0 @@
-import _ from 'lodash';
-import DataGridComponent from '../../components/datagrid/DataGrid';
-import ModalEdit from '../modaledit/ModalEdit';
-import EditTableForm from './EditTable.form';
-
-export default class EditTableComponent extends DataGridComponent {
- static schema(...extend) {
- return DataGridComponent.schema({
- label: 'Edit Table',
- key: 'editTable',
- type: 'edittable',
- input: true,
- tree: true,
- components: [],
- columns: [],
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Edit Table',
- icon: 'th',
- group: 'data',
- weight: 50,
- schema: EditTableComponent.schema()
- };
- }
-
- constructor(...args) {
- super(...args);
-
- const groups = _.get(this.component, 'rowGroups', []);
-
- if (this.hasColumns()) {
- this.component.components = this.componentComponents;
- }
-
- if (this.groupsMode) {
- this.addEmptyRows(this.totalRowsNumber(groups));
- }
- }
-
- /**
- * Checks whether columns are available
- * @return {Boolean}
- */
- hasColumns() {
- return this.getColumns().length > 0;
- }
-
- /** Don't show last col in header **/
- /** @override **/
- hasExtraColumn() {
- return false;
- }
-
- /** @override **/
- hasAddButton() {
- return super.hasAddButton() && this.hasColumns();
- }
-
- componentSchema(...extend) {
- return ModalEdit.schema({
- rows: 0,
- editor: 'ckeditor',
- hideLabel: true,
- }, ...extend);
- }
-
- /**
- * Returns all non-empty columns.
- *
- * @return {Array}
- */
- getColumns() {
- const cols = _.get(this, 'component.columns', []);
-
- return _.filter(
- _.map(cols, c => _.pick(c, ['label', 'key'])),
- c => !_.isEqual(c, this.emptyColumn),
- );
- }
-
- getGroups() {
- return _.get(this.component, 'rowGroups', []);
- }
-
- totalRowsNumber(groups) {
- return _.sum(_.map(groups, 'numberOfRows'));
- }
-
- addEmptyRows(n) {
- this.dataValue = _.range(n).map(() => ({}));
- }
-
- get emptyColumn() {
- return { label: '', key: '' };
- }
-
- get componentComponents() {
- return this.getColumns().map(({ label, key }) => {
- return this.componentSchema({ label, key });
- });
- }
-
- get tableClass() {
- const type = _.get(this.component, 'type', 'edittable');
- const defaultClass = [
- 'table',
- 'table-bordered',
- `table-${type}`,
- 'form-group',
- `formio-${type}-table`
- ].join(' ');
- let className = _.get(this.component, 'tableClass');
-
- if (className === '' || !_.isString(className)) {
- className = defaultClass;
- }
-
- ['striped', 'bordered', 'hover', 'condensed'].forEach((prop) => {
- if (this.component[prop]) {
- className = `${className} table-${prop}`;
- }
- });
-
- return className;
- }
-
- get groupsMode() {
- return _.get(this.component, 'enableRowGroups', false);
- }
-
- /** @override **/
- build(state = {}) {
- super.build(state);
-
- this.tableElement.className = this.tableClass;
-
- if (this.builderMode && !this.hasColumns()) {
- this.element.appendChild(this.builderView());
- }
-
- this.setMeta();
- }
-
- buildRows() {
- super.buildRows();
-
- if (this.groupsMode) {
- this.buildGroups();
- }
- }
-
- buildGroups() {
- const groups = _.get(this.component, 'rowGroups', []);
- const ranges = _.map(groups, 'numberOfRows');
- const rows = this.tableElement.querySelectorAll('tbody>tr');
- const tbody = this.tableElement.querySelector('tbody');
- const chunks = this.getRowChunks(ranges, rows);
- const firstElements = chunks.map(_.head);
- const groupElements = groups.map(g => this.buildGroup(g));
-
- groupElements.forEach((elt, index) => {
- const row = firstElements[index];
-
- if (row) {
- tbody.insertBefore(elt, row);
- }
- });
- }
-
- /**
- * @param {Numbers[]} groups
- * @param {Array
} coll - collection
- *
- * @return {Array}
- */
- getRowChunks(groups, coll) {
- const [, chunks] = groups.reduce(
- ([startIndex, acc], size) => {
- const endIndex = startIndex + size;
- return [endIndex, [...acc, [startIndex, endIndex]]];
- },
- [0, []]
- );
-
- return chunks.map(range => _.slice(coll, ...range));
- }
-
- buildGroup({ label }) {
- const colsNumber = this.getColumns().length;
- const cell = this.ce('td', {
- colspan: colsNumber,
- class: 'edittable-group-label',
- }, label);
- return this.ce('tr', null, cell);
- }
-
- /** @override **/
- buildRow(row, index, state = {}) {
- if (this.builderMode) {
- return null;
- }
-
- this.rows[index] = {};
-
- const colSchemes = this.componentComponents;
- const lastIndex = colSchemes.length - 1;
- const columns = colSchemes.map(
- (col, colIndex) => {
- const colContainer = this.buildComponent(
- col,
- colIndex,
- row,
- index,
- this.getComponentState(col, state)
- );
-
- if (this.hasRemoveButtons() && colIndex === lastIndex) {
- colContainer.append(this.removeButton(index));
- }
-
- return colContainer;
- }
- );
-
- return this.ce('tr', null, columns);
- }
-
- /** override **/
- removeButton(index) {
- const type = _.get(this.component, 'type', 'edittable');
- const button = this.ce(
- 'button',
- {
- type: 'button',
- class: `btn btn-xxs btn-danger formio-${type}-remove`,
- },
- this.ce('i', {
- class: this.iconClass('remove')
- })
- );
-
- this.addEventListener(button, 'click', (event) => {
- event.preventDefault();
- this.removeValue(index);
- });
-
- return button;
- }
-
- builderView() {
- return this.ce('div', { class: 'well edittable-placeholder' }, [
- this.ce('i', { class: this.iconClass('warning-sign') }),
- ' ',
- this.t('No columns provided')
- ]);
- }
-
- getMeta() {
- const groups = this.getGroups();
- if (this.hasColumns && groups.length) {
- return groups.reduce((info, g) => {
- info[g.label] = g.numberOfRows;
- return info;
- }, {});
- }
- else {
- return null;
- }
- }
-
- setMeta() {
- const key = _.get(this.component, 'key');
- const data = this.getMeta();
-
- if (key && data) {
- _.set(this.root, ['_submission', 'metadata', key], data);
- }
- }
-}
-
-EditTableComponent.editForm = EditTableForm;
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.spec.js b/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.spec.js
deleted file mode 100644
index 05a35612..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/EditTable.spec.js
+++ /dev/null
@@ -1,387 +0,0 @@
-import { expect } from 'chai';
-import Harness from '../../../test/harness';
-import EditTable from './EditTable';
-import Webform from '../../Webform';
-import { basic } from './fixtures/index';
-
-const { testCreate: create } = Harness;
-
-describe('EditTable Component', () => {
- it('should create component', done => {
- create(EditTable, basic).then(() => done(), done);
- });
-
- it('should add row groups to form metadata', done => {
- const domRoot = document.createElement('div');
- const form = new Webform(domRoot);
- form
- .setForm({
- title: 'Simple Form',
- components: [{
- type: 'edittable',
- key: 'questions',
- rowGroups: [
- {
- label: 'A',
- numberOfRows: 1
- },
- {
- label: 'B',
- numberOfRows: 1
- },
- {
- label: 'Header',
- numberOfRows: 4
- }
- ],
- input: true
- }]
- })
- .then(() => {
- expect(form._submission.metadata['questions']).to.deep.equal({
- A: 1,
- B: 1,
- Header: 4
- });
- done();
- }, done)
- .catch(done);
- });
-
- describe('hasColumns', () => {
- it('should false if there no columns', done => {
- create(EditTable, basic).then(edittable => {
- expect(edittable.hasColumns()).to.be.false;
- done();
- }, done).catch(done);
- });
-
- it('should true if there columns', done => {
- const schema = Object.assign({}, basic, {
- columns: [{ key: 'name', label: 'Name' }]
- });
-
- create(EditTable, schema).then(edittable => {
- expect(edittable.hasColumns()).to.be.true;
- done();
- }, done).catch(done);
- });
- });
-
- describe('componentSchema', () => {
- it('should return valid schema', done => {
- create(EditTable, basic).then(edittable => {
- const schema = edittable.componentSchema();
- expect(schema).to.have.property('key');
- expect(schema).to.have.property('type');
- expect(schema).to.have.property('label');
- expect(schema).to.have.property('input');
- done();
- }, done).catch(done);
- });
-
- it('should return Modal Edit schema', done => {
- create(EditTable, basic).then(edittable => {
- const schema = edittable.componentSchema();
- expect(schema).to.have.property('key', 'modalEdit');
- expect(schema).to.have.property('type', 'modaledit');
- expect(schema).to.have.property('label', 'Modal Edit');
- expect(schema).to.have.property('input', true);
- done();
- }, done).catch(done);
- });
- });
-
- describe('getColumns', () => {
- it('should return empty array if no columns', done => {
- create(EditTable, basic).then(edittable => {
- expect(edittable.getColumns()).to.be.empty;
- done();
- }, done).catch(done);
- });
- it('should return array of columns', done => {
- const columns = [
- { key: 'name', label: 'Name' },
- { key: 'age', label: 'Age' }
- ];
-
- const schema = Object.assign({}, basic, {
- columns: [...columns],
- });
-
- create(EditTable, schema).then(edittable => {
- expect(edittable.getColumns()).to.deep.equal(columns);
- done();
- }, done).catch(done);
- });
- it('should return non-empty columns', done => {
- const columns = [
- { key: '', label: '' },
- { key: 'name', label: 'Name' },
- { key: '', label: '' },
- { key: 'age', label: 'Age' },
- { key: '', label: '' },
- ];
-
- const schema = Object.assign({}, basic, {
- columns: [...columns],
- });
-
- create(EditTable, schema).then(edittable => {
- expect(edittable.getColumns()).to.deep.equal([
- { key: 'name', label: 'Name' },
- { key: 'age', label: 'Age' }
- ]);
- done();
- }, done).catch(done);
- });
- });
-
- describe('getGroups', () => {
- it('should return empty array if no row groups', done => {
- create(EditTable, basic).then(edittable => {
- expect(edittable.getGroups()).to.be.an('array').empty;
- done();
- }, done).catch(done);
- });
-
- it('should return row groups', done => {
- const groups = [
- {
- label: 'A',
- numberOfRows: 1
- },
- {
- label: 'B',
- numberOfRows: 1
- }
- ];
-
- const schema = Object.assign({}, basic, {
- rowGroups: [...groups]
- });
-
- create(EditTable, schema).then(edittable => {
- expect(edittable.getGroups()).to.deep.equal(groups);
- done();
- }, done).catch(done);
- });
- });
-
- describe('totalRowsNumber', () => {
- it('should return the total count of rows in the provided groups', () => {
- const groups = [
- {
- label: 'A',
- numberOfRows: 1
- },
- {
- label: 'B',
- numberOfRows: 2
- },
- {
- label: 'C',
- numberOfRows: 4
- },
- {
- label: 'D',
- numberOfRows: 9
- }
- ];
-
- const { totalRowsNumber } = EditTable.prototype;
-
- expect(totalRowsNumber(groups)).to.equal(16);
- expect(totalRowsNumber(groups.slice(1))).to.equal(15);
- expect(totalRowsNumber(groups.slice(2))).to.equal(13);
- expect(totalRowsNumber(groups.slice(3))).to.equal(9);
- expect(totalRowsNumber(groups.slice(0, 2))).to.equal(3);
- });
- });
-
- describe('addEmptyRows', () => {
- it('should create an array of n empty rows and set it to dataValue', done => {
- create(EditTable, basic).then(edittable => {
- edittable.addEmptyRows(1);
- expect(edittable.dataValue).to.deep.equal([{}]);
- edittable.addEmptyRows(2);
- expect(edittable.dataValue).to.deep.equal([{}, {}]);
- edittable.addEmptyRows(2);
- expect(edittable.dataValue).to.deep.equal([{}, {}]);
- edittable.addEmptyRows(3);
- expect(edittable.dataValue).to.deep.equal([{}, {}, {}]);
- done();
- }, done).catch(done);
- });
- });
-
- describe('get emptyColumn', () => {
- it('should return object that represents empty column', done => {
- create(EditTable, basic).then(edittable => {
- expect(edittable.emptyColumn).to.deep.equal({ label: '', key: '' });
- done();
- }, done).catch(done);
- });
- });
-
- describe('get tableClass', () => {
- it('should return table class string', done => {
- create(EditTable, basic).then(edittable => {
- expect(edittable.tableClass).to.equal(
- 'table table-bordered table-edittable form-group formio-edittable-table'
- );
- done();
- }, done).catch(done);
- });
- });
-
- describe('getRowChunks', () => {
- it('should return rows split by chunks according to group size', () => {
- const { getRowChunks } = EditTable.prototype;
- let chunks = getRowChunks([2, 2], [0, 0, 0, 0]);
- expect(chunks[0]).to.be.an('array').lengthOf(2);
- expect(chunks[1]).to.be.an('array').lengthOf(2);
-
- chunks = getRowChunks([1, 3], [1, 2, 3, 4]);
- expect(chunks[0]).to.deep.equal([1]);
- expect(chunks[1]).to.deep.equal([2, 3, 4]);
-
- chunks = getRowChunks([2, 2, 5, 1], [1, 2, 3, 4, 5, 6, 7]);
- expect(chunks[0]).to.deep.equal([1, 2]);
- expect(chunks[1]).to.deep.equal([3, 4]);
- expect(chunks[2]).to.deep.equal([5, 6, 7]);
- expect(chunks[3]).to.deep.equal([]);
-
- chunks = getRowChunks([0, 0, 0, 0], [1, 2, 3, 4, 5, 6, 7]);
- expect(chunks[0]).to.deep.equal([]);
- expect(chunks[1]).to.deep.equal([]);
- expect(chunks[2]).to.deep.equal([]);
- expect(chunks[3]).to.deep.equal([]);
-
- chunks = getRowChunks([0, 0, 2, 2], [1, 2, 3, 4, 5, 6, 7]);
- expect(chunks[0]).to.deep.equal([]);
- expect(chunks[1]).to.deep.equal([]);
- expect(chunks[2]).to.deep.equal([1, 2]);
- expect(chunks[3]).to.deep.equal([3, 4]);
- });
- });
-
- describe('componentComponents', () => {
- it('should return array of component scehmas', done => {
- const schema = Object.assign({}, basic, {
- columns: [
- { key: 'name', label: 'Name' },
- { key: 'age', label: 'Age' }
- ],
- });
-
- create(EditTable, schema).then(edittable => {
- const comps = edittable.componentComponents;
-
- comps.forEach(c => {
- expect(c).to.have.property('type');
- expect(c).to.have.property('input');
- expect(c).to.have.property('key');
- expect(c).to.have.property('label');
- });
-
- expect(comps[0].label).to.equal('Name');
- expect(comps[0].key).to.equal('name');
- expect(comps[1].label).to.equal('Age');
- expect(comps[1].key).to.equal('age');
-
- done();
- }, done).catch(done);
- });
- });
-
- describe('build', () => {
- it('in builder, whit no columns, should build placeholder', done => {
- create(EditTable, basic, { builder: true }).then(edittable => {
- expect(edittable.element.querySelector('.edittable-placeholder')).to.not.be.null;
- done();
- }, done).catch(done);
- });
-
- it('should build table', done => {
- create(EditTable, basic).then(edittable => {
- expect(edittable.element.querySelector('table')).to.not.be.null;
- expect(edittable.element.querySelector('table > tbody')).to.not.be.null;
- expect(edittable.element.querySelectorAll('table > tbody > tr')).to.have.lengthOf(1);
- done();
- }, done).catch(done);
- });
-
- it('should build without add button, if ther no columns', done => {
- create(EditTable, basic).then(edittable => {
- expect(edittable.element.querySelector('.btn btn-primary formio-button-add-row')).to.be.null;
- done();
- }, done).catch(done);
- });
- });
-
- describe('getMeta', () => {
- it('should return null if no row groups', done => {
- create(EditTable, basic).then(edittable => {
- expect(edittable.getMeta()).to.be.null;
- done();
- }, done).catch(done);
- });
-
- it('should return meta data when row groups present', done => {
- const groups = [
- {
- label: 'A',
- numberOfRows: 1
- },
- {
- label: 'B',
- numberOfRows: 1
- },
- {
- label: 'Header',
- numberOfRows: 4
- }
- ];
-
- const schema = Object.assign({}, basic, {
- rowGroups: [...groups]
- });
-
- create(EditTable, schema).then(edittable => {
- expect(edittable.getMeta()).to.deep.equal({ A: 1, B: 1, Header: 4 });
- done();
- }, done).catch(done);
- });
- });
-
- describe('setMeta', () => {
- it('should save row groups data to submission metadata', done => {
- const groups = [
- {
- label: 'A',
- numberOfRows: 1
- },
- {
- label: 'B',
- numberOfRows: 1
- },
- {
- label: 'Header',
- numberOfRows: 4
- }
- ];
-
- const schema = Object.assign({}, basic, {
- rowGroups: [...groups]
- });
-
- create(EditTable, schema).then(edittable => {
- const metadata = edittable.getMeta();
- edittable.setMeta();
- expect(edittable.root._submission.metadata[schema.key]).to.deep.equal(metadata);
- done();
- }, done).catch(done);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/editForm/EditTable.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/editForm/EditTable.edit.display.js
deleted file mode 100644
index 6e532ad6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/editForm/EditTable.edit.display.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default [
- {
- key: 'columns',
- type: 'datagrid',
- input: true,
- label: 'Columns',
- weight: 100,
- reorder: true,
- components: [
- {
- key: 'label',
- label: 'Column Label',
- type: 'textfield',
- input: true,
- },
- {
- key: 'key',
- label: 'Column Key',
- type: 'textfield',
- allowCalculateOverride: true,
- input: true,
- calculateValue: { _camelCase: [{ var: 'row.label' }] }
- }
- ]
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/fixtures/basic.js b/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/fixtures/basic.js
deleted file mode 100644
index cfab3a7f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/fixtures/basic.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default {
- label: 'Edit Table',
- columns: [],
- mask: false,
- tableView: true,
- alwaysEnabled: false,
- type: 'edittable',
- input: true,
- key: 'editTable',
- components: []
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/fixtures/index.js
deleted file mode 100644
index de9eca77..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/edittable/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default as basic } from './basic';
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/index.js b/web-client/core/themes/italia/static/formio/css/src/contrib/index.js
deleted file mode 100644
index 2231953b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import StripeComponent from './stripe/stripe/Stripe';
-import StripeCheckoutComponent from './stripe/checkout/StripeCheckout';
-import LocationComponent from './location/Location';
-import EditTableComponent from './edittable/EditTable';
-import ModalEdit from './modaledit/ModalEdit';
-
-const Contrib = {
- stripe: {
- stripe: StripeComponent,
- checkout: StripeCheckoutComponent,
- },
- location: LocationComponent,
- edittable: EditTableComponent,
- modaledit: ModalEdit,
-};
-
-export default Contrib;
-if (typeof global === 'object' && global.Formio) {
- global.Formio.contrib = Contrib;
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.form.js b/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.form.js
deleted file mode 100644
index ba05fd69..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.form.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import baseEditForm from '../../components/_classes/component/Component.form';
-
-import LocationEditMap from './editForm/Location.edit.map';
-
-export default function(...extend) {
- return baseEditForm([
- {
- label: 'Map',
- key: 'map',
- weight: 1,
- components: LocationEditMap
- }
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.js b/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.js
deleted file mode 100644
index c27cb281..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/* global google */
-import TextFieldComponent from '../../components/textfield/TextField';
-import { GlobalFormio as Formio } from '../../Formio';
-
-export default class LocationComponent extends TextFieldComponent {
- static schema(...extend) {
- return TextFieldComponent.schema({
- type: 'location',
- label: 'Location',
- key: 'location',
- map: {
- key: '',
- region: '',
- gmapId: '',
- autocompleteOptions: {}
- }
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Location',
- group: 'advanced',
- icon: 'map',
- weight: 36,
- schema: LocationComponent.schema()
- };
- }
-
- init() {
- super.init();
- // Get the source for Google Maps API
- let src = 'https://maps.googleapis.com/maps/api/js?v=3&libraries=places&callback=googleMapsCallback';
- if (this.component.map && this.component.map.key) {
- src += `&key=${this.component.map.key}`;
- }
- if (this.component.map && this.component.map.region) {
- src += `®ion=${this.component.map.region}`;
- }
- Formio.requireLibrary('googleMaps', 'google.maps.places', src);
- }
-
- get defaultSchema() {
- return LocationComponent.schema();
- }
-
- get emptyValue() {
- return '';
- }
-
- get inputInfo() {
- const info = super.inputInfo;
- info.attr.class += ' Gmap-search';
- return info;
- }
-
- renderElement(value, index) {
- return super.renderElement(value, index) + this.renderTemplate('map', {
- mapId: this.component.map.gmapId,
- });
- }
-
- attach(element) {
- const ret = super.attach(element);
- this.loadRefs(element, { gmapElement: 'multiple' });
- return ret;
- }
-
- attachElement(element, index) {
- super.attachElement(element, index);
- Formio.libraryReady('googleMaps').then(() => {
- const defaultLatlng = new google.maps.LatLng(45.5041482, -73.5574125);
- const options = {
- zoom: 19,
- center: defaultLatlng,
- mapTypeId: google.maps.MapTypeId.ROADMAP,
- styles: [
- {
- 'featureType': 'poi',
- 'stylers': [
- {
- 'visibility': 'off'
- }
- ]
- },
- {
- 'featureType': 'transit',
- 'stylers': [
- {
- 'visibility': 'off'
- }
- ]
- }
- ]
- };
-
- if (!this.refs.gmapElement[index]) {
- return;
- }
- element.map = new google.maps.Map(this.refs.gmapElement[index], options);
- this.addMarker(defaultLatlng, 'Default Marker', element);
-
- let autocompleteOptions = {};
- if (this.component.map) {
- autocompleteOptions = this.component.map.autocompleteOptions || {};
- }
- const autocomplete = new google.maps.places.Autocomplete(element, autocompleteOptions);
- autocomplete.addListener('place_changed', () => {
- const place = autocomplete.getPlace();
- if (!place.geometry) {
- console.log('Autocomplete\'s returned place contains no geometry');
- return;
- }
-
- // If the place has a geometry, then present it on a map.
- if (place.geometry.viewport) {
- element.map.fitBounds(place.geometry.viewport);
- }
- else {
- element.map.setCenter(place.geometry.location);
- element.map.setZoom(17); // Why 17? Because it looks good.
- }
- element.marker.setIcon(/** @type {google.maps.Icon} */({
- url: place.icon,
- size: new google.maps.Size(71, 71),
- origin: new google.maps.Point(0, 0),
- anchor: new google.maps.Point(17, 34),
- scaledSize: new google.maps.Size(35, 35)
- }));
- element.marker.setPosition(place.geometry.location);
- this.setValue(place.name);
- });
- });
- }
-
- addMarker(latlng, title, element) {
- element.marker = new google.maps.Marker({
- position: latlng,
- map: element.map,
- title: title,
- draggable:true
- });
- element.marker.addListener('dragend', (event) => {
- const geocoder = new google.maps.Geocoder;
- const latlng = { lat: parseFloat(event.latLng.lat()), lng: parseFloat(event.latLng.lng()) };
- geocoder.geocode({ 'location': latlng }, (results, status) => {
- if (status === google.maps.GeocoderStatus.OK) {
- if (results[1]) {
- this.setValue(results[0].formatted_address);
- }
- else {
- console.log('No results found');
- }
- }
- else {
- console.log(`Geocoder failed due to: ${status}`);
- }
- });
- });
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.spec.js b/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.spec.js
deleted file mode 100644
index 744ad304..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/location/Location.spec.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import Harness from '../../../test/harness';
-import LocationComponent from './Location';
-
-import {
- comp1
-} from './fixtures/index';
-
-describe('Location Component', function() {
- it('Should build a location component', function() {
- return Harness.testCreate(LocationComponent, comp1);
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/location/editForm/Location.edit.map.js b/web-client/core/themes/italia/static/formio/css/src/contrib/location/editForm/Location.edit.map.js
deleted file mode 100644
index 3f8fb16c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/location/editForm/Location.edit.map.js
+++ /dev/null
@@ -1,28 +0,0 @@
-export default [
- {
- type: 'textfield',
- input: true,
- key: 'map.key',
- label: 'API Key',
- tooltip: "The API key for Google Maps. See Get an API Key for more information.",
- placeholder: 'xxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxx',
- weight: 0
- },
- {
- type: 'textfield',
- input: true,
- label: 'Region Bias',
- key: 'map.region',
- tooltip: "The region bias to use for this search. See Region Biasing for more information.",
- placeholder: 'Dallas',
- weight: 10
- },
- {
- type: 'textfield',
- input: true,
- label: 'Google Map ID',
- key: 'map.gmapId',
- tooltip: 'This is the Google Maps ID you wish to use when showing the location map.',
- weight: 20
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/location/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/contrib/location/fixtures/comp1.js
deleted file mode 100644
index b51f5355..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/location/fixtures/comp1.js
+++ /dev/null
@@ -1,35 +0,0 @@
-export default {
- 'input': true,
- 'tableView': true,
- 'label': 'Location',
- 'key': 'location',
- 'placeholder': '',
- 'multiple': false,
- 'protected': false,
- 'clearOnHide': true,
- 'unique': false,
- 'persistent': true,
- 'map': {
- 'gmapId': '',
- 'region': '',
- 'key': '',
- 'autocompleteOptions' : {
- 'componentRestrictions' : {
- 'country' : [
- ''
- ]
- }
- }
- },
- 'validate': {
- 'required': false
- },
- 'type': 'location',
- 'tags': [
- ],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/location/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/contrib/location/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/location/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/ModalEdit.form.js b/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/ModalEdit.form.js
deleted file mode 100644
index 58c9d0d8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/ModalEdit.form.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import modalEditDisplayForm from './editForm/ModalEdit.edit.display';
-import textAreaEditForm from '../../components/textarea/TextArea.form';
-
-export default function(...extend) {
- return textAreaEditForm([
- {
- key: 'display',
- components: [
- { key: 'rows', ignore: true },
- { key: 'multiple', ignore: true },
- ...modalEditDisplayForm,
- ]
- }
- ], ...extend);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/ModalEdit.js b/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/ModalEdit.js
deleted file mode 100644
index c93bbe6d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/ModalEdit.js
+++ /dev/null
@@ -1,187 +0,0 @@
-import _ from 'lodash';
-import TextAreaComponent from '../../components/textarea/TextArea';
-import ModalEditForm from './ModalEdit.form';
-
-export default class ModalEditComponent extends TextAreaComponent {
- static schema(...extend) {
- return TextAreaComponent.schema({
- type: 'modaledit',
- label: 'Modal Edit',
- key: 'modalEdit',
- modalLayout: 'fixed',
- }, ...extend);
- }
-
- static get builderInfo() {
- return {
- title: 'Modal Edit',
- group: 'data',
- icon: 'font',
- weight: 40,
- schema: ModalEditComponent.schema()
- };
- }
-
- /** @override **/
- renderElement(content = '') {
- return this.renderTemplate('modaledit', { content });
- }
-
- /** @override **/
- attach(element) {
- this.loadRefs(element, {
- container: 'single',
- edit: 'single'
- });
- return super.attach(element);
- }
-
- /** @override **/
- attachElement(element) {
- // Allow work with div as if it would be plain input
- Object.defineProperty(element, 'value', {
- get: function() {
- return this.innerHTML;
- },
- set: function(value) {
- this.innerHTML = value;
- }
- });
-
- const show = this.showModal.bind(this);
-
- this.addEventListener(this.refs.container, 'dblclick', show);
-
- this.addEventListener(this.refs.edit, 'click', show);
- }
-
- /** @override **/
- createModal(element) {
- const self = this;
- const dialog = this.ce('div');
- this.setContent(dialog, this.renderTemplate('modaldialog'));
- dialog.refs = {};
- this.loadRefs.call(dialog, dialog, {
- overlay: 'single',
- content: 'single',
- inner: 'single',
- close: 'single'
- });
- const rect = this.getElementRect(this.refs.container);
- const layout = this.getModalLayout(rect);
- const styles = this.getModalStyle(layout);
- Object.assign(dialog.refs.content.style, styles);
- dialog.refs.inner.appendChild(element);
- this.addEventListener(dialog.refs.overlay, 'click', (event) => {
- event.preventDefault();
- dialog.close();
- });
- this.addEventListener(dialog.refs.close, 'click', (event) => {
- event.preventDefault();
- dialog.close();
- });
- this.addEventListener(dialog, 'close', () => {
- this.removeChildFrom(dialog, document.body);
- });
-
- dialog.close = function() {
- dialog.dispatchEvent(new CustomEvent('close'));
- self.removeChildFrom(dialog, document.body);
- };
-
- document.body.appendChild(dialog);
- return dialog;
- }
-
- /** @override **/
- updateOnChange(flags, changed = false) {
- if (super.updateOnChange(flags, changed)) {
- this.updateContentView(this.dataValue);
- }
- }
-
- showModal() {
- const elt = this.ce('div');
- this.setContent(elt, super.renderElement(this.dataValue));
- const editor = elt.children[0];
- if (this.isPlain) {
- editor.style.resize = 'vertical';
- }
- super.attachElement(editor);
- this.createModal(editor);
- }
-
- updateContentView(content = '') {
- const view = _.get(this, 'refs.input[0]', null);
-
- return this.setContent(view, content);
- }
-
- getElementRect(elt) {
- return elt.getBoundingClientRect();
- }
-
- getModalStyle(args, overrides = {}) {
- const defaultStyles = {
- position: 'absolute',
- height: 'auto',
- };
-
- const layout = _.mapValues(
- _.pick(args, ['top', 'left', 'width']),
- p => `${p}px`
- );
-
- return {
- ...defaultStyles,
- ...overrides,
- ...layout
- };
- }
-
- getModalLayout(rect) {
- const { width, height: minHeight } = this.getModalSize(rect.width, rect.height);
- return {
- left: rect.left,
- minHeight,
- top: rect.top,
- width,
- };
- }
-
- getModalSize(currentWidth, currentHeight) {
- const [dw, dh] = this.defaultModalSize;
- const type = _.get(this.component, 'modalLayout', 'fixed');
- const { widthProp, heightProp } = this.layoutProps[type];
- const width = _.get(this.component, widthProp, dw);
- const height = _.get(this.component, heightProp, dh);
-
- if (type === 'fluid') {
- return {
- width: Math.max(currentWidth, width),
- height: Math.max(currentHeight, height)
- };
- }
-
- return { width, height };
- }
-
- get defaultModalSize() {
- return [475, 300];
- }
-
- get layoutProps() {
- return {
- fixed: {
- widthProp: 'width',
- heightProp: 'height'
- },
- fluid: {
- widthProp: 'minWidth',
- heightProp: 'minHeight'
- }
- };
- }
-}
-
-ModalEditComponent.editForm = ModalEditForm;
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/editForm/ModalEdit.edit.display.js b/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/editForm/ModalEdit.edit.display.js
deleted file mode 100644
index f7dd8a59..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/modaledit/editForm/ModalEdit.edit.display.js
+++ /dev/null
@@ -1,41 +0,0 @@
-export default [
- {
- type: 'radio',
- key: 'modalLayout',
- input: true,
- label: 'Layout Type',
- inline: true,
- values: [
- {
- label: 'Fixed',
- value: 'fixed'
- },
- {
- label: 'Fluid',
- value: 'fluid'
- }
- ],
- defaultValue: 'fluid',
- tooltip: 'Fixed - modal with fixed width.\nFluid - Width of modal will be equal to preview width or minmal width.'
- },
- {
- type: 'number',
- key: 'width',
- label: 'Fixed Width',
- input: true,
- defaultValue: 300,
- conditional: {
- json: { '===': [{ var: 'data.modalLayout' }, 'fixed'] }
- }
- },
- {
- type: 'number',
- key: 'minWidth',
- label: 'Minimum Width',
- input: true,
- defaultValue: 300,
- conditional: {
- json: { '===': [{ var: 'data.modalLayout' }, 'fluid'] }
- }
- }
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/StripeCheckout.js b/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/StripeCheckout.js
deleted file mode 100644
index ff70103b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/StripeCheckout.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/* globals StripeCheckout */
-import _ from 'lodash';
-import ButtonComponent from '../../../components/button/Button';
-import { GlobalFormio as Formio } from '../../../Formio';
-
-export default class StripeCheckoutComponent extends ButtonComponent {
- constructor(component, options, data) {
- super(component, options, data);
-
- // Get the source for Stripe API
- const src = 'https://checkout.stripe.com/checkout.js';
-
- /**
- * Promise when Stripe is ready.
- * @type {Promise}
- */
- this.stripeCheckoutReady = Formio.requireLibrary('stripeCheckout', 'StripeCheckout', src, true);
-
- /**
- * Keep initial component action
- * @type {String}
- */
- this.componentAction = this.component.action;
-
- // Force button to handle event action to build button
- this.component.action = 'event';
- }
-
- static get builderInfo() {
- return {
- group: false,
- schema: ButtonComponent.schema()
- };
- }
-
- getValue() {
- return this.dataValue;
- }
-
- setValue(value, flags = {}) {
- return this.updateValue(value, flags);
- }
-
- /**
- * Handle event dispatched by Stripe library
- * @param {Object} token - The token returned by Stripe.
- */
- onToken(token) {
- this.setValue(token.id);
- // In case of submit, submit the form
- if (this.componentAction === 'submit') {
- this.emit('submitButton');
- }
- else {
- this.addClass(this.element, 'btn-success');
- this.disabled = true;
- }
- }
-
- /**
- * Handle customEvent event on the button
- * @param {Object} event - The event returned by ButtonComponent.
- */
- onClickButton(event) {
- // Return if component call is not the current component
- if (this.component.key !== event.component.key) {
- return;
- }
-
- // Open Checkout with further options:
- const popupConfiguration = _.cloneDeep(this.component.stripe.popupConfiguration) || {};
- _.each(popupConfiguration, (value, key) => {
- popupConfiguration[key] = this.t(value);
- });
-
- if (this.componentAction === 'submit') {
- // In case of submit, validate the form before opening button
- if (this.root.isValid(event.data, true)) {
- this.handler.open(popupConfiguration);
- }
- else {
- // If the form is not valid, submit it to draw errors
- this.emit('submitButton');
- }
- }
- else {
- this.handler.open(popupConfiguration);
- }
- }
-
- build() {
- // Build button
- super.build();
-
- // In case of submit, add event listeners
- if (this.componentAction === 'submit') {
- this.on('submitButton', () => {
- this.loading = true;
- this.disabled = true;
- }, true);
- this.on('submitDone', () => {
- this.loading = false;
- this.disabled = false;
- }, true);
- this.on('change', (value) => {
- this.loading = false;
- this.disabled = (this.component.disableOnInvalid && !this.root.isValid(value.data, true));
- }, true);
- this.on('error', () => {
- this.loading = false;
- }, true);
- }
-
- // When stripe checkout is ready, create the handler and add event listeners
- this.stripeCheckoutReady.then(() => {
- const handlerConfiguration = _.cloneDeep(this.component.stripe.handlerConfiguration) || {};
- handlerConfiguration.key = this.component.stripe.apiKey;
- handlerConfiguration.token = this.onToken.bind(this);
- if (typeof handlerConfiguration.locale === 'undefined') {
- handlerConfiguration.locale = this.options.language;
- }
- this.handler = StripeCheckout.configure(handlerConfiguration);
-
- this.on('customEvent', this.onClickButton.bind(this));
-
- this.addEventListener(window, 'popstate', () => {
- this.handler.close();
- });
- });
- }
-}
-
-if (typeof global === 'object' && global.Formio && global.Formio.registerComponent) {
- global.Formio.registerComponent('stripeCheckout', StripeCheckoutComponent);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/StripeCheckout.spec.js b/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/StripeCheckout.spec.js
deleted file mode 100644
index 66d564fa..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/StripeCheckout.spec.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import Harness from '../../../../test/harness';
-import StripeCheckoutComponent from './StripeCheckout';
-
-import {
- comp1
-} from './fixtures';
-
-// describe('StripeCheckout Component', () => {
-// it('Should build an stripeCheckout component', () => {
-// Harness.testCreate(StripeCheckoutComponent, comp1);
-// });
-// });
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/fixtures/comp1.js
deleted file mode 100644
index dee84c6c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/fixtures/comp1.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default {
- 'type': 'stripeCheckout',
- 'theme': 'primary',
- 'disableOnInvalid': false,
- 'action': 'button',
- 'block': false,
- 'rightIcon': '',
- 'leftIcon': '',
- 'size': 'md',
- 'key': 'card',
- 'tableView': false,
- 'label': 'Authorize payment',
- 'input': true,
- 'stripe': {
- 'apiKey': '',
- 'handlerConfiguration': {},
- 'popupConfiguration': {}
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/checkout/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/Stripe.js b/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/Stripe.js
deleted file mode 100644
index 837f332b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/Stripe.js
+++ /dev/null
@@ -1,270 +0,0 @@
-/* globals Stripe */
-import _ from 'lodash';
-import Validator from '../../../validator/Validator';
-import Component from '../../../components/_classes/component/Component';
-import { GlobalFormio as Formio } from '../../../Formio';
-import NativePromise from 'native-promise-only';
-
-// Register a custom validor to use card validition from Stripe
-if (typeof Validator.validators.stripe === 'undefined') {
- Validator.validators.stripe = {
- key: 'validate.stripe',
- message(component) {
- let stripeMessage = '';
- if (component.lastResult && component.lastResult.error) {
- stripeMessage = component.lastResult.error.message;
- }
- return component.t(component.errorMessage('stripe'), {
- field: component.errorLabel,
- stripe: stripeMessage,
- stripeError: component.lastResult.error,
- data: component.data
- });
- },
- check(component, setting, value) {
- if (!component.paymentDone && component.lastResult) {
- return !component.lastResult.error && !component.isEmpty(value);
- }
- return true;
- }
- };
-}
-
-/**
- * This is the StripeComponent class.
- */
-export default class StripeComponent extends Component {
- constructor(component, options, data) {
- super(component, options, data);
-
- // Get the source for Stripe API
- const src = 'https://js.stripe.com/v3/';
-
- /**
- * Promise when Stripe is ready.
- * @type {Promise}
- */
- this.stripeReady = Formio.requireLibrary('stripe', 'Stripe', src, true);
-
- /**
- * The last result returned by Stripe.
- * @type {Object}
- */
- this.lastResult = null;
-
- /**
- * The state of the payment.
- * @type {Boolean}
- */
- this.paymentDone = false;
-
- // Use stripe validator
- this.validators.push('stripe');
- }
-
- elementInfo() {
- const info = super.elementInfo();
- info.type = 'input';
- info.attr.type = 'hidden';
- info.changeEvent = 'change';
- return info;
- }
-
- /**
- * Set CSS classes for pending authorization
- */
- authorizePending() {
- this.addClass(this.element, 'stripe-submitting');
- this.removeClass(this.element, 'stripe-error');
- this.removeClass(this.element, 'stripe-submitted');
- }
-
- /**
- * Set CSS classes and display error when error occurs during authorization
- * @param {Object} resultError - The result error returned by Stripe API.
- */
- authorizeError(resultError) {
- this.removeClass(this.element, 'stripe-submitting');
- this.addClass(this.element, 'stripe-submit-error');
- this.removeClass(this.element, 'stripe-submitted');
-
- if (!this.lastResult) {
- this.lastResult = {};
- }
- this.lastResult.error = resultError;
- this.setValue(this.getValue(), {
- changed: true
- });
- }
-
- /**
- * Set CSS classes and save token when authorization successed
- * @param {Object} result - The result returned by Stripe API.
- */
- authorizeDone(result) {
- this.removeClass(this.element, 'stripe-submit-error');
- this.removeClass(this.element, 'stripe-submitting');
- this.addClass(this.element, 'stripe-submitted');
-
- this.stripeSuccess.style.display = 'block';
- if (this.component.stripe.payButton && this.component.stripe.payButton.enable) {
- this.stripeElementPayButton.style.display = 'none';
- this.stripeSeparator.style.display = 'none';
- }
- this.stripeElementCard.style.display = 'none';
-
- // Store token in hidden input
- this.setValue(result.token.id);
-
- this.paymentDone = true;
- }
-
- /**
- * Call Stripe API to get token
- */
- authorize() {
- if (this.paymentDone) {
- return;
- }
-
- const that = this;
- return new NativePromise(((resolve, reject) => {
- that.authorizePending();
-
- // Get all additionnal data to send to Stripe
- const cardData = _.cloneDeep(that.component.stripe.cardData) || {};
- _.each(cardData, (value, key) => {
- cardData[key] = that.t(value);
- });
-
- return that.stripe.createToken(that.stripeCard, cardData).then((result) => {
- if (result.error) {
- that.authorizeError(result.error);
- reject(result.error);
- }
- else {
- that.authorizeDone(result);
- resolve();
- }
- });
- }));
- }
-
- /**
- * Handle event dispatched by Stripe library
- * @param {Object} result - The result returned by Stripe.
- */
- onElementCardChange(result) {
- // If the field is not required and the field is empty, do not throw an error
- if (result.empty && (!this.component.validate || !this.component.validate.required)) {
- delete result.error;
- }
-
- // Force change when complete or when an error is thrown or fixed
- const changed = result.complete
- || this.lastResult && (!!this.lastResult.error !== !!result.error)
- || this.lastResult && this.lastResult.error && result.error && this.lastResult.error.code !== result.error.code
- || false;
- this.lastResult = result;
-
- // When the field is not empty, use "." as value to not trigger "required" validator
- const value = result.empty ? '' : '.';
- this.setValue(value, {
- changed: changed
- });
- }
-
- beforeSubmit() {
- // Get the token before submitting when the field is not empty or required
- if (this.lastResult && !this.lastResult.empty || (this.component.validate && this.component.validate.required)) {
- return this.authorize();
- }
- }
-
- build() {
- super.build();
-
- const successLabel = this.component.stripe.payButton.successLabel || 'Payment successful';
- this.stripeSuccess = this.ce('div', {
- class: 'Stripe-success',
- style: 'display: none'
- }, this.t(successLabel));
- this.element.appendChild(this.stripeSuccess);
-
- // Add container for pay button
- if (this.component.stripe.payButton && this.component.stripe.payButton.enable) {
- this.stripeElementPayButton = this.ce('div', {
- class: 'Stripe-paybutton'
- });
- this.element.appendChild(this.stripeElementPayButton);
-
- const separatorLabel = this.component.stripe.payButton.separatorLabel || 'Or';
- this.stripeSeparator = this.ce('div', {
- class: 'Stripe-separator',
- style: 'display: none'
- }, this.t(separatorLabel));
- this.element.appendChild(this.stripeSeparator);
- }
-
- // Create container for stripe cart input
- this.stripeElementCard = this.ce('div');
- this.element.appendChild(this.stripeElementCard);
-
- this.stripeReady.then(() => {
- this.stripe = new Stripe(this.component.stripe.apiKey);
-
- // Create an instance of Elements
- let stripeElementsOptions = {};
- if (this.component.stripe) {
- stripeElementsOptions = _.cloneDeep(this.component.stripe.stripeElementsOptions) || {};
- }
- if (typeof stripeElementsOptions.locale === 'undefined') {
- stripeElementsOptions.locale = this.options.language;
- }
- const elements = this.stripe.elements(stripeElementsOptions);
-
- // Create an instance of the card Element
- let stripeElementOptions = {};
- if (this.component.stripe) {
- stripeElementOptions = this.component.stripe.stripeElementOptions || {};
- }
- this.stripeCard = elements.create('card', stripeElementOptions);
-
- // Add an instance of the card Element into the `card-element`
- this.stripeCard.mount(this.stripeElementCard);
-
- // Handle real-time validation errors from the card Element.
- this.addEventListener(this.stripeCard, 'change', this.onElementCardChange.bind(this));
-
- // If there is a pay button, then create it and add listener
- if (this.component.stripe.payButton && this.component.stripe.payButton.enable) {
- const paymentRequest = this.stripe.paymentRequest(this.component.stripe.payButton.paymentRequest);
-
- this.addEventListener(paymentRequest, 'token', (result) => {
- this.authorizeDone(result, true);
- result.complete('success');
- });
-
- let stripeOptionsPayButton = {};
- if (this.component.stripe.payButton) {
- stripeOptionsPayButton = this.component.stripe.payButton.stripeOptions || {};
- }
- stripeOptionsPayButton.paymentRequest = paymentRequest;
-
- const paymentRequestElement = elements.create('paymentRequestButton', stripeOptionsPayButton);
-
- paymentRequest.canMakePayment().then((result) => {
- if (result) {
- // Display label separator
- this.stripeSeparator.style.display = 'block';
- paymentRequestElement.mount(this.stripeElementPayButton);
- }
- });
- }
- });
- }
-}
-
-if (typeof global === 'object' && global.Formio && global.Formio.registerComponent) {
- global.Formio.registerComponent('stripe', StripeComponent);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/Stripe.spec.js b/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/Stripe.spec.js
deleted file mode 100644
index f8c6debd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/Stripe.spec.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import Harness from '../../../../test/harness';
-import StripeComponent from './Stripe';
-
-import {
- comp1
-} from './fixtures';
-
-// describe('Stripe Component', () => {
-// it('Should build an stripe component', () => {
-// return Harness.testCreate(StripeComponent, comp1);
-// });
-// });
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/fixtures/comp1.js b/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/fixtures/comp1.js
deleted file mode 100644
index 1715e214..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/fixtures/comp1.js
+++ /dev/null
@@ -1,38 +0,0 @@
-export default {
- 'input': true,
- 'tableView': true,
- 'label': 'stripe',
- 'key': 'stripe',
- 'placeholder': '',
- 'multiple': false,
- 'protected': false,
- 'clearOnHide': true,
- 'unique': false,
- 'persistent': true,
- 'action': 'button',
- 'stripe': {
- 'apiKey': '',
- 'payButton': {
- 'enable': false,
- 'separatorLabel': 'Or',
- 'paymentRequest': {},
- 'stripeOptions': {}
- },
- 'cardData': {},
- 'successLabel': 'Payment successful',
- 'stripeElementsOptions': {},
- 'stripeElementOptions': {}
- },
- 'validate': {
- 'required': true
- },
- 'type': 'stripe',
- 'tags': [
-
- ],
- 'conditional': {
- 'show': '',
- 'when': null,
- 'eq': ''
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/fixtures/index.js b/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/fixtures/index.js
deleted file mode 100644
index 8d20e4f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/contrib/stripe/stripe/fixtures/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export comp1 from './comp1';
diff --git a/web-client/core/themes/italia/static/formio/css/src/displays/Displays.js b/web-client/core/themes/italia/static/formio/css/src/displays/Displays.js
deleted file mode 100644
index 66c9e16a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/displays/Displays.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import _ from 'lodash';
-import pdf from '../PDF';
-import webform from '../Webform';
-import wizard from '../Wizard';
-
-export default class Displays {
- static displays = {
- pdf,
- webform,
- wizard,
- };
-
- static addDisplay(name, display) {
- Displays.displays[name] = display;
- }
-
- static addDisplays(displays) {
- Displays.displays = _.merge(Displays.displays, displays);
- }
-
- static getDisplay(name) {
- return Displays.displays[name];
- }
-
- static getDisplays() {
- return Displays.displays;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/displays/index.js b/web-client/core/themes/italia/static/formio/css/src/displays/index.js
deleted file mode 100644
index acfbf661..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/displays/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Displays from './Displays';
-
-export default Displays;
diff --git a/web-client/core/themes/italia/static/formio/css/src/formio.embed.js b/web-client/core/themes/italia/static/formio/css/src/formio.embed.js
deleted file mode 100644
index a7e430ff..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/formio.embed.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import { embed } from './Embed';
-embed();
diff --git a/web-client/core/themes/italia/static/formio/css/src/formio.form.js b/web-client/core/themes/italia/static/formio/css/src/formio.form.js
deleted file mode 100644
index deff7025..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/formio.form.js
+++ /dev/null
@@ -1,151 +0,0 @@
-import _ from 'lodash';
-import Formio from './Formio';
-import AllComponents from './components';
-import Builders from './builders/Builders';
-import Components from './components/Components';
-import Displays from './displays/Displays';
-import Templates from './templates/Templates';
-import Providers from './providers';
-import Rules from './validator/Rules';
-import Conjunctions from './validator/conjunctions';
-import Operators from './validator/operators';
-import QuickRules from './validator/quickRules';
-import Transformers from './validator/transformers';
-import ValueSources from './validator/valueSources';
-import Widgets from './widgets';
-import Form from './Form';
-import Utils from './utils';
-import Evaluator from './utils/Evaluator';
-import Licenses from './licenses';
-
-Formio.loadModules = (path = `${Formio.getApiUrl() }/externalModules.js`, name = 'externalModules') => {
- Formio.requireLibrary(name, name, path, true)
- .then((modules) => {
- Formio.use(modules);
- });
-};
-
-// This is needed to maintain correct imports using the "dist" file.
-Formio.Components = Components;
-Formio.Templates = Templates;
-Formio.Builders = Builders;
-Formio.Utils = Utils;
-Formio.Form = Form;
-Formio.Displays = Displays;
-Formio.Providers = Providers;
-Formio.Rules = Rules;
-Formio.Widgets = Widgets;
-Formio.Evaluator = Evaluator;
-Formio.Conjunctions = Conjunctions;
-Formio.Operators = Operators;
-Formio.QuickRules = QuickRules;
-Formio.Transformers = Transformers;
-Formio.ValueSources = ValueSources;
-Formio.AllComponents = AllComponents;
-Formio.Licenses = Licenses;
-
-// This is strange, but is needed for "premium" components to import correctly.
-Formio.Formio = Formio;
-
-Formio.Components.setComponents(AllComponents);
-
-/**
- * Register a module
- * @param {*} plugin
- * @param {*} options
- * @returns
- */
-const registerPlugin = (plugin, options = {}) => {
- // Sanity check.
- if (typeof plugin !== 'object') {
- return;
- }
- for (const key of Object.keys(plugin)) {
- const current = plugin.framework || Formio.Templates.framework || 'bootstrap';
- switch (key) {
- case 'options':
- Formio.options = _.merge(Formio.options, plugin.options);
- break;
- case 'templates':
- for (const framework of Object.keys(plugin.templates)) {
- Formio.Templates.extendTemplate(framework, plugin.templates[framework]);
- }
- if (plugin.templates[current]) {
- Formio.Templates.current = plugin.templates[current];
- }
- break;
- case 'components':
- Formio.Components.setComponents(plugin.components);
- break;
- case 'framework':
- Formio.Templates.framework = plugin.framework;
- break;
- case 'fetch':
- for (const name of Object.keys(plugin.fetch)) {
- Formio.registerPlugin(plugin.fetch[name], name);
- }
- break;
- case 'providers':
- for (const type of Object.keys(plugin.providers)) {
- Formio.Providers.addProviders(type, plugin.providers[type]);
- }
- break;
- case 'displays':
- Formio.Displays.addDisplays(plugin.displays);
- break;
- case 'builders':
- Formio.Builders.addBuilders(plugin.builders);
- break;
- case 'rules':
- Formio.Rules.addRules(plugin.rules);
- break;
- case 'evaluator':
- Formio.Evaluator.registerEvaluator(plugin.evaluator);
- break;
- case 'conjunctions':
- Formio.Conjunctions.addConjunctions(plugin.conjunctions);
- break;
- case 'operators':
- Formio.Operators.addOperators(plugin.operators);
- break;
- case 'quickRules':
- Formio.QuickRules.addQuickRules(plugin.quickRules);
- break;
- case 'transformers':
- Formio.Transformers.addTransformers(plugin.transformers);
- break;
- case 'valueSources':
- Formio.ValueSources.addValueSources(plugin.valueSources);
- break;
- case 'library':
- options.license
- ? Formio.Licenses.addLicense(plugin.library, options.license)
- : Formio.Licenses.removeLicense(plugin.library);
- break;
- default:
- console.log('Unknown plugin option', key);
- }
- }
-};
-
-/**
- * Allows passing in plugins as an array of plugins or a single plugin.
- *
- * Formio.plugins(plugin1, options);
- * Formio.plugins([plugin1, plugin2, etc], options);
- */
-Formio.use = (plugins, options = {}) => {
- plugins = _.isArray(plugins) ? plugins : [plugins];
-
- plugins.forEach((plugin) => {
- if (Array.isArray(plugin)) {
- plugin.forEach(p => registerPlugin(p, options));
- }
- else {
- registerPlugin(plugin, options);
- }
- });
-};
-
-// Export the components.
-export { Builders, Components, Displays, Providers, Rules, Widgets, Templates, Conjunctions, Operators, QuickRules, Transformers, ValueSources, Utils, Form, Formio, Licenses };
diff --git a/web-client/core/themes/italia/static/formio/css/src/i18n.js b/web-client/core/themes/italia/static/formio/css/src/i18n.js
deleted file mode 100644
index ead24f9f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/i18n.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import enTranslation from './translations/en';
-import {
- fastCloneDeep
-} from './utils/utils';
-export default {
- lng: 'en',
- nsSeparator: '::',
- keySeparator: '.|.',
- pluralSeparator: '._.',
- contextSeparator: '._.',
- resources: {
- en: {
- translation: fastCloneDeep(enTranslation)
- }
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/index.js b/web-client/core/themes/italia/static/formio/css/src/index.js
deleted file mode 100644
index 659d375c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-// DO NOT SAY "export *"!!! This messes up the umd for dist builds.
-export { Builders, Components, Displays, Providers, Rules, Widgets, Templates, Utils, Form, Conjunctions, Operators, QuickRules, Transformers, ValueSources, Formio } from './formio.form';
-export FormBuilder from './FormBuilder';
diff --git a/web-client/core/themes/italia/static/formio/css/src/licenses/Licenses.js b/web-client/core/themes/italia/static/formio/css/src/licenses/Licenses.js
deleted file mode 100644
index f9d2c5eb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/licenses/Licenses.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import _ from 'lodash';
-
-export default class Licenses {
- static licenses = {};
-
- static addLicense(name, license) {
- Licenses.licenses[name] = license;
- }
-
- static getLicense(name) {
- return Licenses.licenses[name];
- }
-
- static removeLicense(name) {
- _.unset(Licenses.licenses, name);
- }
-
- static getLicenses() {
- return Licenses.licenses;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/licenses/index.js b/web-client/core/themes/italia/static/formio/css/src/licenses/index.js
deleted file mode 100644
index 22a84a78..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/licenses/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Licenses from './Licenses';
-
-export default Licenses;
diff --git a/web-client/core/themes/italia/static/formio/css/src/package-lock.json b/web-client/core/themes/italia/static/formio/css/src/package-lock.json
deleted file mode 100644
index 4af04cc0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/package-lock.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "formiojs",
- "lockfileVersion": 1
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/package.json b/web-client/core/themes/italia/static/formio/css/src/package.json
deleted file mode 100644
index 85cf70f5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/package.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "formiojs",
- "version": "",
- "description": "Common js library for client side interaction with
",
- "main": "index.js",
- "types": "index.d.ts",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/formio/formio.js.git"
- },
- "contributors": [
- {
- "name": "Form.io Open Source Community",
- "url": "https://github.com/formio/formio.js/graphs/contributors"
- }
- ],
- "browser": {
- "vm": false
- },
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/formio/formio.js/issues"
- },
- "homepage": "https://github.com/formio/formio.js#readme",
- "dependencies": {}
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/pdf.image.js b/web-client/core/themes/italia/static/formio/css/src/pdf.image.js
deleted file mode 100644
index 1f0a85b0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/pdf.image.js
+++ /dev/null
@@ -1,93 +0,0 @@
-module.exports = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAMAAAC/MqoPAAAAA3NCSVQICAjb4U/gAAAC9FBMVEX' +
- '///+HiYuGhomCg4aCgIF6eX12eHokJCQkICAgICAjHSOOj5KJi46DhYd1dnltb3EkICAgICAjHSOVl5qTlZeOj5KHiYt6eX0kICAjH' +
- 'SOZmp2Vl5qGhokkICDOz9G+vsCztbapq66cnqGbnZ6ZmZmTlZckICCbnZ6Zmp2Vl5qTlZeOj5KMioqGhomCg4aCgIGZmp2TlZeCgIG' +
- 'mqauho6aen6KcnqGmqaucnqGbnZ66u76cnqGZmp2Vl5rKISjS0dLR0NHOz9HMzMzHycrHxsfFxMXCwsPCw8W+vsCen6KbnZ7GISjCw' +
- 'sO+v8K+vsCpq66kpqmeoaObnZ7////7+/v5+vr39/j09fXz8/P88PHx8fL37+/u7+/r7O3r6+zp6uvn5+jj5+fz4+P44eLw4eHj5OX' +
- 'i4+Th4uPf4OLf3+Dc3t/b3N7a29z109TY2tvv1NXv0tPX2NrW19jU1tfS09XP0dLOz9Hrx8jxxMbnxsfMzMzkxMXHycrGx8nDxcfqu' +
- 'bvCw8XCwsPkuLrutbe/wcO+v8Lftre+vsC7vb+6u763ubu1t7riqqzeqquztbbqpqmxs7bZqKmvsbOtr7Kqra+pq67bnJ7gm56mqav' +
- 'XnJ3nl5ulp6qkpqmjpaeho6aeoaPbj5Gen6KcnqHXjpGbnZ7jiYzfio7SjpDdiYyZmp3LjI6ZmZnahoqVl5rXgoaTlZeSk5bSgIOPk' +
- 'ZPOf4Lgen6Oj5LLf4KLjY+Ji46HiYvVcnaGhonNcnWDhYfKcXSCg4bca3DFcXTBcHJ+gIJ9foHRZWl6fH7MZmbOZWnGZGd6eX12eHr' +
- 'BY2bZXGF1dnlydHa4YWNwcXTOV1vKVlvIVlrCVlnPUFW+VVnOTlS3VFe1VFbKS1HGSE3BR0y/R0y7R0zEREq2R0rSP0WzRkmtRUjBO' +
- 'kC4OT6zOD3OMDaqNzrBLTO2KzCzKzCuKi/KISiqKi6lKS2+ICa6HyW7Hya2HySuHiOyHiSrHiKnHSGiHCCeHB+aGx/MBOLyAAAA/HR' +
- 'STlMAERERERERERERESIiIiIiIiIiMzMzMzMzM0RERERVVVVVVVVVVVVmZmZmZmZmZmZ3d3eIiIiImZmZqqqqqrvMzMzMzMzMzMzMz' +
- 'MzM3d3d3e7u7v/////////////////////////////////////////////////////////////////////////////////////////' +
- '//////////////////////////////////////////////////////////////////////////////////////////////////////' +
- '/////////////////////////////////8PeNL3AAAACXBIWXMAAC37AAAt+wH8h0rnAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJ' +
- 'ld29ya3MgQ1M26LyyjAAAFydJREFUeJzt3Xl8FNd9AHD31K56LfSIaOumTY80aeK06R23TXq5xXV8ZIRhzWEkgkAHKICQZCwpQpZsS' +
- 'SsWRQdeR2hlCWEsXFkHyELmtMEkGBvnMKZ2iV1jW2COGAOSwPzT33tv5s2bY3fn+O2slg8//DFikeT97u94b2Zn5FtuuRk342bcjJt' +
- 'xM8zCl5nhaWRm+lJNJuHP8Psy/H6/z7uA/1oG/CvVfL+P/vJS7qP/uQx4wVOJh9f/93q6u6LRzs0dHZH29ra21taWluZwOBRqbGxsq' +
- 'K+vr6urra2trq6qqqqsrKyoqFhHo5TEWiFKtKE8TD6NfgF8ZUUlfJNq+G519Q2NoVA4/Lek2lJI931algO8HeCqvKGBwOsIvFqBV+j' +
- 'hJXHCFF+9Huj1hN7Scs/vQvZTJ/f9Ppe3mcjVlGsyrsv1mpI1mtDo6QtVyvHV1WBvDIWbW1pb2//G58tMjRwaLvAHXE7hIA9RuVzsc' +
- 'sqNGedsHquFf6t+rqd2kndOb2ttn/2p1OQ9w58ZCHxWlbeYyUnKNXAh4cxqEuwFMLVXVpFmh3pvbYP/Zvu9n/Olot+h3AOBzwtyqHX' +
- 'tgNOmXN/ignuVJmQ/56s9D98J0v5YQ2O4pa090gH2jtt/LQV2WNUCgT8Tqp3KhT7n802bcrXSGXqlPrif4tfwzFM7tHsdo3ds7oR+7' +
- '5j9W97LM3wzA1lfUOXNOvn6anFJ0zY5r3UTucznuVfLXrbXQrO3tEU6o13RFrDf9zmv6Zl+fyCQ9cWIblGLKdc2uVLnDFoEUUj/YcH' +
- '0K9XUq3hS8nUNlN7V0xMh9ujtHtMzCH3WbcqEExY1bbWLcqHS1XxTbKE2OF/Wi3aa9ua2SLS7t6+vmdpn/4rHdGj1rNuM8jrDhGO1b' +
- 'tbiWnUBDc4vLOJ6mnm54ysqIe3h1ki0p69/IBoi9s77ftNTuo/0+pc0s12zkREHnJpxNeGCusAYYvJXqZmneYe0h1ragT4wOBwO07x' +
- '3ednwQJ8RyPpyG5/tYpvHk2vhGm8+/DLo2cwX7CTtUPGbu58ZHB7tbpTt/+ApHQr+yyabVy6vUOVrqZzPNgM8XwiNvUi2r+ajvpSkv' +
- 'SHUGunqGxzZNdbYGGomNd915y84lPyT7fgvGv9H4qQY/2sS/6OLN+wE+5JtHE/skPb2aN/A6NjuzfXMHu2685ed0X863WMHdPwaJe+' +
- 'V1fWh1s6egZGx/WNkT89q/hvOhl2qZQljiEw71vAs7S2Rrn6gHwrV1Ss1/40/vkHprOPXMPv6hlBbtG8Y6J3Vtbzmez9/Q9KL2DIn2' +
- '6tqG1s6egZ37T88CgOf13zvX9yI9MJChqf2dRXV9c3tXf2j+w8fq2B2VvO9/3gD0gvYIs+mHaS9DgbdMyN7Dx8LgV2oedv2VMsSxhB' +
- 'd6Cke8r62tKIaBl3v8NihY22lFZqat2tPtSxhDOWzTQ7YSd4h7fXh9u6BXQePRdfK9rBi/7mk0rc+Ur5CglhS/t0D6oPl5UHyYPkjO' +
- '8+onyqJ8apT+rPL8xme2km314Zao/2jB48Okz9o7Hfastt9JiJnyQHjg8Gt6PTly/OVoqdpr25o6ewb2f/y6MrVJbrE3/mzHtElaaf' +
- 'JgyvOmH2qc/qy5QwPRb+SYKHimzt6h/ceHi2kf3Rsd0eXDpg8qNix6Iq9AGp+1Zq16yrrQpGewd2HDy8vFPKuHMz8TJLpK1hvQ30LD' +
- '5YrD34XlZ6Xl8cTDyVfUgrN3tY1MHbotWVGO+Tdcr87o8MHW4WSVx48s5F9dEr41FdZnIn3TePSly4V7atK1lasb4Q5N3bw2NJl+WL' +
- 'Nh2wewDum/5QxH9E+WE4/2qj7VDcBdNUOaYeKr25o7ezfdfDo4qUmee/s+vuk019lpa998JShDTDoon11Ccw5GPGj+4/maezqxs6i3' +
- 'Tld+FB4cIXa2Yh0Yif4goKiVWtKK+ubN5PVrfTBxeY1b82OTWcjYCsiPScnh9pJ4iHtK9eUVtSFI72wiy9d+GCMmv9zL+hB3YMHzCa' +
- 'AK/rixYtzeNHnFxStXltRG470wMK+doHOXsvtf5pUOmvrch3yVdNHXcR/E7pqLyhcvXZdbai9G+glDzB7vibv9AR91+8kk75VHeYik' +
- 'n64BJcuJ57Y8wtXlayrhoUd9jRr5j2gz7tc85HO+34jefQzS+hHB0zp+gnghv6gal8K9oKVQG8E+tih1XONdl7z9yXc2jilH1gRYxn' +
- 'T0yW1AxzSH2R4Nu2WFxSVlFbBnga2c6vu5/Z846ybncjujM5jpyd0NfF5y/OLYHVrIPSDRXPuN8k7r/lEb8S6o2/Uc5NAX7RokWAHI' +
- '4z4hpYobOeKskV7gaHm/y6J9I2aB4WPg/pPdUFfuJDYmT6HVPyqtRWwnesf3V8gZcfLe0fnZ5NFL39V+yD98A1VikN/eiGxL2J2kva' +
- 'CVSUVcMTeN7J3sRTDLuc9cu+v49PLyzdufUP/IP2QreuIW5qnFywkwe15+TDiyXZueDf59vFr/r6fR6fHfhB9I/v0Ao0d6EUl6+gR+' +
- '6hksBtqfraH9Efoh4bV3hWd4VnD5yyFOVdaRU7PbZYW5+eva2wMhRvAG2N9/2vv6OxEzRlk+gI179DsMOKh4rueGd61e//BQ4cOv/z' +
- 'y0WPHXvvhyGCkapVhT/uHXtF3qq2OSudFvzgnj+3nWjq6+gaGR3eN7d67d//Bg/ACHAX+D/f3hrQ1f+8veUM/w5Ju3Oi4pjM7r/iKO' +
- 'nJVTXdf/8DA4PDICH0FCJ/ojw2ExZqP2e6o9FNsd7skzqfapz+wYIGqJ/ZlkPbSitqGMNmyRbu6unt64SUYhAqgfEj+a0ej1WrN/1X' +
- 'y6extGYmffcWii/ZFpNthVwP26rpGcrlwa1s7bF6iXeAfGByh3Q/6Y0f7annN/3bS6UrsjPepTug6e07ecjhyJVeX0Fsj6A0C8ALAQ' +
- 'XpPX/+wrIfoq5Nr/p5f9Ii+M+6nOqKrerKpJfaCIjLMyDWUleT2EHJzCHv/hehHx0APsT9ay/JufiCDTd94Kv6nOqVzO6zfMOrgKLV' +
- 'oNb3OQrmAtpZcON3cGuns6u0nF5fthdg90sLsn0kanb37GoTd7alEn2o7np6no9PjOHL0St+Iki80KSV8qm9t3xzt6YehNwaxa6T7M' +
- 'Wr/VQS65/HUPAgBv5DNupyl7CxlAXkDFl4A+bq6Wnb1NL2YdGR0dHRksC9M7Leb3DiQalnCoHSG16xx9KxNHjs5Xyjr5WuIQ80UD6k' +
- 'fHhzo72sl9s8Y7amWJQwjfYG8r5NPWcnn54meXGvD8C1tHWzD09/f19MKQ7DFeMNIqmUJQ6aLNS93/IPCiVpa+iq+Xu75Poje7q52s' +
- 'H/FcGNgqmUJ46m584x5V+0MT96Vkt9/ZxdV1taHwjDto909PT3d0U5S83+kt6daljCemivaxYbX4vkb8DKetDzJfLQrGt0caWlovMe' +
- 'ns6daljCArtrnae2LBDt5eyJfGHhV6x8jN0hFNnd2bu5ob2tuaPxLnT3VsoRB6IqdpT5G3hV7kTLs6ayHHW4kEmlvaw3VN37Kn5mZd' +
- 'nSrdrnoKZ50/GNkO9NG77RuDtXf7ctwdVOkfBcEvZMhn7zfvywvj7wnlJNDT5WTs0iLFpFjaz6SaIvypz6Xxf3GmKP5TQ1b9uVC0bN' +
- '1Ltwi33raWP8VPwodXz5njvCbni7oE9g1Oxx6X2A4zG7Sabgr4PO7uAdapVM50OllD0y+2JWcoOXfyAcGvB27fFUpuTGQ3vNPb9G5I' +
- '+DLdJF2mZ4UOQ/2Z9GuKXtrNc8anh3VN9B7EO+YGYB2d01n1e5ezsucRHa27hWI0fFx1neh5ql9HT2gZfH1QMDnottlukmfO5SDcA6' +
- 'Xy3blJTD0vL1+Vw5pyA89gFh/dyCQmeGajjThNEnOzpbt/CVwmvd8rZ2cy6mqrqq6Owsq3nXBY8p5qmU7fwlwap7/5IPKu7MCM100u' +
- '0h3PeHEMs/WB1rNK7fAVwA94He+vHE6ptw85siDwHnNF9E7ghX8uq/j0DFmu1H+rW83NZXlavPu0L5csJew+8AJ3efPcElfhjLbtfL' +
- '5z5/9mMbz87md+W3bNXsbbr+L9LrPLR1twgkZl+EQJ+cLjzvOO5vz8m1ixA70Ge7p+PL5H3ysxrP6nndR8yv5DcF3kYLHoFuUz7Umz' +
- '37yYzFyXduFmlfseHTU2T7/rIb+uGHWm9vjnbPS13wJFh15tjdp5B+fzM6WYust4tWDGXo3dMl/4tCR5dkvaekfZ0tSHLudzU0+a3i' +
- 'w49BRJxwJeVlrkuv+cpmU2G48iNWfpVbshdR+BwodW17GxJLECv/y5SYJ345Hx5rtEBKb7z8C7VlGf1JKYI/Z74tinKxciUtH2rdLA' +
- 'v1HVK7QDXYLg97EzmYdGh1TLrEp9zyjg/zyjyXn9lhzHouO1+eSnGtzehy73TmPRMeVy3RS8Cep/JJKT2S3Puv+A4WOLBfoTC7SJR3' +
- 'dsR2LjjXb9XQm19Dj2G3N+X/HoVP5grhykwEXSy6POVjXy8zoSHYcOt5sZyEftwWlJibX0Z3YjTWPREfsc4FeJj3P5JeelKzarc95H' +
- 'DqyXHpcPlaVzsagY8y6f8OiY8oltoe//FITg5vQEexYdKzZzqKY0c+eVeiPG+juZx0SHW22y8F27pcV+aUyI921HYeON9vlOGmB7nb' +
- 'O49Ix+pzGS1r5paAZ3eWcR6WjyaUntfJLpnKXsw6TjieXvq2VfxCD7sr+r3h0lNkuxxKNXL+ZM6fbnXV4dKTZLscHovzS92PR3djR6' +
- 'BblengMufSShm7c0biys5rHoiP2OY3HRfmVptj0ePb4cx6Jji2XikX5FdNl3ao91qzDoaPLodkF+RXzZd2lHY+ONNuVeFakx5Vr6dZ' +
- 'nHRodbbbLUSzIX49Pdzjn/wWJjjfblTjJ5Vdir21u7Eh03D6n0cTlV+KsbRbsseY8Dj0Jcil4VpHHXdus2o2zDpeOKJek5znd5EQFg' +
- 'h2TjjTblchV5FfOxV/cTOhW+h2RjjXbeZy8ooSFZtfjE9vx6HizXYkfc7qltNu99ACNji+XrlyxmXbrcx6TngR5riqfPJeLY58rpB2' +
- 'JngS5VCbQJ/dY/CIbdhy6dblluCQ9KcgnJ52kPWa/00mHSceVS98X5ZNHrH6ZZTsi3Qh3JZc+EOWTk3GP2a3b1SmPR0ftc4igVj553' +
- 'PJXxu93bkejY8uVKafIJydq3Ns1qzsWHV0uTzlVPjFu/Wtj2eeKdiQ68oQj8bpOPjFh5QDOhG6wo9KTIJf0SZ+YsLidNeLN845PR5j' +
- 'tJMoM8omJLTa+PrH9n5NDd9nnEmt1qn6dyycmLO5rTO336+3odCQ5bXVKD57j8gmr21kTu7i+MTs2HUsuKfKfSFsm1LC8r9HbDXv5u' +
- 'dh0nD6XaKuzLh+SpHGVbn1fo6WbHcfg0tHk0OrygIMVrUmlT1lf4ET8HLNjOEw60myn8bpCJ5PtbS6fOm9jgVPtc8zsiHRMuaTI6Ra' +
- 'uTKVP2Vng4tu/hkzHmHAEqyzobKYfV+AQdha4uHY8OqZcGlLom+gfcwX6CZvfKma/o9Exq12SfqLs4orZn7dw+dSUrQVOHfOGvGPRc' +
- 'eVBJennlAfGuXzqtCO50Y5Ex5VLNUrS+WmpGpU+tc2R3GDHoSPLpT3KQYu6jB9X6RcsTzrdM9La8ehYE47EuHK4piJzz6t2i5PO8Iy' +
- '0djQ6pjxXkYsnZjap9Clr56qMdM2cx6IjwkGpHKJrjtTUkr962tKeLiZ9DiYdVS59T6Frspt7gdOvWpx0ce04dFy5xM/LaJO7icuvX' +
- 'i12b08K3aW8RpHrD1FPcPnVdy1+rzj2ZNBdyukultI36f4ieEGRWy75WPYkZd0tfVw5GWeo6jIuv3r1Ief27CT1ulu4VKzITd5z2KH' +
- 'SP3L03msy6a7lZGlj9CGTvzzB6Zbb3YhPzoR3L1fPyZgdogUvqPbnHNqT0+sI8lzl3PN5078uVunXNjiyJ2fCI8jVk5AxTrpv4PJrH' +
- '1lc3Y23BxH79KMfUeixNuo7OP3aR2TPU1yz7YU333zz4idvvvXWi9sffXi+RftXEekYcCk4EbfeSbygyK9de++F966x+ESN97/jNR1' +
- 'FnrDeIYLvcroaAv2T6++bZN6Ax6PjyNV6j3MKDuzX4smvX3/f5Kv0djQ6kpzXe+xrKHI3vPJR3JyT2J7YjkVHkqv1brafgVemZsdpk' +
- '2q/ppdf/zABPRuNjiVX691km5r7xAl1uMdP+vXr34ovB/s0o+cq8nf0fxPc8K66l9HLL8K69pYIv3794QRyLDqWXNqk0LXvqAY3vHJ' +
- 'VCGPOn4ORPv/FeHS9PDt7mtGV/bvmDdWyfReumskvCtV+8Qn4xPdV+XXd8maUT7OsFyvvqO7jD+VuOz111Sh/77maYPAVsdE/3P7N7' +
- 'ar8rYTyaUYfUujK5nzDiakpg/yjFzbIQ3Cb+YiDeDShfJrRz8vvqLKTcrk7Lqgn4/hR+nPiMctDF83lLyaWTy96k3IBARlyNSeEE7C' +
- 'K+wn9mhd8xUz+lqbTzeXTi65cQTAuBbecntLLX9lg+sbDQx8a6NqtnFE+/ej8AoIj+4Q3mZj7hLmbxnc+1MB/8M1E8ulX8EMKXQ831' +
- 'rkuHn3xokL/gW5BN5VPuzF33igH+ukdlk69PvzEdohH9UerMeTTbHFrMpPvs34DgFnElE+vLc3bBvnpTfaukrMjn070Mr18n73rhWz' +
- 'Kp88ePnePttxdJzyhfJpkncFV+RHXCU8snxZ0Ga7IL1gb6W7l04AeVK53x6v0xPLpQA9uOTch0neguK3IU01v4nAmv4CTcivy1NLLh' +
- 'PsbWLnrr6NIihz13RdHzy/3+IRebuvyV5fy1NGDQ5MGuc2Lnt3JU0ZvEm7hOr9Hplu+R92FPNX04uPqbXvntwT3yAu6B+u58D8BxXl' +
- '/3d6TCw6p92oCXMqVy93mbS0u5UiXFth6cmXjXE7gkrQHccZZhaNdUGLjuQW/p96fS+FSGeKMsyH3nF5zjsuPs9YOjk+h7ePsyD2my' +
- 'ymnl7orp1+G5HJH2MdZ73PP6XLKQX6Oj7QavHK3J/eUzm9emzjClzHlvo4dnsu9pO/hd3AJpxrfYXLD2+nY8jkGuXf0oHLX3uTbws5' +
- 'Ffq/hguVr//Dk3tFf53Jhnm2RG93yFZ+Ics/oe8zkTcq51yTLjX3uIb2J97lQ7Yr8HdfrmhO5R/TgOYUu7NOVu3jcN7ojuUd0Xu7qN' +
- 'WHK4drUVJLlpn3uGV1N+oTyUNn4FNaIcyj3hl7D5TKdnHlPtdwb+hYuJzftBWuOTHglj9XnXtPJ4drbx8eFk3EXkvyOYjy5pwUvnIZ' +
- 'k9HfcTrgE8Lhyjyb8uE4un4VM8noep8+9oxefM+b8fEp2r2og/YSShE+yeFwv35f0988TyL2ii28rkh+ntA/hvLObPveSDtF0hF0HO' +
- 'r6vCeNNRbdyL+kkysrcH5lbgVuQe01HC1d9zn7oWprSXcnlH+6N80PX0lGennT3fZ6udBx5GtITwC3L049uGZ5IfqPRLU44xB+mmo7' +
- 'ydKNj9Tnez4xOR3la0RPAbcrTiW4Zbk1+49BtTTgk+gyP6NhyQp/hjj4zkPWllMvt9rlMn+mG7icFf1s6ylnB+13Q/YHArKTTE8Ady' +
- 'ed9bVYg4HdOzyT0rC+mVm57tsv0LELPdEr3ZZBe/0JK6Q4mHP0fHX2V9HqGzyn9Fh9t9ltvvfVP0ivgGdNWdy6/xU8W9lnEnk548nS' +
- 'zZpFl3e+cnuHPDEDaqT2tIguSHsh0PuVI1jMg7ZD3tNLDs4WcB+C5u8j6LX5a8iTxhJ8eMYumnJS7G7lqT7twLQe6PyOT7GcDgZkzU' +
- 's2xEDPoM/X5MmE75pJO+p3+guynSfjlZ+wWTuywlSevYapJFoPUKWzeMeQ0oIDSJzI1O5n/B5/xAXbXPcU5AAAAAElFTkSuQmCC';
diff --git a/web-client/core/themes/italia/static/formio/css/src/polyfills/ElementPolyfill.js b/web-client/core/themes/italia/static/formio/css/src/polyfills/ElementPolyfill.js
deleted file mode 100644
index 3f0e77b4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/polyfills/ElementPolyfill.js
+++ /dev/null
@@ -1,379 +0,0 @@
-// Using polyfill from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
-/* eslint-disable */
-if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
- if (!Element.prototype.matches) {
- Element.prototype.matches = Element.prototype.msMatchesSelector ||
- Element.prototype.webkitMatchesSelector;
- }
-
- if (!Element.prototype.closest) {
- Element.prototype.closest = function(s) {
- var el = this;
- do {
- if (el.matches(s)) return el;
- el = el.parentElement || el.parentNode;
- } while (el !== null && el.nodeType === 1);
- return null;
- };
- }
-}
-
-// Generated by https://polyfill.io/v3/
-/* Polyfill service v3.52.1
- * For detailed credits and licence information see https://github.com/financial-times/polyfill-service.
- *
- * Features requested: DOMTokenList
- *
- * - Object.defineProperty, License: CC0 (required by "_DOMTokenList", "DOMTokenList")
- * - _DOMTokenList, License: ISC (required by "DOMTokenList")
- * - DOMTokenList, License: CC0 */
-
-(function(self, undefined) {
- // Don't try to do polyfills outside of browser context.
- if (typeof document === 'undefined') {
- return;
- }
-
- if (!("defineProperty"in Object&&function(){try{var e={}
- return Object.defineProperty(e,"test",{value:42}),!0}catch(t){return!1}}()
- )) {
-
- // Object.defineProperty
- (function (nativeDefineProperty) {
-
- var supportsAccessors = Object.prototype.hasOwnProperty.call(Object.prototype, '__defineGetter__');
- var ERR_ACCESSORS_NOT_SUPPORTED = 'Getters & setters cannot be defined on this javascript engine';
- var ERR_VALUE_ACCESSORS = 'A property cannot both have accessors and be writable or have a value';
-
- // Polyfill.io - This does not use CreateMethodProperty because our CreateMethodProperty function uses Object.defineProperty.
- Object.defineProperty = function defineProperty(object, property, descriptor) {
-
- // Where native support exists, assume it
- if (nativeDefineProperty && (object === window || object === document || object === Element.prototype || object instanceof Element)) {
- return nativeDefineProperty(object, property, descriptor);
- }
-
- if (object === null || !(object instanceof Object || typeof object === 'object')) {
- throw new TypeError('Object.defineProperty called on non-object');
- }
-
- if (!(descriptor instanceof Object)) {
- throw new TypeError('Property description must be an object');
- }
-
- var propertyString = String(property);
- var hasValueOrWritable = 'value' in descriptor || 'writable' in descriptor;
- var getterType = 'get' in descriptor && typeof descriptor.get;
- var setterType = 'set' in descriptor && typeof descriptor.set;
-
- // handle descriptor.get
- if (getterType) {
- if (getterType !== 'function') {
- throw new TypeError('Getter must be a function');
- }
- if (!supportsAccessors) {
- throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
- }
- if (hasValueOrWritable) {
- throw new TypeError(ERR_VALUE_ACCESSORS);
- }
- Object.__defineGetter__.call(object, propertyString, descriptor.get);
- } else {
- object[propertyString] = descriptor.value;
- }
-
- // handle descriptor.set
- if (setterType) {
- if (setterType !== 'function') {
- throw new TypeError('Setter must be a function');
- }
- if (!supportsAccessors) {
- throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
- }
- if (hasValueOrWritable) {
- throw new TypeError(ERR_VALUE_ACCESSORS);
- }
- Object.__defineSetter__.call(object, propertyString, descriptor.set);
- }
-
- // OK to define value unconditionally - if a getter has been specified as well, an error would be thrown above
- if ('value' in descriptor) {
- object[propertyString] = descriptor.value;
- }
-
- return object;
- };
- }(Object.defineProperty));
-
- }
-
-
- // _DOMTokenList
- /*
- Copyright (c) 2016, John Gardner
-
- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- var _DOMTokenList = (function() { // eslint-disable-line no-unused-vars
- var dpSupport = true;
- var defineGetter = function (object, name, fn, configurable) {
- if (Object.defineProperty)
- Object.defineProperty(object, name, {
- configurable: false === dpSupport ? true : !!configurable,
- get: fn
- });
-
- else object.__defineGetter__(name, fn);
- };
-
- /** Ensure the browser allows Object.defineProperty to be used on native JavaScript objects. */
- try {
- defineGetter({}, "support");
- }
- catch (e) {
- dpSupport = false;
- }
-
-
- var _DOMTokenList = function (el, prop) {
- var that = this;
- var tokens = [];
- var tokenMap = {};
- var length = 0;
- var maxLength = 0;
- var addIndexGetter = function (i) {
- defineGetter(that, i, function () {
- preop();
- return tokens[i];
- }, false);
-
- };
- var reindex = function () {
-
- /** Define getter functions for array-like access to the tokenList's contents. */
- if (length >= maxLength)
- for (; maxLength < length; ++maxLength) {
- addIndexGetter(maxLength);
- }
- };
-
- /** Helper function called at the start of each class method. Internal use only. */
- var preop = function () {
- var error;
- var i;
- var args = arguments;
- var rSpace = /\s+/;
-
- /** Validate the token/s passed to an instance method, if any. */
- if (args.length)
- for (i = 0; i < args.length; ++i)
- if (rSpace.test(args[i])) {
- error = new SyntaxError('String "' + args[i] + '" ' + "contains" + ' an invalid character');
- error.code = 5;
- error.name = "InvalidCharacterError";
- throw error;
- }
-
-
- /** Split the new value apart by whitespace*/
- if (typeof el[prop] === "object") {
- tokens = ("" + el[prop].baseVal).replace(/^\s+|\s+$/g, "").split(rSpace);
- } else {
- tokens = ("" + el[prop]).replace(/^\s+|\s+$/g, "").split(rSpace);
- }
-
- /** Avoid treating blank strings as single-item token lists */
- if ("" === tokens[0]) tokens = [];
-
- /** Repopulate the internal token lists */
- tokenMap = {};
- for (i = 0; i < tokens.length; ++i)
- tokenMap[tokens[i]] = true;
- length = tokens.length;
- reindex();
- };
-
- /** Populate our internal token list if the targeted attribute of the subject element isn't empty. */
- preop();
-
- /** Return the number of tokens in the underlying string. Read-only. */
- defineGetter(that, "length", function () {
- preop();
- return length;
- });
-
- /** Override the default toString/toLocaleString methods to return a space-delimited list of tokens when typecast. */
- that.toLocaleString =
- that.toString = function () {
- preop();
- return tokens.join(" ");
- };
-
- that.item = function (idx) {
- preop();
- return tokens[idx];
- };
-
- that.contains = function (token) {
- preop();
- return !!tokenMap[token];
- };
-
- that.add = function () {
- preop.apply(that, args = arguments);
-
- for (var args, token, i = 0, l = args.length; i < l; ++i) {
- token = args[i];
- if (!tokenMap[token]) {
- tokens.push(token);
- tokenMap[token] = true;
- }
- }
-
- /** Update the targeted attribute of the attached element if the token list's changed. */
- if (length !== tokens.length) {
- length = tokens.length >>> 0;
- if (typeof el[prop] === "object") {
- el[prop].baseVal = tokens.join(" ");
- } else {
- el[prop] = tokens.join(" ");
- }
- reindex();
- }
- };
-
- that.remove = function () {
- preop.apply(that, args = arguments);
-
- /** Build a hash of token names to compare against when recollecting our token list. */
- for (var args, ignore = {}, i = 0, t = []; i < args.length; ++i) {
- ignore[args[i]] = true;
- delete tokenMap[args[i]];
- }
-
- /** Run through our tokens list and reassign only those that aren't defined in the hash declared above. */
- for (i = 0; i < tokens.length; ++i)
- if (!ignore[tokens[i]]) t.push(tokens[i]);
-
- tokens = t;
- length = t.length >>> 0;
-
- /** Update the targeted attribute of the attached element. */
- if (typeof el[prop] === "object") {
- el[prop].baseVal = tokens.join(" ");
- } else {
- el[prop] = tokens.join(" ");
- }
- reindex();
- };
-
- that.toggle = function (token, force) {
- preop.apply(that, [token]);
-
- /** Token state's being forced. */
- if (undefined !== force) {
- if (force) {
- that.add(token);
- return true;
- } else {
- that.remove(token);
- return false;
- }
- }
-
- /** Token already exists in tokenList. Remove it, and return FALSE. */
- if (tokenMap[token]) {
- that.remove(token);
- return false;
- }
-
- /** Otherwise, add the token and return TRUE. */
- that.add(token);
- return true;
- };
-
- return that;
- };
-
- return _DOMTokenList;
- }());
- if (!("DOMTokenList"in self&&function(e){return!("classList"in e)||!e.classList.toggle("x",!1)&&!e.className}(document.createElement("x"))
- )) {
-
- // DOMTokenList
- /* global _DOMTokenList */
- (function (global) {
- var nativeImpl = "DOMTokenList" in global && global.DOMTokenList;
-
- if (
- !nativeImpl ||
- (
- !!document.createElementNS &&
- !!document.createElementNS('http://www.w3.org/2000/svg', 'svg') &&
- !(document.createElementNS("http://www.w3.org/2000/svg", "svg").classList instanceof DOMTokenList)
- )
- ) {
- global.DOMTokenList = _DOMTokenList;
- }
-
- // Add second argument to native DOMTokenList.toggle() if necessary
- (function () {
- var e = document.createElement('span');
- if (!('classList' in e)) return;
- e.classList.toggle('x', false);
- if (!e.classList.contains('x')) return;
- e.classList.constructor.prototype.toggle = function toggle(token /*, force*/) {
- var force = arguments[1];
- if (force === undefined) {
- var add = !this.contains(token);
- this[add ? 'add' : 'remove'](token);
- return add;
- }
- force = !!force;
- this[force ? 'add' : 'remove'](token);
- return force;
- };
- }());
-
- // Add multiple arguments to native DOMTokenList.add() if necessary
- (function () {
- var e = document.createElement('span');
- if (!('classList' in e)) return;
- e.classList.add('a', 'b');
- if (e.classList.contains('b')) return;
- var native = e.classList.constructor.prototype.add;
- e.classList.constructor.prototype.add = function () {
- var args = arguments;
- var l = arguments.length;
- for (var i = 0; i < l; i++) {
- native.call(this, args[i]);
- }
- };
- }());
-
- // Add multiple arguments to native DOMTokenList.remove() if necessary
- (function () {
- var e = document.createElement('span');
- if (!('classList' in e)) return;
- e.classList.add('a');
- e.classList.add('b');
- e.classList.remove('a', 'b');
- if (!e.classList.contains('b')) return;
- var native = e.classList.constructor.prototype.remove;
- e.classList.constructor.prototype.remove = function () {
- var args = arguments;
- var l = arguments.length;
- for (var i = 0; i < l; i++) {
- native.call(this, args[i]);
- }
- };
- }());
-
- }(self));
-
- }
-
- })
- ('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
diff --git a/web-client/core/themes/italia/static/formio/css/src/polyfills/index.js b/web-client/core/themes/italia/static/formio/css/src/polyfills/index.js
deleted file mode 100644
index e2387c3f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/polyfills/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import 'custom-event-polyfill';
-import './ElementPolyfill';
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/Providers.js b/web-client/core/themes/italia/static/formio/css/src/providers/Providers.js
deleted file mode 100644
index 6e7d15c3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/Providers.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import _ from 'lodash';
-
-import address from './address';
-import auth from './auth';
-import storage from './storage';
-
-export default class Providers {
- static providers = {
- address,
- auth,
- storage,
- };
-
- static addProvider(type, name, provider) {
- Providers.providers[type] = Providers.providers[type] || {};
- Providers.providers[type][name] = provider;
- }
-
- static addProviders(type, providers) {
- Providers.providers[type] = _.merge(Providers.providers[type], providers);
- }
-
- static getProvider(type, name) {
- if (Providers.providers[type] && Providers.providers[type][name]) {
- return Providers.providers[type][name];
- }
- }
-
- static getProviders(type) {
- if (Providers.providers[type]) {
- return Providers.providers[type];
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/address/AddressProvider.js b/web-client/core/themes/italia/static/formio/css/src/providers/address/AddressProvider.js
deleted file mode 100644
index d72d9f91..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/address/AddressProvider.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import _ from 'lodash';
-
-import { GlobalFormio as Formio } from '../../Formio';
-
-export class AddressProvider {
- static get name() {
- return 'address';
- }
-
- static get displayName() {
- return 'Address';
- }
-
- constructor(options = {}) {
- this.beforeMergeOptions(options);
- this.options = _.merge({}, this.defaultOptions, options);
- }
-
- beforeMergeOptions() {
- return;
- }
-
- get defaultOptions() {
- return {};
- }
-
- get queryProperty() {
- return 'query';
- }
-
- get responseProperty() {
- return null;
- }
-
- get displayValueProperty() {
- return null;
- }
-
- serialize(params) {
- return _.toPairs(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join('&');
- }
-
- getRequestOptions(options = {}) {
- return _.merge({}, this.options, options);
- }
-
- // eslint-disable-next-line no-unused-vars
- getRequestUrl(options = {}) {
- throw new Error('Method AddressProvider#getRequestUrl(options) is abstract.');
- }
-
- makeRequest(options = {}) {
- return Formio.makeStaticRequest(this.getRequestUrl(options), 'GET', null, {
- noToken: true,
- });
- }
-
- search(query, options = {}) {
- const requestOptions = this.getRequestOptions(options);
- const params = requestOptions.params = requestOptions.params || {};
- params[this.queryProperty] = query;
-
- return this.makeRequest(requestOptions)
- .then((result) => this.responseProperty ? _.get(result, this.responseProperty, []) : result);
- }
-
- getDisplayValue(address) {
- return this.displayValueProperty ? _.get(address, this.displayValueProperty, '') : String(address);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/address/AzureAddressProvider.js b/web-client/core/themes/italia/static/formio/css/src/providers/address/AzureAddressProvider.js
deleted file mode 100644
index a5edb697..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/address/AzureAddressProvider.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { AddressProvider } from './AddressProvider';
-
-export class AzureAddressProvider extends AddressProvider {
- static get name() {
- return 'azure';
- }
-
- static get displayName() {
- return 'Azure Maps';
- }
-
- get defaultOptions() {
- return {
- params: {
- 'api-version': '1.0',
- typeahead: 'true',
- },
- };
- }
-
- get responseProperty() {
- return 'results';
- }
-
- get displayValueProperty() {
- return 'address.freeformAddress';
- }
-
- getRequestUrl(options = {}) {
- const { params } = options;
-
- return `https://atlas.microsoft.com/search/address/json?${this.serialize(params)}`;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/address/CustomAddressProvider.js b/web-client/core/themes/italia/static/formio/css/src/providers/address/CustomAddressProvider.js
deleted file mode 100644
index 49b3d7d8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/address/CustomAddressProvider.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { AddressProvider } from './AddressProvider';
-
-export class CustomAddressProvider extends AddressProvider {
- static get name() {
- return 'custom';
- }
-
- static get displayName() {
- return 'Custom';
- }
-
- get queryProperty() {
- return this.options.queryProperty || super.queryProperty;
- }
-
- get responseProperty() {
- return this.options.responseProperty || super.responseProperty;
- }
-
- get displayValueProperty() {
- return this.options.displayValueProperty || super.displayValueProperty;
- }
-
- getRequestUrl(options = {}) {
- const { params, url } = options;
-
- return `${url}?${this.serialize(params)}`;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/address/GoogleAddressProvider.js b/web-client/core/themes/italia/static/formio/css/src/providers/address/GoogleAddressProvider.js
deleted file mode 100644
index f3e950d8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/address/GoogleAddressProvider.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/* globals google */
-import { GlobalFormio as Formio } from '../../Formio';
-import _ from 'lodash';
-import { AddressProvider } from './AddressProvider';
-import NativePromise from 'native-promise-only';
-
-export class GoogleAddressProvider extends AddressProvider {
- static get name() {
- return 'google';
- }
-
- static get displayName() {
- return 'Google Maps';
- }
-
- constructor(options = {}) {
- super(options);
- this.setAutocompleteOptions();
-
- let src = 'https://maps.googleapis.com/maps/api/js?v=quarterly&libraries=places&callback=googleMapsCallback';
-
- if (options.params?.key) {
- src += `&key=${options.params.key}`;
- }
-
- Formio.requireLibrary(this.getLibraryName(), 'google.maps.places', src);
- }
-
- get displayValueProperty() {
- return 'formattedPlace';
- }
-
- get alternativeDisplayValueProperty() {
- return 'formatted_address';
- }
-
- set autocompleteOptions(options) {
- this._autocompleteOptions = options;
- }
-
- get autocompleteOptions() {
- return this._autocompleteOptions;
- }
-
- setAutocompleteOptions() {
- let options = _.get(this.options, 'params.autocompleteOptions', {});
-
- if (!_.isObject(options)) {
- options = {};
- }
-
- this.addRequiredProviderOptions(options);
- this.autocompleteOptions = options;
- }
-
- beforeMergeOptions(options) {
- // providing support of old Google Provider option
- this.convertRegionToAutocompleteOption(options);
- }
-
- getLibraryName() {
- return 'googleMaps';
- }
-
- convertRegionToAutocompleteOption(options) {
- const providerOptions = options;
- let region = _.get(providerOptions, 'params.region', '');
-
- if (region && !_.has(options, 'params.autocompleteOptions')) {
- region = region.toUpperCase().trim();
- // providing compatibility with ISO 3166-1 Alpha-2 county codes (for checking compatibility https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes)
- const countryCodes = { 'UK': 'GB' };
-
- if (countryCodes[region]) {
- region = countryCodes[region];
- }
-
- _.set(providerOptions, 'params.autocompleteOptions.componentRestrictions.country', [region]);
- }
- }
-
- getRequiredAddressProperties() {
- return ['address_components', 'formatted_address','geometry','place_id', 'plus_code', 'types'];
- }
-
- addRequiredProviderOptions(options) {
- const addressProperties = this.getRequiredAddressProperties();
-
- if (_.isArray(options.fields) && options.fields.length > 0 ) {
- options.fields.forEach(optionalField => {
- if (!addressProperties.some(addressProp => optionalField === addressProp)) {
- addressProperties.push(optionalField);
- }
- });
- }
- options.fields = addressProperties;
- }
-
- filterPlace(place) {
- place = place || {};
- const filteredPlace = {};
-
- if (this.autocompleteOptions) {
- this.autocompleteOptions.fields.forEach(field => {
- if (place[field]) {
- filteredPlace[field] = place[field];
- }
- });
- }
-
- return filteredPlace;
- }
-
- attachAutocomplete(elem, index, onSelectAddress) {
- Formio.libraryReady(this.getLibraryName()).then(() => {
- const autocomplete = new google.maps.places.Autocomplete(elem, this.autocompleteOptions);
-
- autocomplete.addListener('place_changed', ()=>{
- const place = this.filterPlace(autocomplete.getPlace());
- place.formattedPlace = _.get(autocomplete, 'gm_accessors_.place.se.formattedPrediction', place[this.alternativeDisplayValueProperty]);
-
- onSelectAddress(place, elem, index);
- });
- });
- }
-
- search() {
- return NativePromise.resolve();
- }
-
- makeRequest() {
- return NativePromise.resolve();
- }
-
- getDisplayValue(address) {
- const displayedProperty = _.has(address, this.displayValueProperty)
- ? this.displayValueProperty
- : this.alternativeDisplayValueProperty;
-
- return _.get(address, displayedProperty, '');
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/address/NominatimAddressProvider.js b/web-client/core/themes/italia/static/formio/css/src/providers/address/NominatimAddressProvider.js
deleted file mode 100644
index 04a391fd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/address/NominatimAddressProvider.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { AddressProvider } from './AddressProvider';
-
-export class NominatimAddressProvider extends AddressProvider {
- static get name() {
- return 'nominatim';
- }
-
- static get displayName() {
- return 'OpenStreetMap Nominatim';
- }
-
- get defaultOptions() {
- return {
- params: {
- addressdetails: '1',
- format: 'json',
- },
- };
- }
-
- get queryProperty() {
- return 'q';
- }
-
- get displayValueProperty() {
- return 'display_name';
- }
-
- getRequestUrl(options = {}) {
- const { params } = options;
-
- return `https://nominatim.openstreetmap.org/search?${this.serialize(params)}`;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/address/index.js b/web-client/core/themes/italia/static/formio/css/src/providers/address/index.js
deleted file mode 100644
index dcc62860..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/address/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { AzureAddressProvider } from './AzureAddressProvider';
-import { CustomAddressProvider } from './CustomAddressProvider';
-import { GoogleAddressProvider } from './GoogleAddressProvider';
-import { NominatimAddressProvider } from './NominatimAddressProvider';
-
-export default {
- [AzureAddressProvider.name]: AzureAddressProvider,
- [CustomAddressProvider.name]: CustomAddressProvider,
- [GoogleAddressProvider.name]: GoogleAddressProvider,
- [NominatimAddressProvider.name]: NominatimAddressProvider,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/auth/index.js b/web-client/core/themes/italia/static/formio/css/src/providers/auth/index.js
deleted file mode 100644
index ff8b4c56..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/auth/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export default {};
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/index.js b/web-client/core/themes/italia/static/formio/css/src/providers/index.js
deleted file mode 100644
index ab9b302b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Providers from './Providers';
-
-export default Providers;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/processor/fileProcessor.js b/web-client/core/themes/italia/static/formio/css/src/providers/processor/fileProcessor.js
deleted file mode 100644
index f263190a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/processor/fileProcessor.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import NativePromise from 'native-promise-only';
-
-const fileProcessor = (formio, config) => (file, options) =>
- new NativePromise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
-
- // Fire on network error.
- xhr.onerror = (err) => {
- err.networkError = true;
- reject(err);
- };
-
- // Fire on network abort.
- xhr.onabort = (err) => {
- err.networkError = true;
- reject(err);
- };
-
- // Fired when the response has made it back from the server.
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- const mimetype = xhr.getResponseHeader('Content-Type') || file.type;
- resolve(new File([xhr.response], file.name, { type: mimetype }));
- }
- else {
- reject(xhr.response || 'Unable to process file');
- }
- };
-
- // Set the onabort error callback.
- xhr.onabort = reject;
-
- xhr.open('POST', config.url);
- const token = formio.getToken();
- if (token) {
- xhr.setRequestHeader('x-jwt-token', token);
- }
- xhr.responseType = 'arraybuffer';
-
- const data = new FormData();
- data.append('file', file);
- data.append('processorOptions', JSON.stringify(config.options || {}));
- data.append('options', JSON.stringify(options || {}));
-
- // Get the request and send it to the server.
- xhr.send(data);
- });
-
-export default fileProcessor;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/azure.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/azure.js
deleted file mode 100644
index 636ea1ba..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/azure.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import XHR from './xhr';
-const azure = (formio) => ({
- uploadFile(file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback) {
- return XHR.upload(formio, 'azure', (xhr, response) => {
- xhr.openAndSetHeaders('PUT', response.url);
- xhr.setRequestHeader('Content-Type', file.type);
- xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
- return file;
- }, file, fileName, dir, progressCallback, groupPermissions, groupId, abortCallback).then(() => {
- return {
- storage: 'azure',
- name: XHR.path([dir, fileName]),
- size: file.size,
- type: file.type,
- groupPermissions,
- groupId
- };
- });
- },
- downloadFile(file) {
- return formio.makeRequest('file', `${formio.formUrl}/storage/azure?name=${XHR.trim(file.name)}`, 'GET');
- }
-});
-
-azure.title = 'Azure File Services';
-export default azure;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/base64.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/base64.js
deleted file mode 100644
index a3c11bbb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/base64.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import NativePromise from 'native-promise-only';
-const base64 = () => ({
- title: 'Base64',
- name: 'base64',
- uploadFile(file, fileName) {
- const reader = new FileReader();
-
- return new NativePromise((resolve, reject) => {
- reader.onload = (event) => {
- const url = event.target.result;
- resolve({
- storage: 'base64',
- name: fileName,
- url: url,
- size: file.size,
- type: file.type,
- });
- };
-
- reader.onerror = () => {
- return reject(this);
- };
-
- reader.readAsDataURL(file);
- });
- },
- downloadFile(file) {
- // Return the original as there is nothing to do.
- return NativePromise.resolve(file);
- }
-});
-
-base64.title = 'Base64';
-export default base64;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/dropbox.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/dropbox.js
deleted file mode 100644
index 3547a033..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/dropbox.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import NativePromise from 'native-promise-only';
-import { setXhrHeaders } from './xhr';
-const dropbox = (formio) => ({
- uploadFile(file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback) {
- return new NativePromise(((resolve, reject) => {
- // Send the file with data.
- const xhr = new XMLHttpRequest();
-
- if (typeof progressCallback === 'function') {
- xhr.upload.onprogress = progressCallback;
- }
-
- if (typeof abortCallback === 'function') {
- abortCallback(() => xhr.abort());
- }
-
- const fd = new FormData();
- fd.append('name', fileName);
- fd.append('dir', dir);
- fd.append('file', file);
-
- // Fire on network error.
- xhr.onerror = (err) => {
- err.networkError = true;
- reject(err);
- };
-
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- const response = JSON.parse(xhr.response);
- response.storage = 'dropbox';
- response.size = file.size;
- response.type = file.type;
- response.groupId = groupId;
- response.groupPermissions = groupPermissions;
- response.url = response.path_lower;
- resolve(response);
- }
- else {
- reject(xhr.response || 'Unable to upload file');
- }
- };
-
- xhr.onabort = reject;
-
- xhr.open('POST', `${formio.formUrl}/storage/dropbox`);
-
- setXhrHeaders(formio, xhr);
-
- const token = formio.getToken();
- if (token) {
- xhr.setRequestHeader('x-jwt-token', token);
- }
- xhr.send(fd);
- }));
- },
- downloadFile(file) {
- const token = formio.getToken();
- file.url =
- `${formio.formUrl}/storage/dropbox?path_lower=${file.path_lower}${token ? `&x-jwt-token=${token}` : ''}`;
- return NativePromise.resolve(file);
- }
-});
-
-dropbox.title = 'Dropbox';
-export default dropbox;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/googleDrive.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/googleDrive.js
deleted file mode 100644
index df35b31a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/googleDrive.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import NativePromise from 'native-promise-only';
-import { setXhrHeaders } from './xhr';
-const googledrive = (formio) => ({
- uploadFile(file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback) {
- return new NativePromise(((resolve, reject) => {
- // Send the file with data.
- const xhr = new XMLHttpRequest();
-
- if (typeof progressCallback === 'function') {
- xhr.upload.onprogress = progressCallback;
- }
-
- if (typeof abortCallback === 'function') {
- abortCallback(() => xhr.abort());
- }
-
- const fd = new FormData();
- fd.append('name', fileName);
- fd.append('dir', dir);
- fd.append('file', file);
-
- // Fire on network error.
- xhr.onerror = (err) => {
- err.networkError = true;
- reject(err);
- };
-
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- const response = JSON.parse(xhr.response);
- response.storage = 'googledrive';
- response.size = file.size;
- response.type = file.type;
- response.groupId = groupId;
- response.groupPermissions = groupPermissions;
- resolve(response);
- }
- else {
- reject(xhr.response || 'Unable to upload file');
- }
- };
-
- xhr.onabort = reject;
-
- xhr.open('POST', `${formio.formUrl}/storage/gdrive`);
-
- setXhrHeaders(formio, xhr);
-
- const token = formio.getToken();
- if (token) {
- xhr.setRequestHeader('x-jwt-token', token);
- }
- xhr.send(fd);
- }));
- },
- downloadFile(file) {
- const token = formio.getToken();
- file.url =
- `${formio.formUrl}/storage/gdrive?fileId=${file.id}&fileName=${file.originalName}${token ? `&x-jwt-token=${token}` : ''}`;
- return NativePromise.resolve(file);
- }
-});
-
-googledrive.title = 'Google Drive';
-export default googledrive;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/index.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/index.js
deleted file mode 100644
index 47ce8853..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/index.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import base64 from './base64';
-import s3 from './s3';
-import azure from './azure';
-import url from './url';
-import indexeddb from './indexeddb';
-import googledrive from './googleDrive';
-
-export default {
- base64,
- s3,
- url,
- azure,
- indexeddb,
- googledrive
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/indexeddb.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/indexeddb.js
deleted file mode 100644
index a33b46cc..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/indexeddb.js
+++ /dev/null
@@ -1,136 +0,0 @@
-import { v4 as uuidv4 } from 'uuid';
-import NativePromise from 'native-promise-only';
-const indexeddb = () => ({
- title: 'indexedDB',
- name: 'indexeddb',
- uploadFile(file, fileName, dir, progressCallback, url, options) {
- if (!('indexedDB' in window)) {
- console.log('This browser doesn\'t support IndexedDB');
- return;
- }
-
- return new NativePromise((resolve) => {
- const request = indexedDB.open(options.indexeddb, 3);
- request.onsuccess = function(event) {
- const db = event.target.result;
- resolve(db);
- };
- request.onupgradeneeded = function(e) {
- const db = e.target.result;
- db.createObjectStore(options.indexeddbTable);
- };
- }).then((db) => {
- const reader = new FileReader();
-
- return new NativePromise((resolve, reject) => {
- reader.onload = () => {
- const blobObject = new Blob([file], { type: file.type });
-
- const id = uuidv4(blobObject);
-
- const data = {
- id,
- data: blobObject,
- name: file.name,
- size: file.size,
- type: file.type,
- url,
- };
-
- const trans = db.transaction([options.indexeddbTable], 'readwrite');
- const addReq = trans.objectStore(options.indexeddbTable).put(data, id);
-
- addReq.onerror = function(e) {
- console.log('error storing data');
- console.error(e);
- };
-
- trans.oncomplete = function() {
- resolve({
- storage: 'indexeddb',
- name: file.name,
- size: file.size,
- type: file.type,
- url: url,
- id,
- });
- };
- };
-
- reader.onerror = () => {
- return reject(this);
- };
-
- reader.readAsDataURL(file);
- });
- });
- },
- downloadFile(file, options) {
- return new NativePromise((resolve) => {
- const request = indexedDB.open(options.indexeddb, 3);
-
- request.onsuccess = function(event) {
- const db = event.target.result;
- resolve(db);
- };
- }).then((db) => {
- return new NativePromise((resolve, reject) => {
- const trans = db.transaction([options.indexeddbTable], 'readonly');
- const store = trans.objectStore(options.indexeddbTable).get(file.id);
- store.onsuccess = () => {
- trans.oncomplete = () => {
- const result = store.result;
- const dbFile = new File([store.result.data], file.name, {
- type: store.result.type,
- });
-
- const reader = new FileReader();
-
- reader.onload = (event) => {
- result.url = event.target.result;
- result.storage = file.storage;
- resolve(result);
- };
-
- reader.onerror = () => {
- return reject(this);
- };
-
- reader.readAsDataURL(dbFile);
- };
- };
- store.onerror = () => {
- return reject(this);
- };
- });
- });
- },
- deleteFile(file, options) {
- return new NativePromise((resolve) => {
- const request = indexedDB.open(options.indexeddb, 3);
-
- request.onsuccess = function(event) {
- const db = event.target.result;
- resolve(db);
- };
- }).then((db) => {
- return new NativePromise((resolve, reject) => {
- const trans = db.transaction([options.indexeddbTable], 'readwrite');
- const store = trans.objectStore(options.indexeddbTable).delete(file.id);
- store.onsuccess = () => {
- trans.oncomplete = () => {
- const result = store.result;
-
- resolve(result);
- };
- };
- store.onerror = () => {
- return reject(this);
- };
- });
- });
- }
-});
-
-indexeddb.title = 'IndexedDB';
-export default indexeddb;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/s3.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/s3.js
deleted file mode 100644
index 9a8599bb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/s3.js
+++ /dev/null
@@ -1,160 +0,0 @@
-import NativePromise from 'native-promise-only';
-
-import XHR from './xhr';
-import { withRetries } from './util';
-
-const AbortController = window.AbortController || require('abortcontroller-polyfill/dist/cjs-ponyfill');
-function s3(formio) {
- return {
- async uploadFile(file, fileName, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback, multipartOptions) {
- const xhrCallback = async(xhr, response, abortCallback) => {
- response.data.fileName = fileName;
- response.data.key = XHR.path([response.data.key, dir, fileName]);
- if (response.signed) {
- if (multipartOptions && Array.isArray(response.signed)) {
- // patch abort callback
- const abortController = new AbortController();
- const abortSignal = abortController.signal;
- if (typeof abortCallback === 'function') {
- abortCallback(() => abortController.abort());
- }
- try {
- const parts = await this.uploadParts(
- file,
- response.signed,
- response.data.headers,
- response.partSizeActual,
- multipartOptions,
- abortSignal
- );
- await withRetries(this.completeMultipartUpload, [response, parts, multipartOptions], 3);
- return;
- }
- catch (err) {
- // abort in-progress fetch requests
- abortController.abort();
- // attempt to cancel the multipart upload
- this.abortMultipartUpload(response);
- throw err;
- }
- }
- else {
- xhr.openAndSetHeaders('PUT', response.signed);
- xhr.setRequestHeader('Content-Type', file.type);
- Object.keys(response.data.headers).forEach((key) => {
- xhr.setRequestHeader(key, response.data.headers[key]);
- });
- return file;
- }
- }
- else {
- const fd = new FormData();
- for (const key in response.data) {
- fd.append(key, response.data[key]);
- }
- fd.append('file', file);
- xhr.openAndSetHeaders('POST', response.url);
- return fd;
- }
- };
- const response = await XHR.upload(
- formio,
- 's3',
- xhrCallback,
- file,
- fileName,
- dir,
- progressCallback,
- groupPermissions,
- groupId,
- abortCallback,
- multipartOptions
- );
- return {
- storage: 's3',
- name: fileName,
- bucket: response.bucket,
- key: response.data.key,
- url: XHR.path([response.url, response.data.key]),
- acl: response.data.acl,
- size: file.size,
- type: file.type
- };
- },
- async completeMultipartUpload(serverResponse, parts, multipart) {
- const { changeMessage } = multipart;
- const token = formio.getToken();
- changeMessage('Completing AWS S3 multipart upload...');
- const response = await fetch(`${formio.formUrl}/storage/s3/multipart/complete`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- ...(token ? { 'x-jwt-token': token } : {}),
- },
- body: JSON.stringify({ parts, uploadId: serverResponse.uploadId, key: serverResponse.key })
- });
- const message = await response.text();
- if (!response.ok) {
- throw new Error(message || response.statusText);
- }
- // the AWS S3 SDK CompleteMultipartUpload command can return a HTTP 200 status header but still error;
- // we need to parse, and according to AWS, to retry
- if (message?.match(/Error/)) {
- throw new Error(message);
- }
- },
- abortMultipartUpload(serverResponse) {
- const { uploadId, key } = serverResponse;
- const token = formio.getToken();
- fetch(`${formio.formUrl}/storage/s3/multipart/abort`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- ...(token ? { 'x-jwt-token': token } : {}),
- },
- body: JSON.stringify({ uploadId, key })
- }).catch((err) => console.error('Error while aborting multipart upload:', err));
- },
- uploadParts(file, urls, headers, partSize, multipart, abortSignal) {
- const { changeMessage, progressCallback } = multipart;
- changeMessage('Chunking and uploading parts to AWS S3...');
- const promises = [];
- for (let i = 0; i < urls.length; i++) {
- const start = i * partSize;
- const end = (i + 1) * partSize;
- const blob = i < urls.length ? file.slice(start, end) : file.slice(start);
- const promise = fetch(urls[i], {
- method: 'PUT',
- headers,
- body: blob,
- signal: abortSignal,
- }).then((res) => {
- if (res.ok) {
- progressCallback(urls.length);
- const eTag = res.headers.get('etag');
- if (!eTag) {
- throw new Error('ETag header not found; it must be exposed in S3 bucket CORS settings');
- }
- return { ETag: eTag, PartNumber: i + 1 };
- }
- else {
- throw new Error(`Part no ${i} failed with status ${res.status}`);
- }
- });
- promises.push(promise);
- }
- return NativePromise.all(promises);
- },
- downloadFile(file) {
- if (file.acl !== 'public-read') {
- return formio.makeRequest('file', `${formio.formUrl}/storage/s3?bucket=${XHR.trim(file.bucket)}&key=${XHR.trim(file.key)}`, 'GET');
- }
- else {
- return NativePromise.resolve(file);
- }
- }
- };
-}
-
-s3.title = 'S3';
-export default s3;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/s3.unit.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/s3.unit.js
deleted file mode 100644
index a1f21f15..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/s3.unit.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import assert from 'assert';
-import sinon from 'sinon';
-import fetchMock from 'fetch-mock';
-
-import S3 from './s3';
-import { withRetries } from './util';
-
-describe('S3 Provider', () => {
- describe('Function Unit Tests', () => {
- it('withRetries should retry a given function three times, then throw the provided error', (done) => {
- function sleepAndReject(ms) {
- return new Promise((_, reject) => setTimeout(reject, ms));
- }
-
- const spy = sinon.spy(sleepAndReject);
- withRetries(spy, [200], 3, 'Custom error message').catch((err) => {
- assert.equal(err.message, 'Custom error message');
- assert.equal(spy.callCount, 3);
- done();
- });
- });
- });
-
- describe('Provider Integration Tests', () => {
- describe('AWS S3 Multipart Uploads', () => {
- before('Mocks fetch', () => {
- fetchMock
- .post('https://fakeproject.form.io/fakeform/storage/s3', {
- signed: new Array(5).fill('https://fakebucketurl.aws.com/signed'),
- minio: false,
- url: 'https://fakebucketurl.aws.com',
- bucket: 'fakebucket',
- uploadId: 'fakeuploadid',
- key: 'test.jpg',
- partSizeActual: 1,
- data: {}
- })
- .put('https://fakebucketurl.aws.com/signed', { status: 200, headers: { 'Etag': 'fakeetag' } })
- .post('https://fakeproject.form.io/fakeform/storage/s3/multipart/complete', 200)
- .post('https://fakeproject.form.io/fakeform/storage/s3/multipart/abort', 200);
- });
- it('Given an array of signed urls it should upload a file to S3 using multipart upload', (done) => {
- const mockFormio = {
- formUrl: 'https://fakeproject.form.io/fakeform',
- getToken: () => {}
- };
- const s3 = new S3(mockFormio);
- const uploadSpy = sinon.spy(s3, 'uploadParts');
- const completeSpy = sinon.spy(s3, 'completeMultipartUpload');
-
- const mockFile = new File(['test!'], 'test.jpg', { type: 'image/jpeg' });
- s3.uploadFile(
- mockFile,
- 'test.jpg',
- '',
- () => {},
- '',
- {},
- 'test.jpg',
- {},
- '',
- () => {},
- { partSize: 1, changeMessage: () => {}, progressCallback: () => {} }
- ).then((response) => {
- assert.equal(response.storage, 's3');
- assert.equal(response.name, 'test.jpg');
- assert.equal(response.bucket, 'fakebucket');
- assert.equal(response.url, 'https://fakebucketurl.aws.com/test.jpg');
- assert.equal(response.acl, undefined);
- assert.equal(response.size, 5);
- assert.equal(response.type, 'image/jpeg');
- assert.equal(uploadSpy.callCount, 1);
- assert.equal(completeSpy.callCount, 1);
- done();
- });
- });
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/uploadAdapter.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/uploadAdapter.js
deleted file mode 100644
index e83a4d89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/uploadAdapter.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import { uniqueName } from '../../utils/utils';
-import NativePromise from 'native-promise-only';
-
-/**
- * UploadAdapter for CKEditor https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/upload-adapter.html
- */
-class FormioUploadAdapter {
- constructor(loader, fileService, component) {
- this.loader = loader;
- this.fileService = fileService;
- this.component = component;
- }
-
- upload() {
- return this.loader.file
- .then(file => new NativePromise((resolve, reject) => {
- const { uploadStorage, uploadUrl, uploadOptions, uploadDir, fileKey } = this.component.component;
- const uploadParams = [
- uploadStorage,
- file,
- uniqueName(file.name),
- uploadDir || '', //should pass empty string if undefined
- (evt) => this.onUploadProgress(evt),
- uploadUrl,
- uploadOptions,
- fileKey,
- null,
- null
- ];
-
- const uploadPromise = this.fileService.uploadFile(
- ...uploadParams,
- () => this.component.emit('fileUploadingStart', uploadPromise)
- ).then((result) => {
- return this.fileService.downloadFile(result);
- }).then((result) => {
- return resolve({
- default: result.url
- });
- }).catch((err) => {
- console.warn('An Error occured while uploading file', err);
- reject(err);
- }).finally(() => {
- this.component.emit('fileUploadingEnd', uploadPromise);
- });
- }));
- }
-
- abort() {}
-
- onUploadProgress(evt) {
- if (evt.lengthComputable) {
- this.loader.uploadTotal = evt.total;
- this.loader.uploaded = evt.loaded;
- }
- }
-}
-
-const getFormioUploadAdapterPlugin = (fileService, component) => (editor) => {
- editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
- return new FormioUploadAdapter(loader, fileService, component);
- };
-};
-
-export { getFormioUploadAdapterPlugin };
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/url.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/url.js
deleted file mode 100644
index 8ca3ea1a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/url.js
+++ /dev/null
@@ -1,156 +0,0 @@
-import NativePromise from 'native-promise-only';
-
-const url = (formio) => {
- const xhrRequest = (url, name, query, data, options, progressCallback, abortCallback) => {
- return new NativePromise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- const json = (typeof data === 'string');
- const fd = new FormData();
-
- if (typeof progressCallback === 'function') {
- xhr.upload.onprogress = progressCallback;
- }
-
- if (typeof abortCallback === 'function') {
- abortCallback(() => xhr.abort());
- }
-
- if (!json) {
- for (const key in data) {
- fd.append(key, data[key]);
- }
- }
-
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- // Need to test if xhr.response is decoded or not.
- let respData = {};
- try {
- respData = (typeof xhr.response === 'string') ? JSON.parse(xhr.response) : {};
- respData = (respData && respData.data) ? respData.data : respData;
- }
- catch (err) {
- respData = {};
- }
-
- // Get the url of the file.
- let respUrl = respData.hasOwnProperty('url') ? respData.url : `${xhr.responseURL}/${name}`;
-
- // If they provide relative url, then prepend the url.
- if (respUrl && respUrl[0] === '/') {
- respUrl = `${url}${respUrl}`;
- }
- resolve({ url: respUrl, data: respData });
- }
- else {
- reject(xhr.response || 'Unable to upload file');
- }
- };
-
- xhr.onerror = () => reject(xhr);
- xhr.onabort = () => reject(xhr);
-
- let requestUrl = url + (url.indexOf('?') > -1 ? '&' : '?');
- for (const key in query) {
- requestUrl += `${key}=${query[key]}&`;
- }
- if (requestUrl[requestUrl.length - 1] === '&') {
- requestUrl = requestUrl.substr(0, requestUrl.length - 1);
- }
-
- xhr.open('POST', requestUrl);
- if (json) {
- xhr.setRequestHeader('Content-Type', 'application/json');
- }
- const token = formio.getToken();
- if (token) {
- xhr.setRequestHeader('x-jwt-token', token);
- }
-
- //Overrides previous request props
- if (options) {
- const parsedOptions = typeof options === 'string' ? JSON.parse(options) : options;
- for (const prop in parsedOptions) {
- if (prop === 'headers') {
- const headers = parsedOptions['headers'];
- for (const header in headers) {
- xhr.setRequestHeader(header, headers[header]);
- }
- }
- else {
- xhr[prop] = parsedOptions[prop];
- }
- }
- }
- xhr.send(json ? data : fd);
- });
- };
-
- return {
- title: 'Url',
- name: 'url',
- uploadFile(file, name, dir, progressCallback, url, options, fileKey, groupPermissions, groupId, abortCallback) {
- const uploadRequest = function(form) {
- return xhrRequest(url, name, {
- baseUrl: encodeURIComponent(formio.projectUrl),
- project: form ? form.project : '',
- form: form ? form._id : ''
- }, {
- [fileKey]:file,
- name,
- dir
- }, options, progressCallback, abortCallback).then(response => {
- // Store the project and form url along with the metadata.
- response.data = response.data || {};
- response.data.baseUrl = formio.projectUrl;
- response.data.project = form ? form.project : '';
- response.data.form = form ? form._id : '';
- return {
- storage: 'url',
- name,
- url: response.url,
- size: file.size,
- type: file.type,
- data: response.data
- };
- });
- };
- if (file.private && formio.formId) {
- return formio.loadForm().then((form) => uploadRequest(form));
- }
- else {
- return uploadRequest();
- }
- },
- deleteFile(fileInfo) {
- return new NativePromise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- xhr.open('DELETE', fileInfo.url, true);
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- resolve('File deleted');
- }
- else {
- reject(xhr.response || 'Unable to delete file');
- }
- };
- xhr.send(null);
- });
- },
-
- downloadFile(file) {
- if (file.private) {
- if (formio.submissionId && file.data) {
- file.data.submission = formio.submissionId;
- }
- return xhrRequest(file.url, file.name, {}, JSON.stringify(file)).then(response => response.data);
- }
-
- // Return the original as there is nothing to do.
- return NativePromise.resolve(file);
- }
- };
-};
-
-url.title = 'Url';
-export default url;
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/util.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/util.js
deleted file mode 100644
index f8410164..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/util.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export async function withRetries(fn, args, retries = 3, err = null) {
- if (!retries) {
- throw new Error(err);
- }
- return fn(...args).catch(() => withRetries(fn, args, retries - 1, err));
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/providers/storage/xhr.js b/web-client/core/themes/italia/static/formio/css/src/providers/storage/xhr.js
deleted file mode 100644
index 0df51736..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/providers/storage/xhr.js
+++ /dev/null
@@ -1,123 +0,0 @@
-import NativePromise from 'native-promise-only';
-import _trim from 'lodash/trim';
-export const setXhrHeaders = (formio, xhr) => {
- const { headers } = formio.options;
- if (headers) {
- const ValidHeaders = {
- 'Content-Disposition': true,
- 'Authorization': true,
- };
-
- for (const header in headers) {
- if (ValidHeaders[header]) {
- xhr.setRequestHeader(header, headers[header]);
- }
- }
- }
-};
-const XHR = {
- trim(text) {
- return _trim(text, '/');
- },
- path(items) {
- return items.filter(item => !!item).map(XHR.trim).join('/');
- },
- async upload(formio, type, xhrCallback, file, fileName, dir, progressCallback, groupPermissions, groupId, abortCallback, multipartOptions) {
- // make request to Form.io server
- const token = formio.getToken();
- let response;
- try {
- response = await fetch(`${formio.formUrl}/storage/${type}`, {
- method: 'POST',
- headers: {
- 'Accept': 'application/json',
- 'Content-Type': 'application/json; charset=UTF-8',
- ...(token ? { 'x-jwt-token': token } : {}),
- },
- body: JSON.stringify({
- name: XHR.path([dir, fileName]),
- size: file.size,
- type: file.type,
- groupPermissions,
- groupId,
- multipart: multipartOptions
- })
- });
- }
- catch (err) {
- // only throws on network errors
- err.networkError = true;
- throw err;
- }
- if (!response.ok) {
- if (response.status === 504) {
- const error = new Error('Network request failed');
- error.networkError = true;
- throw error;
- }
-
- const message = await response.text();
- throw new Error(message || 'Unable to sign file.');
- }
- const serverResponse = await response.json();
- return await XHR.makeXhrRequest(formio, xhrCallback, serverResponse, progressCallback, abortCallback);
- },
- makeXhrRequest(formio, xhrCallback, serverResponse, progressCallback, abortCallback) {
- return new NativePromise((resolve, reject) => {
- // Send the file with data.
- let xhr = new XMLHttpRequest();
- xhr.openAndSetHeaders = (...params) => {
- xhr.open(...params);
- setXhrHeaders(formio, xhr);
- };
- NativePromise.resolve(xhrCallback(xhr, serverResponse, abortCallback)).then((payload) => {
- // if payload is nullish we can assume the provider took care of the entire upload process
- if (!payload) {
- xhr = null;
- return resolve(serverResponse);
- }
- // Fire on network error.
- xhr.onerror = (err) => {
- err.networkError = true;
- reject(err);
- };
-
- // Fire on network abort.
- xhr.onabort = (err) => {
- err.networkError = true;
- reject(err);
- };
-
- // Set the onabort error callback.
- xhr.onabort = reject;
-
- if (typeof progressCallback === 'function') {
- xhr.upload.onprogress = progressCallback;
- }
-
- if (typeof abortCallback === 'function') {
- abortCallback(() => xhr.abort());
- }
- // Fired when the response has made it back from the server.
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- resolve(serverResponse);
- }
- else if (xhr.status === 504) {
- const error = new Error('Network request failed');
- error.networkError = true;
- reject(error);
- }
- else {
- reject(xhr.response || 'Unable to upload file');
- }
- };
-
- // Get the request and send it to the server.
- xhr.send(payload);
- }).catch(reject);
- });
- }
-};
-
-export default XHR;
diff --git a/web-client/core/themes/italia/static/formio/css/src/sass/formio.embed.scss b/web-client/core/themes/italia/static/formio/css/src/sass/formio.embed.scss
deleted file mode 100644
index 8e1c5705..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/sass/formio.embed.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-.formio-loader {
- position: relative;
- min-height: 60px;
-}
-
-.loader-wrapper {
- z-index: 1000;
- position:absolute;
- top: 0px;
- left: 0px;
- bottom: 0px;
- right: 0px;
- height: 120px;
- background-color:rgba(0, 0, 0, 0);
-}
-
-.loader {
- position:absolute;
- left: 50%;
- top: 50%;
- margin-left: -30px;
- margin-top: -30px;
- z-index: 10000;
- display: inline-block;
- border: 6px solid #f3f3f3; /* Light grey */
- border-top: 6px solid #3498db; /* Blue */
- border-radius: 50%;
- width: 60px;
- height: 60px;
- animation: spin 2s linear infinite;
-}
-
-@keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
-}
\ No newline at end of file
diff --git a/web-client/core/themes/italia/static/formio/css/src/sass/formio.form.builder.scss b/web-client/core/themes/italia/static/formio/css/src/sass/formio.form.builder.scss
deleted file mode 100644
index 7ae7b97b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/sass/formio.form.builder.scss
+++ /dev/null
@@ -1,247 +0,0 @@
-
-.formbuilder {
- position: relative;
-}
-
-.drag-container {
- padding: 10px;
- border: dotted 2px #e8e8e8;
-}
-
-.drag-container:hover {
- cursor: move;
- border: dotted 2px #ccc;
-}
-
-.drag-container.formio-builder-form,
-.drag-container.formio-builder-form:hover,
-.panel-body > .drag-container.formio-builder-components,
-.panel-body > .drag-container.formio-builder-components:hover,
-.tab-pane > .drag-container.formio-builder-components,
-.tab-pane > .drag-container.formio-builder-components:hover {
- padding: 0 0 1rem 0;
- border: none;
-}
-
-.component-btn-group {
- display: flex;
- flex-direction: row-reverse;
- position: absolute;
- right: 0;
- z-index: 1000;
- margin-top: -2px;
-}
-
-.builder-component {
- position: relative;
- min-height: 15px;
- margin-bottom: 15px;
- .formio-component-htmlelement {
- border: dotted 2px #e8e8e8;
- [ref=html]:empty:before {
- content: 'HTML Content';
- color: #aaa;
- }
- }
-}
-
-.builder-component:not(:hover) .component-btn-group {
- display: none;
-}
-
-.builder-group-button {
- background-color: transparent;
- white-space: normal;
- text-align: left;
-}
-
-.form-builder-group-header {
- padding: 0;
-}
-
-.component-btn-group .component-settings-button {
- float: right;
- z-index: 1001;
- margin: 4px 4px 0 0;
- z-index: 1001;
- -webkit-box-shadow: 0px 0px 10px 1px rgba(48,113,169,0.6);
- -moz-box-shadow: 0px 0px 10px 1px rgba(48,113,169,0.6);
- box-shadow: 0px 0px 10px 1px rgba(48,113,169,0.6);
-}
-
-.formbuilder .formio-component-hidden,
-.formbuilder .formio-component-content,
-.formbuilder .formio-component-form,
-.formbuilder .formio-component-datasource {
- border: 2px dashed #ddd;
-}
-
-.formbuilder .formio-component-form,
-.formbuilder .formio-component-hidden,
-.formbuilder .formio-component-datasource {
- min-height: 3em;
- text-align: center;
- color: #aaa;
- padding-top: 0.5em;
-}
-
-.btn-xxs, .btn-group-xxs > .btn, .component-btn-group .component-settings-button {
- padding: 2px 2px;
- font-size: 10px;
- line-height: 1.2em;
- border-radius: 0;
- width: 18px;
- height: 18px;
-}
-
-.formcomponents .formcomponent {
- text-align: left;
- padding: 5px 5px 5px 8px;
- margin-top: 0.2rem;
- font-size: 0.8em;
- line-height: 1.2;
- border-radius: 0.3em;
-}
-
-.form-builder-panel .panel-body {
- padding: 5px;
-}
-
-.formio-component-tabs .ui.tabular.menu .item {
- padding: 0.8em;
-}
-
-.formio-pdf-builder {
- position:relative;
-}
-
-.formio-drop-zone {
- display: none;
- position: absolute;
- z-index:10;
- background-color: #0d87e9;
- opacity: 0.1;
-}
-
-.formio-drop-zone.enabled {
- display: inherit;
-}
-
-.component-settings .formio-dialog-content {
- max-height: 100%;
- .ck-editor__editable ol {
- padding-inline-start: 40px;
- }
-}
-
-.component-btn-group .btn.component-settings-button-paste {
- display: none;
-}
-
-.builder-paste-mode .component-settings-button-paste {
- display: inherit !important;
-}
-
-.wizard-page-label {
- cursor: pointer;
- border-radius: 0;
-}
-
-.panel-body .drag-and-drop-alert {
- margin-bottom: 0;
-}
-
-.builder-sidebar {
- &_scroll {
- position: sticky;
- top: 15px;
- max-height: 100vh;
- overflow-y: auto;
- }
-}
-
-.builder-sidebar_search {
- margin-bottom: 10px;
- appearance: auto;
-}
-
-.formio-wizard-builder-component-title {
- color:#6c757d;
- text-align:center;
- padding: 0.5rem;
-}
-
-.formio-wizard-position {
- position: relative;
-}
-
-.gu-mirror {
- list-style-type: none;
-}
-
-.formio-settings-help {
- color: #8a6d3b;
- background-color: #fcf8e3;
- border-color: #faebcc;
- margin-top: 10px;
-}
-
-.help-block {
- margin: 0px;
-}
-
-.builder-sidebar .btn {
- white-space: normal;
-}
-
-/* Styles for component edit modal */
-.component-settings {
- padding-top: 20px !important;
- padding-bottom: 20px !important;
-}
-
-.component-edit-container {
- height: auto;
- overflow: hidden;
-}
-
-.component-edit-content {
- height: calc(100% - 4em);
-}
-
-.component-edit-tabs.col-sm-6 {
- min-height: 87vh;
- height: 100%;
-}
-
-.component-edit-tabs.col-sm-12 {
- height: calc(100% - 4em);
- overflow-y: auto;
-}
-
-.component-edit-tabs.col-sm-12 .editForm {
- height: calc(100% - 4em);
- overflow-y: auto;
-}
-
-.progress.pdf-progress {
- height: 2rem;
-}
-
-.progress.pdf-progress .progress-bar {
- font-size: 1rem;
- line-height: 2rem;
-}
-
-.builder-sidebar.disabled {
- .formcomponent {
- cursor: not-allowed;
- opacity: 0.65;
- box-shadow: none;
- }
-}
-
-.builder-component-selected {
- border: 2px dashed #919191;
- outline: none !important;
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/sass/formio.form.scss b/web-client/core/themes/italia/static/formio/css/src/sass/formio.form.scss
deleted file mode 100644
index 686a71ce..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/sass/formio.form.scss
+++ /dev/null
@@ -1,1765 +0,0 @@
-@import './formio.embed.scss';
-$dialog-z-index: 10000;
-$autocomplete-in-dialog-z-index: $dialog-z-index + 1000;
-
-.formio-form {
- position: relative;
- min-height: 80px;
-}
-
-.formio-error-wrapper,
-.formio-warning-wrapper {
- padding: 1em;
-}
-
-.formio-error-wrapper {
- color: #721c24;
- background-color: #f8d7da;
- border-color: #f5c6cb;
-
- .formio-errors .error {
- color: #C20000;
- }
-
- .field-required:after {
- color:#C20000;
- }
-}
-
-.formio-warning-wrapper {
- color: #856404;
- background-color: #fff3cd;
- border-color: #ffeeba;
-}
-
-.formio-disabled-input .form-control.flatpickr-input {
- background-color: #eee;
-}
-
-.builder-component.has-error .invalid-feedback,
-.formio-component.has-error .invalid-feedback,
-.formio-component.alert-danger .invalid-feedback,
-.formio-component.has-message .invalid-feedback,
-.formio-component-modal-wrapper.has-message .invalid-feedback,
-.formio-component-modal-wrapper.has-error .invalid-feedback {
- display: block;
- color: inherit;
- margin-top: 4px;
-}
-
-.formio-errors {
- .error {
- color: #dc3545;
- }
- .warning {
- color: #856404;
- }
- .info {
- color: #004085;
- }
-}
-
-.formio-form-group {
- margin-bottom: 1rem;
-}
-
-.formio-wysiwyg-editor {
- min-height: 200px;
- background-color: #fff;
-}
-
-.has-feedback .form-control {
- padding-right: 10px;
-}
-
-.has-feedback .form-control[type=hidden] {
- padding-right: 0px;
-}
-
-.has-error.bg-danger {
- padding: 4px;
-}
-
-.ql-source:after {
- content: "[source]";
- white-space: nowrap;
-}
-
-.quill-source-code {
- width: 100%;
- margin: 0px;
- background: rgb(29, 29, 29);
- box-sizing: border-box;
- color: rgb(204, 204, 204);
- font-size: 15px;
- outline: none;
- padding: 20px;
- line-height: 24px;
- font-family: Consolas, Menlo, Monaco, "Courier New", monospace;
- position: absolute;
- top: 0;
- bottom: 0;
- border: none;
- display:none;
-}
-
-.formio-component-tags tags {
- background-color: #fff;
-}
-
-.field-required:after, .tab-error::after {
- content:" *";
- color:#EB0000;
-}
-
-.field-required:after {
- position: relative;
- z-index: 10;
-}
-
-.glyphicon-spin {
- -webkit-animation: formio-spin 1s infinite linear;
- -moz-animation: formio-spin 1s infinite linear;
- -o-animation: formio-spin 1s infinite linear;
- animation: formio-spin 1s infinite linear;
-}
-
-@-moz-keyframes formio-spin {
- from {
- -moz-transform: rotate(0deg);
- }
- to {
- -moz-transform: rotate(360deg);
- }
-}
-
-@-webkit-keyframes formio-spin {
- from {
- -webkit-transform: rotate(0deg);
- }
- to {
- -webkit-transform: rotate(360deg);
- }
-}
-
-@keyframes formio-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-.button-icon-right {
- margin-left: 5px;
-}
-
-.formio-component-submit .submit-success::after {
- content: '\2713';
- position: relative;
- right: -4px;
- top: 1px;
- line-height: 1;
-}
-
-.formio-component-submit .submit-fail::after {
- content: '\2717';
- position: relative;
- right: -4px;
- top: 1px;
- line-height: 1;
-}
-
-
-.card-vertical {
- display: flex;
- flex-direction: row;
- margin-top: 5px;
-}
-
-.card-vertical .card-body,
-.tab-content,
-.tab {
- flex-grow: 2;
-}
-
-.nav-tabs-vertical {
- display: flex;
- flex-direction: column;
- border-right: 1px solid #ddd;
- padding-left: 5px;
- margin-right: 10px;
- border-bottom: 0;
-}
-
-.card-vertical > .card-body,
-.card-vertical > .tab-content,
-.card-vertical > .tab {
- flex-basis: 85%;
-}
-
-.card-vertical ul>li>.nav-link-vertical {
- border-right-color: transparent;
- border-radius: 4px 0 0 4px;
- margin-right: 0;
-
- &.active {
- border-bottom-color: #ddd;
- border-right-color: transparent;
-
- &:hover {
- border-right-color: transparent;
- }
- }
-}
-
-.nav-tabs-vertical>li {
- margin: 0 -1px 0 0;
-}
-
-.formio-component-submit .submit-fail[disabled] {
- opacity: 1;
-}
-
-.form-control.flatpickr-input {
- background-color: #fff;
-}
-
-.input-group .flatpickr-wrapper {
- flex-grow: 1;
-}
-
-.flatpickr-calendar {
- .flatpickr-current-month .flatpickr-monthDropdown-months:focus,
- .flatpickr-current-month input.cur-year:focus,
- .flatpickr-days:focus {
- outline: auto;
- }
-}
-
-td > .form-group,
-td > .formio-form-group {
- margin-bottom: 0;
-}
-
-.signature-pad-body {
- overflow: hidden;
- position: relative;
-
- .form-control-feedback {
- position: absolute;
- font-size: 0.8rem;
- top: 1px;
- right: 3px;
- }
-}
-
-.signature-pad-canvas {
- border-radius: 4px;
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset;
- border: 1px solid #f4f4f4;
-}
-
-.btn.signature-pad-refresh {
- position:absolute;
- left: 0;
- top: 0;
- z-index: 1000;
- padding: 3px;
- line-height: 0;
-}
-
-[dir="rtl"] .btn.signature-pad-refresh {
- left: unset;
- right: 0;
-}
-
-.formio-component-multiple .choices__input {
- width: 100%;
-}
-
-.formio-component-multiple .is-invalid {
- border-color: #F04124;
-}
-
-.formio-component-multiple :not(.is-invalid) {
- border-color: #ccc;
-}
-
-.choices__list--dropdown .choices__item--selectable{
- padding-right: 0px;
-}
-
-.signature-pad-refresh img {
- height: 1.2em;
-}
-
-.signature-pad-footer {
- text-align: center;
- color: #C3C3C3;
-}
-
-.is-active.choices__list--dropdown {
- z-index: 100;
-}
-
-.choices__list--multiple .choices__item {
- border-radius: 0;
- padding: 2px 8px;
- line-height: 1em;
- margin-bottom: 6px;
-}
-
-.choices__list--single {
- padding: 0;
-}
-
-.choices__item.choices__item--selectable {
- white-space: nowrap;
- overflow: hidden;
- padding-right: 25px;
- text-overflow: ellipsis;
-}
-
-.choices__input {
- padding: 2px;
-}
-
-/* fix for choices.js .choices__input container in rtl */
-.choices[dir="rtl"] > * {
- text-align: right;
-}
-/* end fix for choices.js .choices__input container in rtl */
-
-/* fix for choices.js deletable items in rtl */
-.choices[dir="rtl"] .choices__list--multiple .choices__item[data-deletable] {
- padding-left: 5px;
- float: right;
-}
-
-.choices[dir="rtl"] .choices__list--multiple .choices__item[data-deletable] .choices__button {
- float: left;
- margin: 0 8px 0 -4px;
- padding-left: unset;
- padding-right: 16px;
- border-left: unset;
- border-right: 1px solid #008fa1;
- overflow: hidden;
-}
-/* end fix for choices.js deletable items in rtl */
-
-@-moz-document url-prefix() {
- .choices__button {
- float: right;
- }
-}
-
-.formio-component-file .fileSelector {
- position: relative;
- padding: 15px;
- border: 2px dashed #ddd;
- text-align: center;
-
- .loader-wrapper {
- display: none;
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.1);
-
- .loader {
- height: 45px;
- width: 45px;
- margin-top: -23px;
- margin-left: -23px;
- }
- }
-
- a {
- text-decoration: underline;
- }
-}
-
-.formio-component-file .fileSelector.fileDragOver {
- border-color: #127abe;
-}
-
-.formio-component-file .fileSelector .glyphicon, .formio-component-file .fileSelector .fa {
- font-size: 20px;
- margin-right: 5px;
-}
-
-[dir="rtl"] .formio-component-file .fileSelector .fa, [dir="rtl"] .formio-component-file .fileSelector .glyphicon {
- margin-right: unset;
- margin-left: 5px;
-}
-
-.formio-component-file .fileSelector .browse {
- cursor: pointer;
-}
-
-@-webkit-keyframes formio-dialog-fadeout {
- 0% {
- opacity: 1;
- }
-
- 100% {
- opacity: 0;
- }
-}
-
-@keyframes formio-dialog-fadeout {
- 0% {
- opacity: 1;
- }
-
- 100% {
- opacity: 0;
- }
-}
-
-@-webkit-keyframes formio-dialog-fadein {
- 0% {
- opacity: 0;
- }
-
- 100% {
- opacity: 1;
- }
-}
-
-@keyframes formio-dialog-fadein {
- 0% {
- opacity: 0;
- }
-
- 100% {
- opacity: 1;
- }
-}
-
-.formio-dialog {
- box-sizing: border-box;
- font-size: 0.8em;
- color: #666;
-
- &.formio-modaledit-dialog {
- font-size: inherit;
- }
-}
-
-.formio-dialog *,
-.formio-dialog *:before,
-.formio-dialog *:after {
- box-sizing: inherit;
-}
-
-.formio-dialog {
- position: fixed;
- overflow: auto;
- -webkit-overflow-scrolling: touch;
- z-index: $dialog-z-index;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- /* fix for Scrollbars not clickable on overflow #552 */
- background: rgba(0, 0, 0, 0.4);
- animation: formio-dialog-fadein 0.5s;
- /* end fix for Scrollbars not clickable on overflow #552 */
-}
-
-.formio-dialog.formio-dialog-disabled-animation,
-.formio-dialog.formio-dialog-disabled-animation .formio-dialog-overlay,
-.formio-dialog.formio-dialog-disabled-animation .formio-dialog-content {
- -webkit-animation: none!important;
- animation: none!important;
-}
-
-.formio-dialog-overlay {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- -webkit-backface-visibility: hidden;
- -webkit-animation: formio-dialog-fadein 0.5s;
- animation: formio-dialog-fadein 0.5s;
- /* fix for Scrollbars not clickable on overflow #552 */
- margin-right: 15px;
- background: transparent;
- /* end fix for Scrollbars not clickable on overflow #552 */
-}
-
-.formio-dialog-no-overlay {
- pointer-events: none;
-}
-
-.formio-dialog.formio-dialog-closing .formio-dialog-overlay {
- -webkit-backface-visibility: hidden;
- -webkit-animation: formio-dialog-fadeout 0.5s;
- animation: formio-dialog-fadeout 0.5s;
-}
-
-.formio-dialog-content {
- background: white;
- -webkit-backface-visibility: hidden;
- -webkit-animation: formio-dialog-fadein 0.5s;
- animation: formio-dialog-fadein 0.5s;
- pointer-events: all;
- overflow: auto;
-}
-
-.formio-component-modal-wrapper-select {
- .formio-dialog-content {
- overflow: initial;
- }
-}
-
-.formio-dialog.formio-dialog-closing .formio-dialog-content {
- -webkit-backface-visibility: hidden;
- -webkit-animation: formio-dialog-fadeout 0.5s;
- animation: formio-dialog-fadeout 0.5s;
-}
-
-.formio-dialog-close:before {
- font-family: 'Helvetica', Arial, sans-serif;
- content: '×';
- cursor: pointer;
-}
-
-html.formio-dialog-open,
-body.formio-dialog-open {
- overflow: hidden;
-}
-
-.formio-dialog .tab-content {
- padding-top: 12px;
-}
-
-.formio-dialog-close {
- z-index: 1000;
-}
-
-@-webkit-keyframes formio-dialog-flyin {
- 0% {
- opacity: 0;
- -webkit-transform: translateY(-40px);
- transform: translateY(-40px);
- }
-
- 100% {
- opacity: 1;
- -webkit-transform: translateY(0);
- transform: translateY(0);
- }
-}
-
-@keyframes formio-dialog-flyin {
- 0% {
- opacity: 0;
- -webkit-transform: translateY(-40px);
- transform: translateY(-40px);
- }
-
- 100% {
- opacity: 1;
- -webkit-transform: translateY(0);
- transform: translateY(0);
- }
-}
-
-@-webkit-keyframes formio-dialog-flyout {
- 0% {
- opacity: 1;
- -webkit-transform: translateY(0);
- transform: translateY(0);
- }
-
- 100% {
- opacity: 0;
- -webkit-transform: translateY(-40px);
- transform: translateY(-40px);
- }
-}
-
-@keyframes formio-dialog-flyout {
- 0% {
- opacity: 1;
- -webkit-transform: translateY(0);
- transform: translateY(0);
- }
-
- 100% {
- opacity: 0;
- -webkit-transform: translateY(-40px);
- transform: translateY(-40px);
- }
-}
-
-.formio-dialog.formio-dialog-theme-default {
- padding-bottom: 160px;
- padding-top: 160px;
-
- .component-edit-container {
- padding: 0.5em;
- }
-}
-
-.formio-dialog.formio-dialog-theme-default.formio-dialog-closing .formio-dialog-content {
- -webkit-animation: formio-dialog-flyout .5s;
- animation: formio-dialog-flyout .5s;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-content {
- -webkit-animation: formio-dialog-flyin .5s;
- animation: formio-dialog-flyin .5s;
- background: #f0f0f0;
- border-radius: 5px;
- font-family: 'Helvetica',sans-serif;
- font-size: 1.1em;
- line-height: 1.5em;
- margin: 0 auto;
- max-width: 100%;
- padding: 1em;
- position: relative;
- width: 80%;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-close {
- border: none;
- background: transparent;
- cursor: pointer;
- position: absolute;
- right: 1px;
- top: 1px;
- z-index: 100;
-}
-
-.formio-clickable {
- cursor: pointer;
-}
-
-.component-settings .nav>li>a {
- padding: 8px 10px;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-close:before {
- display: block;
- padding: 3px;
- background: transparent;
- color: #8a8a8a;
- content: '×';
- font-size: 26px;
- font-weight: 400;
- line-height: 26px;
- text-align: center;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-close:hover:before,
-.formio-dialog.formio-dialog-theme-default .formio-dialog-close:active:before {
- color: #777;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-message {
- margin-bottom: .5em;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input {
- margin-bottom: 1em;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input textarea,
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input input[type="text"],
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input input[type="password"],
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input input[type="email"],
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input input[type="url"] {
- background: #fff;
- border: 0;
- border-radius: 3px;
- font-family: inherit;
- font-size: inherit;
- font-weight: inherit;
- margin: 0 0 .25em;
- min-height: 2.5em;
- padding: .25em .67em;
- width: 100%;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input textarea:focus,
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input input[type="text"]:focus,
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input input[type="password"]:focus,
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input input[type="email"]:focus,
-.formio-dialog.formio-dialog-theme-default .formio-dialog-input input[type="url"]:focus {
- box-shadow: inset 0 0 0 2px #8dbdf1;
- outline: none;
-}
-
-.formio-dialog-buttons {
- display: flex;
- justify-content: flex-end;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-buttons {
- *zoom: 1;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-buttons:after {
- content: '';
- display: table;
- clear: both;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-button {
- border: 0;
- border-radius: 3px;
- cursor: pointer;
- float: right;
- font-family: inherit;
- font-size: .8em;
- letter-spacing: .1em;
- line-height: 1em;
- margin: 0 0 0 .5em;
- padding: .75em 2em;
- text-transform: uppercase;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-button:focus {
- -webkit-animation: formio-dialog-pulse 1.1s infinite;
- animation: formio-dialog-pulse 1.1s infinite;
- outline: none;
-}
-
-@media (max-width: 568px) {
- .formio-dialog.formio-dialog-theme-default .formio-dialog-button:focus {
- -webkit-animation: none;
- animation: none;
- }
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-button.formio-dialog-button-primary {
- background: #3288e6;
- color: #fff;
-}
-
-.formio-dialog.formio-dialog-theme-default .formio-dialog-button.formio-dialog-button-secondary {
- background: #e0e0e0;
- color: #777;
-}
-
-.formio-dialog-content .panel {
- margin: 0;
-}
-
-.formio-dialog-content [ref="dialogHeader"] {
- padding-right: 15px;
-}
-
-.formio-placeholder {
- position:absolute;
- color: #999;
-}
-
-.formio-dialog .formio-dialog-close {
- cursor: pointer;
-}
-
-.formio-iframe {
- border: none;
- width: 100%;
- height: 1000px;
-}
-
-.inline-form-button {
- margin-right: 10px;
-}
-
-.tooltip {
- opacity: 1;
-}
-
-.tooltip[x-placement="right"] .tooltip-arrow {
- border-right: 5px solid black;
-}
-
-.tooltip[x-placement="right"] .tooltip-inner {
- margin-left: 8px;
-}
-
-.control-label--bottom {
- margin-bottom: 0;
- margin-top: 5px;
-}
-
-.formio-component-label-hidden {
- position: relative;
-}
-
-.formio-hidden {
- margin: 0;
-}
-
-.formio-removed {
- display: none;
-}
-
-.control-label--hidden {
- position: absolute;
- top: 6px;
- right: 5px;
-}
-
-.formio-component-datetime .control-label--hidden.field-required {
- right: 45px;
- z-index: 3;
-}
-
-.formio-component-survey .control-label--hidden.field-required,
-.formio-component-selectboxes .control-label--hidden.field-required {
- top: 0;
-}
-
-.formio-component-resource .control-label--hidden.field-required,
-.formio-component-select .control-label--hidden.field-required {
- right: 40px;
- z-index: 2;
-}
-
-.formio-component-radio .control-label--hidden.field-required:after,
-.formio-component-selectboxes .control-label--hidden.field-required:after {
- display: none;
-}
-
-.formio-component-radio.formio-component-label-hidden.required .form-check-label:before,
-.formio-component-selectboxes.formio-component-label-hidden.required .form-check-label:before {
- position: relative;
- content: "* ";
- color:#EB0000;
-}
-
-.formio-component-radio.formio-component-label-hidden.required .label-position-right.form-check-label:before,
-.formio-component-selectboxes.formio-component-label-hidden.required .label-position-right.form-check-label:before {
- right: 20px;
-}
-
-/* Fix for Hidden checkbox in component editform. */
-.formio-component-hidden:not(.formio-component-checkbox),
-.formio-component-datasource {
- margin-bottom: 0;
-}
-
-.checkbox-inline label,
-.radio-inline label {
- font-weight: 400;
- cursor: pointer;
-}
-
-.editgrid-listgroup {
- margin-bottom: 10px;
- overflow-wrap: break-word;
-}
-
-.tree-listgroup {
- flex-direction: row;
-}
-
-.formio-component-submit button[disabled]+.has-error {
- display: block;
-}
-
-.formio-choices.form-group,
-.formio-choices.formio-form-group {
- margin-bottom: 0;
-}
-
-.formio-choices[data-type=select-multiple] .form-control {
- height: auto;
-}
-
-.form-control.formio-multiple-mask-select {
- width: 15%;
- z-index: 4;
-}
-
-.form-control.formio-multiple-mask-input {
- width: 85%;
-}
-
-.input-group.formio-multiple-mask-container {
- width: 100%;
-}
-
-.formio-component .table {
- margin-bottom: 0;
- word-break: break-word;
-}
-
-.formio-component-htmlelement {
- word-wrap: break-word;
-
- ol, ul {
- margin-left: 10px;
-
- }
-}
-
-.editgrid-table-container {
- margin-bottom: 10px;
- max-width: calc(100vw - 140px);
-
- .table-responsive {
- display: block;
- width: 100%;
- overflow-x: auto;
- -webkit-overflow-scrolling: touch;
- }
-}
-
-.editgrid-table-column {
- border: none;
-}
-
-.editgrid-table-head {
- border: 1px solid #ddd;
-}
-
-.editgrid-table-body {
- border: 1px solid #ddd;
- border-top: 0;
-}
-
-.formio-hide-label-panel-tooltip {
- margin-top: -10px;
- margin-left: -10px;
-}
-
-.is-disabled .choices__list--multiple .choices__item {
- padding: 5px 10px;
-}
-
-.is-disabled .choices__list--multiple .choices__item .choices__button {
- display: none;
-}
-
-.formio-collapse-icon {
- cursor: pointer;
- margin-right: 4px;
-}
-
-[dir="rtl"] .formio-collapse-icon {
- margin-right: unset;
- margin-left: 4px;
-}
-
-.formio-component-datetime .form-control[type="datetime-local"] ~ .input-group-addon,
-.formio-component-dateTime .form-control[type="datetime-local"] ~ .input-group-addon {
- width: auto;
-}
-
-.formio-component-datagrid .formio-datagrid-remove {
- position: absolute;
- top: 0;
- right: 0;
- visibility: hidden;
- opacity: 0;
- transition: opacity 200ms linear, visibility 0ms 200ms;
-}
-
-.formio-component-datagrid {
- overflow-x: auto;
-
- .datagrid-table {
- &, td, th {
- border: 3px solid #ddd !important;
- padding: 10px;
- }
-
- &>tbody>tr>td:last-child {
- position: relative;
- }
-
- &>tbody>tr:hover>td:last-child .formio-datagrid-remove {
- visibility: visible;
- opacity: 1;
- transition: visibility 0ms, opacity 200ms linear;
- }
- }
-
- // .edittable-group-label {
- // background-color: #ddd;
- // }
-}
-
-.datagrid-table {
- &>tbody>tr>td {
- word-break: auto-phrase;
- }
-}
-
-.formio-component-modaledit {
- .formio-modaledit-view-container {
- position: relative;
- border: 1px solid #ddd;
- min-height: 34px;
- padding: 6px 12px;
- cursor: text;
-
- td & {
- padding: 0;
- border-style: none;
- }
- }
-
- .formio-modaledit-edit {
- position: absolute;
- top: 0;
- left: 0;
- visibility: hidden;
- opacity: 0;
- transition: opacity 200ms linear, visibility 0ms 200ms;
- }
-
- .formio-modaledit-view-container:hover .formio-modaledit-edit {
- visibility: visible;
- opacity: 1;
- transition: visibility 0ms, opacity 200ms linear;
- }
-}
-
-.formio-modaledit-dialog {
- .formio-modaledit-close {
- position: absolute;
- top: 100%;
- right: 0;
- border-radius: 0;
- }
-}
-
-.reset-margins {
- html, body, div, span, applet, object, iframe,
- h1, h2, h3, h4, h5, h6, p, blockquote, pre,
- a, abbr, acronym, address, big, cite, code,
- del, dfn, em, img, ins, kbd, q, s, samp,
- small, strike, strong, sub, sup, tt, var,
- b, u, i, center,
- dl, dt, dd, ol, ul, li,
- fieldset, form, label, legend,
- table, caption, tbody, tfoot, thead, tr, th, td,
- article, aside, canvas, details, embed,
- figure, figcaption, footer, header, hgroup,
- menu, nav, output, ruby, section, summary,
- time, mark, audio, video {
- margin: 0;
- }
-}
-
-.ck-body {
- .ck.ck-balloon-panel {
- z-index: 101000;
- }
-}
-
-.formio-component-select select[disabled="disabled"] {
- -webkit-appearance: none;
- -moz-appearance: none;
- text-indent: 1px;
- text-overflow: '';
-}
-
-.formio-component-select div[disabled="disabled"] button,
-.formio-component-select .choices.is-disabled[data-type*=select-one]:after {
- display: none;
-}
-
-.datagrid-group-label.collapsed > td {
- display: none;
-}
-
-.datagrid-group-header {
- &.clickable {
- cursor: pointer;
-
- .datagrid-group-label {
- &:before {
- display: inline-block;
- vertical-align: middle;
- content: '▾';
- margin: 0 5px;
- }
- }
- }
-
- &.clickable.collapsed {
- .datagrid-group-label {
- &:before {
- content: '▸';
- }
- }
- }
-}
-
-.formio-component.alert-danger .help-block,
-.formio-component.alert-warning .help-block {
- color: inherit;
-}
-
-.tree {
- &__level {
- &_even {
- background-color: #f6f6f6;
- }
- }
-
- &__node-content {
- margin-bottom: 10px;
- overflow-wrap: break-word;
- }
-
- &__node-children {
- margin: 0;
- }
-}
-
-.formio-select-autocomplete-input {
- /* we can't use display: none or visibility: hidden because autocomplete won't work on hidden field */
- opacity: 0;
- position: relative;
- z-index: -1;
- display: block;
- height: 0;
- border: none;
-}
-
-.has-error > .help-block {
- margin-top: 5px;
- margin-bottom: 10px;
-}
-
-.no-top-border-table
- > .table
- > tbody
- > tr:first-child
- > td {
- border-top: none;
-}
-
-.table > tbody > tr > td.cell-align {
- &-left {
- text-align: left;
- }
-
- &-center {
- & > div {
- margin-left: auto;
- margin-right: auto;
- }
-
- text-align: center;
- }
-
- &-right {
- & > div {
- margin-left: auto;
- }
-
- text-align: right;
- }
-}
-
-.table-responsive[ref=component] {
- overflow-x: visible;
-}
-
-.formio-component-textarea {
- .alert .ck-editor__editable {
- color: inherit;
- }
-
- .ck.ck-editor__editable .image .ck-progress-bar {
- height: 4px;
- }
-
- .ck.ck-editor {
- ul, ol {
- margin-left: 10px;
- }
- }
-}
-
-div[data-oembed-url] {
- width: 100%;
-}
-
-.radio label.label-position-left, .checkbox label.label-position-left,
-.radio label.label-position-top, .checkbox label.label-position-top,
-.radio label.label-position-bottom, .checkbox label.label-position-bottom {
- padding-left: 0;
-}
-
-.radio label.label-position-top span, .checkbox label.label-position-top span,
-.radio label.label-position-bottom span, .checkbox label.label-position-bottom span {
- display: block;
-}
-
-.radio label.label-position-top input[type="radio"], .checkbox label.label-position-top input[type="checkbox"],
-.radio label.label-position-bottom input[type="radio"], .checkbox label.label-position-bottom input[type="checkbox"] {
- position: relative;
- margin-left: 0;
-}
-
-.radio label.label-position-top input[type="radio"], .checkbox label.label-position-top input[type="checkbox"] {
- margin-top: 4px;
-}
-
-.radio label.label-position-bottom input[type="radio"], .checkbox label.label-position-bottom input[type="checkbox"] {
- margin-bottom: 8px;
-}
-
-.radio label.label-position-left input[type="radio"] {
- margin-left: 10px;
-}
-
-.checkbox label.label-position-left input[type=checkbox] {
- margin-left: 4px;
- position: relative;
-}
-
-.open-modal-button {
- width: 100%;
- text-align: left;
- white-space: normal;
- height: auto;
-}
-
-.formio-component-modal-wrapper-signature .open-modal-button {
- text-align: center;
- height: 100%;
- font-size: 1.4em;
- padding: 0;
- margin: 0;
-}
-
-/* ckeditor5-image/theme/image.css */
-.formio-component-content .image {
- display: table;
- clear: both;
- text-align: center;
- margin: 1em auto
-}
-/* ckeditor5-image/theme/image.css */
-.formio-component-content .image > img {
- display: block;
- margin: 0 auto;
- max-width: 100%;
- min-width: 50px;
-}
-/* ckeditor5-image/theme/imagecaption.css */
-.formio-component-content .image > figcaption {
- display: table-caption;
- caption-side: bottom;
- word-break: break-word;
- color: hsl(0, 0%, 20%);
- background-color: hsl(0, 0%, 97%);
- padding: .6em;
- font-size: .75em;
- outline-offset: -1px;
-}
-/* ckeditor5-image/theme/imageresize.css */
-.formio-component-content .image.image_resized {
- max-width: 100%;
- display: block;
- box-sizing: border-box
-}
-/* ckeditor5-image/theme/imageresize.css */
-.formio-component-content .image.image_resized img {
- width: 100%;
-}
-/* ckeditor5-image/theme/imageresize.css */
-.formio-component-content .image.image_resized > figcaption {
- display: block;
-}
-/* ckeditor5-media-embed/theme/mediaembed.css */
-.formio-component-content .media {
- clear: both;
- margin: 1em 0;
- display: block;
- min-width: 15em;
-}
-/* ckeditor5-image/theme/imagestyle.css */
-.formio-component-content .image-style-side:not(.image_resized), .formio-component-content .image-style-align-left:not(.image_resized), .formio-component-content .image-style-align-center:not(.image_resized), .formio-component-content .image-style-align-right:not(.image_resized) {
- max-width: 50%;
-}
-/* ckeditor5-image/theme/imagestyle.css */
-.formio-component-content .image-style-side:not(.image_resized), .formio-component-content .image-style-align-left:not(.image_resized), .formio-component-content .image-style-align-center:not(.image_resized), .formio-component-content .image-style-align-right:not(.image_resized) {
- max-width: 50%;
-}
-/* ckeditor5-image/theme/imagestyle.css */
-.formio-component-content .image-style-side:not(.image_resized), .formio-component-content .image-style-align-left:not(.image_resized), .formio-component-content .image-style-align-center:not(.image_resized), .formio-component-content .image-style-align-right:not(.image_resized) {
- max-width: 50%;
-}
-/* ckeditor5-image/theme/imagestyle.css */
-.formio-component-content .image-style-side:not(.image_resized), .formio-component-content .image-style-align-left:not(.image_resized), .formio-component-content .image-style-align-center:not(.image_resized), .formio-component-content .image-style-align-right:not(.image_resized) {
- max-width: 50%;
-}
-/* ckeditor5-image/theme/imagestyle.css */
-.formio-component-content .image-style-side {
- float: right;
- margin-left: var(--ck-image-style-spacing);
-}
-/* ckeditor5-image/theme/imagestyle.css */
-.formio-component-content .image-style-align-left {
- float: left;
- margin-right: var(--ck-image-style-spacing);
-}
-/* ckeditor5-image/theme/imagestyle.css */
-.formio-component-content .image-style-align-center {
- margin-left: auto;
- margin-right: auto;
-}
-/* ckeditor5-image/theme/imagestyle.css */
-.formio-component-content .image-style-align-right {
- float: right;
- margin-left: var(--ck-image-style-spacing);
-}
-/* ckeditor5-block-quote/theme/blockquote.css */
-.formio-component-content blockquote {
- overflow: hidden;
- padding-right: 1.5em;
- padding-left: 1.5em;
- margin-left: 0;
- margin-right: 0;
- font-style: italic;
- border-left: solid 5px hsl(0, 0%, 80%);
-}
-/* ckeditor5-block-quote/theme/blockquote.css */
-.formio-component-content[dir="rtl"] blockquote {
- border-left: 0;
- border-right: solid 5px hsl(0, 0%, 80%);
-}
-
-.formio-component-content {
- & .text-tiny {
- font-size: 0.7em;
- }
-
- & .text-small {
- font-size: 0.85em;
- }
-
- & .text-big {
- font-size: 1.4em;
- }
-
- & .text-huge {
- font-size: 1.8em;
- }
-
- ol {
- padding-inline-start: 40px;
- }
-}
-
-.formio-component-address.formio-component-label-hidden {
- & > label.field-required {
- z-index: 1;
-
- & ~ .address-autocomplete-container .address-autocomplete-remove-value-icon {
- right: 20px;
- }
- }
-}
-
-.address-autocomplete-container {
- position: relative;
-
- .address-autocomplete-remove-value-icon {
- cursor: pointer;
- position: absolute;
- margin-top: -9px;
- right: 10px;
- top: 50%;
-
- &--hidden {
- display: none;
- }
- }
-}
-
-.autocomplete {
- background: white;
- font: 14px/22px "-apple-system", BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
- overflow: auto;
- box-sizing: border-box;
- border: 1px solid rgba(50, 50, 50, 0.6);
- z-index: $autocomplete-in-dialog-z-index;
-}
-
-.autocomplete > div {
- cursor: pointer;
- padding: 6px 10px;
-}
-
-.autocomplete > div:hover:not(.group),
-.autocomplete > div.selected {
- background: #1e90ff;
- color: #ffffff;
-}
-
-.field-wrapper {
- display: flex;
-
- &--reverse {
- flex-direction: row-reverse;
- }
-
- .field-label--right {
- text-align: right;
- }
-}
-
-.formio-component-modal-wrapper {
- margin-bottom: 10px;
- .open-modal-button {
- height: auto;
- }
- .component-rendering-hidden {
- visibility: hidden;
- }
-}
-
-//show textarea submission in read-only mode and PDF view with initial line and space formatting
-.formio-component-textarea {
- div.formio-editor-read-only-content[ref="input"] {
- white-space: pre-wrap;
- }
-}
-
-.formio-editor-read-only-content {
- img {
- max-width: 100%;
- }
-
- li[data-list="bullet"] {
- list-style-type: none;
-
- .ql-ui{
- padding-right: 0.5rem;
-
- &::before {
- content: "\2022";
- }
- }
- }
-
- li[data-list="ordered"] {
- list-style-type: none;
- counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
- counter-increment: list-0;
-
- .ql-ui {
- padding-right: 0.5rem;
-
- &::before {
- content: counter(list-0, decimal) '. ';
- }
- }
- }
-
- figure.table {
- table {
- border-collapse: collapse;
- border-spacing: 0;
- width: 100%;
- height: 100%;
- border: 1px double #b3b3b3;
- table-layout: fixed;
-
- th, td {
- min-width: 2em;
- padding: .4em;
- border: 1px solid #bfbfbf;
- }
- }
- }
-}
-
-.formio-component-textfield,
-.formio-component-textarea,
-.formio-component-password {
- .pull-right:not(:last-child) {
- padding-left: 12px;
- }
-}
-
-.formio-form > div > nav > ul.pagination {
- flex-flow: wrap row;
- justify-content: flex-start;
-
- .page-link {
- cursor: pointer;
- color: #1C74D9;
- }
-
- .page-item.active .page-link {
- color: #fff;
- background-color: #1C74D9;
- border-color: #1C74D9;
- }
-}
-
-.classic-pagination {
- border-bottom: solid 1px #e0e0e0;
- padding: 0 15px 10px 15px;
- line-height: 1em;
-
- &-page {
- padding: 0;
- position: relative;
- }
-
- &-title {
- color: #595959;
- font-size: 16px;
- margin-bottom: 5px;
- }
-
- &-dot {
- position: absolute;
- width: 30px;
- height: 30px;
- display: block;
- background: #fbe8aa;
- top: 40px;
- left: 50%;
- margin-top: -15px;
- margin-left: -15px;
- border-radius: 50%;
-
- &::after {
- content: ' ';
- width: 14px;
- height: 14px;
- background: #fbbd19;
- border-radius: 50px;
- position: absolute;
- top: 8px;
- left: 8px;
- }
- }
-
- .progress, &-progress {
- position: relative;
- border-radius: 0px;
- height: 8px;
- box-shadow: none;
- margin: 20px 0;
- border: none;
- padding: 0;
- background-color: #f6f6f6;
-
- &-bar {
- width: 0px;
- height: 10px;
- box-shadow: none;
- background: #fbe8aa;
- }
- }
-}
-
-.classic-pagination-page {
- &.complete {
- .progress-bar, .classic-pagination-progress-bar {
- width: 100%;
- }
- }
- &.active {
- .progress-bar, .classic-pagination-progress-bar {
- width: 50%;
- }
- }
- &.disabled {
- .classic-pagination-dot {
- background-color: #f5f5f5;
- &::after{
- opacity: 0;
- }
- }
- }
-}
-
-.classic-pagination-page {
- &:first-child {
- .progress, .classic-pagination-progress {
- left: 50%;
- width: 50%;
- }
-
- &.active {
- .progress-bar, .classic-pagination-progress-bar {
- width: 0%;
- }
- }
- }
-
- &:last-child {
- .progress, .classic-pagination-progress {
- width: 50%;
- }
-
- &.active {
- .progress-bar, .classic-pagination-progress-bar {
- width: 100%;
- }
- }
- }
-}
-//styles for google maps dropdown
-.pac-container {
- z-index: 11000;
-}
-
-[ref='buttonMessageContainer'].has-error {
- cursor: pointer;
-}
-
-[ref="passwordStrengthIndicator"] {
- display: inline;
-}
-
-.formio-security-indicator {
- display: flex;
- height: 5px;
-
- [class^="security-"] {
- width: 100%;
- height: 100%;
- }
-
- .security-low {
- background-color: #c51e00;
- }
-
- .security-medium {
- background-color: #ebb400;
- }
-
- .security-high {
- background-color: #bddf00;
- }
-
- .security-very-high {
- background-color: #009118;
- }
-}
-
-.formio-component-textarea {
- .formio-editor-read-only-content {
- .text-big {
- font-size: 1.4em;
- }
-
- .text-huge {
- font-size: 1.8em;
- }
-
- .text-small {
- font-size: 0.85em;
- }
-
- .text-tiny {
- font-size: 0.7em;
- }
- }
-}
-
-.formio-component [ref="valueMaskInput"] {
- display: none;
-}
-
-.formio-wizard-nav-container {
- display: flex;
-
- li {
- margin-right: 0.5rem;
- }
-
- @media not all and (min-width: 30em) {
- flex-direction: column;
-
- li {
- margin-right: 0;
- }
-
- li .btn {
- width: 100%;
- margin-bottom: 0.25rem;
- }
- }
-}
-
-//styles for accessible tooltip
-.formio-tooltip__trigger {
- cursor: pointer;
-}
-
-.formio-tooltip__body {
- background-color: #1b1b1b;
- border-radius: 0.25rem;
- bottom: 0;
- color: #f0f0f0;
- display: none;
- font-size: 1rem;
- padding: 0.5rem;
- position: absolute;
- left: 0;
- transform: translateX(-50%);
- width: auto;
- white-space: pre;
- z-index: 1000;
-
- &.formio-tooltip--is-set {
- display: block;
- }
-
- &--whitespace {
- white-space: normal;
- width: 250px;
- }
-
- &--right {
- top: auto;
- transform: translateX(0);
- }
-
- &--left {
- top: auto;
- left: 0;
- right: auto;
- transform: translateX(0);
- }
-
- &--bottom {
- bottom: auto;
- top: 0;
- }
-}
-
-.formio-tooltip__wrapper {
- position: relative;
- & > span {
- font-weight: normal;
- }
-}
-
-.ace_editor, .ace_editor div, .ace_editor span {
- font-family: "Monaco", "Menlo", "Ubuntu Mono", "Droid Sans Mono", "Consolas", monospace !important;
-}
-
-span[role="link"] {
- text-decoration: underline;
- cursor: pointer;
-}
-
-.hidden {
- display: none !important;
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/Templates.js b/web-client/core/themes/italia/static/formio/css/src/templates/Templates.js
deleted file mode 100644
index 0261151c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/Templates.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import templates from './index';
-import _ from 'lodash';
-
-export default class Templates {
- static get templates() {
- if (!Templates._templates) {
- Templates._templates = templates;
- }
- return Templates._templates;
- }
-
- static addTemplate(name, template) {
- Templates.templates[name] = template;
- }
-
- static extendTemplate(name, template) {
- Templates.templates[name] = _.merge({}, Templates.templates[name], template);
- }
-
- static setTemplate(name, template) {
- Templates.addTemplate(name, template);
- }
-
- static set current(templates) {
- const defaultTemplates = Templates.current;
- Templates._current = _.merge({}, defaultTemplates, templates);
- }
-
- static get current() {
- if (Templates._current) {
- return Templates._current;
- }
-
- return Templates.defaultTemplates;
- }
-
- static get defaultTemplates() {
- return Templates.templates.bootstrap;
- }
-
- static set framework(framework) {
- if (Templates.templates.hasOwnProperty(framework)) {
- Templates._framework = framework;
- Templates._current = Templates.templates[framework];
- }
- }
-
- static get framework() {
- return Templates._framework;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/Templates.unit.js b/web-client/core/themes/italia/static/formio/css/src/templates/Templates.unit.js
deleted file mode 100644
index 2589866d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/Templates.unit.js
+++ /dev/null
@@ -1,128 +0,0 @@
-const renders = require('../../test/renders');
-const forms = require('../../test/formtest');
-const pretty = require('pretty');
-const fs = require('fs');
-import assert from 'power-assert';
-import i18next from 'i18next';
-import NativePromise from 'native-promise-only';
-
-const i18Defaults = require('../i18n');
-const AllComponents = require('../components').default;
-const Components = require('../components/Components').default;
-const templates = require('./index').default;
-const Form = require('../Form').default;
-Components.setComponents(AllComponents);
-const componentDir = 'components';
-
-const fixComponent = (instance, index = 0) => {
- instance.id = instance.key;
- index++;
- if (instance.everyComponent) {
- instance.everyComponent(component => fixComponent(component, index));
- if (instance.hasOwnProperty('subForm') && instance.subForm) {
- instance.subForm.id = instance.key;
- }
- }
- if (instance.type === 'file') {
- instance.support.filereader = true;
- instance.support.hasWarning = false;
- }
-};
-
-describe('Rendering Tests', () => {
- before(() => {
- return new NativePromise((resolve, reject) => {
- i18next.init(i18Defaults, (err) => {
- if (err) {
- return reject(err);
- }
- resolve();
- });
- });
- });
- Object.keys(templates).forEach(framework => {
- describe(`Framework ${framework}`, () => {
- describe('Form Renders', () => {
- Object.keys(forms).forEach(form => {
- it(`Form renders ${form}`, () => {
- return new Form(forms[form], { template: framework }).ready.then(instance => {
- fixComponent(instance);
- assert.equal(renders[`form-${framework}-${form}`], pretty(instance.render(), { ocd: true }));
- });
- });
- });
- });
-
- Object.keys(AllComponents).forEach(component => {
- if (component !== 'componentmodal') {
- describe(`Component ${component}`, () => {
- it(`Renders ${component} for ${framework}`, (done) => {
- const instance = new AllComponents[component]({}, { template: framework });
- fixComponent(instance);
- assert.equal(renders[`component-${framework}-${component}`], pretty(instance.render(), { ocd: true }));
- done();
- });
- it(`Renders ${component} for ${framework} as required`, (done) => {
- const instance = new AllComponents[component]({
- validate: {
- required: true
- }
- }, {
- template: framework,
- });
- fixComponent(instance);
- assert.equal(renders[`component-${framework}-${component}-required`], pretty(instance.render(), { ocd: true }));
- done();
- });
- it(`Renders ${component} for ${framework} as multiple`, (done) => {
- const instance = new AllComponents[component]({
- multiple: true
- }, {
- template: framework,
- });
- fixComponent(instance);
- assert.equal(renders[`component-${framework}-${component}-multiple`], pretty(instance.render(), { ocd: true }));
- done();
- });
-
- if (fs.existsSync(`./lib/${componentDir}/${component}/fixtures/values.js`)) {
- const values = require(`../${componentDir}/${component}/fixtures/values.js`).default.slice(0);
-
- values.unshift(undefined);
-
- values.forEach((value, index) => {
- it(`Renders ${component} for ${framework} value ${index} as html`, (done) => {
- const instance = new AllComponents[component]({}, {
- template: framework,
- flatten: true,
- renderMode: 'html',
- });
- instance.dataValue = value;
- fixComponent(instance);
- assert.equal(renders[`component-${framework}-${component}-html-value${index}`], pretty(instance.render(), { ocd: true }));
- done();
- });
- it(`Renders ${component} for ${framework} value ${index} as string`, (done) => {
- const instance = new AllComponents[component]({}, {
- template: framework,
- flatten: true,
- renderMode: 'html',
- });
- fixComponent(instance);
- const file = renders[`component-${framework}-${component}-string-value${index}`];
- const val = instance.getValueAsString(value);
-
- if (val !== file) {
- console.log('er');
- }
- assert.equal(renders[`component-${framework}-${component}-string-value${index}`], pretty(instance.getValueAsString(value), { ocd: true }));
- done();
- });
- });
- }
- });
- }
- });
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/form.ejs
deleted file mode 100644
index 6723d2f1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/form.ejs
+++ /dev/null
@@ -1,40 +0,0 @@
-{% if (ctx.mode.autocomplete) { %}
-
-
- {% if (!ctx.component.disableClearIcon) { %}
-
- {% } %}
-
-{% } %}
-{% if (ctx.self.manualModeEnabled) { %}
-
-
-
- {{ ctx.component.switchToManualModeLabel }}
-
-
-{% } %}
-{% if (ctx.self.manualMode) { %}
-
- {{ ctx.children }}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/html.ejs
deleted file mode 100644
index 996c51d1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/html.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{% if (ctx.displayValue) { %}{{ctx.displayValue}}{% } else { %}-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/address/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/alert/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/alert/form.ejs
deleted file mode 100644
index 53f2a6a7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/alert/form.ejs
+++ /dev/null
@@ -1,10 +0,0 @@
-
- {{ctx.message}}
- {% if (ctx.options.vpat) { %}
- {{ctx.t('errorListHotkey')}}
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/alert/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/alert/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/alert/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builder/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builder/form.ejs
deleted file mode 100644
index 28fe6555..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builder/form.ejs
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builder/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builder/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builder/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponent/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponent/form.ejs
deleted file mode 100644
index 1901d1bf..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponent/form.ejs
+++ /dev/null
@@ -1,61 +0,0 @@
-
- {% if (!ctx.disableBuilderActions) { %}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {% } %}
- {{ctx.html}}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponent/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponent/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponent/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponents/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponents/form.ejs
deleted file mode 100644
index f38edf99..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponents/form.ejs
+++ /dev/null
@@ -1,3 +0,0 @@
-
- {{ctx.html}}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponents/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponents/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderComponents/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderEditForm/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderEditForm/form.ejs
deleted file mode 100644
index 9610006e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderEditForm/form.ejs
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
{{ctx.t(ctx.componentInfo.title, { _userInput: true })}} {{ctx.t('Component')}}
-
- {% if (ctx.helplinks) { %}
-
- {% } %}
-
-
-
-
- {{ctx.editForm}}
-
- {% if (!ctx.preview) { %}
-
- {{ctx.t('Save')}}
- {{ctx.t('Cancel')}}
- {{ctx.t('Remove')}}
-
- {% } %}
-
- {% if (ctx.preview) { %}
-
-
- {% if (ctx.componentInfo.help) { %}
-
- {{ ctx.t(ctx.componentInfo.help) }}
-
- {% } %}
-
- {{ctx.t('Save')}}
- {{ctx.t('Cancel')}}
- {{ctx.t('Remove')}}
-
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderEditForm/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderEditForm/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderEditForm/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderPlaceholder/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderPlaceholder/form.ejs
deleted file mode 100644
index 47bb3e80..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderPlaceholder/form.ejs
+++ /dev/null
@@ -1,9 +0,0 @@
-
- {{ctx.t('Drag and Drop a form component')}}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderPlaceholder/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderPlaceholder/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderPlaceholder/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebar/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebar/form.ejs
deleted file mode 100644
index b4f0b1e2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebar/form.ejs
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebar/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebar/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebar/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebarGroup/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebarGroup/form.ejs
deleted file mode 100644
index 7163cbc8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebarGroup/form.ejs
+++ /dev/null
@@ -1,49 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebarGroup/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebarGroup/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderSidebarGroup/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderWizard/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderWizard/form.ejs
deleted file mode 100644
index 8cbae158..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderWizard/form.ejs
+++ /dev/null
@@ -1,22 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderWizard/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderWizard/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/builderWizard/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/form.ejs
deleted file mode 100644
index 4e90c887..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/form.ejs
+++ /dev/null
@@ -1,19 +0,0 @@
-<{{ctx.input.type}}
- ref="button"
- {% for (var attr in ctx.input.attr) { %}
- {{attr}}="{{ctx.input.attr[attr]}}"
- {% } %}
- {% if (ctx.component.description) { %}
- aria-describedby="d-{{ctx.instance.id}}-{{ctx.component.key}}"
- {% } %}
->
-{% if (ctx.component.leftIcon) { %} {% } %}
-{{ctx.input.content}}
-{% if (ctx.component.tooltip) { %}
-
-{% } %}
-{% if (ctx.component.rightIcon) { %} {% } %}
-{{ctx.input.type}}>
-
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/html.ejs
deleted file mode 100644
index 8b137891..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/html.ejs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/button/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/form.ejs
deleted file mode 100644
index eea04023..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/form.ejs
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
- <{{ctx.input.type}}
- ref="input"
- {% for (var attr in ctx.input.attr) { %}
- {{attr}}="{{ctx.input.attr[attr]}}"
- {% } %}
- {% if (ctx.checked) { %}checked=true{% } %}
- aria-required="{{ctx.component.validate.required}}"
- {% if (ctx.component.description) { %}
- aria-describedby="d-{{ctx.instance.id}}-{{ctx.component.key}}"
- {% } %}
- >
- {% if (!ctx.self.labelIsHidden()) { %}{{ctx.input.label}} {% } %}
- {{ctx.input.content}}
- {{ctx.input.type}}>
-
- {% if (ctx.component.tooltip) { %}
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/html.ejs
deleted file mode 100644
index 08edcf8a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/html.ejs
+++ /dev/null
@@ -1,5 +0,0 @@
-
- {{ctx.input.content}}
- {% if (!ctx.self.labelIsHidden()) { %}{{ctx.input.label}} {% } %}
-
-{% if (ctx.checked) { %}True{% } else { %}False{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/checkbox/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/columns/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/columns/form.ejs
deleted file mode 100644
index 26e52f55..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/columns/form.ejs
+++ /dev/null
@@ -1,10 +0,0 @@
-{% ctx.component.columns.forEach(function(column, index) { %}
-
- {{ctx.columnComponents[index]}}
-
-{% }) %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/columns/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/columns/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/columns/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/component/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/component/form.ejs
deleted file mode 100644
index dd3c1e3c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/component/form.ejs
+++ /dev/null
@@ -1,6 +0,0 @@
-
- {% if (ctx.visible) { %}
- {{ctx.children}}
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/component/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/component/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/component/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/componentModal/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/componentModal/form.ejs
deleted file mode 100644
index 28933d1e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/componentModal/form.ejs
+++ /dev/null
@@ -1,26 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/componentModal/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/componentModal/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/componentModal/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/components/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/components/form.ejs
deleted file mode 100644
index acf206e0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/components/form.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{{ ctx.children.join('') }}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/components/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/components/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/components/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/container/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/container/form.ejs
deleted file mode 100644
index 6b58eb56..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/container/form.ejs
+++ /dev/null
@@ -1,3 +0,0 @@
-
- {{ctx.children}}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/container/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/container/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/container/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/cssClasses.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/cssClasses.js
deleted file mode 100644
index ccb25086..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/cssClasses.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export default {
- 'border-default': '',
- 'formio-tab-panel-active': 'active',
- 'formio-tab-link-active': 'active',
- 'formio-tab-link-container-active': 'active',
- 'formio-form-error': 'formio-error-wrapper has-message',
- 'formio-form-alert': 'alert alert-danger',
- 'formio-label-error': '',
- 'formio-input-error': '',
- 'formio-alert-danger': 'alert alert-danger',
- 'formio-alert-success': 'alert alert-success',
- 'formio-alert-warning': 'alert alert-warning',
- 'formio-modal-cancel-button': 'btn btn-danger formio-dialog-button',
- 'formio-modal-confirm-button': 'btn btn-primary formio-dialog-button',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/form.ejs
deleted file mode 100644
index 36a6aaf5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/form.ejs
+++ /dev/null
@@ -1,78 +0,0 @@
-
- {% if (ctx.hasHeader) { %}
-
-
- {% if (ctx.component.reorder) { %} {% } %}
- {% ctx.columns.forEach(function(col) { %}
-
- {{ col.hideLabel ? '' : ctx.t(col.label || col.title, { _userInput: true }) }}
- {% if (col.tooltip) { %} {% } %}
-
- {% }) %}
- {% if (ctx.hasExtraColumn) { %}
-
- {{ ctx.t('Add/Remove') }}
- {% if (!ctx.builder && ctx.hasAddButton && ctx.hasTopSubmit) { %}
-
- {{ctx.t(ctx.component.addAnother || 'Add Another', { _userInput: true })}}
-
- {% } %}
-
- {% } %}
-
-
- {% } %}
-
- {% ctx.rows.forEach(function(row, index) { %}
- {% if (ctx.hasGroups && ctx.groups[index]) { %}
-
- {% } %}
-
- {% if (ctx.component.reorder) { %}
-
-
-
- {% } %}
- {% ctx.columns.forEach(function(col) { %}
-
- {{row[col.key]}}
-
- {% }) %}
- {% if (ctx.hasExtraColumn) { %}
- {% if (ctx.hasRemoveButtons) { %}
-
-
-
-
-
- {% } %}
- {% if (ctx.canAddColumn) { %}
-
- {{ctx.placeholder}}
-
- {% } %}
- {% } %}
-
- {% }) %}
-
- {% if (!ctx.builder && ctx.hasAddButton && ctx.hasBottomSubmit) { %}
-
-
-
-
- {{ctx.t(ctx.component.addAnother || 'Add Another', { _userInput: true })}}
-
-
-
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/html.ejs
deleted file mode 100644
index 2bce7517..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/html.ejs
+++ /dev/null
@@ -1,29 +0,0 @@
-
- {% if (ctx.hasHeader) { %}
-
-
- {% ctx.columns.forEach(function(col) { %}
-
- {{ col.hideLabel ? '' : ctx.t(col.label || col.title, { _userInput: true }) }}
- {% if (col.tooltip) { %} {% } %}
-
- {% }) %}
-
-
- {% } %}
-
- {% ctx.rows.forEach(function(row) { %}
-
- {% ctx.columns.forEach(function(col) { %}
-
- {{row[col.key]}}
-
- {% }) %}
-
- {% }) %}
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/datagrid/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/day/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/day/form.ejs
deleted file mode 100644
index e8d30f7f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/day/form.ejs
+++ /dev/null
@@ -1,44 +0,0 @@
-
- {% if (ctx.dayFirst && ctx.showDay) { %}
-
- {% if (!ctx.component.hideInputLabels) { %}
-
{{ctx.t('Day')}}
- {% } %}
-
{{ctx.day}}
-
- {% } %}
- {% if (ctx.showMonth) { %}
-
- {% if (!ctx.component.hideInputLabels) { %}
-
{{ctx.t('Month')}}
- {% } %}
-
{{ctx.month}}
-
- {% } %}
- {% if (!ctx.dayFirst && ctx.showDay) { %}
-
- {% if (!ctx.component.hideInputLabels) { %}
-
{{ctx.t('Day')}}
- {% } %}
-
{{ctx.day}}
-
- {% } %}
- {% if (ctx.showYear) { %}
-
- {% if (!ctx.component.hideInputLabels) { %}
-
{{ctx.t('Year')}}
- {% } %}
-
{{ctx.year}}
-
- {% } %}
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/day/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/day/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/day/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/dialog/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/dialog/form.ejs
deleted file mode 100644
index 1e029342..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/dialog/form.ejs
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/dialog/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/dialog/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/dialog/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/form.ejs
deleted file mode 100644
index 77d8223d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/form.ejs
+++ /dev/null
@@ -1,40 +0,0 @@
-
-{% if (!ctx.readOnly && ctx.hasAddButton) { %}
-
- {{ctx.t(ctx.component.addAnother || 'Add Another', { _userInput: true })}}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/html.ejs
deleted file mode 100644
index 99835f76..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/html.ejs
+++ /dev/null
@@ -1,35 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgrid/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/form.ejs
deleted file mode 100644
index 6b9767b4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/form.ejs
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
- {% if (ctx.header) { %}
-
- {{ctx.header}}
-
- {% } %}
-
- {% ctx.rows.forEach(function(row, rowIndex) { %}
-
- {{row}}
- {% if (ctx.openRows[rowIndex] && !ctx.readOnly) { %}
-
-
- {{ctx.t(ctx.component.saveRow || 'Save', { _userInput: true })}}
- {% if (ctx.component.removeRow) { %}
- {{ctx.t(ctx.component.removeRow || 'Cancel', { _userInput: true })}}
- {% } %}
-
-
- {% } %}
- {% if (ctx.errors[rowIndex]) { %}
-
-
-
- {{ctx.errors[rowIndex]}}
-
-
-
- {% } %}
-
- {% }) %}
-
- {% if (ctx.footer) { %}
-
-
- {{ctx.footer}}
-
-
- {% } %}
-
-
-
-{% if (!ctx.readOnly && ctx.hasAddButton) { %}
-
-
- {{ctx.t(ctx.component.addAnother || 'Add Another', { _userInput: true })}}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/html.ejs
deleted file mode 100644
index 9a7d70ff..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/html.ejs
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
- {% if (ctx.header) { %}
-
- {{ctx.header}}
-
- {% } %}
-
- {% ctx.rows.forEach(function(row, rowIndex) { %}
-
- {{row}}
- {% if (ctx.openRows[rowIndex] && !ctx.readOnly) { %}
-
-
- {{ctx.t(ctx.component.saveRow || 'Save', { _userInput: true })}}
- {% if (ctx.component.removeRow) { %}
- {{ctx.t(ctx.component.removeRow || 'Cancel', { _userInput: true })}}
- {% } %}
-
-
- {% } %}
- {% if (ctx.errors[rowIndex]) { %}
-
-
-
- {{ctx.errors[rowIndex]}}
-
-
-
- {% } %}
-
- {% }) %}
-
- {% if (ctx.footer) { %}
-
-
- {{ctx.footer}}
-
-
- {% } %}
-
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/editgridTable/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/errorsList/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/errorsList/form.ejs
deleted file mode 100644
index baab6f89..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/errorsList/form.ejs
+++ /dev/null
@@ -1,19 +0,0 @@
-{{ctx.t('error')}}
- {% if (ctx.options.vpat) { %}
-
- {% } %}
-
-
- {% ctx.errors.forEach(function(err) { %}
-
-
- {{err.message}}
-
-
- {% }) %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/errorsList/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/errorsList/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/errorsList/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/align.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/align.ejs
deleted file mode 100644
index 6a20a5e3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/align.ejs
+++ /dev/null
@@ -1,26 +0,0 @@
-
- {% if (!ctx.label.hidden) { %}
-
- {{ ctx.labelMarkup }}
-
- {% } %}
-
- {% if (ctx.label.hidden && ctx.label.className && ctx.component.validate.required) { %}
-
-
-
- {% } %}
-
-
- {{ctx.element}}
-
-
-
-{% if (ctx.component.description) { %}
- {{ctx.t(ctx.component.description, { _userInput: true })}}
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/form.ejs
deleted file mode 100644
index 47b2e15f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/form.ejs
+++ /dev/null
@@ -1,16 +0,0 @@
-{% if (!ctx.label.hidden && ctx.label.labelPosition !== 'bottom') { %}
- {{ ctx.labelMarkup }}
-{% } %}
-
-{% if (ctx.label.hidden && ctx.label.className && ctx.component.validate.required) { %}
-
-{% } %}
-
-{{ctx.element}}
-
-{% if (!ctx.label.hidden && ctx.label.labelPosition === 'bottom') { %}
- {{ ctx.labelMarkup }}
-{% } %}
-{% if (ctx.component.description) { %}
- {{ctx.t(ctx.component.description, { _userInput: true })}}
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/index.js
deleted file mode 100644
index 8074260d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/field/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import align from './align.ejs';
-
-export default { form, align };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/fieldset/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/fieldset/form.ejs
deleted file mode 100644
index 72dd3160..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/fieldset/form.ejs
+++ /dev/null
@@ -1,15 +0,0 @@
-
- {% if (ctx.component.legend) { %}
-
- {{ctx.t(ctx.component.legend, { _userInput: true })}}
- {% if (ctx.component.tooltip) { %}
-
- {% } %}
-
- {% } %}
- {% if (!ctx.collapsed) { %}
-
- {{ctx.children}}
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/fieldset/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/fieldset/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/fieldset/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/file/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/file/form.ejs
deleted file mode 100644
index 0dc0638b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/file/form.ejs
+++ /dev/null
@@ -1,143 +0,0 @@
-{% if (ctx.options.vpat) { %}
-
-{% } %}
-{% if (!ctx.self.imageUpload) { %}
- {% if (ctx.options.vpat) { %}
- {{(!ctx.component.filePattern || ctx.component.filePattern === '*') ? 'Any file types are allowed' : ctx.t('Allowed file types: ') + ctx.component.filePattern}}
- {% } %}
-
-
- {% ctx.files.forEach(function(file) { %}
-
-
- {% if (!ctx.disabled) { %}
-
- {% } %}
-
-
{{ctx.fileSize(file.size)}}
- {% if (ctx.self.hasTypes && !ctx.disabled) { %}
-
-
- {% ctx.component.fileTypes.map(function(type) { %}
- {{ctx.t(type.label)}}
- {% }); %}
-
-
- {% } %}
- {% if (ctx.self.hasTypes && ctx.disabled) { %}
-
{{file.fileType}}
- {% } %}
-
-
- {% }) %}
-
-{% } else { %}
-
- {% ctx.files.forEach(function(file) { %}
-
-
-
- {% if (!ctx.disabled) { %}
-
- {% } %}
-
-
- {% }) %}
-
-{% } %}
-{% if (!ctx.disabled && (ctx.component.multiple || !ctx.files.length)) { %}
- {% if (ctx.self.useWebViewCamera) { %}
-
- {{ctx.t('Gallery')}}
- {{ctx.t('Camera')}}
-
- {% } else if (!ctx.self.cameraMode) { %}
-
- {% } else { %}
-
-
-
- {{ctx.t('Take Picture')}}
- {{ctx.t('Switch to file upload')}}
- {% } %}
-{% } %}
-{% ctx.statuses.forEach(function(status) { %}
-
-
-
{{status.originalName}}
-
- {{ctx.t('Remove button. Press to remove ' + status.originalName || status.name + '.')}}
- {{status.message ? status.message.replace(';', '.') : ''}}
-
-
-
{{ctx.fileSize(status.size)}}
-
-
-
- {% if (status.status === 'progress') { %}
-
-
- {{status.progress}}% {{ctx.t('Complete')}}
-
-
- {% } else if (status.status === 'error') { %}
-
{{ctx.t(status.message)}}
- {% } else { %}
-
{{ctx.t(status.message)}}
- {% } %}
-
-
-
-{% }) %}
-{% if (!ctx.component.storage || ctx.support.hasWarning) { %}
-
- {% if (!ctx.component.storage) { %}
-
{{ctx.t('No storage has been set for this field. File uploads are disabled until storage is set up.')}}
- {% } %}
- {% if (!ctx.support.filereader) { %}
-
{{ctx.t('File API & FileReader API not supported.')}}
- {% } %}
- {% if (!ctx.support.formdata) { %}
-
{{ctx.t("XHR2's FormData is not supported.")}}
- {% } %}
- {% if (!ctx.support.progress) { %}
-
{{ctx.t("XHR2's upload progress isn't supported.")}}
- {% } %}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/file/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/file/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/file/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/html/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/html/form.ejs
deleted file mode 100644
index c62acb7e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/html/form.ejs
+++ /dev/null
@@ -1,5 +0,0 @@
-<{{ctx.tag}} class="formio-component-htmlelement {{ ctx.component.className }}" ref="html"
- {% ctx.attrs.forEach(function(attr) { %}
- {{attr.attr}}="{{attr.value}}"
- {% }) %}
->{{ctx.t(ctx.content)}}{% if (!ctx.singleTags || ctx.singleTags.indexOf(ctx.tag) === -1) { %}{{ctx.tag}}>{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/html/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/html/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/html/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/icon/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/icon/form.ejs
deleted file mode 100644
index d6715a0f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/icon/form.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{{ctx.content}}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/icon/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/icon/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/icon/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/iconClass.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/iconClass.js
deleted file mode 100644
index 2e645615..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/iconClass.js
+++ /dev/null
@@ -1,32 +0,0 @@
-export default (iconset, name, spinning) => {
- if (iconset === 'fa') {
- switch (name) {
- case 'save':
- name = 'download';
- break;
- case 'zoom-in':
- name = 'search-plus';
- break;
- case 'zoom-out':
- name = 'search-minus';
- break;
- case 'question-sign':
- name = 'question-circle';
- break;
- case 'remove-circle':
- name = 'times-circle-o';
- break;
- case 'new-window':
- name = 'window-restore';
- break;
- case 'move':
- name = 'arrows';
- break;
- case 'time':
- name = 'clock-o';
- break;
- }
- }
-
- return spinning ? `${iconset} ${iconset}-${name} ${iconset}-spin` : `${iconset} ${iconset}-${name}`;
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/index.js
deleted file mode 100644
index a1d928f2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/index.js
+++ /dev/null
@@ -1,142 +0,0 @@
-import address from './address';
-import builder from './builder';
-import builderComponent from './builderComponent';
-import builderComponents from './builderComponents';
-import builderEditForm from './builderEditForm';
-import builderPlaceholder from './builderPlaceholder';
-import builderSidebar from './builderSidebar';
-import builderSidebarGroup from './builderSidebarGroup';
-import builderWizard from './builderWizard';
-import button from './button';
-import checkbox from './checkbox';
-import columns from './columns';
-import component from './component';
-import componentModal from './componentModal';
-import components from './components';
-import tableComponents from './tableComponents';
-import container from './container';
-import datagrid from './datagrid';
-import day from './day';
-import dialog from './dialog';
-import editgrid from './editgrid';
-import editgridTable from './editgridTable';
-import field from './field';
-import fieldset from './fieldset';
-import file from './file';
-import html from './html';
-import icon from './icon';
-import iconClass from './iconClass';
-import input from './input';
-import label from './label';
-import loader from './loader';
-import loading from './loading';
-import map from './map';
-import message from './message';
-import modaldialog from './modaldialog';
-import modaledit from './modaledit';
-import modalPreview from './modalPreview';
-import multipleMasksInput from './multipleMasksInput';
-import multiValueRow from './multiValueRow';
-import multiValueTable from './multiValueTable';
-import panel from './panel';
-import pdf from './pdf';
-import pdfBuilder from './pdfBuilder';
-import pdfBuilderUpload from './pdfBuilderUpload';
-import radio from './radio';
-import resourceAdd from './resourceAdd';
-import select from './select';
-import selectOption from './selectOption';
-import signature from './signature';
-import survey from './survey';
-import tab from './tab';
-import table from './table';
-import tree from './tree';
-import treePartials from './tree/partials';
-import webform from './webform';
-import well from './well';
-import wizard from './wizard';
-import wizardHeader from './wizardHeader';
-import wizardHeaderClassic from './wizardHeaderClassic';
-import wizardHeaderVertical from './wizardHeaderVertical';
-import wizardNav from './wizardNav';
-import cssClasses from './cssClasses';
-import errorsList from './errorsList';
-import alert from './alert';
-
-export default {
- transform(type, text) {
- if (!text) {
- return text;
- }
- switch (type) {
- case 'class':
- return this.cssClasses.hasOwnProperty(text.toString()) ? this.cssClasses[text.toString()] : text;
- }
- return text;
- },
- defaultIconset: 'fa',
- iconClass,
- cssClasses,
- address,
- builder,
- builderComponent,
- builderComponents,
- builderEditForm,
- builderPlaceholder,
- builderSidebar,
- builderSidebarGroup,
- builderWizard,
- button,
- checkbox,
- columns,
- component,
- componentModal,
- components,
- tableComponents,
- container,
- datagrid,
- day,
- dialog,
- editgrid,
- editgridTable,
- field,
- fieldset,
- file,
- html,
- icon,
- input,
- label,
- loader,
- loading,
- map,
- message,
- modaledit,
- modaldialog,
- modalPreview,
- multipleMasksInput,
- multiValueRow,
- multiValueTable,
- panel,
- pdf,
- pdfBuilder,
- pdfBuilderUpload,
- radio,
- resourceAdd,
- select,
- selectOption,
- signature,
- survey,
- tab,
- table,
- tree,
- ...treePartials,
- webform,
- well,
- wizard,
- wizardHeader,
- wizardHeaderClassic,
- wizardHeaderVertical,
- wizardNav,
- errorsList,
- alert
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/form.ejs
deleted file mode 100644
index 266ca669..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/form.ejs
+++ /dev/null
@@ -1,59 +0,0 @@
-{% if (ctx.prefix || ctx.suffix) { %}
-
-{% } %}
-{% if (ctx.component.showCharCount || ctx.component.showWordCount) { %}
-
- {% if (ctx.component.showCharCount) { %}
-
- {% } %}
- {% if (ctx.component.showWordCount) { %}
-
- {% } %}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/html.ejs
deleted file mode 100644
index 82fffefc..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/html.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{% if (ctx.value) { %}{{ctx.value}}{% } else { %}-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/input/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/label/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/label/form.ejs
deleted file mode 100644
index 7b79bcb4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/label/form.ejs
+++ /dev/null
@@ -1,14 +0,0 @@
-
- {{ ctx.t(ctx.component.label, { _userInput: true }) }}
- {% if (ctx.component.type === 'number' || ctx.component.type === 'phoneNumber' || ctx.component.type === 'currency') { %}
- , {{ctx.t('numeric only')}},
- {% } %}
- {% if (ctx.component.tooltip) { %}
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/label/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/label/index.js
deleted file mode 100644
index 0890c1f2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/label/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import form from './form.ejs';
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loader/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loader/form.ejs
deleted file mode 100644
index b8f1555c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loader/form.ejs
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loader/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loader/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loader/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loading/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loading/form.ejs
deleted file mode 100644
index da285696..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loading/form.ejs
+++ /dev/null
@@ -1 +0,0 @@
-Loading...
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loading/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loading/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/loading/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/map/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/map/form.ejs
deleted file mode 100644
index 579713d3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/map/form.ejs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/map/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/map/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/map/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/message/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/message/form.ejs
deleted file mode 100644
index d79a30eb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/message/form.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{{ctx.message}}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/message/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/message/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/message/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modalPreview/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modalPreview/form.ejs
deleted file mode 100644
index 5f8ac35f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modalPreview/form.ejs
+++ /dev/null
@@ -1,15 +0,0 @@
-
- {{ ctx.t(ctx.component.label, { _userInput: true }) }}. {{ ctx.component.type === 'signature' ? ctx.self.getValueAsString(ctx.previewText) : ctx.previewText }}
-
-
-
- {{ ctx.previewText }}
-
-
- {{ ctx.messages }}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modalPreview/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modalPreview/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modalPreview/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaldialog/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaldialog/form.ejs
deleted file mode 100644
index b6a74f23..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaldialog/form.ejs
+++ /dev/null
@@ -1,13 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaldialog/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaldialog/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaldialog/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaledit/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaledit/form.ejs
deleted file mode 100644
index 00d51585..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaledit/form.ejs
+++ /dev/null
@@ -1,10 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaledit/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaledit/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/modaledit/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueRow/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueRow/form.ejs
deleted file mode 100644
index 5b665817..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueRow/form.ejs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- {{ctx.element}}
-
- {% if (!ctx.disabled) { %}
-
-
-
-
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueRow/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueRow/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueRow/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueTable/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueTable/form.ejs
deleted file mode 100644
index cc143dd4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueTable/form.ejs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- {{ctx.rows}}
- {% if (!ctx.disabled) { %}
-
-
- {{ctx.t(ctx.addAnother, { _userInput: true })}}
-
-
- {% } %}
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueTable/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueTable/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multiValueTable/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multipleMasksInput/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multipleMasksInput/form.ejs
deleted file mode 100644
index 42975ffc..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multipleMasksInput/form.ejs
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- {% ctx.selectOptions.forEach(function(option) { %}
- {{option.label}}
- {% }); %}
-
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multipleMasksInput/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multipleMasksInput/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/multipleMasksInput/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/panel/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/panel/form.ejs
deleted file mode 100644
index b41275c1..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/panel/form.ejs
+++ /dev/null
@@ -1,30 +0,0 @@
-
- {% if (!ctx.component.hideLabel || ctx.builder || ctx.component.collapsible || ctx.component.tooltip) { %}
-
- {% } %}
- {% if (!ctx.collapsed || ctx.builder) { %}
-
- {{ctx.children}}
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/panel/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/panel/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/panel/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdf/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdf/form.ejs
deleted file mode 100644
index 842a18d9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdf/form.ejs
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
- {{ ctx.submitButton }}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdf/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdf/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdf/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilder/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilder/form.ejs
deleted file mode 100644
index 6bd3d453..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilder/form.ejs
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilder/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilder/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilder/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilderUpload/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilderUpload/form.ejs
deleted file mode 100644
index c0ea95dd..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilderUpload/form.ejs
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilderUpload/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilderUpload/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/pdfBuilderUpload/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/form.ejs
deleted file mode 100644
index 9e037506..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/form.ejs
+++ /dev/null
@@ -1,38 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/html.ejs
deleted file mode 100644
index 37cbccef..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/html.ejs
+++ /dev/null
@@ -1,4 +0,0 @@
-
- {% var filtered = ctx.values.filter(function(item) {return ctx.value === item.value || (typeof ctx.value === 'object' && ctx.value.hasOwnProperty(item.value) && ctx.value[item.value])}).map(function(item) { return ctx.t(item.label, { _userInput: true })}).join(', ') %}
- {{ filtered }}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/radio/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/resourceAdd/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/resourceAdd/form.ejs
deleted file mode 100644
index 1823781a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/resourceAdd/form.ejs
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- {{ctx.element}}
-
-
-
-
-
-
- {{ctx.t(ctx.component.addResourceLabel || 'Add Resource', { _userInput: true })}}
-
-
-
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/resourceAdd/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/resourceAdd/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/resourceAdd/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/form.ejs
deleted file mode 100644
index b2490e28..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/form.ejs
+++ /dev/null
@@ -1,23 +0,0 @@
-{{ctx.selectOptions}}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/html.ejs
deleted file mode 100644
index 886cd522..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/html.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{% if (ctx.value) { %}{{ ctx.self.itemValueForHTMLMode(ctx.value) }}{% } else { %}-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/select/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/form.ejs
deleted file mode 100644
index 2bf73ffe..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/form.ejs
+++ /dev/null
@@ -1,8 +0,0 @@
-
- {{ctx.t(ctx.option.label, { _userInput: true })}}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/html.ejs
deleted file mode 100644
index 1eca4830..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/html.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{% if (ctx.selected) { %}{{ctx.t(ctx.option.label, { _userInput: true })}}{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/selectOption/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/form.ejs
deleted file mode 100644
index 29308726..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/form.ejs
+++ /dev/null
@@ -1,23 +0,0 @@
-{{ctx.element}}
-
-
-
-
-
- {% if (ctx.required) { %}
-
-
-
- {% } %}
-
-
-{% if (ctx.component.footer) { %}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/html.ejs
deleted file mode 100644
index f26a2e88..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/html.ejs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/signature/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/form.ejs
deleted file mode 100644
index ce7c9b87..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/form.ejs
+++ /dev/null
@@ -1,32 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/html.ejs
deleted file mode 100644
index 8c204c2c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/html.ejs
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- {% ctx.component.questions.forEach(function(question) { %}
-
- {{ctx.t(question.label)}}
-
- {% ctx.component.values.forEach(function(item) { %}
- {% if (ctx.value && ctx.value.hasOwnProperty(question.value) && ctx.value[question.value] === item.value) { %}
- {{ctx.t(item.label)}}
- {% } %}
- {% }) %}
-
-
- {% }) %}
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/survey/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/flat.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/flat.ejs
deleted file mode 100644
index eaa09571..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/flat.ejs
+++ /dev/null
@@ -1,13 +0,0 @@
-{% ctx.component.components.forEach(function(tab, index) { %}
-
-
-
- {{ ctx.tabComponents[index] }}
-
-
-{% }) %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/form.ejs
deleted file mode 100644
index f3a9a603..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/form.ejs
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
- {% ctx.component.components.forEach(function(tab, index) { %}
-
- {{ctx.tabComponents[index]}}
-
- {% }) %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/index.js
deleted file mode 100644
index 5ec9caef..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tab/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import flat from './flat.ejs';
-import form from './form.ejs';
-
-export default { flat, form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/table/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/table/form.ejs
deleted file mode 100644
index 633b7f23..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/table/form.ejs
+++ /dev/null
@@ -1,26 +0,0 @@
-
- {{ctx.t(ctx.component.label)}}
- {% if (ctx.component.header && ctx.component.header.length > 0) { %}
-
-
- {% ctx.component.header.forEach(function(header) { %}
- {{ctx.t(header)}}
- {% }) %}
-
-
- {% } %}
-
- {% ctx.tableComponents.forEach(function(row, rowIndex) { %}
-
- {% row.forEach(function(column, colIndex) { %}
- {{column}}
- {% }) %}
-
- {% }) %}
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/table/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/table/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/table/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tableComponents/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tableComponents/form.ejs
deleted file mode 100644
index 9fa0c21c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tableComponents/form.ejs
+++ /dev/null
@@ -1,5 +0,0 @@
-{% ctx.children.forEach(function(component) { %}
-
- {{ component }}
-
-{% }) %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tableComponents/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tableComponents/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tableComponents/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/form.ejs
deleted file mode 100644
index 65059419..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/form.ejs
+++ /dev/null
@@ -1,20 +0,0 @@
-{% if (ctx.node.isRoot) { %}
-
-{% } else { %}
-
-{% } %}
- {% if (ctx.content) { %}
-
- {{ ctx.content }}
-
- {% } %}
- {% if (ctx.childNodes && ctx.childNodes.length) { %}
-
- {{ ctx.childNodes.join('') }}
-
- {% } %}
-{% if (ctx.node.isRoot) { %}
-
-{% } else { %}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/edit.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/edit.ejs
deleted file mode 100644
index 468b7ead..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/edit.ejs
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
{{ ctx.children }}
- {% if (!ctx.readOnly) { %}
-
- {{ ctx.t('Save') }}
- {{ ctx.t('Cancel') }}
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/index.js
deleted file mode 100644
index abb7cfb6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import edit from './edit.ejs';
-import view from './view.ejs';
-
-export default {
- treeView: {
- form: view,
- },
- treeEdit: {
- form: edit
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/view.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/view.ejs
deleted file mode 100644
index ab3d98aa..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/tree/partials/view.ejs
+++ /dev/null
@@ -1,22 +0,0 @@
-
- {% ctx.values.forEach(function(value) { %}
-
- {{ value }}
-
- {% }) %}
-
-
- {% if (ctx.node.hasChildren) { %}
- {{ ctx.t(ctx.node.collapsed ? 'Expand' : 'Collapse') }}
- {% } %}
- {% if (!ctx.readOnly) { %}
- {{ ctx.t('Add') }}
- {{ ctx.t('Edit') }}
- {{ ctx.t('Delete') }}
- {% if (ctx.node.revertAvailable) { %}
- {{ ctx.t('Revert') }}
- {% } %}
- {% } %}
-
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/builder.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/builder.ejs
deleted file mode 100644
index cd63e234..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/builder.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{{ ctx.t(ctx.component.title, { _userInput: true }) }}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/form.ejs
deleted file mode 100644
index 2ea21b9b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/form.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{{ctx.children}}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/index.js
deleted file mode 100644
index 97db0356..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/webform/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import builder from './builder.ejs';
-
-export default { form, builder };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/well/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/well/form.ejs
deleted file mode 100644
index 6765e55b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/well/form.ejs
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/well/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/well/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/well/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/builder.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/builder.ejs
deleted file mode 100644
index cd63e234..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/builder.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{{ ctx.t(ctx.component.title, { _userInput: true }) }}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/form.ejs
deleted file mode 100644
index 4ba02c55..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/form.ejs
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- {% if (ctx.wizardHeaderType === 'wizardHeaderVertical') { %}
-
- {% if (ctx.wizardHeaderLocation !== 'right') { %}
-
- {{ ctx.wizardHeader }}
-
- {% } %}
-
- {{ctx.components}}
-
- {% if (ctx.wizardHeaderLocation === 'right') { %}
-
- {{ ctx.wizardHeader }}
-
- {% } %}
-
-
- {% } else { %}
- {{ ctx.wizardHeader }}
-
- {{ctx.components}}
-
- {{ ctx.wizardNav }}
- {% } %}
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/index.js
deleted file mode 100644
index bcece253..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizard/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-import builder from './builder.ejs';
-export default { form, builder };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeader/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeader/form.ejs
deleted file mode 100644
index d8499356..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeader/form.ejs
+++ /dev/null
@@ -1,14 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeader/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeader/index.js
deleted file mode 100644
index 0890c1f2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeader/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import form from './form.ejs';
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderClassic/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderClassic/form.ejs
deleted file mode 100644
index 14d71900..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderClassic/form.ejs
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderClassic/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderClassic/index.js
deleted file mode 100644
index 0890c1f2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderClassic/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import form from './form.ejs';
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderVertical/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderVertical/form.ejs
deleted file mode 100644
index 8feb9550..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderVertical/form.ejs
+++ /dev/null
@@ -1,14 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderVertical/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderVertical/index.js
deleted file mode 100644
index 0890c1f2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardHeaderVertical/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import form from './form.ejs';
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardNav/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardNav/form.ejs
deleted file mode 100644
index b11e012b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardNav/form.ejs
+++ /dev/null
@@ -1,28 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardNav/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardNav/index.js
deleted file mode 100644
index 0890c1f2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap/wizardNav/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import form from './form.ejs';
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/alert/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/alert/form.ejs
deleted file mode 100644
index 6849fb22..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/alert/form.ejs
+++ /dev/null
@@ -1,10 +0,0 @@
-
- {{ctx.message}}
- {% if (ctx.options.vpat) { %}
- {{ctx.t('errorListHotkey')}}
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/alert/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/alert/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/alert/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderEditForm/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderEditForm/form.ejs
deleted file mode 100644
index 842cab11..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderEditForm/form.ejs
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
{{ctx.t(ctx.componentInfo.title, { _userInput: true })}} {{ctx.t('Component')}}
-
- {% if (ctx.helplinks) { %}
-
- {% } %}
-
-
-
-
- {{ctx.editForm}}
-
- {% if (!ctx.preview) { %}
-
- {{ctx.t('Save')}}
- {{ctx.t('Cancel')}}
- {{ctx.t('Remove')}}
-
- {% } %}
-
- {% if (ctx.preview) { %}
-
-
- {% if (ctx.componentInfo.help) { %}
-
- {{ ctx.t(ctx.componentInfo.help) }}
-
- {% } %}
-
- {{ctx.t('Save')}}
- {{ctx.t('Cancel')}}
- {{ctx.t('Remove')}}
-
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderEditForm/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderEditForm/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderEditForm/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebar/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebar/form.ejs
deleted file mode 100644
index e9400a80..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebar/form.ejs
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebar/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebar/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebar/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebarGroup/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebarGroup/form.ejs
deleted file mode 100644
index 538d25ac..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebarGroup/form.ejs
+++ /dev/null
@@ -1,47 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebarGroup/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebarGroup/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderSidebarGroup/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderWizard/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderWizard/form.ejs
deleted file mode 100644
index b971e0d7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderWizard/form.ejs
+++ /dev/null
@@ -1,22 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderWizard/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderWizard/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/builderWizard/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/componentModal/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/componentModal/form.ejs
deleted file mode 100644
index a331220d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/componentModal/form.ejs
+++ /dev/null
@@ -1,26 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/componentModal/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/componentModal/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/componentModal/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/cssClasses.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/cssClasses.js
deleted file mode 100644
index 7be9dbc8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/cssClasses.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default {
- 'form-group': 'formio-form-group',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/datagrid/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/datagrid/form.ejs
deleted file mode 100644
index 661de3d6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/datagrid/form.ejs
+++ /dev/null
@@ -1,78 +0,0 @@
-
- {% if (ctx.hasHeader) { %}
-
-
- {% if (ctx.component.reorder) { %} {% } %}
- {% ctx.columns.forEach(function(col) { %}
-
- {{ col.hideLabel ? '' : ctx.t(col.label || col.title, { _userInput: true }) }}
- {% if (col.tooltip) { %} {% } %}
-
- {% }) %}
- {% if (ctx.hasExtraColumn) { %}
-
- {{ ctx.t('Add/Remove') }}
- {% if (!ctx.builder && ctx.hasAddButton && ctx.hasTopSubmit) { %}
-
- {{ctx.t(ctx.component.addAnother || 'Add Another', { _userInput: true })}}
-
- {% } %}
-
- {% } %}
-
-
- {% } %}
-
- {% ctx.rows.forEach(function(row, index) { %}
- {% if (ctx.hasGroups && ctx.groups[index]) { %}
-
- {% } %}
-
- {% if (ctx.component.reorder) { %}
-
-
-
- {% } %}
- {% ctx.columns.forEach(function(col) { %}
-
- {{row[col.key]}}
-
- {% }) %}
- {% if (ctx.hasExtraColumn) { %}
- {% if (ctx.hasRemoveButtons) { %}
-
-
-
-
-
- {% } %}
- {% if (ctx.canAddColumn) { %}
-
- {{ctx.placeholder}}
-
- {% } %}
- {% } %}
-
- {% }) %}
-
- {% if (!ctx.builder && ctx.hasAddButton && ctx.hasBottomSubmit) { %}
-
-
-
-
- {{ctx.t(ctx.component.addAnother || 'Add Another', { _userInput: true })}}
-
-
-
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/datagrid/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/datagrid/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/datagrid/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/dialog/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/dialog/form.ejs
deleted file mode 100644
index 9b6b4f93..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/dialog/form.ejs
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/dialog/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/dialog/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/dialog/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/file/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/file/form.ejs
deleted file mode 100644
index b30da231..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/file/form.ejs
+++ /dev/null
@@ -1,143 +0,0 @@
-{% if (ctx.options.vpat) { %}
-
-{% } %}
-{% if (!ctx.self.imageUpload) { %}
- {% if (ctx.options.vpat) { %}
- {{(!ctx.component.filePattern || ctx.component.filePattern === '*') ? 'Any file types are allowed' : ctx.t('Allowed file types: ') + ctx.component.filePattern}}
- {% } %}
-
-
- {% ctx.files.forEach(function(file) { %}
-
-
- {% if (!ctx.disabled) { %}
-
- {% } %}
-
-
{{ctx.fileSize(file.size)}}
- {% if (ctx.self.hasTypes && !ctx.disabled) { %}
-
-
- {% ctx.component.fileTypes.map(function(type) { %}
- {{ctx.t(type.label)}}
- {% }); %}
-
-
- {% } %}
- {% if (ctx.self.hasTypes && ctx.disabled) { %}
-
{{file.fileType}}
- {% } %}
-
-
- {% }) %}
-
-{% } else { %}
-
- {% ctx.files.forEach(function(file) { %}
-
-
-
- {% if (!ctx.disabled) { %}
-
- {% } %}
-
-
- {% }) %}
-
-{% } %}
-{% if (!ctx.disabled && (ctx.component.multiple || !ctx.files.length)) { %}
- {% if (ctx.self.useWebViewCamera) { %}
-
- {{ctx.t('Gallery')}}
- {{ctx.t('Camera')}}
-
- {% } else if (!ctx.self.cameraMode) { %}
-
- {% } else { %}
-
-
-
- {{ctx.t('Take Picture')}}
- {{ctx.t('Switch to file upload')}}
- {% } %}
-{% } %}
-{% ctx.statuses.forEach(function(status) { %}
-
-
-
{{status.originalName}}
-
- {{ctx.t('Remove button. Press to remove ' + status.originalName || status.name + '.')}}
- {{status.message ? status.message.replace(';', '.') : ''}}
-
-
-
{{ctx.fileSize(status.size)}}
-
-
-
- {% if (status.status === 'progress') { %}
-
-
- {{status.progress}}% {{ctx.t('Complete')}}
-
-
- {% } else if (status.status === 'error') { %}
-
{{ctx.t(status.message)}}
- {% } else { %}
-
{{ctx.t(status.message)}}
- {% } %}
-
-
-
-{% }) %}
-{% if (!ctx.component.storage || ctx.support.hasWarning) { %}
-
- {% if (!ctx.component.storage) { %}
-
{{ctx.t('No storage has been set for this field. File uploads are disabled until storage is set up.')}}
- {% } %}
- {% if (!ctx.support.filereader) { %}
-
{{ctx.t('File API & FileReader API not supported.')}}
- {% } %}
- {% if (!ctx.support.formdata) { %}
-
{{ctx.t("XHR2's FormData is not supported.")}}
- {% } %}
- {% if (!ctx.support.progress) { %}
-
{{ctx.t("XHR2's upload progress isn't supported.")}}
- {% } %}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/file/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/file/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/file/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/index.js
deleted file mode 100644
index 724fd8c8..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import builderSidebar from './builderSidebar';
-import builderSidebarGroup from './builderSidebarGroup';
-import builderWizard from './builderWizard';
-import componentModal from './componentModal';
-import datagrid from './datagrid';
-import dialog from './dialog';
-import file from './file';
-import input from './input';
-import label from './label';
-import modalPreview from './modalPreview';
-import radio from './radio';
-import table from './table';
-import cssClasses from './cssClasses';
-
-export default {
- transform(type, text) {
- if (!text) {
- return text;
- }
- switch (type) {
- case 'class':
- return this.cssClasses.hasOwnProperty(text.toString()) ? this.cssClasses[text.toString()] : text;
- }
- return text;
- },
- builderSidebar,
- builderSidebarGroup,
- builderWizard,
- componentModal,
- datagrid,
- dialog,
- file,
- input,
- label,
- modalPreview,
- radio,
- table,
- cssClasses
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/form.ejs
deleted file mode 100644
index 65947f8d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/form.ejs
+++ /dev/null
@@ -1,55 +0,0 @@
-{% if (ctx.prefix || ctx.suffix) { %}
-
-{% } %}
-{% if (ctx.component.showCharCount || ctx.component.showWordCount) { %}
-
- {% if (ctx.component.showCharCount) { %}
-
- {% } %}
- {% if (ctx.component.showWordCount) { %}
-
- {% } %}
-
-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/html.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/html.ejs
deleted file mode 100644
index 82fffefc..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/html.ejs
+++ /dev/null
@@ -1 +0,0 @@
-{% if (ctx.value) { %}{{ctx.value}}{% } else { %}-{% } %}
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/index.js
deleted file mode 100644
index 7f65740d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/input/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import form from './form.ejs';
-import html from './html.ejs';
-
-export default { form, html };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/label/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/label/form.ejs
deleted file mode 100644
index e83fd99a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/label/form.ejs
+++ /dev/null
@@ -1,14 +0,0 @@
-
- {{ ctx.t(ctx.component.label, { _userInput: true }) }}
- {% if (ctx.component.type === 'number' || ctx.component.type === 'phoneNumber' || ctx.component.type === 'currency') { %}
- , {{ctx.t('numeric only')}},
- {% } %}
- {% if (ctx.component.tooltip) { %}
-
- {% } %}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/label/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/label/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/label/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/modalPreview/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/modalPreview/form.ejs
deleted file mode 100644
index d307130e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/modalPreview/form.ejs
+++ /dev/null
@@ -1,15 +0,0 @@
-
- {{ ctx.t(ctx.component.label, { _userInput: true }) }}. {{ ctx.component.type === 'signature' ? ctx.self.getValueAsString(ctx.previewText) : ctx.previewText }}
-
-
-
- {{ ctx.previewText }}
-
-
- {{ ctx.messages }}
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/modalPreview/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/modalPreview/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/modalPreview/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/radio/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/radio/form.ejs
deleted file mode 100644
index 769b8cd9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/radio/form.ejs
+++ /dev/null
@@ -1,38 +0,0 @@
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/radio/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/radio/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/radio/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/table/form.ejs b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/table/form.ejs
deleted file mode 100644
index 39532d9e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/table/form.ejs
+++ /dev/null
@@ -1,26 +0,0 @@
-
- {{ctx.t(ctx.component.label)}}
- {% if (ctx.component.header && ctx.component.header.length > 0) { %}
-
-
- {% ctx.component.header.forEach(function(header) { %}
- {{ctx.t(header)}}
- {% }) %}
-
-
- {% } %}
-
- {% ctx.tableComponents.forEach(function(row, rowIndex) { %}
-
- {% row.forEach(function(column, colIndex) { %}
- {{column}}
- {% }) %}
-
- {% }) %}
-
-
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/table/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/table/index.js
deleted file mode 100644
index 4d4897d4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/bootstrap5/table/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import form from './form.ejs';
-
-export default { form };
diff --git a/web-client/core/themes/italia/static/formio/css/src/templates/index.js b/web-client/core/themes/italia/static/formio/css/src/templates/index.js
deleted file mode 100644
index a36404b7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/templates/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import bootstrap from './bootstrap';
-import bootstrap5 from './bootstrap5';
-
-// Deprecated. Semantic and bootstrap3 will be removed in 5.x.
-// Use external modules instead.
-import bootstrap3 from '@formio/bootstrap3';
-import semantic from '@formio/semantic';
-export default {
- bootstrap,
- bootstrap3: bootstrap3.templates.bootstrap3,
- bootstrap5,
- semantic: semantic.templates.semantic,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/translations/en.js b/web-client/core/themes/italia/static/formio/css/src/translations/en.js
deleted file mode 100644
index 6c8e3c4a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/translations/en.js
+++ /dev/null
@@ -1,67 +0,0 @@
-export default {
- unsavedRowsError: 'Please save all rows before proceeding.',
- invalidRowsError: 'Please correct invalid rows before proceeding.',
- invalidRowError: 'Invalid row. Please correct it or delete.',
- alertMessageWithLabel: '{{label}}: {{message}}',
- alertMessage: '{{message}}',
- complete: 'Submission Complete',
- error: 'Please fix the following errors before submitting.',
- errorListHotkey: 'Press Ctrl + Alt + X to go back to the error list.',
- errorsListNavigationMessage: 'Click to navigate to the field with following error.',
- submitError: 'Please check the form and correct all errors before submitting.',
- required: '{{field}} is required',
- unique: '{{field}} must be unique',
- array: '{{field}} must be an array',
- array_nonempty: '{{field}} must be a non-empty array', // eslint-disable-line camelcase
- nonarray: '{{field}} must not be an array',
- select: '{{field}} contains an invalid selection',
- pattern: '{{field}} does not match the pattern {{pattern}}',
- minLength: '{{field}} must have at least {{length}} characters.',
- maxLength: '{{field}} must have no more than {{length}} characters.',
- minWords: '{{field}} must have at least {{length}} words.',
- maxWords: '{{field}} must have no more than {{length}} words.',
- min: '{{field}} cannot be less than {{min}}.',
- max: '{{field}} cannot be greater than {{max}}.',
- maxDate: '{{field}} should not contain date after {{- maxDate}}',
- minDate: '{{field}} should not contain date before {{- minDate}}',
- maxYear: '{{field}} should not contain year greater than {{maxYear}}',
- minYear: '{{field}} should not contain year less than {{minYear}}',
- invalid_email: '{{field}} must be a valid email.', // eslint-disable-line camelcase
- invalid_url: '{{field}} must be a valid url.', // eslint-disable-line camelcase
- invalid_regex: '{{field}} does not match the pattern {{regex}}.', // eslint-disable-line camelcase
- invalid_date: '{{field}} is not a valid date.', // eslint-disable-line camelcase
- invalid_day: '{{field}} is not a valid day.', // eslint-disable-line camelcase
- mask: '{{field}} does not match the mask.',
- valueIsNotAvailable: '{{ field }} is an invalid value.',
- stripe: '{{stripe}}',
- month: 'Month',
- day: 'Day',
- year: 'Year',
- january: 'January',
- february: 'February',
- march: 'March',
- april: 'April',
- may: 'May',
- june: 'June',
- july: 'July',
- august: 'August',
- september: 'September',
- october: 'October',
- november: 'November',
- december: 'December',
- next: 'Next',
- previous: 'Previous',
- cancel: 'Cancel',
- submit: 'Submit Form',
- confirmCancel: 'Are you sure you want to cancel?',
- saveDraftInstanceError: 'Cannot save draft because there is no formio instance.',
- saveDraftAuthError: 'Cannot save draft unless a user is authenticated.',
- restoreDraftInstanceError: 'Cannot restore draft because there is no formio instance.',
- saveDraftError: 'Unable to save draft.',
- restoreDraftError: 'Unable to restore draft.',
- time: 'Invalid time',
- cancelButtonAriaLabel: 'Cancel button. Click to reset the form',
- previousButtonAriaLabel:'Previous button. Click to go back to the previous tab',
- nextButtonAriaLabel:'Next button. Click to go to the next tab',
- submitButtonAriaLabel:'Submit Form button. Click to submit the form',
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/ChoicesWrapper.js b/web-client/core/themes/italia/static/formio/css/src/utils/ChoicesWrapper.js
deleted file mode 100644
index e802db57..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/ChoicesWrapper.js
+++ /dev/null
@@ -1,243 +0,0 @@
-import Choices from '@formio/choices.js';
-
-/**
- * TODO: REMOVE THIS ONCE THE PULL REQUEST HAS BEEN RESOLVED.
- *
- * https://github.com/jshjohnson/Choices/pull/788
- *
- * This is intentionally not part of the extended class, since other components use Choices and need this fix as well.
- * @type {Choices._generatePlaceholderValue}
- * @private
- */
-Choices.prototype._generatePlaceholderValue = function() {
- if (this._isSelectElement && this.passedElement.placeholderOption) {
- const { placeholderOption } = this.passedElement;
- return placeholderOption ? placeholderOption.text : false;
- }
- const { placeholder, placeholderValue } = this.config;
- const {
- element: { dataset },
- } = this.passedElement;
-
- if (placeholder) {
- if (placeholderValue) {
- return placeholderValue;
- }
-
- if (dataset.placeholder) {
- return dataset.placeholder;
- }
- }
-
- return false;
-};
-
-export const KEY_CODES = {
- BACK_KEY: 46,
- DELETE_KEY: 8,
- TAB_KEY: 9,
- ENTER_KEY: 13,
- A_KEY: 65,
- ESC_KEY: 27,
- UP_KEY: 38,
- DOWN_KEY: 40,
- PAGE_UP_KEY: 33,
- PAGE_DOWN_KEY: 34,
-};
-
-class ChoicesWrapper extends Choices {
- constructor(...args) {
- super(...args);
-
- this._onTabKey = this._onTabKey.bind(this);
- this.isDirectionUsing = false;
- this.shouldOpenDropDown = true;
- }
-
- _onTouchEnd(event) {
- var target = (event || event.touches[0]).target;
- var touchWasWithinContainer = this._wasTap && this.containerOuter.element.contains(target);
- if (touchWasWithinContainer) {
- var containerWasExactTarget = target === this.containerOuter.element || target === this.containerInner.element;
- if (containerWasExactTarget) {
- if (this._isTextElement) {
- this.input.focus();
- }
- else if (this._isSelectMultipleElement) {
- this.input.focus();
- this.showDropdown();
- }
- }
- // Prevents focus event firing
- event.stopPropagation();
- }
- this._wasTap = true;
- }
-
- _handleButtonAction(activeItems, element) {
- if (!this._isSelectOneElement) {
- return super._handleButtonAction(activeItems, element);
- }
-
- if (
- !activeItems ||
- !element ||
- !this.config.removeItems ||
- !this.config.removeItemButton
- ) {
- return;
- }
-
- super._handleButtonAction(activeItems, element);
- }
-
- _onEnterKey(args) {
- // Prevent dropdown form opening when removeItemButton was pressed using 'Enter' on keyboard
- if (args.event.target.className === 'choices__button') {
- this.shouldOpenDropDown = false;
- }
- super._onEnterKey(args);
- }
-
- _onDirectionKey(...args) {
- if (!this._isSelectOneElement) {
- return super._onDirectionKey(...args);
- }
-
- this.isDirectionUsing = true;
-
- super._onDirectionKey(...args);
-
- this.onSelectValue(...args);
-
- clearTimeout(this.timeout);
- this.timeout = setTimeout(() => {
- this.isDirectionUsing = false;
- }, 250);
- }
-
- _onTabKey({ activeItems, hasActiveDropdown }) {
- if (hasActiveDropdown) {
- this._selectHighlightedChoice(activeItems);
- }
- }
-
- _selectHighlightedChoice(activeItems) {
- const highlightedChoice = this.dropdown.getChild(
- `.${this.config.classNames.highlightedState}`,
- );
-
- if (highlightedChoice) {
- this._handleChoiceAction(activeItems, highlightedChoice);
- }
-
- event.preventDefault();
- }
-
- _onKeyDown(event) {
- if (!this._isSelectOneElement) {
- return super._onKeyDown(event);
- }
-
- const { target, keyCode, ctrlKey, metaKey } = event;
-
- if (
- target !== this.input.element &&
- !this.containerOuter.element.contains(target)
- ) {
- return;
- }
-
- const activeItems = this._store.activeItems;
- const hasFocusedInput = this.input.isFocussed;
- const hasActiveDropdown = this.dropdown.isActive;
- const hasItems = this.itemList.hasChildren;
- const keyString = String.fromCharCode(keyCode);
-
- const {
- BACK_KEY,
- DELETE_KEY,
- TAB_KEY,
- ENTER_KEY,
- A_KEY,
- ESC_KEY,
- UP_KEY,
- DOWN_KEY,
- PAGE_UP_KEY,
- PAGE_DOWN_KEY,
- } = KEY_CODES;
- const hasCtrlDownKeyPressed = ctrlKey || metaKey;
-
- // If a user is typing and the dropdown is not active
- if (!hasActiveDropdown && !this._isTextElement && /[a-zA-Z0-9-_ ]/.test(keyString)) {
- const currentValue = this.input.element.value;
- this.input.element.value = currentValue ? `${currentValue}${keyString}` : keyString;
- this.showDropdown();
- }
-
- // Map keys to key actions
- const keyDownActions = {
- [A_KEY]: this._onAKey,
- [TAB_KEY]: this._onTabKey,
- [ENTER_KEY]: this._onEnterKey,
- [ESC_KEY]: this._onEscapeKey,
- [UP_KEY]: this._onDirectionKey,
- [PAGE_UP_KEY]: this._onDirectionKey,
- [DOWN_KEY]: this._onDirectionKey,
- [PAGE_DOWN_KEY]: this._onDirectionKey,
- [DELETE_KEY]: this._onDeleteKey,
- [BACK_KEY]: this._onDeleteKey,
- };
-
- // If keycode has a function, run it
- if (keyDownActions[keyCode]) {
- keyDownActions[keyCode]({
- event,
- target,
- keyCode,
- metaKey,
- activeItems,
- hasFocusedInput,
- hasActiveDropdown,
- hasItems,
- hasCtrlDownKeyPressed,
- });
- }
- }
-
- onSelectValue({ event, activeItems, hasActiveDropdown }) {
- if (hasActiveDropdown) {
- this._selectHighlightedChoice(activeItems);
- }
- else if (this._isSelectOneElement) {
- this.showDropdown();
- event.preventDefault();
- }
- }
-
- showDropdown(...args) {
- if (!this.shouldOpenDropDown) {
- this.shouldOpenDropDown = true;
- return;
- }
-
- super.showDropdown(...args);
- }
-
- hideDropdown(...args) {
- if (this.isDirectionUsing) {
- return;
- }
-
- super.hideDropdown(...args);
- }
-
- _onBlur(...args) {
- if (this._isScrollingOnIe) {
- return;
- }
- super._onBlur(...args);
- }
-}
-
-export default ChoicesWrapper;
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/Evaluator.js b/web-client/core/themes/italia/static/formio/css/src/utils/Evaluator.js
deleted file mode 100644
index c3c7e449..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/Evaluator.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import _ from 'lodash';
-import stringHash from 'string-hash';
-const Evaluator = {
- noeval: false,
- protectedEval: false, // This property can be customized only by plugins
- cache: {},
- templateSettings: {
- evaluate: /\{%([\s\S]+?)%\}/g,
- interpolate: /\{\{([\s\S]+?)\}\}/g,
- escape: /\{\{\{([\s\S]+?)\}\}\}/g
- },
- evaluator(func, ...params) {
- if (Evaluator.noeval) {
- console.warn('No evaluations allowed for this renderer.');
- return _.noop;
- }
-
- if (typeof params[0] === 'object') {
- params = _.keys(params[0]);
- }
- return new Function(...params, func);
- },
- template(template, hash) {
- hash = hash || stringHash(template);
- if (Evaluator.cache[hash]) {
- return Evaluator.cache[hash];
- }
- try {
- // Ensure we handle copied templates from the ejs files.
- template = template.replace(/ctx\./g, '');
- return (Evaluator.cache[hash] = _.template(template, Evaluator.templateSettings));
- }
- catch (err) {
- console.warn('Error while processing template', err, template);
- }
- },
- interpolate(rawTemplate, data, _options) {
- // Ensure reverse compatability.
- const options = _.isObject(_options) ? _options : { noeval: _options };
- if (typeof rawTemplate === 'function') {
- try {
- return rawTemplate(data);
- }
- catch (err) {
- console.warn('Error interpolating template', err, data);
- return err.message;
- }
- }
-
- rawTemplate = String(rawTemplate);
- let template;
- if (Evaluator.noeval || options.noeval) {
- // No cached template methods available. Use poor-mans interpolate without eval.
- return rawTemplate.replace(/({{\s*(.*?)\s*}})/g, (match, $1, $2) => {
- // Allow for conditional values.
- const parts = $2.split('||').map(item => item.trim());
- let value = '';
- let path = '';
- for (let i = 0; i < parts.length; i++) {
- path = parts[i];
- value = _.get(data, path);
- if (value) {
- break;
- }
- }
- if (options.data) {
- _.set(options.data, path, value);
- }
- return value;
- });
- }
- else {
- template = Evaluator.template(rawTemplate);
- }
- if (typeof template === 'function') {
- try {
- if (data.component && data.component.filter === rawTemplate && !data.options.building) {
- data.data = _.mapValues(data.data, (val) => _.isString(val) ? encodeURIComponent(val) : val);
- }
- return template(data);
- }
- catch (err) {
- console.warn('Error interpolating template', err, rawTemplate, data);
- return err.message;
- }
- }
- return template;
- },
- evaluate(func, args) {
- return Array.isArray(args) ? func(...args) : func(args);
- }
-};
-
-Evaluator.registerEvaluator = (evaluator) => {
- Object.keys(evaluator).forEach((key) => {
- Evaluator[key] = evaluator[key];
- });
-};
-
-export default Evaluator;
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/builder.js b/web-client/core/themes/italia/static/formio/css/src/utils/builder.js
deleted file mode 100644
index 04126280..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/builder.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import _ from 'lodash';
-import { eachComponent, uniqueKey } from './utils';
-export default {
- /**
- * Appends a number to a component.key to keep it unique
- *
- * @param {Object} form
- * The components parent form.
- * @param {Object} component
- * The component to uniquify
- */
- uniquify(container, component) {
- let changed = false;
- const formKeys = {};
- eachComponent(container, (comp) => {
- formKeys[comp.key] = true;
-
- if (['address', 'container', 'datagrid', 'editgrid', 'dynamicWizard', 'tree'].includes(comp.type) || comp.tree || comp.arrayTree) {
- return true;
- }
- }, true);
-
- // Recurse into all child components.
- eachComponent([component], (component) => {
- // Skip key uniquification if this component doesn't have a key.
- if (!component.key) {
- return;
- }
-
- const newKey = uniqueKey(formKeys, component.key);
- if (newKey !== component.key) {
- component.key = newKey;
- changed = true;
- }
-
- formKeys[newKey] = true;
-
- if (['address', 'container', 'datagrid', 'editgrid', 'dynamicWizard', 'tree'].includes(component.type) || component.tree || component.arrayTree) {
- return true;
- }
- }, true);
- return changed;
- },
-
- additionalShortcuts: {
- button: [
- 'Enter',
- 'Esc'
- ]
- },
-
- getAlphaShortcuts() {
- return _.range('A'.charCodeAt(), 'Z'.charCodeAt() + 1).map((charCode) => String.fromCharCode(charCode));
- },
-
- getAdditionalShortcuts(type) {
- return this.additionalShortcuts[type] || [];
- },
-
- getBindedShortcuts(components, input) {
- const result = [];
-
- eachComponent(components, (component) => {
- if (component === input) {
- return;
- }
-
- if (component.shortcut) {
- result.push(component.shortcut);
- }
- if (component.values) {
- component.values.forEach((value) => {
- if (value.shortcut) {
- result.push(value.shortcut);
- }
- });
- }
- }, true);
-
- return result;
- },
-
- getAvailableShortcuts(form, component) {
- if (!component) {
- return [];
- }
- return [''].concat(_.difference(
- this.getAlphaShortcuts().concat(this.getAdditionalShortcuts(component.type)),
- this.getBindedShortcuts(form.components, component)),
- ).map((shortcut) => ({
- label: shortcut,
- value: shortcut,
- }));
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/calendarUtils.js b/web-client/core/themes/italia/static/formio/css/src/utils/calendarUtils.js
deleted file mode 100644
index e3969a3e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/calendarUtils.js
+++ /dev/null
@@ -1,147 +0,0 @@
-import moment from 'moment';
-import _ from 'lodash';
-
-export const CALENDAR_ERROR_MESSAGES = {
- INVALID: 'You entered the Invalid Date',
- INCOMPLETE: 'You entered an incomplete date.',
- greater(date, format) {
- return `The entered date is greater than ${ date.format(format)}`;
- },
- less(date, format) {
- return `The entered date is less than ${date.format(format)}`;
- }
-};
-
-/**
- * Builds the response for checkInvalidDate.
- *
- * @param {String} message
- * The message for response.
- * @param {Boolean} result
- * The boolean flag for response.
- * * @return {{message: string, result: boolean}}
- */
-function buildResponse(message, result) {
- return {
- message,
- result
- };
-}
-
-/**
- * Checks the value for a min date and max date.
- *
- * @param {moment} value
- * The value to check.
- * @param {[String]} format
- * A moment formats.
- * @param {Date} maxDate
- * The max date.
- * @param {Date} minDate
- * The min date.
- * * @return {{message: string, result: boolean}}
- */
-export function lessOrGreater(value, format, maxDate, minDate) {
- let message = '';
- let result = true;
-
- if (maxDate && value.isValid()) {
- const maxDateMoment = moment(maxDate, format);
-
- if (value > maxDateMoment) {
- message = CALENDAR_ERROR_MESSAGES.greater(maxDateMoment, format);
- result = false;
- }
- }
-
- if (minDate && value.isValid()) {
- const minDateMoment = moment(minDate, format);
-
- if (value < minDateMoment) {
- message = CALENDAR_ERROR_MESSAGES.less(minDateMoment, format);
- result = false;
- }
- }
-
- return {
- message,
- result
- };
-}
-
-/**
- * Checks the entered date for validity.
- *
- * @param {String} value
- * The value to check.
- * @param {[String]} format
- * A moment formats.
- * @param {Date} maxDate
- * The max date.
- * @param {Date} minDate
- * The min date.
- * * @return {{message: string, result: boolean}}
- */
-export function checkInvalidDate(value, format, minDate, maxDate) {
- const date = moment(value, format, true);
- const isValidDate = date.isValid();
-
- if (!isValidDate) {
- const delimeters = value.match(/[^a-z0-9_]/gi);
- const delimetersRegEx = new RegExp(delimeters.join('|'), 'gi');
-
- const inputParts = value.replace(/_*/gi, '').split(delimetersRegEx);
- const formatParts = format[1] ? format[1].split(delimetersRegEx) : format[0].split(delimetersRegEx);
-
- const timeIndex = _.findIndex(formatParts, (part, index) => part.length === 1 && index === formatParts.length - 1);
- const yearIndex = _.findIndex(formatParts, part => part.match(/yyyy/gi));
-
- if (inputParts[yearIndex]/ 1000 < 1) {
- return buildResponse(CALENDAR_ERROR_MESSAGES.INVALID, false);
- }
-
- if (inputParts[0].length === formatParts[0].length) {
- const modifiedParts = inputParts.map((part, index) => {
- let partValue = part;
- if (!part && index === timeIndex) {
- partValue = 'AM';
- }
- else if (!part) {
- partValue = '01';
- }
- if (delimeters[index]) {
- partValue = `${partValue}${delimeters[index]}`;
- }
-
- return partValue;
- });
-
- const problemDate = moment(modifiedParts.join(''), format, true);
-
- if (problemDate.isValid()) {
- const checkedLessOrGreater = lessOrGreater(problemDate, format[0], maxDate, minDate);
- if (!checkedLessOrGreater.result) {
- const { message, result } = checkedLessOrGreater;
- return buildResponse(message, result);
- }
-
- return buildResponse(CALENDAR_ERROR_MESSAGES.INCOMPLETE, false);
- }
- else {
- return buildResponse(CALENDAR_ERROR_MESSAGES.INVALID, false);
- }
- }
- else {
- return buildResponse(CALENDAR_ERROR_MESSAGES.INVALID, false);
- }
- }
- else if (isValidDate && value.indexOf('_') === -1) {
- const checkedLessOrGreater = lessOrGreater(date, format[0], maxDate, minDate);
- if (!checkedLessOrGreater.result) {
- const { message, result } = checkedLessOrGreater;
- return buildResponse(message, result);
- }
- }
-
- return buildResponse('', true);
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/ConditionOperator.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/ConditionOperator.js
deleted file mode 100644
index 43d77d1e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/ConditionOperator.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import _ from 'lodash';
-
-/* eslint-disable no-unused-vars */
-export default class ConditionOperator {
- static get operatorKey() {
- return '';
- }
-
- static get displayedName() {
- return '';
- }
-
- static get requireValue() {
- return true;
- }
-
- execute(options) {
- return true;
- }
-
- getResult(options = {}) {
- const { value } = options;
-
- if (_.isArray(value)) {
- return _.some(value, valueItem => this.execute({ ...options, value: valueItem }));
- }
-
- return this.execute(options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateGreaterThan.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateGreaterThan.js
deleted file mode 100644
index 81eda99f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateGreaterThan.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import moment from 'moment';
-export default class DateGeaterThan extends ConditionOperator {
- static get operatorKey() {
- return 'dateGreaterThan';
- }
-
- static get displayedName() {
- return 'Greater Than';
- }
-
- getFormattedDates({ value, comparedValue, conditionTriggerComponent }) {
- const hasValidationFormat = conditionTriggerComponent ? conditionTriggerComponent.getValidationFormat : null;
- const date = hasValidationFormat ? moment(value, conditionTriggerComponent.getValidationFormat()) : moment(value);
- const comparedDate = hasValidationFormat ? moment(comparedValue, conditionTriggerComponent.getValidationFormat()) : moment(comparedValue);
-
- return { date, comparedDate };
- }
-
- execute(options, functionName = 'isAfter') {
- const { value, instance, conditionComponentPath } = options;
-
- if (!value) {
- return false;
- }
-
- let conditionTriggerComponent = null;
-
- if (instance && instance.root) {
- conditionTriggerComponent = instance.root.getComponent(conditionComponentPath);
- }
-
- if ( conditionTriggerComponent && conditionTriggerComponent.isPartialDay && conditionTriggerComponent.isPartialDay(value)) {
- return false;
- }
-
- const { date, comparedDate } = this.getFormattedDates({ ...options, conditionTriggerComponent });
-
- return date[functionName](comparedDate);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateGreaterThanOrEqual.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateGreaterThanOrEqual.js
deleted file mode 100644
index 7edc595a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateGreaterThanOrEqual.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import DateGeaterThan from './DateGreaterThan';
-
-export default class DateGreaterThanOrEqual extends DateGeaterThan {
- static get operatorKey() {
- return 'dateGreaterThanOrEqual';
- }
-
- static get displayedName() {
- return 'Greater Than Or Equal To';
- }
-
- execute(options) {
- return super.execute(options, 'isSameOrAfter');
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateLessThan.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateLessThan.js
deleted file mode 100644
index 93cad088..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateLessThan.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import DateGeaterThan from './DateGreaterThan';
-
-export default class DateLessThan extends DateGeaterThan {
- static get operatorKey() {
- return 'dateLessThan';
- }
-
- static get displayedName() {
- return 'Less Than';
- }
-
- execute(options) {
- return super.execute(options, 'isBefore');
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateLessThanOrEqual.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateLessThanOrEqual.js
deleted file mode 100644
index 0a4031e7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/DateLessThanOrEqual.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import DateGeaterThan from './DateGreaterThan';
-
-export default class DateLessThanOrEqual extends DateGeaterThan {
- static get operatorKey() {
- return 'dateLessThanOrEqual';
- }
-
- static get displayedName() {
- return 'Less Than Or Equal To';
- }
-
- execute(options) {
- return super.execute(options, 'isSameOrBefore');
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/EndsWith.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/EndsWith.js
deleted file mode 100644
index a69f58b2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/EndsWith.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-
-export default class EndsWith extends ConditionOperator {
- static get operatorKey() {
- return 'endsWith';
- }
-
- static get displayedName() {
- return 'Ends With';
- }
-
- execute({ value, comparedValue }) {
- return _.endsWith(value, comparedValue);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/GreaterThan.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/GreaterThan.js
deleted file mode 100644
index b04db5f4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/GreaterThan.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-
-export default class GeaterThan extends ConditionOperator {
- static get operatorKey() {
- return 'greaterThan';
- }
-
- static get displayedName() {
- return 'Greater Than';
- }
-
- execute({ value, comparedValue }) {
- return _.isNumber(value) && value > comparedValue;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/GreaterThanOrEqual.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/GreaterThanOrEqual.js
deleted file mode 100644
index 7a351a1d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/GreaterThanOrEqual.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-
-export default class GreaterThanOrEqual extends ConditionOperator {
- static get operatorKey() {
- return 'greaterThanOrEqual';
- }
-
- static get displayedName() {
- return 'Greater Than Or Equal To';
- }
-
- execute({ value, comparedValue }) {
- return _.isNumber(value) && (value > comparedValue || _.isEqual(value, comparedValue));
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/Includes.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/Includes.js
deleted file mode 100644
index 8ec7f69c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/Includes.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-
-export default class Includes extends ConditionOperator {
- static get operatorKey() {
- return 'includes';
- }
-
- static get displayedName() {
- return 'Includes';
- }
-
- execute({ value, comparedValue }) {
- return _.includes(value, comparedValue);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsDateEqual.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsDateEqual.js
deleted file mode 100644
index 78ff9897..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsDateEqual.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import DateGeaterThan from './DateGreaterThan';
-
-export default class IsDateEqual extends DateGeaterThan {
- static get operatorKey() {
- return 'isDateEqual';
- }
-
- static get displayedName() {
- return 'Is Equal To';
- }
-
- execute(options) {
- return super.execute(options, 'isSame');
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsEmptyValue.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsEmptyValue.js
deleted file mode 100644
index d1c28068..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsEmptyValue.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-
-export default class IsEmptyValue extends ConditionOperator {
- static get operatorKey() {
- return 'isEmpty';
- }
-
- static get displayedName() {
- return 'Is Empty';
- }
-
- static get requireValue() {
- return false;
- }
-
- execute({ value, instance, conditionComponentPath }) {
- const isEmptyValue = _.isEmpty(value);
-
- if (instance && instance.root) {
- const conditionTriggerComponent = instance.root.getComponent(conditionComponentPath);
- return conditionTriggerComponent ? conditionTriggerComponent.isEmpty() : isEmptyValue;
- }
-
- return isEmptyValue;
- }
-
- getResult(options) {
- return this.execute(options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsEqualTo.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsEqualTo.js
deleted file mode 100644
index b6c7e6b0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsEqualTo.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-import { getItemTemplateKeys, isSelectResourceWithObjectValue } from '../utils';
-
-export default class IsEqualTo extends ConditionOperator {
- static get operatorKey() {
- return 'isEqual';
- }
-
- static get displayedName() {
- return 'Is Equal To';
- }
-
- execute({ value, comparedValue, instance, conditionComponentPath }) {
- if ((value || value === false) && comparedValue && typeof value !== typeof comparedValue && _.isString(comparedValue)) {
- try {
- comparedValue = JSON.parse(comparedValue);
- }
- // eslint-disable-next-line no-empty
- catch (e) {}
- }
-
- if (instance && instance.root) {
- const conditionTriggerComponent = instance.root.getComponent(conditionComponentPath);
-
- if (
- conditionTriggerComponent
- && isSelectResourceWithObjectValue(conditionTriggerComponent.component)
- && conditionTriggerComponent.component?.template
- ) {
- if (!value || !_.isPlainObject(value)) {
- return false;
- }
-
- const { template, valueProperty } = conditionTriggerComponent.component;
-
- if (valueProperty === 'data') {
- value = { data: value };
- comparedValue = { data: comparedValue };
- }
-
- return _.every(getItemTemplateKeys(template) || [], k => _.isEqual(_.get(value, k), _.get(comparedValue, k)));
- }
- }
-
- //special check for select boxes
- if (_.isObject(value) && comparedValue && _.isString(comparedValue)) {
- return value[comparedValue];
- }
-
- return _.isEqual(value, comparedValue);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotDateEqual.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotDateEqual.js
deleted file mode 100644
index 28f0ab0d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotDateEqual.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import DateGeaterThan from './DateGreaterThan';
-
-export default class IsNotDateEqual extends DateGeaterThan {
- static get operatorKey() {
- return 'isNotDateEqual';
- }
-
- static get displayedName() {
- return 'Is Not Equal To';
- }
-
- execute(options) {
- return !super.execute(options, 'isSame');
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotEmptyValue.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotEmptyValue.js
deleted file mode 100644
index f0eafb0d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotEmptyValue.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import IsEmptyValue from './IsEmptyValue';
-
-export default class IsNotEmptyValue extends IsEmptyValue {
- static get operatorKey() {
- return 'isNotEmpty';
- }
-
- static get displayedName() {
- return 'Is Not Empty';
- }
-
- getResult(options) {
- return !super.getResult(options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotEqualTo.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotEqualTo.js
deleted file mode 100644
index 2daf0d6e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/IsNotEqualTo.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import IsEqualTo from './IsEqualTo';
-
-export default class IsNotEqualTo extends IsEqualTo {
- static get operatorKey() {
- return 'isNotEqual';
- }
-
- static get displayedName() {
- return 'Is Not Equal To';
- }
-
- execute(options) {
- return !super.execute(options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/LessThan.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/LessThan.js
deleted file mode 100644
index be06837c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/LessThan.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-
-export default class LessThan extends ConditionOperator {
- static get operatorKey() {
- return 'lessThan';
- }
-
- static get displayedName() {
- return 'Less Than';
- }
-
- execute({ value, comparedValue }) {
- return _.isNumber(value) && value < comparedValue;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/LessThanOrEqual.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/LessThanOrEqual.js
deleted file mode 100644
index 682cfb40..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/LessThanOrEqual.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-
-export default class LessThanOrEqual extends ConditionOperator {
- static get operatorKey() {
- return 'lessThanOrEqual';
- }
-
- static get displayedName() {
- return 'Less Than Or Equal To';
- }
-
- execute({ value, comparedValue }) {
- return _.isNumber(value) && (value < comparedValue || _.isEqual(value, comparedValue));
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/NotIncludes.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/NotIncludes.js
deleted file mode 100644
index 99a8ebcb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/NotIncludes.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import Includes from './Includes';
-
-export default class NotIncludes extends Includes {
- static get operatorKey() {
- return 'notIncludes';
- }
-
- static get displayedName() {
- return 'Not Includes';
- }
-
- execute(options) {
- return !super.execute(options);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/StartsWith.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/StartsWith.js
deleted file mode 100644
index 7504ecf5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/StartsWith.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import ConditionOperator from './ConditionOperator';
-import _ from 'lodash';
-
-export default class StartsWith extends ConditionOperator {
- static get operatorKey() {
- return 'startsWith';
- }
-
- static get displayedName() {
- return 'Starts With';
- }
-
- execute({ value, comparedValue }) {
- return _.startsWith(value, comparedValue);
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/index.js b/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/index.js
deleted file mode 100644
index d47ca848..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/conditionOperators/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import IsNotEqualTo from './IsNotEqualTo';
-import IsEmptyValue from './IsEmptyValue';
-import IsNotEmptyValue from './IsNotEmptyValue';
-import LessThan from './LessThan';
-import GreaterThan from './GreaterThan';
-import IsEqualTo from './IsEqualTo';
-import DateGreaterThan from './DateGreaterThan';
-import DateLessThan from './DateLessThan';
-import Includes from './Includes';
-import StartsWith from './StartsWith';
-import NotIncludes from './NotIncludes';
-import EndsWith from './EndsWith';
-import DateGreaterThanOrEqual from './DateGreaterThanOrEqual';
-import DateLessThanOrEqual from './DateLessThanOrEqual';
-import LessThanOrEqual from './LessThanOrEqual';
-import GreaterThanOrEqual from './GreaterThanOrEqual';
-import IsDateEqual from './IsDateEqual';
-import IsNotDateEqual from './IsNotDateEqual';
-
-const ConditionOperators = {
- [`${IsNotEqualTo.operatorKey}`]: IsNotEqualTo,
- [`${IsEqualTo.operatorKey}`]: IsEqualTo,
- [`${IsEmptyValue.operatorKey}`]: IsEmptyValue,
- [`${IsNotEmptyValue.operatorKey}`]: IsNotEmptyValue,
- [`${LessThan.operatorKey}`]: LessThan,
- [`${GreaterThan.operatorKey}`]: GreaterThan,
- [`${DateGreaterThan.operatorKey}`]: DateGreaterThan,
- [`${DateLessThan.operatorKey}`]: DateLessThan,
- [`${Includes.operatorKey}`]: Includes,
- [`${StartsWith.operatorKey}`]: StartsWith,
- [`${EndsWith.operatorKey}`]: EndsWith,
- [`${NotIncludes.operatorKey}`]: NotIncludes,
- [`${DateGreaterThanOrEqual.operatorKey}`]: DateGreaterThanOrEqual,
- [`${DateLessThanOrEqual.operatorKey}`]: DateLessThanOrEqual,
- [`${LessThanOrEqual.operatorKey}`]: LessThanOrEqual,
- [`${GreaterThanOrEqual.operatorKey}`]: GreaterThanOrEqual,
- [`${IsDateEqual.operatorKey}`]: IsDateEqual,
- [`${IsNotDateEqual.operatorKey}`]: IsNotDateEqual
-};
-
-export default ConditionOperators;
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components.json b/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components.json
deleted file mode 100644
index 292726cf..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components.json
+++ /dev/null
@@ -1,90 +0,0 @@
-[
- {
- "type": "textfield",
- "key": "one",
- "order": 1
- },
- {
- "input": false,
- "key": "parent1",
- "components": [
- {
- "type": "textfield",
- "key": "two",
- "order": 2
- },
- {
- "input": false,
- "key": "parent2",
- "columns": [
- {
- "components": [
- {
- "type": "textfield",
- "key": "three",
- "order": 3
- }
- ]
- },
- {
- "components": [
- {
- "rows": [
- [
- {
- "components": [
- {
- "key": "four",
- "order": 4,
- "type": "textfield"
- }
- ]
- },
- {
- "components": [
- {
- "key": "five",
- "order": 5,
- "type": "textfield"
- }
- ]
- }
- ],
- [
- {
- "components": [
- {
- "key": "six",
- "order": 6,
- "type": "textfield"
- }
- ]
- },
- {
- "components": [
- {
- "key": "seven",
- "order": 7,
- "type": "textarea",
- "rows": 3
- }
- ]
- }
- ]
- ],
- "type": "table"
- }
- ]
- }
- ],
- "type": "columns"
- }
- ],
- "type": "well"
- },
- {
- "key": "eight",
- "order": 8,
- "type": "button"
- }
-]
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components2.json b/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components2.json
deleted file mode 100644
index 12d5f4f9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components2.json
+++ /dev/null
@@ -1,512 +0,0 @@
-[
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "a",
- "label": "A",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "lockKey": true,
- "key": "b",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "type": "fieldset",
- "components": [
- {
- "lockKey": true,
- "key": "c",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "type": "columns",
- "columns": [
- {
- "components": [
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "d",
- "label": "D",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "type": "container",
- "persistent": true,
- "protected": false,
- "key": "f",
- "label": "F",
- "tableView": true,
- "components": [
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "g",
- "label": "G",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "h",
- "label": "H",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "i",
- "label": "I",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ],
- "tree": true,
- "input": true
- }
- ]
- },
- {
- "components": [
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "e",
- "label": "E",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ]
- }
- ],
- "input": false
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "j",
- "label": "J",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ],
- "legend": "B",
- "tableView": true,
- "input": false
- },
- {
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "type": "datagrid",
- "persistent": true,
- "protected": false,
- "key": "k",
- "label": "K",
- "tableView": true,
- "components": [
- {
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "hideLabel": true,
- "type": "container",
- "persistent": true,
- "protected": false,
- "key": "n",
- "label": "N",
- "tableView": true,
- "components": [
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "o",
- "label": "O",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "p",
- "label": "P",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "q",
- "label": "Q",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ],
- "tree": true,
- "input": true
- },
- {
- "hideLabel": true,
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "m",
- "label": "M",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "hideLabel": true,
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "l",
- "label": "L",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ],
- "tree": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "r",
- "label": "R",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "button",
- "theme": "primary",
- "disableOnInvalid": true,
- "action": "submit",
- "block": false,
- "rightIcon": "",
- "leftIcon": "",
- "size": "md",
- "key": "submit",
- "tableView": false,
- "label": "Submit",
- "input": true
- },
- {
- "label": "Tagpad",
- "tableView": false,
- "key": "tagpad",
- "type": "tagpad",
- "input": true,
- "components": [
- {
- "label": "Text Field",
- "tableView": true,
- "key": "a",
- "type": "textfield",
- "input": true
- }
- ]
- }
-]
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components3.json b/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components3.json
deleted file mode 100644
index 4dfaba8b..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components3.json
+++ /dev/null
@@ -1,517 +0,0 @@
-[
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "properties": {
- "path": "b"
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "a",
- "label": "A",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "lockKey": true,
- "key": "b",
- "properties": {
- "path": "a"
- },
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "type": "fieldset",
- "components": [
- {
- "lockKey": true,
- "key": "c",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "type": "columns",
- "columns": [
- {
- "components": [
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "d",
- "label": "D",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "properties": {
- "path": "b"
- },
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "type": "container",
- "persistent": true,
- "protected": false,
- "key": "f",
- "label": "F",
- "tableView": true,
- "components": [
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "g",
- "label": "G",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "h",
- "label": "H",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "i",
- "label": "I",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ],
- "tree": true,
- "input": true
- }
- ]
- },
- {
- "components": [
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "properties": {
- "path": "a"
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "e",
- "label": "E",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ]
- }
- ],
- "input": false
- },
- {
- "properties": {
- "path": "a"
- },
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "j",
- "label": "J",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ],
- "legend": "B",
- "tableView": true,
- "input": false
- },
- {
- "properties": {
- "path": "b"
- },
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "type": "datagrid",
- "persistent": true,
- "protected": false,
- "key": "k",
- "label": "K",
- "tableView": true,
- "components": [
- {
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "hideLabel": true,
- "type": "container",
- "persistent": true,
- "protected": false,
- "key": "n",
- "label": "N",
- "tableView": true,
- "components": [
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "o",
- "label": "O",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "p",
- "label": "P",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "q",
- "label": "Q",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ],
- "tree": true,
- "input": true
- },
- {
- "hideLabel": true,
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "properties": {
- "path": "a"
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "m",
- "label": "M",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "hideLabel": true,
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "l",
- "label": "L",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- }
- ],
- "tree": true,
- "input": true
- },
- {
- "type": "textfield",
- "conditional": {
- "eq": "",
- "when": null,
- "show": null
- },
- "validate": {
- "customPrivate": false,
- "custom": "",
- "pattern": "",
- "maxLength": "",
- "minLength": "",
- "required": false
- },
- "persistent": true,
- "unique": false,
- "protected": false,
- "defaultValue": "",
- "multiple": false,
- "suffix": "",
- "prefix": "",
- "placeholder": "",
- "key": "r",
- "label": "R",
- "inputMask": "",
- "inputType": "text",
- "tableView": true,
- "input": true
- },
- {
- "type": "button",
- "theme": "primary",
- "disableOnInvalid": true,
- "action": "submit",
- "block": false,
- "rightIcon": "",
- "leftIcon": "",
- "size": "md",
- "key": "submit",
- "tableView": false,
- "label": "Submit",
- "input": true
- }
-]
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components4.json b/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components4.json
deleted file mode 100644
index 9c04ad4e..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components4.json
+++ /dev/null
@@ -1,94 +0,0 @@
-[
- {
- "type": "textfield",
- "key": "one",
- "label": "1",
- "order": 1
- },
- {
- "input": false,
- "key": "parent1",
- "components": [
- {
- "type": "textfield",
- "key": "two",
- "label": "2",
- "order": 2
- },
- {
- "input": false,
- "key": "parent2",
- "columns": [
- {
- "components": [
- {
- "type": "textfield",
- "key": "three",
- "label": "3",
- "order": 3
- }
- ]
- },
- {
- "components": [
- {
- "rows": [
- [
- {
- "components": [
- {
- "key": "four",
- "order": 4,
- "label": "4",
- "type": "textfield"
- }
- ]
- },
- {
- "components": [
- {
- "key": "five",
- "order": 5,
- "type": "textfield"
- }
- ]
- }
- ],
- [
- {
- "components": [
- {
- "key": "six",
- "order": 6,
- "type": "textfield"
- }
- ]
- },
- {
- "components": [
- {
- "key": "seven",
- "order": 7,
- "type": "textarea",
- "rows": 3
- }
- ]
- }
- ]
- ],
- "type": "table"
- }
- ]
- }
- ],
- "type": "columns"
- }
- ],
- "type": "well"
- },
- {
- "key": "eight",
- "order": 8,
- "type": "button"
- }
-]
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components5.json b/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components5.json
deleted file mode 100644
index d33299ab..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/components5.json
+++ /dev/null
@@ -1,27 +0,0 @@
-[
- {
- "label": "HTML",
- "tag": "p",
- "content": "",
- "key": "html",
- "type": "htmlelement"
- },
- {
- "html": "some text
",
- "label": "Content",
- "key": "content",
- "type": "content"
- },
- {
- "label": "Text Field",
- "key": "textField",
- "type": "textfield",
- "input": true
- },
- {
- "label": "Number",
- "key": "number",
- "type": "number",
- "input": true
- }
-]
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/submission1.json b/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/submission1.json
deleted file mode 100644
index eecd04b6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/fixtures/submission1.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "data": {
- "name": "John Smith",
- "age": "30",
- "colors": [
- {"value": "red", "label": "Red"},
- {"value": "blue", "label": "Blue"},
- {"value": "green", "label": "Green"}
- ],
- "selectboxes": {
- "car": false,
- "boat": true
- },
- "mycontainer": {
- "checked": true,
- "animalname": "Fluffy"
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/formUtils.js b/web-client/core/themes/italia/static/formio/css/src/utils/formUtils.js
deleted file mode 100644
index c6634bbe..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/formUtils.js
+++ /dev/null
@@ -1,620 +0,0 @@
-import get from 'lodash/get';
-import set from 'lodash/set';
-import has from 'lodash/has';
-import clone from 'lodash/clone';
-import forOwn from 'lodash/forOwn';
-import isString from 'lodash/isString';
-import isNaN from 'lodash/isNaN';
-import isNil from 'lodash/isNil';
-import isPlainObject from 'lodash/isPlainObject';
-import round from 'lodash/round';
-import chunk from 'lodash/chunk';
-import pad from 'lodash/pad';
-import { compare, applyPatch } from 'fast-json-patch';
-import _ from 'lodash';
-
-/**
- * Determine if a component is a layout component or not.
- *
- * @param {Object} component
- * The component to check.
- *
- * @returns {Boolean}
- * Whether or not the component is a layout component.
- */
-export function isLayoutComponent(component) {
- return Boolean(
- (component.columns && Array.isArray(component.columns)) ||
- (component.rows && Array.isArray(component.rows)) ||
- (component.components && Array.isArray(component.components))
- );
-}
-
-/**
- * Iterate through each component within a form.
- *
- * @param {Object} components
- * The components to iterate.
- * @param {Function} fn
- * The iteration function to invoke for each component.
- * @param {Boolean} includeAll
- * Whether or not to include layout components.
- * @param {String} path
- * The current data path of the element. Example: data.user.firstName
- * @param {Object} parent
- * The parent object.
- */
-export function eachComponent(components, fn, includeAll, path, parent, inRecursion) {
- if (!components) return;
- path = path || '';
- if (inRecursion) {
- if (components.noRecurse) {
- delete components.noRecurse;
- return;
- }
- components.noRecurse = true;
- }
- components.forEach((component) => {
- if (!component) {
- return;
- }
- const hasColumns = component.columns && Array.isArray(component.columns);
- const hasRows = component.rows && Array.isArray(component.rows);
- const hasComps = component.components && Array.isArray(component.components);
- let noRecurse = false;
- const newPath = component.key ? (path ? (`${path}.${component.key}`) : component.key) : '';
-
- // Keep track of parent references.
- if (parent) {
- // Ensure we don't create infinite JSON structures.
- component.parent = clone(parent);
- delete component.parent.components;
- delete component.parent.componentMap;
- delete component.parent.columns;
- delete component.parent.rows;
- }
-
- // there's no need to add other layout components here because we expect that those would either have columns, rows or components
- const layoutTypes = ['htmlelement', 'content'];
- const isLayoutComponent = hasColumns || hasRows || (hasComps && !component.input) || layoutTypes.indexOf(component.type) > -1;
- if (includeAll || component.tree || !isLayoutComponent) {
- noRecurse = fn(component, newPath, components);
- }
-
- const subPath = () => {
- if (
- component.key &&
- !['panel', 'table', 'well', 'columns', 'fieldset', 'tabs', 'form'].includes(component.type) &&
- (
- ['datagrid', 'container', 'editgrid', 'address', 'dynamicWizard', 'datatable', 'tagpad'].includes(component.type) ||
- component.tree
- )
- ) {
- return newPath;
- }
- else if (
- component.key &&
- component.type === 'form'
- ) {
- return `${newPath}.data`;
- }
- return path;
- };
-
- if (!noRecurse) {
- if (hasColumns) {
- component.columns.forEach((column) =>
- eachComponent(column.components, fn, includeAll, subPath(), parent ? component : null), true);
- }
-
- else if (hasRows) {
- component.rows.forEach((row) => {
- if (Array.isArray(row)) {
- row.forEach((column) =>
- eachComponent(column.components, fn, includeAll, subPath(), parent ? component : null), true);
- }
- });
- }
-
- else if (hasComps) {
- eachComponent(component.components, fn, includeAll, subPath(), parent ? component : null, true);
- }
- }
- });
- if (components.noRecurse) {
- delete components.noRecurse;
- }
-}
-
-/**
- * Matches if a component matches the query.
- *
- * @param component
- * @param query
- * @return {boolean}
- */
-export function matchComponent(component, query) {
- if (isString(query)) {
- return (component.key === query) || (component.path === query);
- }
- else {
- let matches = false;
- forOwn(query, (value, key) => {
- matches = (get(component, key) === value);
- if (!matches) {
- return false;
- }
- });
- return matches;
- }
-}
-
-/**
- * Get a component by its key
- *
- * @param {Object} components
- * The components to iterate.
- * @param {String|Object} key
- * The key of the component to get, or a query of the component to search.
- *
- * @returns {Object}
- * The component that matches the given key, or undefined if not found.
- */
-export function getComponent(components, key, includeAll) {
- let result;
- eachComponent(components, (component, path) => {
- if ((path === key) || (component.path === key)) {
- result = component;
- return true;
- }
- }, includeAll);
- return result;
-}
-
-/**
- * Finds a component provided a query of properties of that component.
- *
- * @param components
- * @param query
- * @return {*}
- */
-export function searchComponents(components, query) {
- const results = [];
- eachComponent(components, (component) => {
- if (matchComponent(component, query)) {
- results.push(component);
- }
- }, true);
- return results;
-}
-
-/**
- * Deprecated version of findComponents. Renamed to searchComponents.
- *
- * @param components
- * @param query
- * @returns {*}
- */
-export function findComponents(components, query) {
- console.warn('formio.js/utils findComponents is deprecated. Use searchComponents instead.');
- return searchComponents(components, query);
-}
-
-/**
- * This function will find a component in a form and return the component AND THE PATH to the component in the form.
- * Path to the component is stored as an array of nested components and their indexes.The Path is being filled recursively
- * when you iterating through the nested structure.
- * If the component is not found the callback won't be called and function won't return anything.
- *
- * @param components
- * @param key
- * @param fn
- * @param path
- * @returns {*}
- */
-export function findComponent(components, key, path, fn) {
- if (!components) return;
- path = path || [];
-
- if (!key) {
- return fn(components);
- }
-
- components.forEach(function(component, index) {
- var newPath = path.slice();
- // Add an index of the component it iterates through in nested structure
- newPath.push(index);
- if (!component) return;
-
- if (component.hasOwnProperty('columns') && Array.isArray(component.columns)) {
- newPath.push('columns');
- component.columns.forEach(function(column, index) {
- var colPath = newPath.slice();
- colPath.push(index);
- colPath.push('components');
- findComponent(column.components, key, colPath, fn);
- });
- }
-
- if (component.hasOwnProperty('rows') && Array.isArray(component.rows)) {
- newPath.push('rows');
- component.rows.forEach(function(row, index) {
- var rowPath = newPath.slice();
- rowPath.push(index);
- row.forEach(function(column, index) {
- var colPath = rowPath.slice();
- colPath.push(index);
- colPath.push('components');
- findComponent(column.components, key, colPath, fn);
- });
- });
- }
-
- if (component.hasOwnProperty('components') && Array.isArray(component.components)) {
- newPath.push('components');
- findComponent(component.components, key, newPath, fn);
- }
-
- if (component.key === key) {
- //Final callback if the component is found
- fn(component, newPath, components);
- }
- });
-}
-
-/**
- * Remove a component by path.
- *
- * @param components
- * @param path
- */
-export function removeComponent(components, path) {
- // Using _.unset() leave a null value. Use Array splice instead.
- var index = path.pop();
- if (path.length !== 0) {
- components = get(components, path);
- }
- components.splice(index, 1);
-}
-
-export function generateFormChange(type, data) {
- let change;
- switch (type) {
- case 'add':
- change = {
- op: 'add',
- key: data.component.key,
- container: data.parent.key, // Parent component
- path: data.path, // Path to container within parent component.
- index: data.index, // Index of component in parent container.
- component: data.component
- };
- break;
- case 'edit':
- change = {
- op: 'edit',
- key: data.originalComponent.key,
- patches: compare(data.originalComponent, data.component)
- };
-
- // Don't save if nothing changed.
- if (!change.patches.length) {
- change = null;
- }
- break;
- case 'remove':
- change = {
- op: 'remove',
- key: data.component.key,
- };
- break;
- }
-
- return change;
-}
-
-export function applyFormChanges(form, changes) {
- const failed = [];
- changes.forEach(function(change) {
- var found = false;
- switch (change.op) {
- case 'add':
- var newComponent = change.component;
-
- // Find the container to set the component in.
- findComponent(form.components, change.container, null, function(parent) {
- if (!change.container) {
- parent = form;
- }
-
- // A move will first run an add so remove any existing components with matching key before inserting.
- findComponent(form.components, change.key, null, function(component, path) {
- // If found, use the existing component. (If someone else edited it, the changes would be here)
- newComponent = component;
- removeComponent(form.components, path);
- });
-
- found = true;
- var container = get(parent, change.path);
- container.splice(change.index, 0, newComponent);
- });
- break;
- case 'remove':
- findComponent(form.components, change.key, null, function(component, path) {
- found = true;
- const oldComponent = get(form.components, path);
- if (oldComponent.key !== component.key) {
- path.pop();
- }
- removeComponent(form.components, path);
- });
- break;
- case 'edit':
- findComponent(form.components, change.key, null, function(component, path) {
- found = true;
- try {
- const oldComponent = get(form.components, path);
- const newComponent = applyPatch(component, change.patches).newDocument;
-
- if (oldComponent.key !== newComponent.key) {
- path.pop();
- }
-
- set(form.components, path, newComponent);
- }
- catch (err) {
- failed.push(change);
- }
- });
- break;
- case 'move':
- break;
- }
- if (!found) {
- failed.push(change);
- }
- });
-
- return {
- form,
- failed
- };
-}
-
-/**
- * Flatten the form components for data manipulation.
- *
- * @param {Object} components
- * The components to iterate.
- * @param {Boolean} includeAll
- * Whether or not to include layout components.
- *
- * @returns {Object}
- * The flattened components map.
- */
-export function flattenComponents(components, includeAll) {
- const flattened = {};
- eachComponent(components, (component, path) => {
- flattened[path] = component;
- }, includeAll);
- return flattened;
-}
-
-/**
- * Returns if this component has a conditional statement.
- *
- * @param component - The component JSON schema.
- *
- * @returns {boolean} - TRUE - This component has a conditional, FALSE - No conditional provided.
- */
-export function hasCondition(component) {
- return Boolean(
- (component.customConditional) ||
- (component.conditional && (component.conditional.when ||
- (_.some(component.conditional.conditions || [], (condition => condition.component && condition.operator))) ||
- component.conditional.json ||
- component.conditional.condition
- ))
- );
-}
-
-/**
- * Extension of standard #parseFloat(value) function, that also clears input string.
- *
- * @param {any} value
- * The value to parse.
- *
- * @returns {Number}
- * Parsed value.
- */
-export function parseFloatExt(value) {
- return parseFloat(isString(value)
- ? value.replace(/[^\de.+-]/gi, '')
- : value);
-}
-
-/**
- * Formats provided value in way how Currency component uses it.
- *
- * @param {any} value
- * The value to format.
- *
- * @returns {String}
- * Value formatted for Currency component.
- */
-export function formatAsCurrency(value) {
- const parsedValue = parseFloatExt(value);
-
- if (isNaN(parsedValue)) {
- return '';
- }
-
- const parts = round(parsedValue, 2)
- .toString()
- .split('.');
- parts[0] = chunk(Array.from(parts[0]).reverse(), 3)
- .reverse()
- .map((part) => part
- .reverse()
- .join(''))
- .join(',');
- parts[1] = pad(parts[1], 2, '0');
- return parts.join('.');
-}
-
-/**
- * Escapes RegEx characters in provided String value.
- *
- * @param {String} value
- * String for escaping RegEx characters.
- * @returns {string}
- * String with escaped RegEx characters.
- */
-export function escapeRegExCharacters(value) {
- return value.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
-}
-
-/**
- * Get the value for a component key, in the given submission.
- *
- * @param {Object} submission
- * A submission object to search.
- * @param {String} key
- * A for components API key to search for.
- */
-export function getValue(submission, key) {
- const search = (data) => {
- if (isPlainObject(data)) {
- if (has(data, key)) {
- return _.get(data, key);
- }
-
- let value = null;
-
- forOwn(data, (prop) => {
- const result = search(prop);
- if (!isNil(result)) {
- value = result;
- return false;
- }
- });
-
- return value;
- }
- else {
- return null;
- }
- };
-
- return search(submission.data);
-}
-
-/**
- * Iterate over all components in a form and get string values for translation.
- * @param form
- */
-export function getStrings(form) {
- const properties = ['label', 'title', 'legend', 'tooltip', 'description', 'placeholder', 'prefix', 'suffix', 'errorLabel', 'content', 'html'];
- const strings = [];
- eachComponent(form.components, component => {
- properties.forEach(property => {
- if (component.hasOwnProperty(property) && component[property]) {
- strings.push({
- key: component.key,
- type: component.type,
- property,
- string: component[property]
- });
- }
- });
- if ((!component.dataSrc || component.dataSrc === 'values') && component.hasOwnProperty('values') && Array.isArray(component.values) && component.values.length) {
- component.values.forEach((value, index) => {
- strings.push({
- key: component.key,
- property: `value[${index}].label`,
- string: component.values[index].label
- });
- });
- }
-
- // Hard coded values from Day component
- if (component.type === 'day') {
- [
- 'day',
- 'month',
- 'year',
- 'Day',
- 'Month',
- 'Year',
- 'january',
- 'february',
- 'march',
- 'april',
- 'may',
- 'june',
- 'july',
- 'august',
- 'september',
- 'october',
- 'november',
- 'december'
- ].forEach(string => {
- strings.push({
- key: component.key,
- property: 'day',
- string,
- });
- });
-
- if (component.fields.day.placeholder) {
- strings.push({
- key: component.key,
- property: 'fields.day.placeholder',
- string: component.fields.day.placeholder,
- });
- }
-
- if (component.fields.month.placeholder) {
- strings.push({
- key: component.key,
- property: 'fields.month.placeholder',
- string: component.fields.month.placeholder,
- });
- }
-
- if (component.fields.year.placeholder) {
- strings.push({
- key: component.key,
- property: 'fields.year.placeholder',
- string: component.fields.year.placeholder,
- });
- }
- }
-
- if (component.type === 'editgrid') {
- const string = component.addAnother || 'Add Another';
- if (component.addAnother) {
- strings.push({
- key: component.key,
- property: 'addAnother',
- string,
- });
- }
- }
-
- if (component.type === 'select') {
- [
- 'loading...',
- 'Type to search'
- ].forEach(string => {
- strings.push({
- key: component.key,
- property: 'select',
- string,
- });
- });
- }
- }, true);
-
- return strings;
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/index.js b/web-client/core/themes/italia/static/formio/css/src/utils/index.js
deleted file mode 100644
index 0970a5fe..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import * as FormioUtils from './utils';
-if (typeof global === 'object') {
- global.FormioUtils = FormioUtils;
-}
-export default FormioUtils;
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/jsonlogic/operators.js b/web-client/core/themes/italia/static/formio/css/src/utils/jsonlogic/operators.js
deleted file mode 100644
index c3e217c0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/jsonlogic/operators.js
+++ /dev/null
@@ -1,262 +0,0 @@
-// Use only immutable useful functions from Lodash.
-// Visit https://lodash.com/docs for more info.
-export const lodashOperators = [
- // Array
- 'chunk',
- 'compact',
- 'concat',
- 'difference',
- 'differenceBy',
- 'differenceWith',
- 'drop',
- 'dropRight',
- 'dropRightWhile',
- 'dropWhile',
- 'findIndex',
- 'findLastIndex',
- 'first',
- 'flatten',
- 'flattenDeep',
- 'flattenDepth',
- 'fromPairs',
- 'head',
- 'indexOf',
- 'initial',
- 'intersection',
- 'intersectionBy',
- 'intersectionWith',
- 'join',
- 'last',
- 'lastIndexOf',
- 'nth',
- 'slice',
- 'sortedIndex',
- 'sortedIndexBy',
- 'sortedIndexOf',
- 'sortedLastIndex',
- 'sortedLastIndexBy',
- 'sortedLastIndexOf',
- 'sortedUniq',
- 'sortedUniqBy',
- 'tail',
- 'take',
- 'takeRight',
- 'takeRightWhile',
- 'takeWhile',
- 'union',
- 'unionBy',
- 'unionWith',
- 'uniq',
- 'uniqBy',
- 'uniqWith',
- 'unzip',
- 'unzipWith',
- 'without',
- 'xor',
- 'xorBy',
- 'xorWith',
- 'zip',
- 'zipObject',
- 'zipObjectDeep',
- 'zipWith',
- // Collection
- 'countBy',
- 'every',
- 'filter',
- 'find',
- 'findLast',
- 'flatMap',
- 'flatMapDeep',
- 'flatMapDepth',
- 'groupBy',
- 'includes',
- 'invokeMap',
- 'keyBy',
- 'map',
- 'orderBy',
- 'partition',
- 'reduce',
- 'reduceRight',
- 'reject',
- 'sample',
- 'sampleSize',
- 'shuffle',
- 'size',
- 'some',
- 'sortBy',
- // Date
- 'now',
- // Function
- 'flip',
- 'negate',
- 'overArgs',
- 'partial',
- 'partialRight',
- 'rearg',
- 'rest',
- 'spread',
- // Lang
- 'castArray',
- 'clone',
- 'cloneDeep',
- 'cloneDeepWith',
- 'cloneDeep',
- 'conformsTo',
- 'eq',
- 'gt',
- 'gte',
- 'isArguments',
- 'isArray',
- 'isArrayBuffer',
- 'isArrayLike',
- 'isArrayLikeObject',
- 'isBoolean',
- 'isBuffer',
- 'isDate',
- 'isElement',
- 'isEmpty',
- 'isEqual',
- 'isEqualWith',
- 'isError',
- 'isFinite',
- 'isFunction',
- 'isInteger',
- 'isLength',
- 'isMap',
- 'isMatch',
- 'isMatchWith',
- 'isNaN',
- 'isNative',
- 'isNil',
- 'isNull',
- 'isNumber',
- 'isObject',
- 'isObjectLike',
- 'isPlainObject',
- 'isRegExp',
- 'isSafeInteger',
- 'isSet',
- 'isString',
- 'isSymbol',
- 'isTypedArray',
- 'isUndefined',
- 'isWeakMap',
- 'isWeakSet',
- 'lt',
- 'lte',
- 'toArray',
- 'toFinite',
- 'toInteger',
- 'toLength',
- 'toNumber',
- 'toPlainObject',
- 'toSafeInteger',
- 'toString',
- // Math
- 'add',
- 'ceil',
- 'divide',
- 'floor',
- 'max',
- 'maxBy',
- 'mean',
- 'meanBy',
- 'min',
- 'minBy',
- 'multiply',
- 'round',
- 'subtract',
- 'sum',
- 'sumBy',
- // Number
- 'clamp',
- 'inRange',
- 'random',
- // Object
- 'at',
- 'entries',
- 'entriesIn',
- 'findKey',
- 'findLastKey',
- 'functions',
- 'functionsIn',
- 'get',
- 'has',
- 'hasIn',
- 'invert',
- 'invertBy',
- 'invoke',
- 'keys',
- 'keysIn',
- 'mapKeys',
- 'mapValues',
- 'omit',
- 'omitBy',
- 'pick',
- 'pickBy',
- 'result',
- 'toPairs',
- 'toPairsIn',
- 'transform',
- 'values',
- 'valuesIn',
- // String
- 'camelCase',
- 'capitalize',
- 'deburr',
- 'endsWith',
- 'escape',
- 'escapeRegExp',
- 'kebabCase',
- 'lowerCase',
- 'lowerFirst',
- 'pad',
- 'padEnd',
- 'padStart',
- 'parseInt',
- 'repeat',
- 'replace',
- 'snakeCase',
- 'split',
- 'startCase',
- 'startsWith',
- 'toLower',
- 'toUpper',
- 'trim',
- 'trimEnd',
- 'trimStart',
- 'truncate',
- 'unescape',
- 'upperCase',
- 'upperFirst',
- 'words',
- // Util
- 'cond',
- 'conforms',
- 'constant',
- 'defaultTo',
- 'flow',
- 'flowRight',
- 'identity',
- 'iteratee',
- 'matches',
- 'matchesProperty',
- 'method',
- 'methodOf',
- 'nthArg',
- 'over',
- 'overEvery',
- 'overSome',
- 'property',
- 'propertyOf',
- 'range',
- 'rangeRight',
- 'stubArray',
- 'stubFalse',
- 'stubObject',
- 'stubString',
- 'stubTrue',
- 'times',
- 'toPath',
- 'uniqueId',
-];
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/jsonlogic/operators.spec.js b/web-client/core/themes/italia/static/formio/css/src/utils/jsonlogic/operators.spec.js
deleted file mode 100644
index cc941354..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/jsonlogic/operators.spec.js
+++ /dev/null
@@ -1,124 +0,0 @@
-import { expect } from 'chai';
-import { jsonLogic } from '../utils';
-
-describe('Lodash operators', () => {
- describe('Arrays', () => {
-
- });
- describe('Collection', () => {
-
- });
- describe('Date', () => {
-
- });
- describe('Function', () => {
-
- });
- describe('Lang', () => {
- it('isEqual', () => {
- const logicTrue = { _isEqual: [[2, 3], [2, 3]] };
- const logicFalse = { _isEqual: [[2, 3], [2, 4]] };
- expect(jsonLogic.apply(logicTrue)).to.be.equal(true);
- expect(jsonLogic.apply(logicFalse)).to.be.equal(false);
- });
- });
- describe('Math', () => {
- it('add', () => {
- const logic = { _add: [2, 3] };
- expect(jsonLogic.apply(logic)).to.be.equal(5);
- });
- it('ceil', () => {
- const logic = { _ceil: [4.006] };
- expect(jsonLogic.apply(logic)).to.be.equal(5);
- });
- it('divide', () => {
- const logic = { _divide: [6, 3] };
- expect(jsonLogic.apply(logic)).to.be.equal(2);
- });
- it('floor', () => {
- const logic = { _floor: [4.906] };
- expect(jsonLogic.apply(logic)).to.be.equal(4);
- });
- it('max', () => {
- const logic = { _max: [[2, 5, 6, 3]] };
- expect(jsonLogic.apply(logic)).to.be.equal(6);
- });
- it('maxBy', () => {
- const data = [{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }];
- const logic1 = { _maxBy: [{ 'var': '' }, 'n'] };
- const logic2 = { _maxBy: [{ 'var': '' }, { _property: 'n' }] };
- expect(jsonLogic.apply(logic1, data)).to.be.equal(data[2]);
- expect(jsonLogic.apply(logic2, data)).to.be.equal(data[2]);
- });
- it('mean', () => {
- const logic = { _mean: [[2, 5, 6, 3]] };
- expect(jsonLogic.apply(logic)).to.be.equal(4);
- });
- it('meanBy', () => {
- const data = [{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }];
- const logic1 = { _meanBy: [{ 'var': '' }, 'n'] };
- const logic2 = { _meanBy: [{ 'var': '' }, { _property: 'n' }] };
- expect(jsonLogic.apply(logic1, data)).to.be.equal(5);
- expect(jsonLogic.apply(logic2, data)).to.be.equal(5);
- });
- it('min', () => {
- const logic = { _min: [[2, 5, 6, 3]] };
- expect(jsonLogic.apply(logic)).to.be.equal(2);
- });
- it('minBy', () => {
- const data = [{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }];
- const logic1 = { _minBy: [{ 'var': '' }, 'n'] };
- const logic2 = { _minBy: [{ 'var': '' }, { _property: 'n' }] };
- expect(jsonLogic.apply(logic1, data)).to.be.equal(data[1]);
- expect(jsonLogic.apply(logic2, data)).to.be.equal(data[1]);
- });
- it('multiply', () => {
- const logic = { _multiply: [2, 3] };
- expect(jsonLogic.apply(logic)).to.be.equal(6);
- });
- it('round', () => {
- const logic1 = { _round: [4.006] };
- const logic2 = { _round: [4.906] };
- expect(jsonLogic.apply(logic1)).to.be.equal(4);
- expect(jsonLogic.apply(logic2)).to.be.equal(5);
- });
- it('multiply', () => {
- const logic = { _multiply: [2, 3] };
- expect(jsonLogic.apply(logic)).to.be.equal(6);
- });
- it('subtract', () => {
- const logic = { _subtract: [2, 3] };
- expect(jsonLogic.apply(logic)).to.be.equal(-1);
- });
- it('sum', () => {
- const logic = { _sum: [[2, 3]] };
- expect(jsonLogic.apply(logic)).to.be.equal(5);
- });
- it('sumBy', () => {
- const data = [{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }];
- const logic1 = { _sumBy: [{ 'var': '' }, 'n'] };
- const logic2 = { _sumBy: [{ 'var': '' }, { _property: 'n' }] };
- expect(jsonLogic.apply(logic1, data)).to.be.equal(20);
- expect(jsonLogic.apply(logic2, data)).to.be.equal(20);
- });
- });
- describe('Number', () => {
-
- });
- describe('Object', () => {
-
- });
- describe('String', () => {
-
- });
- describe('Util', () => {
- it('property', () => {
- const data = [
- { 'a': { 'b': 2 } },
- { 'a': { 'b': 1 } }
- ];
- const logic = { _sumBy: [{ 'var': '' }, { _property: 'a.b' }] };
- expect(jsonLogic.apply(logic, data)).to.be.equal(3);
- });
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/utils.js b/web-client/core/themes/italia/static/formio/css/src/utils/utils.js
deleted file mode 100644
index 3a843bcb..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/utils.js
+++ /dev/null
@@ -1,1596 +0,0 @@
-/* global $ */
-
-import _ from 'lodash';
-import fetchPonyfill from 'fetch-ponyfill';
-import jsonLogic from 'json-logic-js';
-import moment from 'moment-timezone/moment-timezone';
-import jtz from 'jstimezonedetect';
-import { lodashOperators } from './jsonlogic/operators';
-import NativePromise from 'native-promise-only';
-import dompurify from 'dompurify';
-import { getValue } from './formUtils';
-import Evaluator from './Evaluator';
-import ConditionOperators from './conditionOperators';
-const interpolate = Evaluator.interpolate;
-const { fetch } = fetchPonyfill({
- Promise: NativePromise
-});
-
-export * from './formUtils';
-
-// Configure JsonLogic
-lodashOperators.forEach((name) => jsonLogic.add_operation(`_${name}`, _[name]));
-
-// Retrieve Any Date
-jsonLogic.add_operation('getDate', (date) => {
- return moment(date).toISOString();
-});
-
-// Set Relative Minimum Date
-jsonLogic.add_operation('relativeMinDate', (relativeMinDate) => {
- return moment().subtract(relativeMinDate, 'days').toISOString();
-});
-
-// Set Relative Maximum Date
-jsonLogic.add_operation('relativeMaxDate', (relativeMaxDate) => {
- return moment().add(relativeMaxDate, 'days').toISOString();
-});
-
-export { jsonLogic, moment, ConditionOperators };
-
-function setPathToComponentAndPerentSchema(component) {
- component.path = getComponentPath(component);
- const dataParent = getDataParentComponent(component);
- if (dataParent && typeof dataParent === 'object') {
- dataParent.path = getComponentPath(dataParent);
- }
-}
-
-/**
- * Evaluate a method.
- *
- * @param func
- * @param args
- * @return {*}
- */
-export function evaluate(func, args, ret, tokenize) {
- let returnVal = null;
- const component = args.component ? args.component : { key: 'unknown' };
- if (!args.form && args.instance) {
- args.form = _.get(args.instance, 'root._form', {});
- }
-
- const componentKey = component.key;
-
- if (typeof func === 'string') {
- if (ret) {
- func += `;return ${ret}`;
- }
-
- if (tokenize) {
- // Replace all {{ }} references with actual data.
- func = func.replace(/({{\s+(.*)\s+}})/, (match, $1, $2) => {
- if ($2.indexOf('data.') === 0) {
- return _.get(args.data, $2.replace('data.', ''));
- }
- else if ($2.indexOf('row.') === 0) {
- return _.get(args.row, $2.replace('row.', ''));
- }
-
- // Support legacy...
- return _.get(args.data, $2);
- });
- }
-
- try {
- func = Evaluator.evaluator(func, args);
- args = _.values(args);
- }
- catch (err) {
- console.warn(`An error occured within the custom function for ${componentKey}`, err);
- returnVal = null;
- func = false;
- }
- }
-
- if (typeof func === 'function') {
- try {
- returnVal = Evaluator.evaluate(func, args);
- }
- catch (err) {
- returnVal = null;
- console.warn(`An error occured within custom function for ${componentKey}`, err);
- }
- }
- else if (typeof func === 'object') {
- try {
- returnVal = jsonLogic.apply(func, args);
- }
- catch (err) {
- returnVal = null;
- console.warn(`An error occured within custom function for ${componentKey}`, err);
- }
- }
- else if (func) {
- console.warn(`Unknown function type for ${componentKey}`);
- }
- return returnVal;
-}
-
-export function getRandomComponentId() {
- return `e${Math.random().toString(36).substring(7)}`;
-}
-
-/**
- * Get a property value of an element.
- *
- * @param style
- * @param prop
- * @return {number}
- */
-export function getPropertyValue(style, prop) {
- let value = style.getPropertyValue(prop);
- value = value ? value.replace(/[^0-9.]/g, '') : '0';
- return parseFloat(value);
-}
-
-/**
- * Get an elements bounding rectagle.
- *
- * @param element
- * @return {{x: string, y: string, width: string, height: string}}
- */
-export function getElementRect(element) {
- const style = window.getComputedStyle(element, null);
- return {
- x: getPropertyValue(style, 'left'),
- y: getPropertyValue(style, 'top'),
- width: getPropertyValue(style, 'width'),
- height: getPropertyValue(style, 'height')
- };
-}
-
-/**
- * Determines the boolean value of a setting.
- *
- * @param value
- * @return {boolean}
- */
-export function boolValue(value) {
- if (_.isBoolean(value)) {
- return value;
- }
- else if (_.isString(value)) {
- return (value.toLowerCase() === 'true');
- }
- else {
- return !!value;
- }
-}
-
-/**
- * Check to see if an ID is a mongoID.
- * @param text
- * @return {Array|{index: number, input: string}|Boolean|*}
- */
-export function isMongoId(text) {
- return text.toString().match(/^[0-9a-fA-F]{24}$/);
-}
-
-/**
- * Checks the calculated value for a provided component and data.
- *
- * @param {Object} component
- * The component to check for the calculated value.
- * @param {Object} submission
- * A submission object.
- * @param data
- * The full submission data.
- */
-export function checkCalculated(component, submission, rowData) {
- // Process calculated value stuff if present.
- if (component.calculateValue) {
- _.set(rowData, component.key, evaluate(component.calculateValue, {
- value: undefined,
- data: submission ? submission.data : rowData,
- row: rowData,
- util: this,
- component
- }, 'value'));
- }
-}
-
-/**
- * Check if a simple conditional evaluates to true.
- *
- * @param condition
- * @param condition
- * @param row
- * @param data
- * @param instance
- * @returns {boolean}
- */
- export function checkSimpleConditional(component, condition, row, data, instance) {
- if (condition.when) {
- const value = getComponentActualValue(condition.when, data, row);
-
- const eq = String(condition.eq);
- const show = String(condition.show);
-
- // Special check for selectboxes component.
- if (_.isObject(value) && _.has(value, condition.eq)) {
- return String(value[condition.eq]) === show;
- }
- // FOR-179 - Check for multiple values.
- if (Array.isArray(value) && value.map(String).includes(eq)) {
- return show === 'true';
- }
-
- return (String(value) === eq) === (show === 'true');
- }
- else {
- const { conditions = [], conjunction = 'all', show = true } = condition;
-
- if (!conditions.length) {
- return true;
- }
-
- const conditionsResult = _.map(conditions, (cond) => {
- const { value: comparedValue, operator, component: conditionComponentPath } = cond;
- if (!conditionComponentPath) {
- return true;
- }
- const value = getComponentActualValue(conditionComponentPath, data, row);
-
- const СonditionOperator = ConditionOperators[operator];
- return СonditionOperator
- ? new СonditionOperator().getResult({ value, comparedValue, instance, component, conditionComponentPath })
- : true;
- });
-
- let result = false;
-
- switch (conjunction) {
- case 'any':
- result = _.some(conditionsResult, res => !!res);
- break;
- default:
- result = _.every(conditionsResult, res => !!res);
- }
-
- return show ? result : !result;
- }
-}
-
-export function getComponentActualValue(compPath, data, row) {
- let value = null;
-
- if (row) {
- value = getValue({ data: row }, compPath);
- }
- if (data && _.isNil(value)) {
- value = getValue({ data }, compPath);
- }
- // FOR-400 - Fix issue where falsey values were being evaluated as show=true
- if (_.isNil(value) || (_.isObject(value) && _.isEmpty(value))) {
- value = '';
- }
- return value;
-}
-
-/**
- * Check custom javascript conditional.
- *
- * @param component
- * @param custom
- * @param row
- * @param data
- * @returns {*}
- */
-export function checkCustomConditional(component, custom, row, data, form, variable, onError, instance) {
- if (typeof custom === 'string') {
- custom = `var ${variable} = true; ${custom}; return ${variable};`;
- }
- const value = (instance && instance.evaluate) ?
- instance.evaluate(custom, { row, data, form }) :
- evaluate(custom, { row, data, form });
- if (value === null) {
- return onError;
- }
- return value;
-}
-
-export function checkJsonConditional(component, json, row, data, form, onError) {
- try {
- return jsonLogic.apply(json, {
- data,
- row,
- form,
- _,
- });
- }
- catch (err) {
- console.warn(`An error occurred in jsonLogic advanced condition for ${component.key}`, err);
- return onError;
- }
-}
-
-function getRow(component, row, instance, conditional) {
- const condition = conditional || component.conditional;
- // If no component's instance passed (happens only in 6.x server), calculate its path based on the schema
- if (!instance) {
- instance = _.cloneDeep(component);
- setPathToComponentAndPerentSchema(instance);
- }
- const dataParent = getDataParentComponent(instance);
- const parentPath = dataParent ? getComponentPath(dataParent) : null;
- const isTriggerCondtionComponentPath = condition.when || !condition.conditions
- ? condition.when?.startsWith(parentPath)
- : _.some(condition.conditions, cond => cond.component.startsWith(parentPath));
-
- if (dataParent && isTriggerCondtionComponentPath) {
- const newRow = {};
- _.set(newRow, parentPath, row);
- row = newRow;
- }
-
- return row;
-}
-
-/**
- * Checks the conditions for a provided component and data.
- *
- * @param component
- * The component to check for the condition.
- * @param row
- * The data within a row
- * @param data
- * The full submission data.
- *
- * @returns {boolean}
- */
-export function checkCondition(component, row, data, form, instance) {
- const { customConditional, conditional } = component;
- if (customConditional) {
- return checkCustomConditional(component, customConditional, row, data, form, 'show', true, instance);
- }
- else if (conditional && (conditional.when || _.some(conditional.conditions || [], condition => condition.component && condition.operator))) {
- row = getRow(component, row, instance);
- return checkSimpleConditional(component, conditional, row, data, instance);
- }
- else if (conditional && conditional.json) {
- return checkJsonConditional(component, conditional.json, row, data, form, true);
- }
-
- // Default to show.
- return true;
-}
-
-/**
- * Test a trigger on a component.
- *
- * @param component
- * @param action
- * @param data
- * @param row
- * @returns {mixed}
- */
-export function checkTrigger(component, trigger, row, data, form, instance) {
- // If trigger is empty, don't fire it
- if (!trigger[trigger.type]) {
- return false;
- }
-
- switch (trigger.type) {
- case 'simple':
- row = getRow(component, row, instance, trigger.simple);
- return checkSimpleConditional(component, trigger.simple, row, data, instance);
- case 'javascript':
- return checkCustomConditional(component, trigger.javascript, row, data, form, 'result', false, instance);
- case 'json':
- return checkJsonConditional(component, trigger.json, row, data, form, false);
- }
- // If none of the types matched, don't fire the trigger.
- return false;
-}
-
-export function setActionProperty(component, action, result, row, data, instance) {
- const property = action.property.value;
-
- switch (action.property.type) {
- case 'boolean': {
- const currentValue = _.get(component, property, false).toString();
- const newValue = action.state.toString();
-
- if (currentValue !== newValue) {
- _.set(component, property, newValue === 'true');
- }
-
- break;
- }
- case 'string': {
- const evalData = {
- data,
- row,
- component,
- result,
- };
- const textValue = action.property.component ? action[action.property.component] : action.text;
- const currentValue = _.get(component, property, '');
- const newValue = (instance && instance.interpolate)
- ? instance.interpolate(textValue, evalData)
- : Evaluator.interpolate(textValue, evalData);
-
- if (newValue !== currentValue) {
- _.set(component, property, newValue);
- }
-
- break;
- }
- }
-
- return component;
-}
-
-/**
- * Unescape HTML characters like <, >, & and etc.
- * @param str
- * @returns {string}
- */
-export function unescapeHTML(str) {
- if (typeof window === 'undefined' || !('DOMParser' in window)) {
- return str;
- }
-
- const doc = new window.DOMParser().parseFromString(str, 'text/html');
- return doc.documentElement.textContent;
-}
-
-/**
- * Make HTML element from string
- * @param str
- * @param selector
- * @returns {HTMLElement}
- */
-
-export function convertStringToHTMLElement(str, selector) {
- const doc = new window.DOMParser().parseFromString(str, 'text/html');
- return doc.body.querySelector(selector);
-}
-
-/**
- * Make a filename guaranteed to be unique.
- * @param name
- * @param template
- * @param evalContext
- * @returns {string}
- */
-export function uniqueName(name, template, evalContext) {
- template = template || '{{fileName}}-{{guid}}';
- //include guid in template anyway, to prevent overwriting issue if filename matches existing file
- if (!template.includes('{{guid}}')) {
- template = `${template}-{{guid}}`;
- }
- const parts = name.split('.');
- let fileName = parts.slice(0, parts.length - 1).join('.');
- const extension = parts.length > 1
- ? `.${_.last(parts)}`
- : '';
- //allow only 100 characters from original name to avoid issues with filename length restrictions
- fileName = fileName.substr(0, 100);
- evalContext = Object.assign(evalContext || {}, {
- fileName,
- guid: guid()
- });
- //only letters, numbers, dots, dashes, underscores and spaces are allowed. Anything else will be replaced with dash
- const uniqueName = `${Evaluator.interpolate(template, evalContext)}${extension}`.replace(/[^0-9a-zA-Z.\-_ ]/g, '-');
- return uniqueName;
-}
-
-export function guid() {
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
- const r = Math.random()*16|0;
- const v = c === 'x'
- ? r
- : (r&0x3|0x8);
- return v.toString(16);
- });
-}
-
-/**
- * Return a translated date setting.
- *
- * @param date
- * @return {(null|Date)}
- */
-export function getDateSetting(date) {
- if (_.isNil(date) || _.isNaN(date) || date === '') {
- return null;
- }
-
- if (date instanceof Date) {
- return date;
- }
- else if (typeof date.toDate === 'function') {
- return date.isValid() ? date.toDate() : null;
- }
-
- let dateSetting = ((typeof date !== 'string') || (date.indexOf('moment(') === -1)) ? moment(date) : null;
- if (dateSetting && dateSetting.isValid()) {
- return dateSetting.toDate();
- }
-
- dateSetting = null;
- try {
- const value = Evaluator.evaluator(`return ${date};`, 'moment')(moment);
- if (typeof value === 'string') {
- dateSetting = moment(value);
- }
- else if (typeof value.toDate === 'function') {
- dateSetting = moment(value.toDate().toUTCString());
- }
- else if (value instanceof Date) {
- dateSetting = moment(value);
- }
- }
- catch (e) {
- return null;
- }
-
- if (!dateSetting) {
- return null;
- }
-
- // Ensure this is a date.
- if (!dateSetting.isValid()) {
- return null;
- }
-
- return dateSetting.toDate();
-}
-
-export function isValidDate(date) {
- return _.isDate(date) && !_.isNaN(date.getDate());
-}
-
-/**
- * Get the current timezone string.
- *
- * @return {string}
- */
-export function currentTimezone() {
- if (moment.currentTimezone) {
- return moment.currentTimezone;
- }
- moment.currentTimezone = jtz.determine().name();
- return moment.currentTimezone;
-}
-
-/**
- * Get an offset date provided a date object and timezone object.
- *
- * @param date
- * @param timezone
- * @return {Date}
- */
-export function offsetDate(date, timezone) {
- if (timezone === 'UTC') {
- return {
- date: new Date(date.getTime() + (date.getTimezoneOffset() * 60000)),
- abbr: 'UTC'
- };
- }
- const dateMoment = moment(date).tz(timezone);
- return {
- date: new Date(date.getTime() + ((dateMoment.utcOffset() + date.getTimezoneOffset()) * 60000)),
- abbr: dateMoment.format('z')
- };
-}
-
-/**
- * Returns if the zones are loaded.
- *
- * @return {boolean}
- */
-export function zonesLoaded() {
- return moment.zonesLoaded;
-}
-
-/**
- * Returns if we should load the zones.
- *
- * @param timezone
- * @return {boolean}
- */
-export function shouldLoadZones(timezone) {
- if (timezone === currentTimezone() || timezone === 'UTC') {
- return false;
- }
- return true;
-}
-
-/**
- * Externally load the timezone data.
- *
- * @return {Promise | *}
- */
-export function loadZones(url, timezone) {
- if (timezone && !shouldLoadZones(timezone)) {
- // Return non-resolving promise.
- return new NativePromise(_.noop);
- }
-
- if (moment.zonesPromise) {
- return moment.zonesPromise;
- }
- return moment.zonesPromise = fetch(url)
- .then(resp => resp.json().then(zones => {
- moment.tz.load(zones);
- moment.zonesLoaded = true;
-
- // Trigger a global event that the timezones have finished loading.
- if (document && document.createEvent && document.body && document.body.dispatchEvent) {
- var event = document.createEvent('Event');
- event.initEvent('zonesLoaded', true, true);
- document.body.dispatchEvent(event);
- }
- }));
-}
-
-/**
- * Get the moment date object for translating dates with timezones.
- *
- * @param value
- * @param format
- * @param timezone
- * @return {*}
- */
-export function momentDate(value, format, timezone) {
- const momentDate = moment(value);
- if (!timezone) {
- return momentDate;
- }
- if (timezone === 'UTC') {
- timezone = 'Etc/UTC';
- }
- if ((timezone !== currentTimezone() || (format && format.match(/\s(z$|z\s)/))) && moment.zonesLoaded) {
- return momentDate.tz(timezone);
- }
- return momentDate;
-}
-
-/**
- * Format a date provided a value, format, and timezone object.
- *
- * @param value
- * @param format
- * @param timezone
- * @return {string}
- */
-export function formatDate(timezonesUrl, value, format, timezone, flatPickrInputFormat) {
- const momentDate = moment(value, flatPickrInputFormat || undefined);
- if (timezone === currentTimezone()) {
- // See if our format contains a "z" timezone character.
- if (format.match(/\s(z$|z\s)/)) {
- loadZones(timezonesUrl);
- if (moment.zonesLoaded) {
- return momentDate.tz(timezone).format(convertFormatToMoment(format));
- }
- else {
- return momentDate.format(convertFormatToMoment(format.replace(/\s(z$|z\s)/, '')));
- }
- }
-
- // Return the standard format.
- return momentDate.format(convertFormatToMoment(format));
- }
- if (timezone === 'UTC') {
- const offset = offsetDate(momentDate.toDate(), 'UTC');
- return `${moment(offset.date).format(convertFormatToMoment(format))} UTC`;
- }
-
- // Load the zones since we need timezone information.
- loadZones(timezonesUrl);
- if (moment.zonesLoaded && timezone) {
- return momentDate.tz(timezone).format(`${convertFormatToMoment(format)} z`);
- }
- else {
- return momentDate.format(convertFormatToMoment(format));
- }
-}
-
-/**
- * Pass a format function to format within a timezone.
- *
- * @param formatFn
- * @param date
- * @param format
- * @param timezone
- * @return {string}
- */
-export function formatOffset(timezonesUrl, formatFn, date, format, timezone) {
- if (timezone === currentTimezone()) {
- return formatFn(date, format);
- }
- if (timezone === 'UTC') {
- return `${formatFn(offsetDate(date, 'UTC').date, format)} UTC`;
- }
-
- // Load the zones since we need timezone information.
- loadZones(timezonesUrl);
- if (moment.zonesLoaded) {
- const offset = offsetDate(date, timezone);
- return `${formatFn(offset.date, format)} ${offset.abbr}`;
- }
- else {
- return formatFn(date, format);
- }
-}
-
-export function getLocaleDateFormatInfo(locale) {
- const formatInfo = {};
-
- const day = 21;
- const exampleDate = new Date(2017, 11, day);
- const localDateString = exampleDate.toLocaleDateString(locale);
-
- formatInfo.dayFirst = localDateString.slice(0, 2) === day.toString();
-
- return formatInfo;
-}
-
-/**
- * Convert the format from the angular-datepicker module to flatpickr format.
- * @param format
- * @return {string}
- */
-export function convertFormatToFlatpickr(format) {
- return format
- // Remove the Z timezone offset, not supported by flatpickr.
- .replace(/Z/g, '')
-
- // Year conversion.
- .replace(/y/g, 'Y')
- .replace('YYYY', 'Y')
- .replace('YY', 'y')
-
- // Month conversion.
- .replace('MMMM', 'F')
- .replace(/M/g, 'n')
- .replace('nnn', 'M')
- .replace('nn', 'm')
-
- // Day in month.
- .replace(/d/g, 'j')
- .replace(/jj/g, 'd')
-
- // Day in week.
- .replace('EEEE', 'l')
- .replace('EEE', 'D')
-
- // Hours, minutes, seconds
- .replace('HH', 'H')
- .replace('hh', 'G')
- .replace('mm', 'i')
- .replace('ss', 'S')
- .replace(/a/g, 'K');
-}
-
-/**
- * Convert the format from the angular-datepicker module to moment format.
- * @param format
- * @return {string}
- */
-export function convertFormatToMoment(format) {
- return format
- // Year conversion.
- .replace(/y/g, 'Y')
- // Day in month.
- .replace(/d/g, 'D')
- // Day in week.
- .replace(/E/g, 'd')
- // AM/PM marker
- .replace(/a/g, 'A')
- // Unix Timestamp
- .replace(/U/g, 'X');
-}
-
-export function convertFormatToMask(format) {
- return format
- // Long month replacement.
- .replace(/M{4}/g, 'MM')
- // Initial short month conversion.
- .replace(/M{3}/g, '***')
- // Short month conversion if input as text.
- .replace(/e/g, 'Q')
- // Year conversion.
- .replace(/[ydhmsHMG]/g, '9')
- // AM/PM conversion.
- .replace(/a/g, 'AA');
-}
-
-/**
- * Returns an input mask that is compatible with the input mask library.
- * @param {string} mask - The Form.io input mask.
- * @param {string} placeholderChar - Char which is used as a placeholder.
- * @returns {Array} - The input mask for the mask library.
- */
-export function getInputMask(mask, placeholderChar) {
- if (mask instanceof Array) {
- return mask;
- }
- const maskArray = [];
- maskArray.numeric = true;
- for (let i = 0; i < mask.length; i++) {
- switch (mask[i]) {
- case '9':
- maskArray.push(/\d/);
- break;
- case 'A':
- maskArray.numeric = false;
- maskArray.push(/[a-zA-Z]/);
- break;
- case 'a':
- maskArray.numeric = false;
- maskArray.push(/[a-z]/);
- break;
- case '*':
- maskArray.numeric = false;
- maskArray.push(/[a-zA-Z0-9]/);
- break;
- // If char which is used inside mask placeholder was used in the mask, replace it with space to prevent errors
- case placeholderChar:
- maskArray.numeric = false;
- maskArray.push(' ');
- break;
- default:
- maskArray.numeric = false;
- maskArray.push(mask[i]);
- break;
- }
- }
- return maskArray;
-}
-
-export function unmaskValue(value, mask, placeholderChar) {
- if (!mask || !value || value.length > mask.length) {
- return value;
- }
-
- let unmaskedValue = value.split('');
-
- for (let i = 0; i < mask.length; i++) {
- const char = value[i] || '';
- const charPart = mask[i];
-
- if (!_.isRegExp(charPart) && char === charPart) {
- unmaskedValue[i] = '';
- }
- }
-
- unmaskedValue = unmaskedValue.join('').replace(placeholderChar, '');
-
- return unmaskedValue;
-}
-
-export function matchInputMask(value, inputMask) {
- if (!inputMask) {
- return true;
- }
-
- // If value is longer than mask, it isn't valid.
- if (value.length > inputMask.length) {
- return false;
- }
-
- for (let i = 0; i < inputMask.length; i++) {
- const char = value[i] || '';
- const charPart = inputMask[i];
-
- if (!(_.isRegExp(charPart) && charPart.test(char) || charPart === char)) {
- return false;
- }
- }
-
- return true;
-}
-
-export function getNumberSeparators(lang = 'en') {
- const formattedNumberString = (12345.6789).toLocaleString(lang);
- const delimeters = formattedNumberString.match(/..(.)...(.)../);
- if (!delimeters) {
- return {
- delimiter: ',',
- decimalSeparator: '.'
- };
- }
- return {
- delimiter: (delimeters.length > 1) ? delimeters[1] : ',',
- decimalSeparator: (delimeters.length > 2) ? delimeters[2] : '.',
- };
-}
-
-export function getNumberDecimalLimit(component, defaultLimit) {
- if (_.has(component, 'decimalLimit')) {
- return _.get(component, 'decimalLimit');
- }
- // Determine the decimal limit. Defaults to 20 but can be overridden by validate.step or decimalLimit settings.
- let decimalLimit = defaultLimit || 20;
- const step = _.get(component, 'validate.step', 'any');
-
- if (step !== 'any') {
- const parts = step.toString().split('.');
- if (parts.length > 1) {
- decimalLimit = parts[1].length;
- }
- }
-
- return decimalLimit;
-}
-
-export function getCurrencyAffixes({
- currency = 'USD',
- decimalLimit,
- decimalSeparator,
- lang,
- }) {
- // Get the prefix and suffix from the localized string.
- let regex = `(.*)?${(100).toLocaleString(lang)}`;
- if (decimalLimit) {
- regex += `${decimalSeparator === '.' ? '\\.' : decimalSeparator}${(0).toLocaleString(lang)}{${decimalLimit}}`;
- }
- regex += '(.*)?';
- const parts = (100).toLocaleString(lang, {
- style: 'currency',
- currency,
- useGrouping: true,
- maximumFractionDigits: decimalLimit || 0,
- minimumFractionDigits: decimalLimit || 0
- }).replace('.', decimalSeparator).match(new RegExp(regex));
- return {
- prefix: parts?.[1] || '',
- suffix: parts?.[2] || ''
- };
-}
-
-/**
- * Fetch the field data provided a component.
- *
- * @param data
- * @param component
- * @return {*}
- */
-export function fieldData(data, component) {
- if (!data) {
- return '';
- }
- if (!component || !component.key) {
- return data;
- }
- if (component.key.includes('.')) {
- let value = data;
- const parts = component.key.split('.');
- let key = '';
- for (let i = 0; i < parts.length; i++) {
- key = parts[i];
-
- // Handle nested resources
- if (value.hasOwnProperty('_id')) {
- value = value.data;
- }
-
- // Return if the key is not found on the value.
- if (!value.hasOwnProperty(key)) {
- return;
- }
-
- // Convert old single field data in submissions to multiple
- if (key === parts[parts.length - 1] && component.multiple && !Array.isArray(value[key])) {
- value[key] = [value[key]];
- }
-
- // Set the value of this key.
- value = value[key];
- }
- return value;
- }
- else {
- // Convert old single field data in submissions to multiple
- if (component.multiple && !Array.isArray(data[component.key])) {
- data[component.key] = [data[component.key]];
- }
-
- // Fix for checkbox type radio submission values in tableView
- if (component.type === 'checkbox' && component.inputType === 'radio') {
- return data[component.name] === component.value;
- }
-
- return data[component.key];
- }
-}
-
-/**
- * Delays function execution with possibility to execute function synchronously or cancel it.
- *
- * @param fn Function to delay
- * @param delay Delay time
- * @return {*}
- */
-export function delay(fn, delay = 0, ...args) {
- const timer = setTimeout(fn, delay, ...args);
-
- function cancel() {
- clearTimeout(timer);
- }
-
- function earlyCall() {
- cancel();
- return fn(...args);
- }
-
- earlyCall.timer = timer;
- earlyCall.cancel = cancel;
-
- return earlyCall;
-}
-
-/**
- * Iterate the given key to make it unique.
- *
- * @param {String} key
- * Modify the component key to be unique.
- *
- * @returns {String}
- * The new component key.
- */
-export function iterateKey(key) {
- if (!key.match(/(\d+)$/)) {
- return `${key}1`;
- }
-
- return key.replace(/(\d+)$/, function(suffix) {
- return Number(suffix) + 1;
- });
-}
-
-/**
- * Determines a unique key within a map provided the base key.
- *
- * @param map
- * @param base
- * @return {*}
- */
-export function uniqueKey(map, base) {
- let newKey = base;
- while (map.hasOwnProperty(newKey)) {
- newKey = iterateKey(newKey);
- }
- return newKey;
-}
-
-/**
- * Determines the major version number of bootstrap.
- *
- * @return {number}
- */
-export function bootstrapVersion(options) {
- if (options.bootstrap) {
- return options.bootstrap;
- }
- if ((typeof $ === 'function') && (typeof $().collapse === 'function')) {
- return parseInt($.fn.collapse.Constructor.VERSION.split('.')[0], 10);
- }
- return 0;
-}
-
-/**
- * Retrun provided argument.
- * If argument is a function, returns the result of a function call.
- * @param {*} e;
- *
- * @return {*}
- */
-export function unfold(e) {
- if (typeof e === 'function') {
- return e();
- }
-
- return e;
-}
-
-/**
- * Map values through unfold and return first non-nil value.
- * @param {Array} collection;
- *
- * @return {T}
- */
-export const firstNonNil = _.flow([
- _.partialRight(_.map, unfold),
- _.partialRight(_.find, v => !_.isUndefined(v))
-]);
-
-/*
- * Create enclosed state.
- * Returns functions to getting and cycling between states.
- * @param {*} a - initial state.
- * @param {*} b - next state.
- * @return {Functions[]} -- [get, toggle];
- */
-export function withSwitch(a, b) {
- let state = a;
- let next = b;
-
- function get() {
- return state;
- }
-
- function toggle() {
- const prev = state;
- state = next;
- next = prev;
- }
-
- return [get, toggle];
-}
-
-export function observeOverload(callback, options = {}) {
- const { limit = 50, delay = 500 } = options;
- let callCount = 0;
- let timeoutID = 0;
-
- const reset = () => callCount = 0;
-
- return () => {
- if (timeoutID !== 0) {
- clearTimeout(timeoutID);
- timeoutID = 0;
- }
-
- timeoutID = setTimeout(reset, delay);
-
- callCount += 1;
-
- if (callCount >= limit) {
- clearTimeout(timeoutID);
- reset();
- return callback();
- }
- };
-}
-
-export function getContextComponents(context, excludeNested, excludedTypes = []) {
- const values = [];
-
- context.utils.eachComponent(context.instance.options.editForm.components, (component, path) => {
- const addToContextComponents = excludeNested ? !component.tree : true;
- if (component.key !== context.data.key && addToContextComponents && !_.includes(excludedTypes, component.type)) {
- values.push({
- label: `${component.label || component.key} (${path})`,
- value: path,
- });
- }
- });
-
- return values;
-}
-
-export function getContextButtons(context) {
- const values = [];
-
- context.utils.eachComponent(context.instance.options.editForm.components, (component) => {
- if (component.type === 'button') {
- values.push({
- label: `${component.key} (${component.label})`,
- value: component.key,
- });
- }
- });
-
- return values;
-}
-
-// Tags that could be in text, that should be ommited or handled in a special way
-const inTextTags = ['#text', 'A', 'B', 'EM', 'I', 'SMALL', 'STRONG', 'SUB', 'SUP', 'INS', 'DEL', 'MARK', 'CODE'];
-
-/**
- * Helper function for 'translateHTMLTemplate'. Translates text value of the passed html element.
- *
- * @param {HTMLElement} elem
- * @param {Function} translate
- *
- * @returns {String}
- * Translated element template.
- */
-function translateElemValue(elem, translate) {
- if (!elem.innerText) {
- return elem.innerHTML;
- }
-
- const elemValue = elem.innerText.replace(Evaluator.templateSettings.interpolate, '').replace(/\s\s+/g, ' ').trim();
- const translatedValue = translate(elemValue);
-
- if (elemValue !== translatedValue) {
- const links = elem.innerHTML.match(/]*>(.*?)<\/a>/g);
-
- if (links && links.length) {
- if (links.length === 1 && links[0].length === elem.innerHTML.length) {
- return elem.innerHTML.replace(elemValue, translatedValue);
- }
-
- const translatedLinks = links.map(link => {
- const linkElem = document.createElement('a');
- linkElem.innerHTML = link;
- return translateElemValue(linkElem, translate);
- });
-
- return `${translatedValue} (${translatedLinks.join(', ')})`;
- }
- else {
- return elem.innerText.replace(elemValue, translatedValue);
- }
- }
- else {
- return elem.innerHTML;
- }
-}
-
-/**
- * Helper function for 'translateHTMLTemplate'. Goes deep through html tag children and calls function to translate their text values.
- *
- * @param {HTMLElement} tag
- * @param {Function} translate
- *
- * @returns {void}
- */
-function translateDeepTag(tag, translate) {
- const children = tag.children.length && [...tag.children];
- const shouldTranslateEntireContent = children && children.every(child =>
- child.children.length === 0
- && inTextTags.some(tag => child.nodeName === tag)
- );
-
- if (!children || shouldTranslateEntireContent) {
- tag.innerHTML = translateElemValue(tag, translate);
- }
- else {
- children.forEach(child => translateDeepTag(child, translate));
- }
-}
-
-/**
- * Translates text values in html template.
- *
- * @param {String} template
- * @param {Function} translate
- *
- * @returns {String}
- * Html template with translated values.
- */
-export function translateHTMLTemplate(template, translate) {
- const isHTML = /<[^>]*>/.test(template);
-
- if (!isHTML) {
- return translate(template);
- }
-
- const tempElem = document.createElement('div');
- tempElem.innerHTML = template;
-
- if (tempElem.innerText && tempElem.children.length) {
- translateDeepTag(tempElem, translate);
- return tempElem.innerHTML;
- }
-
- return template;
-}
-
-/**
- * Sanitize an html string.
- *
- * @param string
- * @returns {*}
- */
-export function sanitize(string, options) {
- if (typeof dompurify.sanitize !== 'function') {
- return string;
- }
- // Dompurify configuration
- const sanitizeOptions = {
- ADD_ATTR: ['ref', 'target'],
- USE_PROFILES: { html: true }
- };
- // Add attrs
- if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addAttr) && options.sanitizeConfig.addAttr.length > 0) {
- options.sanitizeConfig.addAttr.forEach((attr) => {
- sanitizeOptions.ADD_ATTR.push(attr);
- });
- }
- // Add tags
- if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addTags) && options.sanitizeConfig.addTags.length > 0) {
- sanitizeOptions.ADD_TAGS = options.sanitizeConfig.addTags;
- }
- // Allow tags
- if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.allowedTags) && options.sanitizeConfig.allowedTags.length > 0) {
- sanitizeOptions.ALLOWED_TAGS = options.sanitizeConfig.allowedTags;
- }
- // Allow attributes
- if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.allowedAttrs) && options.sanitizeConfig.allowedAttrs.length > 0) {
- sanitizeOptions.ALLOWED_ATTR = options.sanitizeConfig.allowedAttrs;
- }
- // Allowd URI Regex
- if (options.sanitizeConfig && options.sanitizeConfig.allowedUriRegex) {
- sanitizeOptions.ALLOWED_URI_REGEXP = options.sanitizeConfig.allowedUriRegex;
- }
- // Allow to extend the existing array of elements that are safe for URI-like values
- if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addUriSafeAttr) && options.sanitizeConfig.addUriSafeAttr.length > 0) {
- sanitizeOptions.ADD_URI_SAFE_ATTR = options.sanitizeConfig.addUriSafeAttr;
- }
- return dompurify.sanitize(string, sanitizeOptions);
-}
-
-/**
- * Fast cloneDeep for JSON objects only.
- */
-export function fastCloneDeep(obj) {
- return obj ? JSON.parse(JSON.stringify(obj)) : obj;
-}
-
-export { Evaluator, interpolate };
-
-export function isInputComponent(componentJson) {
- if (componentJson.input === false || componentJson.input === true) {
- return componentJson.input;
- }
- switch (componentJson.type) {
- case 'htmlelement':
- case 'content':
- case 'columns':
- case 'fieldset':
- case 'panel':
- case 'table':
- case 'tabs':
- case 'well':
- case 'button':
- return false;
- default:
- return true;
- }
-}
-
-export function getArrayFromComponentPath(pathStr) {
- if (!pathStr || !_.isString(pathStr)) {
- if (!_.isArray(pathStr)) {
- return [pathStr];
- }
- return pathStr;
- }
- return pathStr.replace(/[[\]]/g, '.')
- .replace(/\.\./g, '.')
- .replace(/(^\.)|(\.$)/g, '')
- .split('.')
- .map(part => _.defaultTo(_.toNumber(part), part));
-}
-
-export function hasInvalidComponent(component) {
- return component.getComponents().some((comp) => {
- if (_.isArray(comp.components)) {
- return hasInvalidComponent(comp);
- }
- return comp.error;
- });
-}
-
-export function getStringFromComponentPath(path) {
- if (!_.isArray(path)) {
- return path;
- }
- let strPath = '';
- path.forEach((part, i) => {
- if (_.isNumber(part)) {
- strPath += `[${part}]`;
- }
- else {
- strPath += i === 0 ? part : `.${part}`;
- }
- });
- return strPath;
-}
-
-export function round(number, precision) {
- if (_.isNumber(number)) {
- return number.toFixed(precision);
- }
- return number;
-}
-
-/**
- * Check for Internet Explorer browser version
- *
- * @return {(number|null)}
- */
-export function getIEBrowserVersion() {
- const { ie, version } = getBrowserInfo();
-
- return ie ? version : null;
-}
-
-/**
- * Get browser name and version (modified from 'jquery-browser-plugin')
- *
- * @return {Object} -- {{browser name, version, isWebkit?}}
- * Possible browser names: chrome, safari, ie, edge, opera, mozilla, yabrowser
- */
-export function getBrowserInfo() {
- const browser = {};
-
- if (typeof window === 'undefined') {
- return browser;
- }
-
- const ua = window.navigator.userAgent.toLowerCase();
- const match = /(edge|edg)\/([\w.]+)/.exec(ua) ||
- /(opr)[/]([\w.]+)/.exec(ua) ||
- /(yabrowser)[ /]([\w.]+)/.exec(ua) ||
- /(chrome)[ /]([\w.]+)/.exec(ua) ||
- /(iemobile)[/]([\w.]+)/.exec(ua) ||
- /(version)(applewebkit)[ /]([\w.]+).*(safari)[ /]([\w.]+)/.exec(ua) ||
- /(webkit)[ /]([\w.]+).*(version)[ /]([\w.]+).*(safari)[ /]([\w.]+)/.exec(ua) ||
- /(webkit)[ /]([\w.]+)/.exec(ua) ||
- /(opera)(?:.*version|)[ /]([\w.]+)/.exec(ua) ||
- /(msie) ([\w.]+)/.exec(ua) ||
- ua.indexOf('trident') >= 0 && /(rv)(?::| )([\w.]+)/.exec(ua) ||
- ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
- [];
- const matched = {
- browser: match[5] || match[3] || match[1] || '',
- version: match[4] || match[2] || '0'
- };
-
- if (matched.browser) {
- browser[matched.browser] = true;
- browser.version = parseInt(matched.version, 10);
- }
- // Chrome, Opera 15+, Safari and Yandex.Browser are webkit based browsers
- if (browser.chrome || browser.opr || browser.safari || browser.edg || browser.yabrowser) {
- browser.isWebkit = true;
- }
- // IE11 has a new token so we will assign it ie to avoid breaking changes
- if (browser.rv || browser.iemobile) {
- browser.ie = true;
- }
- // Edge has a new token since it became webkit based
- if (browser.edg) {
- browser.edge = true;
- }
- // Opera 15+ are identified as opr
- if (browser.opr) {
- browser.opera = true;
- }
-
- return browser;
-}
-
-export function getComponentPathWithoutIndicies(path = '') {
- return path.replace(/\[\d+\]/, '');
-}
-
-/**
- * Returns a path to the component which based on its schema
- * @param {*} component is a component's schema containing link to its parent's schema in the 'parent' property
- */
-export function getComponentPath(component, path = '') {
- if (!component || !component.key || component?._form?.display === 'wizard') { // unlike the Webform, the Wizard has the key and it is a duplicate of the panel key
- return path;
- }
- path = component.isInputComponent || component.input === true ? `${component.key}${path ? '.' : ''}${path}` : path;
- return getComponentPath(component.parent, path);
-}
-
-/**
- * Returns a parent component of the passed component instance skipping all the Layout components
- * @param {*} componentInstance
- * @return {(Component|undefined)}
- */
-export function getDataParentComponent(componentInstance) {
- if (!componentInstance) {
- return;
- }
- const { parent } = componentInstance;
- if (parent && (parent.isInputComponent || parent.input)) {
- return parent;
- }
- else {
- return getDataParentComponent(parent);
- }
-}
-
-/**
- * Returns whether the value is a promise
- * @param value
- * @return {boolean}
- */
- export function isPromise(value) {
- return value
- && value.then
- && typeof value.then === 'function'
- && Object.prototype.toString.call(value) === '[object Promise]';
- }
-
-/**
- * Determines if the component has a scoping parent in tree (a component which scopes its children and manages its
- * changes by itself, e.g. EditGrid)
- * @param componentInstance
- * @param firstPass
- * @returns {boolean|boolean|*}
- */
-export function isInsideScopingComponent(componentInstance, firstPass = true) {
- if (!firstPass && componentInstance?.hasScopedChildren) {
- return true;
- }
- const dataParent = getDataParentComponent(componentInstance);
- if (dataParent?.hasScopedChildren) {
- return true;
- }
- else if (dataParent?.parent) {
- return isInsideScopingComponent(dataParent.parent, false);
- }
- return false;
-}
-
-export function getFocusableElements(element) {
- const focusableSelector =
- `button:not([disabled]), input:not([disabled]), select:not([disabled]),
- textarea:not([disabled]), button:not([disabled]), [href]`;
- return element.querySelectorAll(focusableSelector);
-}
-
-// Export lodash to save space with other libraries.
-export { _ };
-
-export const componentValueTypes = {
- number: 'number',
- string: 'string',
- boolean: 'boolean',
- array: 'array',
- object: 'object',
- date: 'date',
- any: 'any',
-};
-
-export function getComponentSavedTypes(fullSchema) {
- const schema = fullSchema || {};
-
- if (schema.persistent !== true) {
- return [];
- }
-
- if (schema.multiple) {
- return [componentValueTypes.array];
- }
-
- return null;
-}
-
-export function getItemTemplateKeys(template) {
- const templateKeys = [];
- if (!template) {
- return templateKeys;
- }
- const keys = template.match(/({{\s*(.*?)\s*}})/g);
-
- if (keys) {
- keys.forEach((key) => {
- const propKey = key.match(/{{\s*item\.(.*?)\s*}}/);
- if (propKey && propKey.length > 1) {
- templateKeys.push(propKey[1]);
- }
- });
- }
-
- return templateKeys;
-}
-
-export function isSelectResourceWithObjectValue(comp = {}) {
- const { reference, dataSrc, valueProperty } = comp;
- return reference || (dataSrc === 'resource' && (!valueProperty || valueProperty === 'data'));
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/utils/utils.unit.js b/web-client/core/themes/italia/static/formio/css/src/utils/utils.unit.js
deleted file mode 100644
index 81dfacc5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/utils/utils.unit.js
+++ /dev/null
@@ -1,874 +0,0 @@
-/* eslint-disable no-irregular-whitespace */
-import * as fs from 'fs';
-import { expect, assert } from 'chai';
-import _ from 'lodash';
-import writtenNumber from 'written-number';
-import utils from '.';
-const components = JSON.parse(fs.readFileSync('src/utils/fixtures/components.json'));
-const components2 = JSON.parse(fs.readFileSync('src/utils/fixtures/components2.json'));
-const components3 = JSON.parse(fs.readFileSync('src/utils/fixtures/components3.json'));
-const components4 = JSON.parse(fs.readFileSync('src/utils/fixtures/components4.json'));
-const components5 = JSON.parse(fs.readFileSync('src/utils/fixtures/components5.json'));
-const submission1 = JSON.parse(fs.readFileSync('src/utils/fixtures/submission1.json'));
-
-describe('Util Tests', () => {
- describe('eachComponent', () => {
- it('should iterate through nested components in the right order', () => {
- let n = 1;
- utils.eachComponent(components, (component) => {
- expect(component.order).to.equal(n);
- n += 1;
- });
- });
-
- it('should include layouts components if provided', () => {
- let numComps = 0;
- let numLayout = 0;
- utils.eachComponent(components, (component) => {
- if (utils.isLayoutComponent(component)) {
- numLayout++;
- }
- else {
- numComps++;
- }
- }, true);
- expect(numLayout).to.be.equal(3);
- expect(numComps).to.be.equal(8);
- });
-
- it('Should provide the paths to all of the components', () => {
- const paths = [
- 'one',
- 'parent1',
- 'two',
- 'parent2',
- 'three',
- '',
- 'four',
- 'five',
- 'six',
- 'seven',
- 'eight'
- ];
- const testPaths = [];
- utils.eachComponent(components, (component, path) => {
- testPaths.push(path);
- }, true);
- expect(paths).to.deep.equal(testPaths);
- });
-
- describe('findComponent', () => {
- it('should find correct component in nested structure', () => {
- utils.findComponent(components4, 'four', null, (component) => {
- expect(component.label).to.equal('4');
- });
- });
- it('should find correct component in flat structure', () => {
- utils.findComponent(components4, 'one', null, (component) => {
- expect(component.label).to.equal('1');
- });
- });
- });
-
- it('Should be able to find all textfield components', () => {
- const comps = utils.findComponents(components, { type: 'textfield' });
- expect(comps.length).to.equal(6);
- });
-
- it('Should be able to find components with special properties.', () => {
- const comps = utils.findComponents(components3, { 'properties.path': 'a' });
- expect(comps.length).to.equal(4);
- expect(comps[0].key).to.equal('b');
- expect(comps[1].key).to.equal('e');
- expect(comps[2].key).to.equal('j');
- expect(comps[3].key).to.equal('m');
- });
-
- it('Should be able to generate paths based on component types', () => {
- const paths = [
- 'a',
- 'b',
- 'c',
- 'd',
- 'f',
- 'f.g',
- 'f.h',
- 'f.i',
- 'e',
- 'j',
- 'k',
- 'k.n',
- 'k.n.o',
- 'k.n.p',
- 'k.n.q',
- 'k.m',
- 'k.l',
- 'r',
- 'submit',
- 'tagpad',
- 'tagpad.a',
- ];
- const testPaths = [];
- utils.eachComponent(components2, (component, path) => {
- testPaths.push(path);
- }, true);
- expect(paths).to.deep.equal(testPaths);
- });
-
- it('Should still provide the correct paths when it is not recursive', () => {
- const paths = [
- 'a',
- 'd',
- 'f',
- 'f.g',
- 'f.h',
- 'f.i',
- 'e',
- 'j',
- 'k',
- 'k.n',
- 'k.n.o',
- 'k.n.p',
- 'k.n.q',
- 'k.m',
- 'k.l',
- 'r',
- 'submit',
- 'tagpad',
- 'tagpad.a',
- ];
- const testPaths = [];
- utils.eachComponent(components2, (component, path) => {
- testPaths.push(path);
- });
- expect(paths).to.deep.equal(testPaths);
- });
-
- it('should be able to block recursion', () => {
- let numComps = 0;
- let numLayout = 0;
- utils.eachComponent(components, (component) => {
- if (utils.isLayoutComponent(component)) {
- numLayout++;
- }
- else {
- numComps++;
- }
-
- if (component.type === 'table') {
- let numInTable = 0;
- [].concat.apply([], component.rows).forEach((row) => {
- utils.eachComponent(row.components, () => {
- numInTable++;
- });
- });
- expect(numInTable).to.be.equal(4);
- return true;
- }
- }, true);
- expect(numLayout).to.be.equal(3);
- expect(numComps).to.be.equal(4);
- });
-
- it('should not include `htmlelement` components when `includeAll` is not provided', () => {
- let htmlComponentsAmount = 0;
- utils.eachComponent(components5, (component) => {
- if (component.type === 'htmlelement') {
- htmlComponentsAmount++;
- }
- });
- expect(htmlComponentsAmount).to.be.equal(0);
- });
-
- it('should include `htmlelement` components when `includeAll` is provided', () => {
- let htmlComponentsAmount = 0;
- utils.eachComponent(components5, (component) => {
- if (component.type === 'htmlelement') {
- htmlComponentsAmount++;
- }
- }, true);
- expect(htmlComponentsAmount).to.be.equal(1);
- });
-
- it('should not include `content` components when `includeAll` is not provided', () => {
- let contentComponentsAmount = 0;
- utils.eachComponent(components5, (component) => {
- if (component.type === 'content') {
- contentComponentsAmount++;
- }
- });
- expect(contentComponentsAmount).to.be.equal(0);
- });
-
- it('should include `content` components when `includeAll` is provided', () => {
- let contentComponentsAmount = 0;
- utils.eachComponent(components5, (component) => {
- if (component.type === 'content') {
- contentComponentsAmount++;
- }
- }, true);
- expect(contentComponentsAmount).to.be.equal(1);
- });
- });
-
- describe('getComponent', () => {
- it('should return the correct components', () => {
- for (let n = 1; n <= 8; n += 1) {
- const component = utils.getComponent(components, writtenNumber(n));
- expect(component).not.to.be.null;
- expect(component).not.to.be.undefined;
- expect(component).to.be.an('object');
- expect(component.order).to.equal(n);
- expect(component.key).to.equal(writtenNumber(n));
- }
- });
-
- it('should work with a different this context', () => {
- for (let n = 1; n <= 8; n += 1) {
- const component = utils.getComponent.call({}, components, writtenNumber(n));
- expect(component).not.to.be.null;
- expect(component).not.to.be.undefined;
- expect(component).to.be.an('object');
- expect(component.order).to.equal(n);
- expect(component.key).to.equal(writtenNumber(n));
- }
- });
- });
-
- describe('flattenComponents', () => {
- it('should return an object of flattened components', () => {
- const flattened = utils.flattenComponents(components);
- for (let n = 1; n <= 8; n += 1) {
- const component = flattened[writtenNumber(n)];
- expect(component).not.to.be.undefined;
- expect(component).to.be.an('object');
- expect(component.order).to.equal(n);
- expect(component.key).to.equal(writtenNumber(n));
- }
- });
-
- it('should work with a different this context', () => {
- const flattened = utils.flattenComponents.call({}, components);
- for (let n = 1; n <= 8; n += 1) {
- const component = flattened[writtenNumber(n)];
- expect(component).not.to.be.undefined;
- expect(component).to.be.an('object');
- expect(component.order).to.equal(n);
- expect(component.key).to.equal(writtenNumber(n));
- }
- });
- });
-
- describe('getValue', () => {
- it('should be able to get a simple value', () => {
- expect(utils.getValue(submission1, 'name')).to.be.equal(submission1.data.name);
- });
-
- it('should be able to get a value from a container', () => {
- expect(utils.getValue(submission1, 'animalname')).to.be.equal(submission1.data.mycontainer.animalname);
- });
- });
-
- describe('parseFloat', () => {
- it('should clear input and parse value', () => {
- expect(utils.parseFloatExt('12,345,678.90')).to.be.equal(12345678.90);
- });
- });
-
- describe('formatAsCurrency', () => {
- it('should be able to format Float value for Currency component', () => {
- expect(utils.formatAsCurrency(123.4)).to.be.equal('123.40');
- expect(utils.formatAsCurrency(12345678.9)).to.be.equal('12,345,678.90');
- expect(utils.formatAsCurrency(12345678.915)).to.be.equal('12,345,678.92');
- });
-
- it('should be able to format String value for Currency component', () => {
- expect(utils.formatAsCurrency('12345678.915')).to.be.equal('12,345,678.92');
- });
- });
-
- describe('checkCalculated', () => {
- it('should be able to calculate value based on javascript code', () => {
- const component = {
- key: 'sum',
- calculateValue: 'value = 3'
- };
- const data = {};
-
- utils.checkCalculated(component, null, data);
- expect(data.sum).to.be.equal(3);
- });
-
- it('should be able to calculate value based on json logic', () => {
- const component = {
- key: 'sum',
- calculateValue: {
- '_sum': { var: 'data.test' }
- }
- };
- const data = { test: [1, 2, 3] };
-
- utils.checkCalculated(component, null, data);
- expect(data.sum).to.be.equal(6);
- });
-
- it('should return undefined if no logic provided', () => {
- const component = {
- key: 'sum',
- calculateValue: '/* do nothing */'
- };
- const data = {};
-
- utils.checkCalculated(component, null, data);
- expect(data.sum).to.be.undefined;
- });
- });
-
- describe('checkCondition', () => {
- it('should display component by default', () => {
- expect(utils.checkCondition({}, null, {})).to.be.equal(true);
- });
-
- it('should calculate simple triggers', () => {
- const component = {
- key: 'sum',
- conditional: {
- when: 'test',
- eq: 3,
- show: true
- }
- };
- const data1 = { test: 3 };
- const data2 = { test: 5 };
- expect(utils.checkCondition(component, null, data1)).to.be.equal(true);
- expect(utils.checkCondition(component, null, data2)).to.be.equal(false);
- });
-
- it('should be able to calculate condition based on javascript code', () => {
- const component = {
- key: 'sum',
- customConditional(context) {
- return context.data.test === 3;
- }
- };
- const data1 = { test: 3 };
- const data2 = { test: 5 };
-
- expect(utils.checkCondition(component, null, data1)).to.be.equal(true);
- expect(utils.checkCondition(component, null, data2)).to.be.equal(false);
- });
-
- it('should be able to calculate condition based on json logic', () => {
- const component = {
- key: 'sum',
- conditional: {
- json: {
- '===': [
- { '_sum': { var: 'data.test' } },
- 6
- ]
- }
- }
- };
- const data1 = { test: [1, 2, 3] };
- const data2 = { test: [1, 2, 4] };
-
- expect(utils.checkCondition(component, null, data1)).to.be.equal(true);
- expect(utils.checkCondition(component, null, data2)).to.be.equal(false);
- });
- });
-
- describe('getDateSetting', () => {
- it('should return null if no date provided', () => {
- expect(utils.getDateSetting()).to.be.equal(null);
- expect(utils.getDateSetting(null)).to.be.equal(null);
- expect(utils.getDateSetting(undefined)).to.be.equal(null);
- expect(utils.getDateSetting(NaN)).to.be.equal(null);
- expect(utils.getDateSetting('')).to.be.equal(null);
- expect(utils.getDateSetting('should be invalid')).to.be.equal(null);
- });
-
- it('should return valid Date on serialized date provided', () => {
- const date = new Date(0);
- expect(utils.getDateSetting(date)).to.be.eql(date);
- expect(utils.getDateSetting(date.valueOf())).to.be.eql(date);
- expect(utils.getDateSetting(date.toString())).to.be.eql(date);
- expect(utils.getDateSetting(date.toISOString())).to.be.eql(date);
- });
-
- it('should be able to get value using moment APIs', () => {
- const validMomentExpression = 'moment(0)';
- const validDate = new Date(0);
- const invalidMomentExpression = "moment('')";
-
- expect(utils.getDateSetting(validMomentExpression)).to.be.eql(validDate);
- expect(utils.getDateSetting(invalidMomentExpression)).to.be.equal(null);
- });
- });
-
- describe('checkTrigger', () => {
- it('should default to false', () => {
- expect(utils.checkCondition({}, { type: 'none' }, null, {})).to.be.equal(true);
- });
-
- it('should calculate simple triggers', () => {
- const component = {
- key: 'sum'
- };
- const trigger = {
- type: 'simple',
- simple: {
- when: 'test',
- eq: 3,
- show: true
- }
- };
- const data1 = { test: 3 };
- const data2 = { test: 5 };
- expect(utils.checkTrigger(component, trigger, null, data1)).to.be.equal(true);
- expect(utils.checkTrigger(component, trigger, null, data2)).to.be.equal(false);
- });
-
- it('should be able to calculate trigger based on javascript code', () => {
- const component = {
- key: 'sum'
- };
- const trigger = {
- type: 'javascript',
- javascript: 'result = data.test === 3'
- };
- const data1 = { test: 3 };
- const data2 = { test: 5 };
-
- expect(utils.checkTrigger(component, trigger, null, data1)).to.be.equal(true);
- expect(utils.checkTrigger(component, trigger, null, data2)).to.be.equal(false);
- });
-
- it('should be able to calculate trigger based on json logic', () => {
- const component = {
- key: 'sum'
- };
- const trigger = {
- type: 'json',
- json: {
- '===': [
- { '_sum': { var: 'data.test' } },
- 6
- ]
- }
- };
- const data1 = { test: [1, 2, 3] };
- const data2 = { test: [1, 2, 4] };
-
- expect(utils.checkTrigger(component, trigger, null, data1)).to.be.equal(true);
- expect(utils.checkTrigger(component, trigger, null, data2)).to.be.equal(false);
- });
- });
-
- describe('setActionProperty', () => {
- it('should set a boolean action property to true', () => {
- const component = {
- key: 'test',
- disabled: false,
- };
- const action = {
- type: 'property',
- property: {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean',
- },
- state: true,
- };
-
- utils.setActionProperty(component, action);
-
- expect(component.disabled).to.be.equal(true);
- });
-
- it('should set a boolean action property to false', () => {
- const component = {
- key: 'test',
- disabled: true,
- };
- const action = {
- type: 'property',
- property: {
- label: 'Disabled',
- value: 'disabled',
- type: 'boolean',
- },
- state: false,
- };
-
- utils.setActionProperty(component, action);
-
- expect(component.disabled).to.be.equal(false);
- });
-
- it('should set a boolean action nested property', () => {
- const component = {
- key: 'test',
- validate: {
- required: true,
- },
- };
- const action = {
- type: 'property',
- property: {
- label: 'Required',
- value: 'validate.required',
- type: 'boolean',
- },
- state: false,
- };
-
- utils.setActionProperty(component, action);
-
- expect(component.validate.required).to.be.equal(false);
- });
-
- it('should set a string action property', () => {
- const component = {
- key: 'test',
- label: 'foo',
- };
- const action = {
- type: 'property',
- property: {
- label: 'Label',
- value: 'label',
- type: 'string',
- },
- text: 'bar',
- };
-
- utils.setActionProperty(component, action);
-
- expect(component.label).to.be.equal('bar');
- });
-
- it('should set a string action property with result templating', () => {
- const component = {
- key: 'test',
- label: 'foo',
- };
- const action = {
- type: 'property',
- property: {
- label: 'Label',
- value: 'label',
- type: 'string',
- },
- text: 'bar {{ result }}',
- };
-
- utils.setActionProperty(component, action, 'baz');
-
- expect(component.label).to.be.equal('bar baz');
- });
-
- it('should set a string action property with row templating', () => {
- const component = {
- key: 'test',
- label: 'foo',
- };
- const action = {
- type: 'property',
- property: {
- label: 'Label',
- value: 'label',
- type: 'string',
- },
- text: 'bar {{ row.field }}',
- };
-
- utils.setActionProperty(component, action, true, { field: 'baz' });
-
- expect(component.label).to.be.equal('bar baz');
- });
-
- it('should set a string action property with data templating', () => {
- const component = {
- key: 'test',
- label: 'foo',
- };
- const action = {
- type: 'property',
- property: {
- label: 'Label',
- value: 'label',
- type: 'string',
- },
- text: 'bar {{ data.field }}',
- };
-
- utils.setActionProperty(component, action, true, {}, { field: 'baz' });
-
- expect(component.label).to.be.equal('bar baz');
- });
-
- it('should set a string action property with component templating', () => {
- const component = {
- key: 'test',
- label: 'foo',
- };
- const action = {
- type: 'property',
- property: {
- label: 'Label',
- value: 'label',
- type: 'string',
- },
- text: 'bar {{ component.key }}',
- };
-
- utils.setActionProperty(component, action);
-
- expect(component.label).to.be.equal('bar test');
- });
-
- it('should do nothing with a bad request', () => {
- const component = {
- key: 'test',
- label: 'foo',
- };
- const originalComponent = _.cloneDeep(component);
-
- expect(component).to.deep.equal(originalComponent);
- });
- });
-
- describe('delay', () => {
- let score = 0;
-
- function incScore(value) {
- score += value || 1;
- }
-
- beforeEach(() => {
- score = 0;
- });
-
- it('should act as regular setTimeout()', (done) => {
- utils.delay(incScore);
- utils.delay(incScore, 0);
- utils.delay(incScore, 100, 2);
- utils.delay(() => {
- if (score === 4) {
- done();
- }
- }, 200);
- });
-
- it('should be cancelable via direct timer access', (done) => {
- const delay = utils.delay(incScore);
- clearTimeout(delay.timer);
- setTimeout(() => {
- if (score === 0) {
- done();
- }
- }, 100);
- });
-
- it('should be cancelable via cancel() method', (done) => {
- const delay = utils.delay(incScore);
- delay.cancel();
- setTimeout(() => {
- if (score === 0) {
- done();
- }
- }, 100);
- });
-
- it('should be able to call passed function synchronously', (done) => {
- const delay = utils.delay(incScore);
- delay();
- if (score === 1) {
- done();
- }
- });
- });
-
- describe('withSwitch', () => {
- it('should return Array with two functions', () => {
- const fns = utils.withSwitch();
-
- expect(fns).to.be.an('array').and.have.lengthOf(2);
- expect(fns[0]).to.be.a('function');
- expect(fns[1]).to.be.a('function');
- });
-
- describe('#get', () => {
- it('should return one of state', () => {
- const [get] = utils.withSwitch(42, 24);
- expect(get()).to.be.equal(42);
- });
-
- it('should be pure', () => {
- const [get] = utils.withSwitch(42, 24);
- expect(get()).to.be.equal(42);
- expect(get()).to.be.equal(42);
- expect(get()).to.be.equal(42);
- expect(get()).to.be.equal(42);
- });
- });
-
- describe('#toggle', () => {
- it('should cycle between states', () => {
- const [get, toggle] = utils.withSwitch(42, 24);
- expect(get()).to.be.equal(42);
- toggle();
- expect(get()).to.be.equal(24);
- toggle();
- expect(get()).to.be.equal(42);
- });
- });
- });
-
- describe('unfold', () => {
- it('should return provided argument', () => {
- const parameters = [{}, 1, null, 'string'];
-
- parameters.forEach(p => {
- assert(p === utils.unfold(p));
- });
- });
-
- it('should call parameter, if it is function and return result', () => {
- const x = Symbol('__unfold__');
- assert(utils.unfold(() => x) === x);
- });
- });
-
- describe('firstNonNil', () => {
- it('should return first non nil value', () => {
- expect(utils.firstNonNil([1])).to.equal(1);
- expect(utils.firstNonNil([1, 3])).to.equal(1);
- expect(utils.firstNonNil([3, 2, 1])).to.equal(3);
- expect(utils.firstNonNil([undefined, undefined, 3, 1])).to.equal(3);
- });
- it('should unfold all functions in array', () => {
- expect(utils.firstNonNil([() => 1])).to.equal(1);
- expect(utils.firstNonNil([() => 1, 3])).to.equal(1);
- expect(utils.firstNonNil([undefined, undefined, () => 3, 1])).to.equal(3);
- });
- });
-
- describe('observeOverload', () => {
- it('should invoke the callback, if there too many dispatches in a short time', done => {
- try {
- const dispatch = utils.observeOverload(() => true);
-
- for (let i = 0; i < 100; i += 1) {
- if (dispatch()) {
- return done();
- }
- }
-
- throw new Error('Callback not called');
- }
- catch (error) {
- done(error);
- }
- });
-
- it('should allow configuring the events limit', done => {
- try {
- for (let i = 1; i < 10; i += 1) {
- const dispatch = utils.observeOverload(() => done('Limit option is ignored1'), { limit: 100 });
- for (let j = 0; j < i * 10; j += 1) {
- dispatch();
- }
- }
-
- // exit if we done, otherwise throw
- let called = false;
- const dispatch = utils.observeOverload(() => {
- called = true;
- done();
- }, { limit: 100 });
-
- for (let i = 0; i < 110; i += 1) {
- dispatch();
- }
-
- if (!called) {
- throw new Error('Limit option is ignored2');
- }
- }
- catch (error) {
- done(error);
- }
- });
-
- it('should not invoke callback, if time between calls longer then options.delay', done => {
- try {
- const dispatch = utils.observeOverload(() => done('Callback should not be called'), { delay: 100, limit: 2 });
- let count = 0;
-
- const id = setInterval(() => {
- dispatch();
- count += 1;
- if (count >= 3) {
- done();
- clearInterval(id);
- }
- }, 110);
- }
- catch (error) {
- done(error);
- }
- });
-
- it('Should return string without HTML characters', () => {
- const unescapedString = utils.unescapeHTML('<p>ampersand & "quotes" test</p>');
- expect(unescapedString).to.equal('ampersand & "quotes" test
');
- });
- });
-
- describe('getCurrencyAffixes', () => {
- it('USD en', (done) => {
- try {
- const affixes = utils.getCurrencyAffixes({
- currency: 'USD',
- decimalLimit: 2,
- decimalSeparator: '.',
- lang: 'en',
- });
- const expectedResult = {
- prefix: '$',
- suffix: '',
- };
- expect(affixes.prefix).to.equal(expectedResult.prefix);
- expect(affixes.suffix).to.equal(expectedResult.suffix);
- done();
- }
- catch (err) {
- done(err);
- }
- });
-/*
- it('USD ar-SA', (done) => {
- try {
- const affixes2 = utils.getCurrencyAffixes({
- currency: 'USD',
- decimalLimit: 2,
- decimalSeparator: '٫',
- lang: 'ar-SA',
- });
- const expectedResult = {
- prefix: '',
- suffix: ' US$',
- };
- expect(affixes2.prefix).to.equal(expectedResult.prefix);
- expect(affixes2.suffix).to.equal(expectedResult.suffix);
- done();
- }
- catch (err) {
- done(err);
- }
- });
-*/
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/Rules.js b/web-client/core/themes/italia/static/formio/css/src/validator/Rules.js
deleted file mode 100644
index 2fd96cc4..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/Rules.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import rules from './rules/index';
-
-export default class Rules {
- static rules = rules;
-
- static addRule(name, rule) {
- Rules.rules[name] = rule;
- }
-
- static addRules(rules) {
- Rules.rules = { ...Rules.rules, ...rules };
- }
-
- static getRule(name) {
- return Rules.rules[name];
- }
-
- static getRules() {
- return Rules.rules;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/Validator.js b/web-client/core/themes/italia/static/formio/css/src/validator/Validator.js
deleted file mode 100644
index d02167c7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/Validator.js
+++ /dev/null
@@ -1,1236 +0,0 @@
-import _ from 'lodash';
-import {
- boolValue,
- getInputMask,
- matchInputMask,
- getDateSetting,
- escapeRegExCharacters,
- interpolate,
- convertFormatToMoment, getArrayFromComponentPath, unescapeHTML
-} from '../utils/utils';
-import moment from 'moment';
-import NativePromise from 'native-promise-only';
-import fetchPonyfill from 'fetch-ponyfill';
-const { fetch, Headers, Request } = fetchPonyfill({
- Promise: NativePromise
-});
-import {
- checkInvalidDate,
- CALENDAR_ERROR_MESSAGES
-} from '../utils/calendarUtils';
-import Rules from './Rules';
-
-class ValidationChecker {
- constructor(config = {}) {
- this.config = _.defaults(config, ValidationChecker.config);
- this.validators = {
- required: {
- key: 'validate.required',
- method: 'validateRequired',
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('required'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value) {
- if (!boolValue(setting) || component.isValueHidden()) {
- return true;
- }
-
- const isCalendar = component.validators.some(validator => validator === 'calendar');
-
- if (!value && isCalendar && component.widget.enteredDate) {
- return !this.validators.calendar.check.call(this, component, setting, value);
- }
-
- return !component.isEmpty(value);
- }
- },
- onlyAvailableItems: {
- key: 'validate.onlyAvailableItems',
- method: 'validateValueAvailability',
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('valueIsNotAvailable'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting) {
- return !boolValue(setting);
- }
- },
- unique: {
- key: 'validate.unique',
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('unique'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value) {
- // Skip if setting is falsy
- if (!boolValue(setting)) {
- return true;
- }
-
- // Skip if value is empty object or falsy
- if (!value || _.isObjectLike(value) && _.isEmpty(value)) {
- return true;
- }
-
- // Skip if we don't have a database connection
- if (!this.config.db) {
- return true;
- }
-
- return new NativePromise(resolve => {
- const form = this.config.form;
- const submission = this.config.submission;
- const path = `data.${component.path}`;
-
- const addPathQueryParams = (pathQueryParams, query, path) => {
- const pathArray = path.split(/\[\d+\]?./);
- const needValuesInArray = pathArray.length > 1;
-
- let pathToValue = path;
-
- if (needValuesInArray) {
- pathToValue = pathArray.shift();
- const pathQueryObj = {};
-
- _.reduce(pathArray, (pathQueryPath, pathPart, index) => {
- const isLastPathPart = index === (pathArray.length - 1);
- const obj = _.get(pathQueryObj, pathQueryPath, pathQueryObj);
- const addedPath = `$elemMatch['${pathPart}']`;
-
- _.set(obj, addedPath, isLastPathPart ? pathQueryParams : {});
-
- return pathQueryPath ? `${pathQueryPath}.${addedPath}` : addedPath;
- }, '');
-
- query[pathToValue] = pathQueryObj;
- }
- else {
- query[pathToValue] = pathQueryParams;
- }
- };
-
- // Build the query
- const query = { form: form._id };
- let collationOptions = {};
-
- if (_.isString(value)) {
- if (component.component.dbIndex) {
- addPathQueryParams(value, query, path);
- }
- // These are kind of hacky but provides for a more efficient "unique" validation when the string is an email,
- // because we (by and large) only have to worry about ASCII and partial unicode; this way, we can use collation-
- // aware indexes with case insensitive email searches to make things like login and registration a whole lot faster
- else if (
- component.component.type === 'email' ||
- (component.component.type === 'textfield' && component.component.validate?.pattern === '[A-Za-z0-9]+')
- ) {
- addPathQueryParams(value, query, path);
- collationOptions = { collation: { locale: 'en', strength: 2 } };
- }
- else {
- addPathQueryParams({
- $regex: new RegExp(`^${escapeRegExCharacters(value)}$`),
- $options: 'i'
- }, query, path);
- }
- }
- // FOR-213 - Pluck the unique location id
- else if (
- _.isPlainObject(value) &&
- value.address &&
- value.address['address_components'] &&
- value.address['place_id']
- ) {
- addPathQueryParams({
- $regex: new RegExp(`^${escapeRegExCharacters(value.address['place_id'])}$`),
- $options: 'i'
- }, query, `${path}.address.place_id`);
- }
- // Compare the contents of arrays vs the order.
- else if (_.isArray(value)) {
- addPathQueryParams({ $all: value }, query, path);
- }
- else if (_.isObject(value) || _.isNumber(value)) {
- addPathQueryParams({ $eq: value }, query, path);
- }
- // Only search for non-deleted items
- query.deleted = { $eq: null };
- query.state = 'submitted';
- const uniqueValidationCallback = (err, result) => {
- if (err) {
- return resolve(false);
- }
- else if (result) {
- // Only OK if it matches the current submission
- if (submission._id && (result._id.toString() === submission._id)) {
- resolve(true);
- }
- else {
- component.conflictId = result._id.toString();
- return resolve(false);
- }
- }
- else {
- return resolve(true);
- }
- };
- // Try to find an existing value within the form
- this.config.db.findOne(query, null, collationOptions, (err, result) => {
- if (err && collationOptions.collation) {
- // presume this error comes from db compatibility, try again as regex
- delete query[path];
- addPathQueryParams({
- $regex: new RegExp(`^${escapeRegExCharacters(value)}$`),
- $options: 'i'
- }, query, path);
- this.config.db.findOne(query, uniqueValidationCallback);
- }
- else {
- return uniqueValidationCallback(err, result);
- }
- });
- }).catch(() => false);
- }
- },
- multiple: {
- key: 'validate.multiple',
- hasLabel: true,
- message(component) {
- const shouldBeArray = boolValue(component.component.multiple) || Array.isArray(component.emptyValue);
- const isRequired = component.component.validate.required;
- const messageKey = shouldBeArray ? (isRequired ? 'array_nonempty' : 'array') : 'nonarray';
-
- return component.t(component.errorMessage(messageKey), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value) {
- // Skip multiple validation if the component tells us to
- if (!component.validateMultiple()) {
- return true;
- }
-
- const shouldBeArray = boolValue(setting);
- const canBeArray = Array.isArray(component.emptyValue);
- const isArray = Array.isArray(value);
- const isRequired = component.component.validate.required;
-
- if (shouldBeArray) {
- if (isArray) {
- return isRequired ? !!value.length : true;
- }
- else {
- // Null/undefined is ok if this value isn't required; anything else should fail
- return _.isNil(value) ? !isRequired : false;
- }
- }
- else {
- return canBeArray || !isArray;
- }
- }
- },
- select: {
- key: 'validate.select',
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('select'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value, data, index, row, async) {
- // Skip if setting is falsy
- if (!boolValue(setting)) {
- return true;
- }
-
- // Skip if value is empty
- if (!value || _.isEmpty(value)) {
- return true;
- }
-
- // Skip if we're not async-capable
- if (!async) {
- return true;
- }
-
- const schema = component.component;
-
- // Initialize the request options
- const requestOptions = {
- url: setting,
- method: 'GET',
- qs: {},
- json: true,
- headers: {}
- };
-
- // If the url is a boolean value
- if (_.isBoolean(requestOptions.url)) {
- requestOptions.url = !!requestOptions.url;
-
- if (
- !requestOptions.url ||
- schema.dataSrc !== 'url' ||
- !schema.data.url ||
- !schema.searchField
- ) {
- return true;
- }
-
- // Get the validation url
- requestOptions.url = schema.data.url;
-
- // Add the search field
- requestOptions.qs[schema.searchField] = value;
-
- // Add the filters
- if (schema.filter) {
- requestOptions.url += (!requestOptions.url.includes('?') ? '?' : '&') + schema.filter;
- }
-
- // If they only wish to return certain fields.
- if (schema.selectFields) {
- requestOptions.qs.select = schema.selectFields;
- }
- }
-
- if (!requestOptions.url) {
- return true;
- }
-
- // Make sure to interpolate.
- requestOptions.url = interpolate(requestOptions.url, { data: component.data });
-
- // Add query string to URL
- requestOptions.url += (requestOptions.url.includes('?') ? '&' : '?') + _.chain(requestOptions.qs)
- .map((val, key) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`)
- .join('&')
- .value();
-
- // Set custom headers.
- if (schema.data && schema.data.headers) {
- _.each(schema.data.headers, header => {
- if (header.key) {
- requestOptions.headers[header.key] = header.value;
- }
- });
- }
-
- // Set form.io authentication.
- if (schema.authenticate && this.config.token) {
- requestOptions.headers['x-jwt-token'] = this.config.token;
- }
-
- return fetch(new Request(requestOptions.url, {
- headers: new Headers(requestOptions.headers)
- }))
- .then(response => {
- if (!response.ok) {
- return false;
- }
-
- return response.json();
- })
- .then((results) => {
- return results && results.length;
- })
- .catch(() => false);
- }
- },
- min: {
- key: 'validate.min',
- hasLabel: true,
- message(component, setting) {
- return component.t(component.errorMessage('min'), {
- field: component.errorLabel,
- min: parseFloat(setting),
- data: component.data
- });
- },
- check(component, setting, value) {
- const min = parseFloat(setting);
- const parsedValue = parseFloat(value);
-
- if (Number.isNaN(min) || Number.isNaN(parsedValue)) {
- return true;
- }
-
- return parsedValue >= min;
- }
- },
- max: {
- key: 'validate.max',
- hasLabel: true,
- message(component, setting) {
- return component.t(component.errorMessage('max'), {
- field: component.errorLabel,
- max: parseFloat(setting),
- data: component.data
- });
- },
- check(component, setting, value) {
- const max = parseFloat(setting);
- const parsedValue = parseFloat(value);
-
- if (Number.isNaN(max) || Number.isNaN(parsedValue)) {
- return true;
- }
-
- return parsedValue <= max;
- }
- },
- minSelectedCount: {
- key: 'validate.minSelectedCount',
- message(component, setting) {
- return component.component.minSelectedCountMessage
- ? component.component.minSelectedCountMessage
- : component.t(component.errorMessage('minSelectedCount'), {
- minCount: parseFloat(setting),
- data: component.data
- });
- },
- check(component, setting, value) {
- const min = parseFloat(setting);
-
- if (!min) {
- return true;
- }
- const count = Object.keys(value).reduce((total, key) =>{
- if (value[key]) {
- total++;
- }
- return total;
- }, 0);
-
- // Should not be triggered if there is no options selected at all
- return !count || count >= min;
- }
- },
- maxSelectedCount: {
- key: 'validate.maxSelectedCount',
- message(component, setting) {
- return component.component.maxSelectedCountMessage
- ? component.component.maxSelectedCountMessage
- : component.t(component.errorMessage('maxSelectedCount'), {
- minCount: parseFloat(setting),
- data: component.data
- });
- },
- check(component, setting, value) {
- const max = parseFloat(setting);
-
- if (!max) {
- return true;
- }
- const count = Object.keys(value).reduce((total, key) =>{
- if (value[key]) {
- total++;
- }
- return total;
- }, 0);
-
- return count <= max;
- }
- },
- minLength: {
- key: 'validate.minLength',
- hasLabel: true,
- message(component, setting) {
- return component.t(component.errorMessage('minLength'), {
- field: component.errorLabel,
- length: setting,
- data: component.data
- });
- },
- check(component, setting, value) {
- const minLength = parseInt(setting, 10);
- if (!value || !minLength || (typeof value !== 'string') || component.isEmpty(value)) {
- return true;
- }
- return (value.length >= minLength);
- }
- },
- maxLength: {
- key: 'validate.maxLength',
- hasLabel: true,
- message(component, setting) {
- return component.t(component.errorMessage('maxLength'), {
- field: component.errorLabel,
- length: setting,
- data: component.data
- });
- },
- check(component, setting, value) {
- const maxLength = parseInt(setting, 10);
- if (!maxLength || (typeof value !== 'string')) {
- return true;
- }
- return (value.length <= maxLength);
- }
- },
- maxWords: {
- key: 'validate.maxWords',
- hasLabel: true,
- message(component, setting) {
- return component.t(component.errorMessage('maxWords'), {
- field: component.errorLabel,
- length: setting,
- data: component.data
- });
- },
- check(component, setting, value) {
- const maxWords = parseInt(setting, 10);
- if (!maxWords || (typeof value !== 'string')) {
- return true;
- }
- return (value.trim().split(/\s+/).length <= maxWords);
- }
- },
- minWords: {
- key: 'validate.minWords',
- hasLabel: true,
- message(component, setting) {
- return component.t(component.errorMessage('minWords'), {
- field: component.errorLabel,
- length: setting,
- data: component.data
- });
- },
- check(component, setting, value) {
- const minWords = parseInt(setting, 10);
- if (!minWords || !value || (typeof value !== 'string')) {
- return true;
- }
- return (value.trim().split(/\s+/).length >= minWords);
- }
- },
- email: {
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('invalid_email'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value) {
- /* eslint-disable max-len */
- // From http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
- const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
- /* eslint-enable max-len */
-
- // Allow emails to be valid if the component is pristine and no value is provided.
- return !value || re.test(value);
- }
- },
- url: {
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('invalid_url'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value) {
- /* eslint-disable max-len */
- // From https://stackoverflow.com/questions/8667070/javascript-regular-expression-to-validate-url
- const re = /^(?:(?:(?:https?|ftp):)?\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i;
- // From http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
- const emailRe = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
- /* eslint-enable max-len */
-
- // Allow urls to be valid if the component is pristine and no value is provided.
- return !value || (re.test(value) && !emailRe.test(value));
- }
- },
- date: {
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('invalid_date'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value) {
- if (!value) {
- return true;
- }
- if (value === 'Invalid date' || value === 'Invalid Date') {
- return false;
- }
- if (typeof value === 'string') {
- value = new Date(value);
- }
- return value instanceof Date === true && value.toString() !== 'Invalid Date';
- }
- },
- day: {
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('invalid_day'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value) {
- if (!value) {
- return true;
- }
- const [DAY, MONTH, YEAR] = component.dayFirst ? [0, 1, 2] : [1, 0, 2];
- const values = value.split('/').map(x => parseInt(x, 10)),
- day = values[DAY],
- month = values[MONTH],
- year = values[YEAR],
- maxDay = getDaysInMonthCount(month, year);
-
- if (day < 0 || day > maxDay) {
- return false;
- }
- if (month < 0 || month > 12) {
- return false;
- }
- if (year < 0 || year > 9999) {
- return false;
- }
- return true;
-
- function isLeapYear(year) {
- // Year is leap if it is evenly divisible by 400 or evenly divisible by 4 and not evenly divisible by 100.
- return !(year % 400) || (!!(year % 100) && !(year % 4));
- }
-
- function getDaysInMonthCount(month, year) {
- switch (month) {
- case 1: // January
- case 3: // March
- case 5: // May
- case 7: // July
- case 8: // August
- case 10: // October
- case 12: // December
- return 31;
- case 4: // April
- case 6: // June
- case 9: // September
- case 11: // November
- return 30;
- case 2: // February
- return isLeapYear(year) ? 29 : 28;
- default:
- return 31;
- }
- }
- }
- },
- pattern: {
- key: 'validate.pattern',
- hasLabel: true,
- message(component, setting) {
- return component.t(_.get(component, 'component.validate.patternMessage', component.errorMessage('pattern')), {
- field: component.errorLabel,
- pattern: setting,
- data: component.data
- });
- },
- check(component, setting, value) {
- if (component.isEmpty(value)) return true;
-
- const pattern = setting;
- if (!pattern) {
- return true;
- }
- const regex = new RegExp(`^${pattern}$`);
- return regex.test(value);
- }
- },
- json: {
- key: 'validate.json',
- check(component, setting, value, data, index, row) {
- if (!setting) {
- return true;
- }
- const valid = component.evaluate(setting, {
- data,
- row,
- rowIndex: index,
- input: value
- });
- if (valid === null) {
- return true;
- }
- return valid;
- }
- },
- mask: {
- key: 'inputMask',
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage('mask'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value) {
- let inputMask;
- if (component.isMultipleMasksField) {
- const maskName = value ? value.maskName : undefined;
- const formioInputMask = component.getMaskByName(maskName);
- if (formioInputMask) {
- inputMask = formioInputMask;
- }
- value = value ? value.value : value;
- }
- else {
- inputMask = setting;
- }
-
- inputMask = inputMask ? getInputMask(inputMask) : null;
-
- if (value && inputMask && !component.skipMaskValidation) {
- // If char which is used inside mask placeholder was used in the mask, replace it with space to prevent errors
- inputMask = inputMask.map((char) => char === component.placeholderChar ? ' ' : char);
- return matchInputMask(value, inputMask);
- }
-
- return true;
- }
- },
- custom: {
- key: 'validate.custom',
- message(component) {
- return component.t(component.errorMessage('custom'), {
- field: component.errorLabel,
- data: component.data
- });
- },
- check(component, setting, value, data, index, row) {
- if (!setting) {
- return true;
- }
- const valid = component.evaluate(setting, {
- valid: true,
- data,
- rowIndex: index,
- row,
- input: value
- }, 'valid', true);
- if (valid === null) {
- return true;
- }
- return valid;
- }
- },
- maxDate: {
- key: 'maxDate',
- hasLabel: true,
- message(component, setting) {
- const date = getDateSetting(setting);
- return component.t(component.errorMessage('maxDate'), {
- field: component.errorLabel,
- maxDate: moment(date).format(component.format),
- });
- },
- check(component, setting, value) {
- //if any parts of day are missing, skip maxDate validation
- if (component.isPartialDay && component.isPartialDay(value)) {
- return true;
- }
- const date = component.getValidationFormat ? moment(value, component.getValidationFormat()) : moment(value);
- const maxDate = getDateSetting(setting);
-
- if (_.isNull(maxDate)) {
- return true;
- }
- else {
- maxDate.setHours(0, 0, 0, 0);
- }
-
- return date.isBefore(maxDate) || date.isSame(maxDate);
- }
- },
- minDate: {
- key: 'minDate',
- hasLabel: true,
- message(component, setting) {
- const date = getDateSetting(setting);
- return component.t(component.errorMessage('minDate'), {
- field: component.errorLabel,
- minDate: moment(date).format(component.format),
- });
- },
- check(component, setting, value) {
- //if any parts of day are missing, skip minDate validation
- if (component.isPartialDay && component.isPartialDay(value)) {
- return true;
- }
- const date = component.getValidationFormat ? moment(value, component.getValidationFormat()) : moment(value);
- const minDate = getDateSetting(setting);
- if (_.isNull(minDate)) {
- return true;
- }
- else {
- minDate.setHours(0, 0, 0, 0);
- }
-
- return date.isAfter(minDate) || date.isSame(minDate);
- }
- },
- minYear: {
- key: 'minYear',
- hasLabel: true,
- message(component, setting) {
- return component.t(component.errorMessage('minYear'), {
- field: component.errorLabel,
- minYear: setting,
- });
- },
- check(component, setting, value) {
- const minYear = setting;
- let year = /\d{4}$/.exec(value);
- year = year ? year[0] : null;
-
- if (!(+minYear) || !(+year)) {
- return true;
- }
-
- return +year >= +minYear;
- }
- },
- maxYear: {
- key: 'maxYear',
- hasLabel: true,
- message(component, setting) {
- return component.t(component.errorMessage('maxYear'), {
- field: component.errorLabel,
- maxYear: setting,
- });
- },
- check(component, setting, value) {
- const maxYear = setting;
- let year = /\d{4}$/.exec(value);
- year = year ? year[0] : null;
-
- if (!(+maxYear) || !(+year)) {
- return true;
- }
-
- return +year <= +maxYear;
- }
- },
- calendar: {
- key: 'validate.calendar',
- messageText: '',
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage(this.validators.calendar.messageText), {
- field: component.errorLabel,
- maxDate: moment(component.dataValue).format(component.format),
- });
- },
- check(component, setting, value, data, index) {
- this.validators.calendar.messageText = '';
- const widget = component.getWidget(index);
- if (!widget) {
- return true;
- }
- const { settings, enteredDate } = widget;
- const { minDate, maxDate, format } = settings;
- const momentFormat = [convertFormatToMoment(format)];
-
- if (momentFormat[0].match(/M{3,}/g)) {
- momentFormat.push(momentFormat[0].replace(/M{3,}/g, 'MM'));
- }
-
- if (!value && enteredDate) {
- const { message, result } = checkInvalidDate(enteredDate, momentFormat, minDate, maxDate);
-
- if (!result) {
- this.validators.calendar.messageText = message;
- return result;
- }
- }
-
- if (value && enteredDate) {
- if (moment(value).format() !== moment(enteredDate, momentFormat, true).format() && enteredDate.match(/_/gi)) {
- this.validators.calendar.messageText = CALENDAR_ERROR_MESSAGES.INCOMPLETE;
- return false;
- }
- else {
- widget.enteredDate = '';
- return true;
- }
- }
- }
- },
- time: {
- key: 'validate.time',
- messageText: 'Invalid time',
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage(this.validators.time.messageText), {
- field: component.errorLabel
- });
- },
- check(component, setting, value) {
- if (component.isEmpty(value)) return true;
- return moment(value, component.component.format).isValid();
- }
- },
- availableValueProperty: {
- key: 'validate.availableValueProperty',
- method: 'validateValueProperty',
- messageText: 'Invalid Value Property',
- hasLabel: true,
- message(component) {
- return component.t(component.errorMessage(this.validators.availableValueProperty.messageText), {
- field: component.errorLabel,
- });
- },
- check(component, setting, value) {
- if (component.component.dataSrc === 'url' && (_.isUndefined(value) || _.isObject(value))) {
- return false;
- }
-
- return true;
- }
- }
- };
- }
-
- checkValidator(component, validator, setting, value, data, index, row, async) {
- let resultOrPromise = null;
-
- // Allow each component to override their own validators by implementing the validator.method
- if (validator.method && (typeof component[validator.method] === 'function')) {
- resultOrPromise = component[validator.method](setting, value, data, index, row, async);
- }
- else {
- resultOrPromise = validator.check.call(this, component, setting, value, data, index, row, async);
- }
-
- const processResult = result => {
- if (typeof result === 'string') {
- return result;
- }
-
- if (!result && validator.message) {
- return validator.message.call(this, component, setting, index, row);
- }
-
- return '';
- };
-
- if (async) {
- return NativePromise.resolve(resultOrPromise).then(processResult);
- }
- else {
- return processResult(resultOrPromise);
- }
- }
-
- validate(component, validatorName, value, data, index, row, async, conditionallyVisible, validationObj) {
- // Skip validation for conditionally hidden components
- if (!conditionallyVisible) {
- return false;
- }
-
- const validator = this.validators[validatorName];
- const setting = _.get(validationObj || component.component, validator.key, null);
- const resultOrPromise = this.checkValidator(component, validator, setting, value, data, index, row, async);
-
- const processResult = result => {
- if (result) {
- const resultData = {
- message: unescapeHTML(_.get(result, 'message', result)),
- level: _.get(result, 'level') === 'warning' ? 'warning' : 'error',
- path: getArrayFromComponentPath(component.path || ''),
- context: {
- validator: validatorName,
- hasLabel: validator.hasLabel,
- setting,
- key: component.key,
- label: component.label,
- value,
- index,
- input: component.refs.input?.[index]
- }
- };
- if (validatorName ==='unique' && component.conflictId) {
- resultData.conflictId = component.conflictId;
- }
- return resultData;
- }
- else {
- return false;
- }
- };
-
- if (async) {
- return NativePromise.resolve(resultOrPromise).then(processResult);
- }
- else {
- return processResult(resultOrPromise);
- }
- }
-
- checkComponent(component, data, row, includeWarnings = false, async = false) {
- const isServerSidePersistent = typeof process !== 'undefined'
- && _.get(process, 'release.name') === 'node'
- && !_.defaultTo(component.component.persistent, true);
-
- // If we're server-side and it's not a persistent component, don't run validation at all
- if (isServerSidePersistent || component.component.validate === false) {
- return async ? NativePromise.resolve([]) : [];
- }
-
- data = data || component.rootValue;
- row = row || component.data;
-
- const values = (component.component.multiple && Array.isArray(component.validationValue))
- ? component.validationValue
- : [component.validationValue];
- const conditionallyVisible = component.conditionallyVisible();
- const addonsValidations = [];
-
- if (component?.addons?.length) {
- values.forEach((value) => {
- component.addons.forEach((addon) => {
- if (!addon.checkValidity(value)) {
- addonsValidations.push(...(addon.errors || []));
- }
- });
- });
- }
-
- // If this component has the new validation system enabled, use it instead.
- const validations = _.get(component, 'component.validations');
- let nextGenResultsOrPromises = [];
-
- if (validations && Array.isArray(validations) && validations.length) {
- const validationsGroupedByMode = _.chain(validations)
- .groupBy((validation) => validation.mode)
- .value();
-
- if (component.calculateCondition) {
- includeWarnings = true;
-
- const uiGroupedValidation = _.chain(validationsGroupedByMode.ui)
- .filter('active')
- .groupBy((validation) => validation.group || null)
- .value();
-
- const commonValidations = uiGroupedValidation.null || [];
- delete uiGroupedValidation.null;
-
- commonValidations.forEach(({ condition, message, severity }) => {
- if (!component.calculateCondition(condition)) {
- nextGenResultsOrPromises.push({
- level: severity || 'error',
- message: component.t(message),
- componentInstance: component,
- });
- }
- });
-
- _.forEach(uiGroupedValidation, (validationGroup) => {
- _.forEach(validationGroup, ({ condition, message, severity }) => {
- if (!component.calculateCondition(condition)) {
- nextGenResultsOrPromises.push({
- level: severity || 'error',
- message: component.t(message),
- componentInstance: component,
- });
-
- return false;
- }
- });
- });
- }
- else {
- nextGenResultsOrPromises = this.checkValidations(component, validations, data, row, values, async);
- }
- if (component.validators.includes('custom') && validationsGroupedByMode.js) {
- _.each(validationsGroupedByMode.js, (validation) => {
- nextGenResultsOrPromises.push(_.map(values, (value, index) => this.validate(component, 'custom', value, data, index, row, async, conditionallyVisible, validation)));
- });
- }
- if (component.validators.includes('json') && validationsGroupedByMode.json) {
- _.each(validationsGroupedByMode.json, (validation) => {
- nextGenResultsOrPromises.push(_.map(values, (value, index) => this.validate(component, 'json', value, data, index, row, async, conditionallyVisible, validation)));
- });
- }
- }
-
- const validateCustom = _.get(component, 'component.validate.custom');
- const customErrorMessage = _.get(component, 'component.validate.customMessage');
-
- // Run primary validators
- const resultsOrPromises = _(component.validators).chain()
- .map(validatorName => {
- if (!this.validators.hasOwnProperty(validatorName)) {
- return {
- message: `Validator for "${validatorName}" is not defined`,
- level: 'warning',
- context: {
- validator: validatorName,
- key: component.key,
- label: component.label
- }
- };
- }
-
- // Handle the case when there is no values defined and it is required.
- if (validatorName === 'required' && !values.length) {
- return [this.validate(component, validatorName, null, data, 0, row, async, conditionallyVisible)];
- }
-
- return _.map(values, (value, index) => this.validate(component, validatorName, value, data, index, row, async, conditionallyVisible));
- })
- .flatten()
- .value();
-
- // Run the "unique" pseudo-validator
- component.component.validate = component.component.validate || {};
- component.component.validate.unique = component.component.unique;
- resultsOrPromises.push(this.validate(component, 'unique', component.validationValue, data, 0, data, async, conditionallyVisible));
-
- // Run the "multiple" pseudo-validator
- component.component.validate.multiple = component.component.multiple;
- resultsOrPromises.push(this.validate(component, 'multiple', component.validationValue, data, 0, data, async, conditionallyVisible));
-
- resultsOrPromises.push(...addonsValidations);
- resultsOrPromises.push(...nextGenResultsOrPromises);
-
- // Define how results should be formatted
- const formatResults = results => {
- // Condense to a single flat array
- results = _(results).chain().flatten().compact().value();
-
- if (customErrorMessage || validateCustom) {
- _.each(results, result => {
- result.message = component.t(customErrorMessage || result.message, {
- field: component.errorLabel,
- data,
- row,
- error: result
- });
- result.context.hasLabel = false;
- });
- }
-
- return includeWarnings ? results : _.reject(results, result => result.level === 'warning');
- };
- // Wait for results if using async mode, otherwise process and return immediately
- if (async) {
- return NativePromise.all(resultsOrPromises).then(formatResults);
- }
- else {
- return formatResults(resultsOrPromises);
- }
- }
-
- /**
- * Use the new validations engine to evaluate any errors.
- *
- * @param component
- * @param validations
- * @param data
- * @param row
- * @param values
- * @returns {any[]}
- */
- checkValidations(component, validations, data, row, values, async) {
- // Get results.
- const results = validations.map((validation) => {
- return this.checkRule(component, validation, data, row, values, async);
- });
-
- // Flatten array and filter out empty results.
- const messages = results.reduce((prev, result) => {
- if (result) {
- return [...prev, ...result];
- }
- return prev;
- }, []).filter((result) => result);
-
- // Keep only the last error for each rule.
- const rules = messages.reduce((prev, message) => {
- prev[message.context.validator] = message;
- return prev;
- }, {});
-
- return Object.values(rules);
- }
-
- checkRule(component, validation, data, row, values, async) {
- const Rule = Rules.getRule(validation.rule);
- const results = [];
- if (Rule) {
- const rule = new Rule(component, validation.settings, this.config);
- values.map((value, index) => {
- const result = rule.check(value, data, row, async);
- if (result !== true) {
- results.push({
- level: validation.level || 'error',
- message: component.t(validation.message || rule.defaultMessage, {
- settings: validation.settings,
- field: component.errorLabel,
- data,
- row,
- error: result,
- }),
- context: {
- key: component.key,
- index,
- label: component.label,
- validator: validation.rule,
- },
- });
- }
- });
- }
- // If there are no results, return false so it is removed by filter.
- return results.length === 0 ? false : results;
- }
-
- get check() {
- return this.checkComponent;
- }
-
- get() {
- _.get.call(this, arguments);
- }
-
- each() {
- _.each.call(this, arguments);
- }
-
- has() {
- _.has.call(this, arguments);
- }
-}
-
-ValidationChecker.config = {
- db: null,
- token: null,
- form: null,
- submission: null
-};
-
-const instance = new ValidationChecker();
-
-export {
- instance as default,
- ValidationChecker
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/Validator.unit.js b/web-client/core/themes/italia/static/formio/css/src/validator/Validator.unit.js
deleted file mode 100644
index 74242b19..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/Validator.unit.js
+++ /dev/null
@@ -1,1312 +0,0 @@
-'use strict';
-import DateTimeComponent from '../components/datetime/DateTime';
-import { comp1 } from '../components/datetime/fixtures';
-import Harness from '../../test/harness';
-import Validator from './Validator';
-import Component from '../components/_classes/component/Component';
-import assert from 'power-assert';
-
-describe('Legacy Validator Tests', () => {
- const baseComponent = new Component({});
-
- it('Should test for minLength', () => {
- assert.equal(Validator.validators.minLength.check(baseComponent, 5, 'test'), false);
- assert.equal(Validator.validators.minLength.check(baseComponent, 4, 'test'), true);
- assert.equal(Validator.validators.minLength.check(baseComponent, 3, 'test'), true);
- assert.equal(Validator.validators.minLength.check(baseComponent, 6, 'test'), false);
- assert.equal(Validator.validators.minLength.check(baseComponent, 6, ''), true);
- });
-
- it('Should test for maxLength', () => {
- assert.equal(Validator.validators.maxLength.check(baseComponent, 5, 'test'), true);
- assert.equal(Validator.validators.maxLength.check(baseComponent, 4, 'test'), true);
- assert.equal(Validator.validators.maxLength.check(baseComponent, 3, 'test'), false);
- assert.equal(Validator.validators.maxLength.check(baseComponent, 6, 'test'), true);
- assert.equal(Validator.validators.maxLength.check(baseComponent, 6, ''), true);
- });
-
- it('Should test for email', () => {
- assert.equal(Validator.validators.email.check(baseComponent, '', 'test'), false);
- assert.equal(Validator.validators.email.check(baseComponent, '', 'test@a'), false);
- assert.equal(Validator.validators.email.check(baseComponent, '', 'test@example.com'), true);
- assert.equal(Validator.validators.email.check(baseComponent, '', 'test@a.com'), true);
- assert.equal(Validator.validators.email.check(baseComponent, '', 'test@a.co'), true);
- });
-
- it('Should test for required', () => {
- assert.equal(Validator.validators.required.check(baseComponent, true, ''), false);
- assert.equal(Validator.validators.required.check(baseComponent, true, 't'), true);
- assert.equal(Validator.validators.required.check(baseComponent, false, ''), true);
- assert.equal(Validator.validators.required.check(baseComponent, false, 'tes'), true);
- assert.equal(Validator.validators.required.check(baseComponent, true, undefined), false);
- assert.equal(Validator.validators.required.check(baseComponent, true, null), false);
- assert.equal(Validator.validators.required.check(baseComponent, true, []), false);
- assert.equal(Validator.validators.required.check(baseComponent, true, ['test']), true);
- });
-
- it('Should test for custom', () => {
- assert.equal(Validator.validators.custom.check(baseComponent, 'valid = (input == "test")', 'test'), true);
- assert.equal(Validator.validators.custom.check(baseComponent, 'valid = (input == "test")', 'test2'), false);
- assert.equal(Validator.validators.custom.check(baseComponent, 'valid = (input == "test") ? true : "Should be false."', 'test2'), 'Should be false.');
- assert.equal(Validator.validators.custom.check(baseComponent, 'valid = (input == "test") ? true : "Should be false."', 'test'), true);
- });
-
- it('Should test for pattern', () => {
- assert.equal(Validator.validators.pattern.check(baseComponent, 'A.*', 'A'), true);
- assert.equal(Validator.validators.pattern.check(baseComponent, 'A.*', 'Aaaa'), true);
- assert.equal(Validator.validators.pattern.check(baseComponent, 'w+', 'test'), false);
- assert.equal(Validator.validators.pattern.check(baseComponent, '\\w+', 'test'), true);
- assert.equal(Validator.validators.pattern.check(baseComponent, '\\w+@\\w+', 'test@a'), true);
- assert.equal(Validator.validators.pattern.check(baseComponent, '\\w+@\\w+', 'test@example.com'), false);
- });
-
- it('Should test for json', () => {
- assert.equal(Validator.validators.json.check(baseComponent, {
- or: [{ '_isEqual': [{ var: 'data.test' }, ['1', '2', '3']] }, 'Should be false.']
- }, null, { test: ['1', '2', '3'] }), true);
- assert.equal(Validator.validators.json.check(baseComponent, {
- or: [{ '_isEqual': [{ var: 'data.test' }, ['1', '2', '3']] }, 'Should be false.']
- }, null, { test: ['1', '2', '4'] }), 'Should be false.');
- });
-
- it('Should test for date', (done) => {
- Harness.testCreate(DateTimeComponent, comp1).then((dateTime) => {
- const pass = [];
- const assertFail = (checkResults, message = 'Should fail') => {
- assert.equal(checkResults?.length, 1, message);
- assert.equal(checkResults[0].message, 'Date is not a valid date.', message);
- };
-
- dateTime.dataValue = '01/02/2000';
- assert.deepEqual(Validator.checkComponent(dateTime, {}), pass, 'Should be valid');
- dateTime.dataValue = 'January 23, 2012';
- assert.deepEqual(Validator.checkComponent(dateTime, {}), pass, 'Should be valid');
- dateTime.dataValue = '2010-10-10T10:10:10.626Z';
- assert.deepEqual(Validator.checkComponent(dateTime, {}), pass, 'Should be valid');
- dateTime.dataValue = new Date();
- assert.deepEqual(Validator.checkComponent(dateTime, {}), pass, 'Should be valid');
- dateTime.dataValue = null;
- assert.deepEqual(Validator.checkComponent(dateTime, {}), pass, 'Should be valid');
- dateTime.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(dateTime, {}), pass, 'Should be valid');
- dateTime.dataValue = '';
- assert.deepEqual(Validator.checkComponent(dateTime, {}), pass, 'Should be valid');
- dateTime.dataValue = 'Some string';
- assertFail(Validator.checkComponent(dateTime, {}), 'Should fail with a string');
- dateTime.dataValue = new Date('Some string');
- assertFail(Validator.checkComponent(dateTime, {}), 'Should fail with an invalid Date object');
- done();
- }).catch(done);
- });
-});
-
-describe('Validator Tests', () => {
- it('Validates for required', (done) => {
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'required',
- }
- ]
- });
- assert.deepEqual(Validator.checkComponent(component, {}), [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'required',
- },
- level: 'error',
- message: 'Test is required',
- }
- ]);
- done();
- });
-
- it('Overrides the message and level', (done) => {
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'required',
- level: 'info',
- message: 'ABC',
- }
- ]
- });
- assert.deepEqual(Validator.checkComponent(component, {}, {}, true), [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'required',
- },
- level: 'info',
- message: 'ABC',
- }
- ]);
- done();
- });
-
- it('Only returns the last message for a rule', (done) => {
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'required',
- level: 'info',
- message: 'ABC',
- },
- {
- rule: 'required',
- level: 'error',
- message: 'DEF',
- }
- ]
- });
- assert.deepEqual(Validator.checkComponent(component, {}), [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'required',
- },
- level: 'error',
- message: 'DEF',
- }
- ]);
- done();
- });
-
- it('Fulfills custom validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'custom',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'custom',
- level: 'error',
- message: 'DEF',
- settings: {
- custom: 'valid = input === "foo";',
- }
- }
- ]
- });
- // Null is empty value so false passes for Component.
- component.dataValue = 'foo';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'bar';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'a';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
-
- done();
- });
-
- it('Fulfills custom validation (multiple)', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'custom',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
- const pass = [];
- const component = new Component({
- key: 'test',
- label: 'Test',
- multiple: true,
- validations: [
- {
- rule: 'custom',
- level: 'error',
- message: 'DEF',
- settings: {
- custom: 'valid = input === "foo";',
- }
- }
- ]
- });
-
- component.dataValue = [];
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = ['test'];
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
-
- done();
- });
-
- it('Fulfills date validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'date',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'date',
- level: 'error',
- message: 'DEF',
- settings: {}
- }
- ]
- });
- component.dataValue = '01/05/12';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'January 5, 2012';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2019-12-04T16:33:10.626Z';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = new Date();
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'a';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills day validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'day',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'day',
- level: 'error',
- message: 'DEF',
- settings: {}
- }
- ]
- });
- component.dataValue = '01/05/2012';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'January 5, 2012';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '2019-12-04T16:33:10.626Z';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = new Date();
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'a';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills email validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'email',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'email',
- level: 'error',
- message: 'DEF',
- settings: {}
- }
- ]
- });
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'test';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'test@example';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'test@example.com';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'test.test@example.com';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'test.test@example.io';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills json validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'json',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'json',
- level: 'error',
- message: 'DEF',
- settings: {
- json: { '==' : [{ var: 'input' }, 'foo'] },
- }
- }
- ]
- });
- component.dataValue = 'foo';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'bar';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'a';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
-
- done();
- });
-
- it('Fulfills json validation (multiple)', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'json',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- multiple: true,
- validations: [
- {
- rule: 'json',
- level: 'error',
- message: 'DEF',
- settings: {
- json: { '==' : [{ var: 'input' }, 'foo'] },
- }
- }
- ]
- });
-
- component.dataValue = [];
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- component.dataValue = ['test'];
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
-
- done();
- });
-
- it('Fulfills mask validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'mask',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'mask',
- level: 'error',
- message: 'DEF',
- settings: {
- mask: '999',
- }
- }
- ]
- });
- component.dataValue = '123';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'aaa';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '12';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '1234';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '1a2';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills max validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'max',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'max',
- level: 'error',
- message: 'DEF',
- settings: {
- limit: '10',
- }
- }
- ]
- });
- component.dataValue = -1;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 0;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 1;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 9;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 10;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 11;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 1000000000;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '12';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills maxDate validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'maxDate',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'maxDate',
- level: 'error',
- message: 'DEF',
- settings: {
- dateLimit: '2019-12-04T00:00:00.000Z',
- }
- }
- ]
- });
- component.dataValue = '2010-12-03T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2019-12-03T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2019-12-04T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2019-12-05T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '2029-12-05T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills maxLength validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'maxLength',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'maxLength',
- level: 'error',
- message: 'DEF',
- settings: {
- length: '10',
- }
- }
- ]
- });
- component.dataValue = 'a';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '123456789';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '123456789a';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '1234567890a';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'this is a really long string';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills maxWords validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'maxWords',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'maxWords',
- level: 'error',
- message: 'DEF',
- settings: {
- length: '3',
- }
- }
- ]
- });
- component.dataValue = 'This';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'This is';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'This is a';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'This is a test';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'this is a really long string';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills maxYear validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'maxYear',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'maxYear',
- level: 'error',
- message: 'DEF',
- settings: '2020'
- }
- ]
- });
- component.dataValue = '2030';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '2021';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '3040';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '0000';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2000';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills minYear validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'minYear',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'minYear',
- level: 'error',
- message: 'DEF',
- settings: '2000'
- }
- ]
- });
- component.dataValue = '1880';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '0011';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '1990';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '0000';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2020';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2000';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills min validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'min',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'min',
- level: 'error',
- message: 'DEF',
- settings: {
- limit: '10',
- }
- }
- ]
- });
- component.dataValue = -1;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 0;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 1;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 9;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 10;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 11;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 1000000000;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '12';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills minDate validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'minDate',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'minDate',
- level: 'error',
- message: 'DEF',
- settings: {
- dateLimit: '2019-12-04T00:00:00.000Z',
- }
- }
- ]
- });
- component.dataValue = '2010-12-03T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '2019-12-03T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '2019-12-04T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2019-12-05T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '2029-12-05T00:00:00.000Z';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills minLength validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'minLength',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'minLength',
- level: 'error',
- message: 'DEF',
- settings: {
- length: '10',
- }
- }
- ]
- });
- component.dataValue = 'a';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '123456789';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = '123456789a';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '1234567890a';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'this is a really long string';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills minWords validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'minWords',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'minWords',
- level: 'error',
- message: 'DEF',
- settings: {
- length: '3',
- }
- }
- ]
- });
- component.dataValue = 'This';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'This is';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'This is a';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'This is a test';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'this is a really long string';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills pattern validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'pattern',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'pattern',
- level: 'error',
- message: 'DEF',
- settings: {
- pattern: 'a.c',
- }
- }
- ]
- });
- component.dataValue = 'abc';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'adc';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'aaa';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'ccc';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = 'a';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
-
- done();
- });
-
- it('Fulfills pattern validation (multiple)', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'pattern',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- multiple: true,
- validations: [
- {
- rule: 'pattern',
- level: 'error',
- message: 'DEF',
- settings: {
- pattern: 'a.c',
- }
- }
- ]
- });
-
- component.dataValue = [];
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = ['abc'];
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = ['abv'];
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
-
- done();
- });
-
- it('Fulfills required validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'required',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'required',
- level: 'error',
- message: 'DEF',
- }
- ]
- });
- // Null is empty value so false passes for Component.
- component.dataValue = false;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = true;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 't';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = 'test';
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- component.dataValue = '';
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = undefined;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = null;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
-
- done();
- });
-
- it('Fulfills required validation (multiple)', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'required',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- type: 'textfield',
- multiple: true,
- validations: [
- {
- rule: 'required',
- level: 'error',
- message: 'DEF',
- }
- ]
- });
-
- component.dataValue = [''];
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- component.dataValue = ['test'];
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
-
- done();
- });
-
- it('Fulfills url validation', (done) => {
- const fail = [
- {
- context: {
- index: 0,
- key: 'test',
- label: 'Test',
- validator: 'url',
- },
- level: 'error',
- message: 'DEF',
- }
- ];
-
- const pass = [];
-
- const component = new Component({
- key: 'test',
- label: 'Test',
- validations: [
- {
- rule: 'url',
- level: 'error',
- message: 'DEF',
- }
- ]
- });
-
- const valid = [
- 'test.com',
- 'http://test.com',
- 'https://test.com',
- 'https://www.test.com',
- 'https://one.two.three.four.test.io',
- 'https://www.test.com/test',
- 'https://www.test.com/test/test.html',
- 'https://www.test.com/one/two/three/four/test.html',
- 'www.example.com',
- 'http://www.example.com#up',
- 'https://wikipedia.org/@/ru',
- 'https://wikipedia.com/@',
- 'http://www.site.com:8008',
- 'ftp://www.site.com',
- undefined,
- null,
- ];
-
- const invalid = [
- 't',
- 'test',
- 'http://test',
- 'test@gmail.com',
- 'test@gmail.com ',
- 'test@gmail...com',
- 'test..com',
- 'http://test...com',
- 'http:://test.com',
- 'http:///test.com',
- 'https://www..example.com',
- ];
-
- try {
- valid.forEach((value) => {
- component.dataValue = value;
- assert.deepEqual(Validator.checkComponent(component, {}), pass);
- });
-
- invalid.forEach((value) => {
- component.dataValue = value;
- assert.deepEqual(Validator.checkComponent(component, {}), fail);
- });
-
- done();
- }
- catch (e) {
- done(e);
- }
- });
-});
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/conjunctions/index.js b/web-client/core/themes/italia/static/formio/css/src/validator/conjunctions/index.js
deleted file mode 100644
index 081cce9d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/conjunctions/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default class Conjunctions {
- static conjunctions = {};
-
- static addConjunction(name, conjunction) {
- Conjunctions.conjunctions[name] = conjunction;
- }
-
- static addConjunctions(conjunctions) {
- Conjunctions.conjunctions = { ...Conjunctions.conjunctions, ...conjunctions };
- }
-
- static getConjunction(name) {
- return Conjunctions.conjunctions[name];
- }
-
- static getConjunctions() {
- return Conjunctions.conjunctions;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/operators/index.js b/web-client/core/themes/italia/static/formio/css/src/validator/operators/index.js
deleted file mode 100644
index e8639030..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/operators/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default class Operators {
- static operators = {};
-
- static addOperator(name, operator) {
- Operators.operators[name] = operator;
- }
-
- static addOperators(operators) {
- Operators.operators = { ...Operators.operators, ...operators };
- }
-
- static getOperator(name) {
- return Operators.operators[name];
- }
-
- static getOperators() {
- return Operators.operators;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/quickRules/index.js b/web-client/core/themes/italia/static/formio/css/src/validator/quickRules/index.js
deleted file mode 100644
index a3169ea0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/quickRules/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default class QuickRules {
- static quickRules = {};
-
- static addQuickRule(name, quickRule) {
- QuickRules.quickRules[name] = quickRule;
- }
-
- static addQuickRules(quickRules) {
- QuickRules.quickRules = { ...QuickRules.quickRules, ...quickRules };
- }
-
- static getQuickRule(name) {
- return QuickRules.quickRules[name];
- }
-
- static getQuickRules() {
- return QuickRules.quickRules;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Custom.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Custom.js
deleted file mode 100644
index 101dc689..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Custom.js
+++ /dev/null
@@ -1,27 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class Custom extends Rule {
- defaultMessage = '{{error}}';
-
- check(value, data, row, index) {
- const custom = this.settings.custom;
-
- if (!custom) {
- return true;
- }
-
- const valid = this.component.evaluate(custom, {
- valid: true,
- data,
- row,
- rowIndex: index,
- input: value,
- }, 'valid', true);
-
- if (valid === null) {
- return true;
- }
-
- return valid;
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Date.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Date.js
deleted file mode 100644
index 027d13de..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Date.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class DateRule extends Rule {
- defaultMessage = '{{field}} is not a valid date.';
-
- check(value) {
- if (!value) {
- return true;
- }
- if (value === 'Invalid date' || value === 'Invalid Date') {
- return false;
- }
- if (typeof value === 'string') {
- value = new Date(value);
- }
- return value instanceof Date === true && value.toString() !== 'Invalid Date';
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Day.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Day.js
deleted file mode 100644
index 298970a0..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Day.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class Day extends Rule {
- defaultMessage = '{{field}} is not a valid day.';
-
- check(value) {
- if (!value) {
- return true;
- }
- if (typeof value !== 'string') {
- return false;
- }
- const [DAY, MONTH, YEAR] = this.component.dayFirst ? [0, 1, 2] : [1, 0, 2];
- const values = value.split('/').map(x => parseInt(x, 10)),
- day = values[DAY],
- month = values[MONTH],
- year = values[YEAR],
- maxDay = getDaysInMonthCount(month, year);
-
- if (isNaN(day) || day < 0 || day > maxDay) {
- return false;
- }
- if (isNaN(month) || month < 0 || month > 12) {
- return false;
- }
- if (isNaN(year) || year < 0 || year > 9999) {
- return false;
- }
- return true;
-
- function isLeapYear(year) {
- // Year is leap if it is evenly divisible by 400 or evenly divisible by 4 and not evenly divisible by 100.
- return !(year % 400) || (!!(year % 100) && !(year % 4));
- }
-
- function getDaysInMonthCount(month, year) {
- switch (month) {
- case 1: // January
- case 3: // March
- case 5: // May
- case 7: // July
- case 8: // August
- case 10: // October
- case 12: // December
- return 31;
- case 4: // April
- case 6: // June
- case 9: // September
- case 11: // November
- return 30;
- case 2: // February
- return isLeapYear(year) ? 29 : 28;
- default:
- return 31;
- }
- }
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Email.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Email.js
deleted file mode 100644
index dbba3ed9..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Email.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class Email extends Rule {
- defaultMessage = '{{field}} must be a valid email.';
-
- check(value) {
- if (!value) {
- return true;
- }
-
- /* eslint-disable max-len */
- // From http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
- const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
- /* eslint-enable max-len */
-
- // Allow emails to be valid if the component is pristine and no value is provided.
- return re.test(value);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/JSON.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/JSON.js
deleted file mode 100644
index 8344c98a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/JSON.js
+++ /dev/null
@@ -1,26 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class JSON extends Rule {
- defaultMessage = '{{error}}';
-
- check(value, data, row, index) {
- const { json } = this.settings;
-
- if (!json) {
- return true;
- }
-
- const valid = this.component.evaluate(json, {
- data,
- row,
- rowIndex: index,
- input: value
- });
-
- if (valid === null) {
- return true;
- }
-
- return valid;
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Mask.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Mask.js
deleted file mode 100644
index 453ff5b2..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Mask.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import { getInputMask, matchInputMask } from '../../utils/utils';
-
-const Rule = require('./Rule');
-
-module.exports = class Mask extends Rule {
- defaultMessage = '{{field}} does not match the mask.';
-
- check(value) {
- let inputMask;
- if (this.component.isMultipleMasksField) {
- const maskName = value ? value.maskName : undefined;
- const formioInputMask = this.component.getMaskByName(maskName);
- if (formioInputMask) {
- inputMask = getInputMask(formioInputMask);
- }
- value = value ? value.value : value;
- }
- else {
- inputMask = getInputMask(this.settings.mask);
- }
- if (value && inputMask) {
- return matchInputMask(value, inputMask);
- }
- return true;
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Max.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Max.js
deleted file mode 100644
index fc433cba..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Max.js
+++ /dev/null
@@ -1,16 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class Max extends Rule {
- defaultMessage = '{{field}} cannot be greater than {{settings.limit}}.';
-
- check(value) {
- const max = parseFloat(this.settings.limit);
- const parsedValue = parseFloat(value);
-
- if (Number.isNaN(max) || Number.isNaN(parsedValue)) {
- return true;
- }
-
- return parsedValue <= max;
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxDate.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxDate.js
deleted file mode 100644
index ce10ef3d..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxDate.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import { getDateSetting } from '../../utils/utils';
-import moment from 'moment';
-import _ from 'lodash';
-
-const Rule = require('./Rule');
-
-module.exports = class MaxDate extends Rule {
- defaultMessage = '{{field}} should not contain date after {{settings.dateLimit}}';
-
- check(value) {
- if (!value) {
- return true;
- }
-
- // If they are the exact same string or object, then return true.
- if (value === this.settings.dateLimit) {
- return true;
- }
-
- const date = moment(value);
- const maxDate = getDateSetting(this.settings.dateLimit);
-
- if (_.isNull(maxDate)) {
- return true;
- }
- else {
- maxDate.setHours(0, 0, 0, 0);
- }
-
- return date.isBefore(maxDate) || date.isSame(maxDate);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxLength.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxLength.js
deleted file mode 100644
index a11e3ce5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxLength.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class MaxLength extends Rule {
- defaultMessage = '{{field}} must have no more than {{- settings.length}} characters.';
-
- check(value) {
- const maxLength = parseInt(this.settings.length, 10);
- if (!value || !maxLength || !value.hasOwnProperty('length')) {
- return true;
- }
- return (value.length <= maxLength);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxWords.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxWords.js
deleted file mode 100644
index 57a998d5..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxWords.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class MaxWords extends Rule {
- defaultMessage = '{{field}} must have no more than {{- settings.length}} words.';
-
- check(value) {
- const maxWords = parseInt(this.settings.length, 10);
- if (!maxWords || (typeof value !== 'string')) {
- return true;
- }
- return (value.trim().split(/\s+/).length <= maxWords);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxYear.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxYear.js
deleted file mode 100644
index 2dc131ca..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MaxYear.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class MaxYear extends Rule {
- defaultMessage = '{{field}} should not contain year greater than {{maxYear}}';
-
- check(value) {
- const maxYear = this.settings;
- let year = /\d{4}$/.exec(value);
- year = year ? year[0] : null;
-
- if (!(+maxYear) || !(+year)) {
- return true;
- }
-
- return +year <= +maxYear;
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Min.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Min.js
deleted file mode 100644
index fe4d6999..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Min.js
+++ /dev/null
@@ -1,16 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class Min extends Rule {
- defaultMessage = '{{field}} cannot be less than {{settings.limit}}.';
-
- check(value) {
- const min = parseFloat(this.settings.limit);
- const parsedValue = parseFloat(value);
-
- if (Number.isNaN(min) || Number.isNaN(parsedValue)) {
- return true;
- }
-
- return parsedValue >= min;
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinDate.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinDate.js
deleted file mode 100644
index 79e6d999..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinDate.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { getDateSetting } from '../../utils/utils';
-import moment from 'moment';
-import _ from 'lodash';
-
-const Rule = require('./Rule');
-
-module.exports = class MinDate extends Rule {
- defaultMessage = '{{field}} should not contain date before {{settings.dateLimit}}';
-
- check(value) {
- if (!value) {
- return true;
- }
-
- const date = moment(value);
- const minDate = getDateSetting(this.settings.dateLimit);
-
- if (_.isNull(minDate)) {
- return true;
- }
- else {
- minDate.setHours(0, 0, 0, 0);
- }
-
- return date.isAfter(minDate) || date.isSame(minDate);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinLength.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinLength.js
deleted file mode 100644
index 58ad86ff..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinLength.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class MinLength extends Rule {
- defaultMessage = '{{field}} must have no more than {{- settings.length}} characters.';
-
- check(value) {
- const minLength = parseInt(this.settings.length, 10);
- if (!minLength || !value || !value.hasOwnProperty('length') || this.component.isEmpty(value)) {
- return true;
- }
- return (value.length >= minLength);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinWords.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinWords.js
deleted file mode 100644
index ebf9ea01..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinWords.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class MinWords extends Rule {
- defaultMessage = '{{field}} must have at least {{- settings.length}} words.';
-
- check(value) {
- const minWords = parseInt(this.settings.length, 10);
- if (!minWords || !value || (typeof value !== 'string')) {
- return true;
- }
- return (value.trim().split(/\s+/).length >= minWords);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinYear.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinYear.js
deleted file mode 100644
index f50c54f7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/MinYear.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class MinYear extends Rule {
- defaultMessage = '{{field}} should not contain year less than {{minYear}}';
-
- check(value) {
- const minYear = this.settings;
- let year = /\d{4}$/.exec(value);
- year = year ? year[0] : null;
-
- if (!(+minYear) || !(+year)) {
- return true;
- }
-
- return +year >= +minYear;
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Pattern.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Pattern.js
deleted file mode 100644
index 6e4a0cad..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Pattern.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class Pattern extends Rule {
- defaultMessage = '{{field}} does not match the pattern {{settings.pattern}}';
-
- check(value) {
- const { pattern } = this.settings;
-
- if (!pattern) {
- return true;
- }
-
- return (new RegExp(`^${pattern}$`)).test(value);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Required.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Required.js
deleted file mode 100644
index 8d2a1404..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Required.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class Required extends Rule {
- defaultMessage = '{{field}} is required';
-
- check(value) {
- // TODO: Day, Survey overrides.
-
- return !this.component.isValueHidden() && !this.component.isEmpty(value);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Rule.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Rule.js
deleted file mode 100644
index df5bc2c3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Rule.js
+++ /dev/null
@@ -1,11 +0,0 @@
-module.exports = class Rule {
- constructor(component, settings, config) {
- this.component = component;
- this.settings = settings;
- this.config = config;
- }
-
- check() {
-
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Select.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Select.js
deleted file mode 100644
index 062d0c7c..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Select.js
+++ /dev/null
@@ -1,108 +0,0 @@
-import { interpolate } from '../../utils/utils';
-import NativePromise from 'native-promise-only';
-import fetchPonyfill from 'fetch-ponyfill';
-const { fetch, Headers, Request } = fetchPonyfill({
- Promise: NativePromise
-});
-import _ from 'lodash';
-
-const Rule = require('./Rule');
-
-module.exports = class Select extends Rule {
- defaultMessage = '{{field}} contains an invalid selection';
-
- check(value, data, row, async) {
- // Skip if value is empty
- if (!value || _.isEmpty(value)) {
- return true;
- }
-
- // Skip if we're not async-capable
- if (!async) {
- return true;
- }
-
- const schema = this.component.component;
-
- // Initialize the request options
- const requestOptions = {
- url: this.settings.url,
- method: 'GET',
- qs: {},
- json: true,
- headers: {}
- };
-
- // If the url is a boolean value
- if (_.isBoolean(requestOptions.url)) {
- requestOptions.url = !!requestOptions.url;
-
- if (
- !requestOptions.url ||
- schema.dataSrc !== 'url' ||
- !schema.data.url ||
- !schema.searchField
- ) {
- return true;
- }
-
- // Get the validation url
- requestOptions.url = schema.data.url;
-
- // Add the search field
- requestOptions.qs[schema.searchField] = value;
-
- // Add the filters
- if (schema.filter) {
- requestOptions.url += (!requestOptions.url.includes('?') ? '?' : '&') + schema.filter;
- }
-
- // If they only wish to return certain fields.
- if (schema.selectFields) {
- requestOptions.qs.select = schema.selectFields;
- }
- }
-
- if (!requestOptions.url) {
- return true;
- }
-
- // Make sure to interpolate.
- requestOptions.url = interpolate(requestOptions.url, { data: this.component.data });
-
- // Add query string to URL
- requestOptions.url += (requestOptions.url.includes('?') ? '&' : '?') + _.chain(requestOptions.qs)
- .map((val, key) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`)
- .join('&')
- .value();
-
- // Set custom headers.
- if (schema.data && schema.data.headers) {
- _.each(schema.data.headers, header => {
- if (header.key) {
- requestOptions.headers[header.key] = header.value;
- }
- });
- }
-
- // Set form.io authentication.
- if (schema.authenticate && this.config.token) {
- requestOptions.headers['x-jwt-token'] = this.config.token;
- }
-
- return fetch(new Request(requestOptions.url, {
- headers: new Headers(requestOptions.headers)
- }))
- .then(response => {
- if (!response.ok) {
- return false;
- }
-
- return response.json();
- })
- .then((results) => {
- return results && results.length;
- })
- .catch(() => false);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Time.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Time.js
deleted file mode 100644
index a763b9c6..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Time.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const Rule = require('./Rule');
-import moment from 'moment';
-
-module.exports = class Time extends Rule {
- defaultMessage = '{{field}} must contain valid time';
-
- check(value) {
- if (this.component.isEmpty(value)) return true;
- return moment(value, this.component.component.format).isValid();
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Unique.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Unique.js
deleted file mode 100644
index 5f548555..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Unique.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import { escapeRegExCharacters } from '../../utils/utils';
-import _ from 'lodash';
-import NativePromise from 'native-promise-only';
-
-const Rule = require('./Rule');
-
-module.exports = class Unique extends Rule {
- defaultMessage = '{{field}} must be unique';
-
- check(value) {
- // Skip if value is empty object or falsy
- if (!value || _.isObjectLike(value) && _.isEmpty(value)) {
- return true;
- }
-
- // Skip if we don't have a database connection
- if (!this.config.db) {
- return true;
- }
-
- return new NativePromise(resolve => {
- const form = this.config.form;
- const submission = this.config.submission;
- const path = `data.${this.component.path}`;
-
- // Build the query
- const query = { form: form._id };
-
- if (_.isString(value)) {
- query[path] = {
- $regex: new RegExp(`^${escapeRegExCharacters(value)}$`),
- $options: 'i'
- };
- }
- else if (
- _.isPlainObject(value) &&
- value.address &&
- value.address['address_components'] &&
- value.address['place_id']
- ) {
- query[`${path}.address.place_id`] = {
- $regex: new RegExp(`^${escapeRegExCharacters(value.address['place_id'])}$`),
- $options: 'i'
- };
- }
- // Compare the contents of arrays vs the order.
- else if (_.isArray(value)) {
- query[path] = { $all: value };
- }
- else if (_.isObject(value) || _.isNumber(value)) {
- query[path] = { $eq: value };
- }
-
- // Only search for non-deleted items
- query.deleted = { $eq: null };
-
- // Try to find an existing value within the form
- this.config.db.findOne(query, (err, result) => {
- if (err) {
- return resolve(false);
- }
- else if (result) {
- // Only OK if it matches the current submission
- return resolve(submission._id && (result._id.toString() === submission._id));
- }
- else {
- return resolve(true);
- }
- });
- }).catch(() => false);
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Url.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/Url.js
deleted file mode 100644
index 39d082c3..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/Url.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const Rule = require('./Rule');
-
-module.exports = class Url extends Rule {
- defaultMessage = '{{field}} must be a valid url.';
-
- check(value) {
- /* eslint-disable max-len */
- // From https://stackoverflow.com/questions/8667070/javascript-regular-expression-to-validate-url
- const re = /^(?:(?:(?:https?|ftp):)?\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i;
- // From http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
- const emailRe = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
- /* eslint-enable max-len */
-
- // Allow urls to be valid if the component is pristine and no value is provided.
- return !value || (re.test(value) && !emailRe.test(value));
- }
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/rules/index.js b/web-client/core/themes/italia/static/formio/css/src/validator/rules/index.js
deleted file mode 100644
index ab0ebeb7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/rules/index.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const custom = require('./Custom');
-const date = require('./Date');
-const day = require('./Day');
-const email = require('./Email');
-const json = require('./JSON');
-const mask = require('./Mask');
-const max = require('./Max');
-const maxDate = require('./MaxDate');
-const maxLength = require('./MaxLength');
-const maxWords = require('./MaxWords');
-const min = require('./Min');
-const minDate = require('./MinDate');
-const minLength = require('./MinLength');
-const minWords = require('./MinWords');
-const pattern = require('./Pattern');
-const required = require('./Required');
-const select = require('./Select');
-const unique = require('./Unique');
-const url = require('./Url');
-const minYear = require('./MinYear');
-const maxYear = require('./MaxYear');
-const time = require('./Time');
-
-module.exports = {
- custom,
- date,
- day,
- email,
- json,
- mask,
- max,
- maxDate,
- maxLength,
- maxWords,
- min,
- minDate,
- minLength,
- minWords,
- pattern,
- required,
- select,
- unique,
- url,
- minYear,
- maxYear,
- time,
-};
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/transformers/index.js b/web-client/core/themes/italia/static/formio/css/src/validator/transformers/index.js
deleted file mode 100644
index a3263637..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/transformers/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default class Transformers {
- static transformers = {};
-
- static addTransformer(name, transformer) {
- Transformers.transformers[name] = transformer;
- }
-
- static addTransformers(transformers) {
- Transformers.transformers = { ...Transformers.transformers, ...transformers };
- }
-
- static getTransformer(name) {
- return Transformers.transformers[name];
- }
-
- static getTransformers() {
- return Transformers.transformers;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/validator/valueSources/index.js b/web-client/core/themes/italia/static/formio/css/src/validator/valueSources/index.js
deleted file mode 100644
index 4ffac40a..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/validator/valueSources/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default class ValueSources {
- static valueSources = {};
-
- static addValueSource(name, valueSource) {
- ValueSources.valueSources[name] = valueSource;
- }
-
- static addValueSources(valueSources) {
- ValueSources.valueSources = { ...ValueSources.valueSources, ...valueSources };
- }
-
- static getValueSource(name) {
- return ValueSources.valueSources[name];
- }
-
- static getValueSources() {
- return ValueSources.valueSources;
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/widgets/CalendarWidget.js b/web-client/core/themes/italia/static/formio/css/src/widgets/CalendarWidget.js
deleted file mode 100644
index 92e0c9a7..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/widgets/CalendarWidget.js
+++ /dev/null
@@ -1,552 +0,0 @@
-import { GlobalFormio as Formio } from '../Formio';
-import InputWidget from './InputWidget';
-import {
- convertFormatToFlatpickr,
- convertFormatToMask,
- convertFormatToMoment,
- formatDate,
- formatOffset,
- getBrowserInfo,
- getDateSetting,
- getLocaleDateFormatInfo,
- momentDate,
- zonesLoaded,
- shouldLoadZones,
- loadZones,
-} from '../utils/utils';
-import moment from 'moment';
-import _ from 'lodash';
-
-const DEFAULT_FORMAT = 'yyyy-MM-dd hh:mm a';
-const ISO_8601_FORMAT = 'yyyy-MM-ddTHH:mm:ssZ';
-
-const isIEBrowser = getBrowserInfo().ie;
-
-export default class CalendarWidget extends InputWidget {
- /* eslint-disable camelcase */
- static get defaultSettings() {
- return {
- type: 'calendar',
- altInput: true,
- allowInput: true,
- clickOpens: true,
- enableDate: true,
- enableTime: true,
- mode: 'single',
- noCalendar: false,
- format: DEFAULT_FORMAT,
- dateFormat: ISO_8601_FORMAT,
- useLocaleSettings: false,
- language: 'us-en',
- hourIncrement: 1,
- minuteIncrement: 5,
- time_24hr: false,
- saveAs: 'date',
- displayInTimezone: '',
- timezone: '',
- disable: [],
- minDate: '',
- maxDate: ''
- };
- }
- /* eslint-enable camelcase */
-
- constructor(settings, component, instance, index) {
- super(settings, component, instance, index);
- // Change the format to map to the settings.
- if (this.settings.noCalendar) {
- this.settings.format = this.settings.format.replace(/yyyy-MM-dd /g, '');
- }
- if (!this.settings.enableTime) {
- this.settings.format = this.settings.format.replace(/ hh:mm a$/g, '');
- }
- else if (this.settings.time_24hr) {
- this.settings.format = this.settings.format.replace(/hh:mm a$/g, 'HH:mm');
- }
- this.zoneLoading = false;
- this.timezonesUrl = `${Formio.cdn['moment-timezone']}/data/packed/latest.json`;
- }
-
- /**
- * Load the timezones.
- *
- * @return {boolean} TRUE if the zones are loading, FALSE otherwise.
- */
- loadZones() {
- const timezone = this.timezone;
-
- if (this.zoneLoading) {
- return true;
- }
-
- if (!zonesLoaded() && shouldLoadZones(timezone)) {
- this.zoneLoading = true;
- loadZones(this.timezonesUrl, timezone).then(() => {
- this.zoneLoading = false;
- this.emit('redraw');
- });
-
- // Return zones are loading.
- return true;
- }
-
- // Zones are already loaded.
- return false;
- }
-
- attach(input) {
- const superAttach = super.attach(input);
-
- const dateFormatInfo = getLocaleDateFormatInfo(this.settings.language);
- this.defaultFormat = {
- date: dateFormatInfo.dayFirst ? 'd/m/Y ' : 'm/d/Y ',
- time: 'G:i K'
- };
-
- this.closedOn = 0;
- this.valueFormat = (this.settings.saveAs === 'date') ? ISO_8601_FORMAT : this.settings.dateFormat || ISO_8601_FORMAT;
- this.valueMomentFormat = convertFormatToMoment(this.valueFormat);
-
- const isReadOnly = this.settings.readOnly;
-
- this.settings.minDate = isReadOnly ? null : getDateSetting(this.settings.minDate);
- this.settings.maxDate = isReadOnly ? null : getDateSetting(this.settings.maxDate);
- this.settings.disable = this.disabledDates;
- this.settings.disableWeekends ? this.settings.disable.push(this.disableWeekends) : '';
- this.settings.disableWeekdays ? this.settings.disable.push(this.disableWeekdays) : '';
- this.settings.disableFunction ? this.settings.disable.push(this.disableFunction) : '';
- this.settings.wasDefaultValueChanged = false;
- this.settings.defaultValue = '';
- this.settings.manualInputValue = '';
- this.settings.isManuallyOverriddenValue = false;
- this.settings.currentValue = '';
- this.settings.altFormat = convertFormatToFlatpickr(this.settings.format);
- this.settings.dateFormat = convertFormatToFlatpickr(this.settings.dateFormat);
- this.settings.position = 'auto center';
- this.settings.onChange = () => {
- if (this.settings.allowInput) {
- if (this.settings.isManuallyOverriddenValue && this.settings.enableTime) {
- this.calendar._input.value = this.settings.manualInputValue;
- }
- else {
- this.settings.manualInputValue = '';
- }
-
- this.settings.isManuallyOverriddenValue = false;
- }
-
- this.emit('update');
- };
- this.settings.onOpen = () => this.hook('onCalendarOpen');
- this.settings.onClose = () => {
- this.hook('onCalendarClose');
- this.closedOn = Date.now();
-
- if (this.settings.allowInput && this.settings.enableTime) {
- this.calendar._input.value = this.settings.manualInputValue || this.calendar._input.value;
- this.settings.isManuallyOverriddenValue = false;
- this.emit('update');
- }
-
- if (this.settings.wasDefaultValueChanged) {
- this.calendar._input.value = this.settings.defaultValue;
- this.settings.wasDefaultValueChanged = false;
- }
- if (this.calendar) {
- this.emit('blur');
- }
- };
-
- Formio.requireLibrary('flatpickr-css', 'flatpickr', [
- { type: 'styles', src: `${Formio.cdn['flatpickr-formio']}/flatpickr.min.css` }
- ], true);
-
- if (this.component.shortcutButtons) {
- this.component.shortcutButtons = this.component.shortcutButtons.filter((btn) => btn.label && btn.onClick);
- }
-
- if (this.component.shortcutButtons?.length) {
- Formio.requireLibrary('shortcut-buttons-flatpickr-css', 'ShortcutButtonsPlugin', [
- { type: 'styles', src: `${Formio.cdn['shortcut-buttons-flatpickr']}/themes/light.min.css` }
- ], true);
- }
-
- return superAttach
- .then(() => {
- if (this.component.shortcutButtons?.length) {
- return Formio.requireLibrary(
- 'shortcut-buttons-flatpickr', 'ShortcutButtonsPlugin', `${Formio.cdn['shortcut-buttons-flatpickr']}/shortcut-buttons-flatpickr.min.js`, true
- );
- }
- })
- .then((ShortcutButtonsPlugin) => {
- return Formio.requireLibrary('flatpickr', 'flatpickr', `${Formio.cdn['flatpickr-formio']}/flatpickr.min.js`, true)
- .then((Flatpickr) => {
- if (this.component.shortcutButtons?.length && ShortcutButtonsPlugin) {
- this.initShortcutButtonsPlugin(ShortcutButtonsPlugin);
- }
-
- this.settings.formatDate = this.getFlatpickrFormatDate(Flatpickr);
-
- if (this._input) {
- const { locale } = this.settings;
-
- if (locale && locale.length >= 2 && locale !== 'en') {
- return Formio.requireLibrary(
- `flatpickr-${locale}`,
- `flatpickr-${locale}`,
- `${Formio.cdn['flatpickr-formio']}/l10n/flatpickr-${locale}.js`,
- true).then(() => this.initFlatpickr(Flatpickr));
- }
- else {
- this.initFlatpickr(Flatpickr);
- }
- }
- });
- })
- .catch((err) => {
- console.warn(err);
- });
- }
-
- get disableWeekends() {
- return function(date) {
- return (date.getDay() === 0 || date.getDay() === 6);
- };
- }
-
- get disableWeekdays() {
- return (date) => !this.disableWeekends(date);
- }
-
- get disableFunction() {
- return (date) => this.evaluate(`return ${this.settings.disableFunction}`, {
- date
- });
- }
-
- get timezone() {
- return this.componentInstance.getTimezone(this.settings);
- }
-
- get defaultSettings() {
- return CalendarWidget.defaultSettings;
- }
-
- addSuffix(suffix) {
- this.addEventListener(suffix, 'click', () => {
- setTimeout(() => {
- if (this.calendar) {
- if (!this.calendar.isOpen && ((Date.now() - this.closedOn) > 200)) {
- this.calendar.open();
- }
- else if (this.calendar.isOpen) {
- this.calendar.close();
- }
- }
- }, 0);
- });
-
- return suffix;
- }
-
- set disabled(disabled) {
- super.disabled = disabled;
- if (this.calendar) {
- if (disabled) {
- this.calendar._input.setAttribute('disabled', 'disabled');
- }
- else {
- this.calendar._input.removeAttribute('disabled');
- }
- this.calendar.close();
- this.calendar.redraw();
- }
- }
-
- get input() {
- return this.calendar ? this.calendar.altInput : null;
- }
-
- get disabledDates() {
- if (this.settings.disabledDates) {
- const disabledDates = this.settings.disabledDates.split(',');
- return disabledDates.map((item) => {
- const dateMask = /\d{4}-\d{2}-\d{2}/g;
- const dates = item.match(dateMask);
- if (dates && dates.length) {
- return dates.length === 1 ? item.match(dateMask)[0] : {
- from: item.match(dateMask)[0],
- to: item.match(dateMask)[1],
- };
- }
- });
- }
- return [];
- }
-
- get localeFormat() {
- let format = '';
-
- if (this.settings.enableDate) {
- format += this.defaultFormat.date;
- }
-
- if (this.settings.enableTime) {
- format += this.defaultFormat.time;
- }
-
- return format;
- }
-
- get dateTimeFormat() {
- return this.settings.useLocaleSettings ? this.localeFormat : convertFormatToFlatpickr(this.dateFormat);
- }
-
- get dateFormat() {
- return _.get(this.settings, 'format', DEFAULT_FORMAT);
- }
-
- /**
- * Return the date value.
- *
- * @param date
- * @param format
- * @return {string}
- */
- getDateValue(date, format, useTimezone) {
- if (useTimezone) {
- return momentDate(date, this.valueFormat, this.timezone).format(convertFormatToMoment(format));
- }
- return moment(date).format(convertFormatToMoment(format));
- }
-
- /**
- * Return the value of the selected date.
- *
- * @return {*}
- */
- getValue() {
- // Standard output format.
- if (!this.calendar) {
- return super.getValue();
- }
-
- // Get the selected dates from the calendar widget.
- const dates = this.calendar.selectedDates;
- if (!dates || !dates.length) {
- return super.getValue();
- }
-
- if (!(dates[0] instanceof Date)) {
- return 'Invalid Date';
- }
-
- return this.getDateValue(dates[0], this.valueFormat, (this.settings.saveAs === 'date'));
- }
-
- isValueISO8601(value) {
- return value && (typeof value === 'string') && value.match(/-[0-9]{2}T[0-9]{2}:/);
- }
-
- /**
- * Set the selected date value.
- *
- * @param value
- */
- setValue(value) {
- const saveAsText = (this.settings.saveAs === 'text');
- if (!this.calendar) {
- value = value ? formatDate(this.timezonesUrl, value, convertFormatToMoment(this.settings.format), this.timezone, convertFormatToMoment(this.valueMomentFormat)) : value;
- return super.setValue(value);
- }
-
- const zonesLoading = this.loadZones();
- if (value) {
- if (!saveAsText && this.settings.readOnly && !zonesLoading) {
- this.calendar.setDate(momentDate(value, this.valueFormat, this.timezone).format(), false);
- }
- else if (this.isValueISO8601(value)) {
- this.calendar.setDate(value, false);
- }
- else {
- this.calendar.setDate(moment(value, this.valueMomentFormat).toDate(), false);
- }
- }
- else {
- this.calendar.clear(false);
- }
- }
-
- getValueAsString(value, format) {
- const inputFormat = format || this.dateFormat;
- const valueFormat = this.calendar ? this.valueFormat : this.settings.dateFormat;
- if (this.settings.saveAs === 'text' && this.componentInstance.parent && !this.settings.readOnly) {
- return moment(value, convertFormatToMoment(valueFormat)).format(convertFormatToMoment(valueFormat));
- }
- return formatDate(this.timezonesUrl, value, inputFormat, this.timezone, convertFormatToMoment(valueFormat));
- }
-
- setErrorClasses(hasErrors) {
- if (!this.input) {
- return;
- }
-
- if (hasErrors) {
- this.addClass(this.input, 'is-invalid');
- this.input.setAttribute('aria-invalid', 'true');
- }
- else {
- this.removeClass(this.input, 'is-invalid');
- this.input.setAttribute('aria-invalid', 'false');
- }
- }
-
- validationValue(value) {
- if (typeof value === 'string') {
- return new Date(value);
- }
- return value.map(val => new Date(val));
- }
-
- isCalendarElement(element) {
- if (!element) {
- return true;
- }
-
- if (this.calendar?.config?.appendTo?.contains(element)) {
- return true;
- }
-
- return this.calendar?.calendarContainer?.contains(element);
- }
-
- initFlatpickr(Flatpickr) {
- // Create a new flatpickr.
- this.calendar = new Flatpickr(this._input, { ...this.settings, disableMobile: true });
- this.calendar.altInput.addEventListener('input', (event) => {
- if (this.settings.allowInput && this.settings.currentValue !== event.target.value) {
- this.settings.manualInputValue = event.target.value;
- this.settings.isManuallyOverriddenValue = true;
- this.settings.currentValue = event.target.value;
- }
-
- if (event.target.value === '' && this.calendar.selectedDates.length > 0) {
- this.settings.wasDefaultValueChanged = true;
- this.settings.defaultValue = event.target.value;
- this.calendar.clear();
- }
- else {
- this.settings.wasDefaultValueChanged = false;
- }
- });
-
- const excludedFromMaskFormats = ['MMMM'];
-
- if (!this.settings.readOnly && !_.some(excludedFromMaskFormats, format => _.includes(this.settings.format, format))) {
- // Enforce the input mask of the format.
- this.setInputMask(this.calendar._input, convertFormatToMask(this.settings.format));
- }
-
- // Fixes an issue with IE11 where value is set only after the second click
- // TODO: Remove when the issue is solved in the flatpickr library
- if (isIEBrowser) {
- // Remove the original blur listener, because value will be set to empty since relatedTarget is null in IE11
- const originalBlurListener = this.calendar._handlers.find(({ event, element }) => event === 'blur' && element === this.calendar._input);
- this.calendar._input.removeEventListener('blur', originalBlurListener.handler);
- // Add the same event listener as in the original library, but with workaround for IE11 issue
- this.addEventListener(this.calendar._input, 'blur', (event) => {
- const activeElement = this.settings.shadowRoot ? this.settings.shadowRoot.activeElement : document.activeElement;
- const relatedTarget = event.relatedTarget ? event.relatedTarget : activeElement;
- const isInput = event.target === this.calendar._input;
-
- if (isInput && !this.isCalendarElement(relatedTarget)) {
- this.calendar.setDate(
- this.calendar._input.value,
- true,
- event.target === this.calendar.altInput
- ? this.calendar.config.altFormat
- : this.calendar.config.dateFormat
- );
- }
- });
- }
- // Make sure we commit the value after a blur event occurs.
- this.addEventListener(this.calendar._input, 'blur', (event) => {
- const activeElement = this.settings.shadowRoot ? this.settings.shadowRoot.activeElement : document.activeElement;
- const relatedTarget = event.relatedTarget ? event.relatedTarget : activeElement;
-
- if (!(isIEBrowser && !relatedTarget) && !this.isCalendarElement(relatedTarget)) {
- const inputValue = this.calendar.input.value;
- const dateValue = inputValue ? moment(this.calendar.input.value, convertFormatToMoment(this.valueFormat)).toDate() : inputValue;
-
- this.calendar.setDate(dateValue, true, this.settings.altFormat);
- }
- else if (!this.calendar.input.value && this.calendar.config.noCalendar) {
- const value = moment({ hour: this.calendar?.config?.defaultHour, minute: this.calendar?.config?.defaultMinute }).toDate();
- this.calendar.setDate(value, true, this.settings.format);
- }
- });
-
- // FJS-1103: When hit the enter button, the field not saving the year correctly
- this.addEventListener(this.calendar.altInput, 'keydown', (event) => {
- if (event.keyCode === 13) {
- if (this.calendar.isOpen) {
- this.calendar.close();
- event.stopPropagation();
- }
- }
- });
-
- // Restore the calendar value from the component value.
- this.setValue(this.componentValue);
- }
-
- initShortcutButtonsPlugin(ShortcutButtonsPlugin) {
- this.settings.plugins = [
- // eslint-disable-next-line new-cap
- ShortcutButtonsPlugin({
- button: this.component.shortcutButtons.map((btn) => ({ label: btn.label, attributes: btn.attribute })),
- onClick: (index) => {
- const getValue = this.component.shortcutButtons[index].onClick;
- const date = this.evaluate(getValue, { date: new Date() }, 'date');
- this.calendar.setDate(date, true);
- }
- })
- ];
- }
-
- get componentValue() {
- let compValue = this.componentInstance.dataValue;
- if (Array.isArray(compValue)) {
- compValue = compValue[this.valueIndex];
- }
- return compValue;
- }
-
- getFlatpickrFormatDate(Flatpickr) {
- return (date, format) => {
- // Only format this if this is the altFormat and the form is readOnly.
- if (this.settings.readOnly && (format === this.settings.altFormat)) {
- if (!this.settings.enableTime || this.loadZones()) {
- return Flatpickr.formatDate(date, format);
- }
-
- const currentValue = new Date(this.getValue());
- if (currentValue.toString() === date.toString()) {
- return formatOffset(this.timezonesUrl, Flatpickr.formatDate.bind(Flatpickr), new Date(this.componentValue), format, this.timezone);
- }
- return formatOffset(this.timezonesUrl, Flatpickr.formatDate.bind(Flatpickr), date, format, this.timezone);
- }
-
- return Flatpickr.formatDate(date, format);
- };
- }
-
- destroy() {
- super.destroy();
- if (this.calendar) {
- this.calendar.destroy();
- }
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/widgets/InputWidget.js b/web-client/core/themes/italia/static/formio/css/src/widgets/InputWidget.js
deleted file mode 100644
index daf0b3bf..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/widgets/InputWidget.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import _ from 'lodash';
-import Element from '../Element';
-import NativePromise from 'native-promise-only';
-export default class InputWidget extends Element {
- static get defaultSettings() {
- return {
- type: 'input'
- };
- }
-
- constructor(settings, component, instance, index) {
- super(settings);
- this.valueIndex = index || 0;
- this.componentInstance = instance;
- this.namespace = 'formio.widget';
- this.component = component || {};
- this.settings = _.merge({}, this.defaultSettings, settings || {});
- }
-
- attach(input) {
- this._input = input;
- return NativePromise.resolve();
- }
-
- get defaultSettings() {
- return {};
- }
-
- set disabled(disabled) {
- if (disabled) {
- this._input.setAttribute('disabled', 'disabled');
- }
- else {
- this._input.removeAttribute('disabled');
- }
- }
-
- get input() {
- return this._input;
- }
-
- getValue() {
- return this._input.value;
- }
-
- getValueAsString(value) {
- return value;
- }
-
- validationValue(value) {
- return value;
- }
-
- addPrefix() {
- return null;
- }
-
- addSuffix() {
- return null;
- }
-
- setValue(value) {
- this._input.value = value;
- }
-
- evalContext(additional) {
- return super.evalContext(Object.assign({
- component: this.component,
- row: this.componentInstance.data,
- rowIndex: this.componentInstance.rowIndex,
- data: this.componentInstance.rootValue,
- value: this.componentInstance.dataValue,
- t: this.t.bind(this),
- submission: (this.componentInstance.root ? this.componentInstance.root._submission : {
- data: this.componentInstance.rootValue
- }),
- form: this.componentInstance.root ? this.componentInstance.root._form : {},
- options: this.options,
- }, additional));
- }
-}
diff --git a/web-client/core/themes/italia/static/formio/css/src/widgets/index.js b/web-client/core/themes/italia/static/formio/css/src/widgets/index.js
deleted file mode 100644
index 8363436f..00000000
--- a/web-client/core/themes/italia/static/formio/css/src/widgets/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import InputWidget from './InputWidget';
-import CalendarWidget from './CalendarWidget';
-export default {
- input: InputWidget,
- calendar: CalendarWidget
-};