UNPKG

formiojs

Version:

Common js library for client side interaction with <form.io>

1,129 lines (1,100 loc) • 80.2 kB
"use strict"; require("core-js/modules/es.object.define-property.js"); require("core-js/modules/es.object.set-prototype-of.js"); require("core-js/modules/es.object.get-prototype-of.js"); require("core-js/modules/es.reflect.construct.js"); require("core-js/modules/es.object.create.js"); require("core-js/modules/es.reflect.get.js"); require("core-js/modules/es.object.get-own-property-descriptor.js"); require("core-js/modules/es.object.get-own-property-descriptors.js"); require("core-js/modules/es.object.define-properties.js"); require("core-js/modules/es.symbol.iterator.js"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; require("core-js/modules/es.array.map.js"); require("core-js/modules/es.array.sort.js"); require("core-js/modules/es.array.filter.js"); require("core-js/modules/es.object.to-string.js"); require("core-js/modules/es.regexp.exec.js"); require("core-js/modules/es.string.replace.js"); require("core-js/modules/es.array.includes.js"); require("core-js/modules/es.string.includes.js"); require("core-js/modules/es.function.name.js"); require("core-js/modules/es.function.bind.js"); require("core-js/modules/es.object.keys.js"); require("core-js/modules/es.array.index-of.js"); require("core-js/modules/es.array.is-array.js"); require("core-js/modules/es.array.concat.js"); require("core-js/modules/es.array.for-each.js"); require("core-js/modules/web.dom-collections.for-each.js"); require("core-js/modules/es.array.slice.js"); require("core-js/modules/es.string.match.js"); require("core-js/modules/es.array.join.js"); require("core-js/modules/es.array.from.js"); require("core-js/modules/es.string.iterator.js"); require("core-js/modules/es.array.find.js"); require("core-js/modules/es.array.find-index.js"); require("core-js/modules/es.array.some.js"); require("core-js/modules/es.array.splice.js"); require("core-js/modules/es.array.iterator.js"); require("core-js/modules/es.map.js"); require("core-js/modules/web.dom-collections.iterator.js"); require("core-js/modules/es.string.starts-with.js"); require("core-js/modules/es.regexp.flags.js"); require("core-js/modules/es.symbol.to-primitive.js"); require("core-js/modules/es.date.to-primitive.js"); require("core-js/modules/es.symbol.js"); require("core-js/modules/es.symbol.description.js"); require("core-js/modules/es.number.constructor.js"); var _Webform = _interopRequireDefault(require("./Webform")); var _Component2 = _interopRequireDefault(require("./components/_classes/component/Component")); var _tippy = _interopRequireDefault(require("tippy.js")); var _nativePromiseOnly = _interopRequireDefault(require("native-promise-only")); var _Components = _interopRequireDefault(require("./components/Components")); var _Formio = require("./Formio"); var _utils = require("./utils/utils"); var _formUtils = require("./utils/formUtils"); var _builder = _interopRequireDefault(require("./utils/builder")); var _lodash = _interopRequireDefault(require("lodash")); var _domAutoscroller = _interopRequireDefault(require("dom-autoscroller")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } require('./components/builder'); var Templates = _Formio.GlobalFormio.Templates; if (!Templates) { Templates = require('./templates/Templates')["default"]; } var 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'); } var WebformBuilder = /*#__PURE__*/function (_Component) { _inherits(WebformBuilder, _Component); var _super = _createSuper(WebformBuilder); // eslint-disable-next-line max-statements function WebformBuilder() { var _this; _classCallCheck(this, WebformBuilder); var 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'; _this = _super.call(this, null, options); _defineProperty(_assertThisInitialized(_this), "moveHandler", function (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); } }); _this.element = element; _this.builderHeight = 0; _this.schemas = {}; _this.repeatablePaths = []; _this.sideBarScroll = _lodash["default"].get(_this.options, 'sideBarScroll', true); _this.sideBarScrollOffset = _lodash["default"].get(_this.options, 'sideBarScrollOffset', 0); _this.dragDropEnabled = true; // Setup the builder options. _this.builder = _lodash["default"].defaultsDeep({}, _this.options.builder, _this.defaultGroups); // Turn off if explicitely said to do so... _lodash["default"].each(_this.defaultGroups, function (config, key) { if (config === false) { _this.builder[key] = false; } }); // Add the groups.//// _this.groups = {}; _this.groupOrder = []; var _loop = function _loop(group) { 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(function (groupKey) { _this.groups[group].groups[groupKey].componentOrder = Object.keys(_this.groups[group].groups[groupKey].components).map(function (key) { return key; }); return _this.groups[group].groups[groupKey]; }); _this.groupOrder.push(_this.groups[group]); } }; for (var group in _this.builder) { _loop(group); } _this.groupOrder = _this.groupOrder.filter(function (group) { return group && !group.ignore; }).sort(function (a, b) { return a.weight - b.weight; }).map(function (group) { return group.key; }); for (var type in _Components["default"].components) { var component = _Components["default"].components[type]; if (component.builderInfo && component.builderInfo.schema) { _this.schemas[type] = component.builderInfo.schema; component.type = type; var builderInfo = component.builderInfo; builderInfo.key = component.type; _this.addBuilderComponentInfo(builderInfo); } } // Filter out any extra components. // Add the components in each group. for (var _group in _this.groups) { var info = _this.groups[_group]; for (var key in info.components) { var compKey = _group === 'resource' ? "component-".concat(key) : key; var comp = info.components[compKey]; if (comp === true && _Components["default"].components[key] && _Components["default"].components[key].builderInfo) { comp = _Components["default"].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 = function (html, _ref) { var _self$component, _self$options; var component = _ref.component, self = _ref.self; if (self.type === 'form' && !self.key) { var 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: html, disableBuilderActions: self === null || self === void 0 ? void 0 : (_self$component = self.component) === null || _self$component === void 0 ? void 0 : _self$component.disableBuilderActions, childComponent: component, design: self === null || self === void 0 ? void 0 : (_self$options = self.options) === null || _self$options === void 0 ? void 0 : _self$options.design }); }; _this.options.hooks.renderComponents = function (html, _ref2) { var components = _ref2.components, self = _ref2.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: html }); }; _this.options.hooks.renderInput = function (html, _ref3) { var self = _ref3.self; if (self.type === 'hidden') { return html + self.name; } return html; }; _this.options.hooks.renderLoading = function (html, _ref4) { var self = _ref4.self; if (self.type === 'form' && self.key) { return self.name; } return html; }; _this.options.hooks.attachComponents = function (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. var containerElement = element.querySelector("[ref=\"".concat(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 = function (element, component) { component.loadRefs(element, _defineProperty({}, "".concat(component.key, "-container"), 'single')); var dataGridContainer = component.refs["".concat(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(_assertThisInitialized(_this)); // Load resources tagged as 'builder' var 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']; } var formio = new _Formio.GlobalFormio(_Formio.GlobalFormio.projectUrl); var isResourcesDisabled = _this.options.builder && _this.options.builder.resource === false; formio.loadProject().then(function (project) { if (project && (_lodash["default"].get(project, 'settings.addConfigToForms', false) || _lodash["default"].get(project, 'addConfigToForms', false))) { var config = project.config || {}; _this.options.formConfig = config; var pathToFormConfig = 'webform._form.config'; var webformConfig = _lodash["default"].get(_assertThisInitialized(_this), pathToFormConfig); if (_this.webform && !webformConfig) { _lodash["default"].set(_assertThisInitialized(_this), pathToFormConfig, config); } } })["catch"](function (err) { console.warn("Could not load project settings: ".concat(err.message || err)); }); if (!formio.noProject && !isResourcesDisabled) { var resourceOptions = _this.options.builder && _this.options.builder.resource; formio.loadForms(query).then(function (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 = []; return _this; } _createClass(WebformBuilder, [{ key: "allowDrop", value: function allowDrop() { return true; } }, { key: "addExistingResourceFields", value: function addExistingResourceFields(resources) { var _this2 = this; _lodash["default"].each(resources, function (resource, index) { var resourceKey = "resource-".concat(resource.name); var subgroup = { key: resourceKey, title: resource.title, components: [], componentOrder: [], "default": index === 0 }; (0, _formUtils.eachComponent)(resource.components, function (component) { if (component.type === 'button') return; if (_this2.options && _this2.options.resourceFilter && (!component.tags || component.tags.indexOf(_this2.options.resourceFilter) === -1)) return; var componentName = component.label; if (!componentName && component.key) { componentName = _lodash["default"].upperFirst(component.key); } subgroup.componentOrder.push("component-".concat(component.key)); subgroup.components["component-".concat(component.key)] = _lodash["default"].merge((0, _utils.fastCloneDeep)(_Components["default"].components[component.type] ? _Components["default"].components[component.type].builderInfo : _Components["default"].components['unknown'].builderInfo), { key: component.key, title: componentName, group: 'resource', subgroup: resourceKey }, { schema: _objectSpread(_objectSpread({}, component), {}, { label: component.label, key: component.key, lockKey: true, source: !_this2.options.noSource ? resource._id : undefined, isNew: true }) }); }, true); _this2.groups.resource.subgroups.push(subgroup); }); this.triggerRedraw(); } }, { key: "attachTooltip", value: function attachTooltip(component, title) { return (0, _tippy["default"])(component, { allowHTML: true, trigger: 'mouseenter focus', placement: 'top', delay: [200, 0], zIndex: 10000, content: title }); } }, { key: "attachComponent", value: function attachComponent(element, component) { var _this3 = this; 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', function () { return _this3.copyComponent(component); }); } if (component.refs.pasteComponent) { var pasteToolTip = this.attachTooltip(component.refs.pasteComponent, this.t('Paste below')); component.addEventListener(component.refs.pasteComponent, 'click', function () { pasteToolTip.hide(); _this3.pasteComponent(component); }); } if (component.refs.moveComponent) { this.attachTooltip(component.refs.moveComponent, this.t('Move')); if (this.keyboardActionsEnabled) { component.addEventListener(component.refs.moveComponent, 'click', function () { _this3.moveComponent(component); }); } } var parent = this.getParentElement(element); if (component.refs.editComponent) { this.attachTooltip(component.refs.editComponent, this.t('Edit')); component.addEventListener(component.refs.editComponent, 'click', function () { return _this3.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', function () { return _this3.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', function () { return _this3.removeComponent(component.schema, parent, component.component, component); }); } return element; } }, { key: "createForm", value: function createForm(options) { this.webform = new _Webform["default"](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. */ }, { key: "ready", get: function get() { return this.webform.ready; } }, { key: "defaultGroups", get: function get() { 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 } }; } }, { key: "redraw", value: function redraw() { return _Webform["default"].prototype.redraw.call(this); } }, { key: "form", get: function get() { return this.webform.form; }, set: function set(value) { this.setForm(value); } }, { key: "schema", get: function get() { return this.webform.schema; } }, { key: "container", get: function get() { 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 */ }, { key: "findNamespaceRoot", value: function findNamespaceRoot(component) { var path = (0, _utils.getArrayFromComponentPath)(component.path); // First get the component with nested parents. var comp = this.webform.getComponent(path); comp = Array.isArray(comp) ? comp[0] : comp; var namespaceKey = this.recurseNamespace(comp); // If there is no key, it is the root form. if (!namespaceKey || this.form.key === namespaceKey) { return this.form.components; } var componentSchema = component.component; // If the current component is the namespace, we don't need to find it again. if (namespaceKey === component.key) { return [].concat(_toConsumableArray(componentSchema.components), [componentSchema]); } // Get the namespace component so we have the original object. var namespaceComponent = (0, _formUtils.getComponent)(this.form.components, namespaceKey, true); return namespaceComponent ? namespaceComponent.components : comp.components; } }, { key: "recurseNamespace", value: function 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); } }, { key: "render", value: function render() { var _this4 = this; return this.renderTemplate('builder', { sidebar: this.renderTemplate('builderSidebar', { scrollEnabled: this.sideBarScroll, groupOrder: this.groupOrder, groupId: "builder-sidebar-".concat(this.id), groups: this.groupOrder.map(function (groupKey) { return _this4.renderTemplate('builderSidebarGroup', { group: _this4.groups[groupKey], groupKey: groupKey, groupId: "builder-sidebar-".concat(_this4.id), subgroups: _this4.groups[groupKey].subgroups.map(function (group) { return _this4.renderTemplate('builderSidebarGroup', { group: group, groupKey: group.key, groupId: "group-container-".concat(groupKey), subgroups: [] }); }), keyboardActionsEnabled: _this4.keyboardActionsEnabled }); }) }), form: this.webform.render() }); } }, { key: "attach", value: function attach(element) { var _this5 = this; this.on('change', function (form) { _this5.populateCaptchaSettings(form); _this5.webform.setAlert(false); }); return _get(_getPrototypeOf(WebformBuilder.prototype), "attach", this).call(this, element).then(function () { _this5.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 (_this5.sideBarScroll && Templates.current.handleBuilderSidebarScroll) { Templates.current.handleBuilderSidebarScroll.call(_this5, _this5); } // Add the paste status in form if (typeof window !== 'undefined' && window.sessionStorage) { var data = window.sessionStorage.getItem('formio.clipboard'); if (data) { _this5.addClass(_this5.refs.form, 'builder-paste-mode'); } } if (!(0, _utils.bootstrapVersion)(_this5.options)) { // Initialize _this5.refs['sidebar-group'].forEach(function (group) { group.style.display = group.getAttribute('data-default') === 'true' ? 'inherit' : 'none'; }); // Click event _this5.refs['sidebar-anchor'].forEach(function (anchor, index) { _this5.addEventListener(anchor, 'click', function () { var clickedParentId = anchor.getAttribute('data-parent').slice('#builder-sidebar-'.length); var clickedId = anchor.getAttribute('data-target').slice('#group-'.length); _this5.refs['sidebar-group'].forEach(function (group, groupIndex) { var openByDefault = group.getAttribute('data-default') === 'true'; var groupId = group.getAttribute('id').slice('group-'.length); var groupParent = group.getAttribute('data-parent').slice('#builder-sidebar-'.length); group.style.display = openByDefault && groupParent === clickedId || groupId === clickedParentId || groupIndex === index ? 'inherit' : 'none'; }); }, true); }); } if (_this5.keyboardActionsEnabled) { _this5.refs['sidebar-component'].forEach(function (component) { _this5.addEventListener(component, 'keydown', function (event) { if (event.keyCode === 13) { _this5.addNewComponent(component); } }); }); } _this5.addEventListener(_this5.refs['sidebar-search'], 'input', _lodash["default"].debounce(function (e) { var searchString = e.target.value; _this5.searchFields(searchString); }, 300)); if (_this5.dragDropEnabled) { _this5.initDragula(); } var drake = _this5.dragula; if (_this5.refs.form) { (0, _domAutoscroller["default"])([window], { margin: 20, maxSpeed: 6, scrollWhenOutside: true, autoScroll: function autoScroll() { return this.down && (drake === null || drake === void 0 ? void 0 : drake.dragging); } }); return _this5.webform.attach(_this5.refs.form); } }); } }, { key: "searchFields", value: function searchFields() { var _this6 = this; var searchString = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var searchValue = searchString.toLowerCase(); var sidebar = this.refs['sidebar']; var sidebarGroups = this.refs['sidebar-groups']; if (!sidebar || !sidebarGroups) { return; } var filterGroupBy = function filterGroupBy(group) { var searchValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var result = _lodash["default"].toPlainObject(group); var _result$subgroups = result.subgroups, subgroups = _result$subgroups === void 0 ? [] : _result$subgroups, components = result.components; var filteredComponents = []; for (var key in components) { var isMatchedToTitle = components[key].title.toLowerCase().match(searchValue); var isMatchedToKey = components[key].key.toLowerCase().match(searchValue); if (isMatchedToTitle || isMatchedToKey) { filteredComponents.push(components[key]); } } _this6.orderComponents(result, filteredComponents); if (searchValue) { result["default"] = true; } if (result.componentOrder.length || subgroups.length) { return result; } return null; }; var filterGroupOrder = function filterGroupOrder(groupOrder, searchValue) { var result = _lodash["default"].cloneDeep(groupOrder); return result.filter(function (key) { return filterGroupBy(_this6.groups[key], searchValue); }); }; var filterSubgroups = function filterSubgroups(groups, searchValue) { var result = _lodash["default"].clone(groups); return result.map(function (subgroup) { return filterGroupBy(subgroup, searchValue); }).filter(function (subgroup) { return !_lodash["default"].isNull(subgroup); }); }; var toTemplate = function toTemplate(groupKey) { return { group: filterGroupBy(_this6.groups[groupKey], searchValue), groupKey: groupKey, groupId: sidebar.id || sidebarGroups.id, subgroups: filterSubgroups(_this6.groups[groupKey].subgroups, searchValue).map(function (group) { return _this6.renderTemplate('builderSidebarGroup', { group: group, groupKey: group.key, groupId: "group-container-".concat(groupKey), subgroups: [] }); }) }; }; sidebarGroups.innerHTML = filterGroupOrder(this.groupOrder, searchValue).map(function (groupKey) { return _this6.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(); } } }, { key: "orderComponents", value: function orderComponents(groupInfo, foundComponents) { var components = foundComponents || groupInfo.components; var isResource = groupInfo.key.indexOf('resource-') === 0; if (components) { groupInfo.componentOrder = Object.keys(components).map(function (key) { return components[key]; }).filter(function (component) { return component && !component.ignore && !component.ignoreForForm; }).sort(function (a, b) { return a.weight - b.weight; }).map(function (component) { return isResource ? "component-".concat(component.key) : component.key; }); } } }, { key: "updateDragAndDrop", value: function updateDragAndDrop() { if (this.dragDropEnabled) { this.initDragula(); } if (this.refs.form) { return this.webform.attach(this.refs.form); } } }, { key: "initDragula", value: function initDragula() { var _this7 = this; var options = this.options; if (this.dragula) { this.dragula.destroy(); } var containersArray = Array.prototype.slice.call(this.refs['sidebar-container']).filter(function (item) { return item.id !== 'group-container-resource'; }); if (!dragula) { return; } this.dragula = dragula(containersArray, { moves: function moves(el) { var moves = true; var list = Array.from(el.classList).filter(function (item) { return item.indexOf('formio-component-') === 0; }); list.forEach(function (item) { var 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: function copy(el) { return el.classList.contains('drag-copy'); }, accepts: function accepts(el, target) { return !el.contains(target) && !target.classList.contains('no-drop'); } }).on('drop', function (element, target, source, sibling) { return _this7.onDrop(element, target, source, sibling); }); } }, { key: "detach", value: function detach() { if (this.dragula) { this.dragula.destroy(); } this.dragula = null; if (this.sideBarScroll && Templates.current.clearBuilderSidebarScroll) { Templates.current.clearBuilderSidebarScroll.call(this, this); } _get(_getPrototypeOf(WebformBuilder.prototype), "detach", this).call(this); } }, { key: "getComponentInfo", value: function getComponentInfo(key, group) { var 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. var resourceGroups = this.groups.resource.subgroups; var resourceGroup = _lodash["default"].find(resourceGroups, { key: group }); if (resourceGroup && resourceGroup.components.hasOwnProperty("component-".concat(key))) { info = (0, _utils.fastCloneDeep)(resourceGroup.components["component-".concat(key)].schema); } } // This is a new component else if (this.schemas.hasOwnProperty(key)) { info = (0, _utils.fastCloneDeep)(this.schemas[key]); } else if (this.groups.hasOwnProperty(group)) { var groupComponents = this.groups[group].components; if (groupComponents.hasOwnProperty(key)) { info = (0, _utils.fastCloneDeep)(groupComponents[key].schema); } } else if (group === 'searchFields') { //Search components go into this group var _resourceGroups = this.groups.resource.subgroups; for (var ix = 0; ix < _resourceGroups.length; ix++) { var _resourceGroup = _resourceGroups[ix]; if (_resourceGroup.components.hasOwnProperty("component-".concat(key))) { info = (0, _utils.fastCloneDeep)(_resourceGroup.components["component-".concat(key)].schema); break; } } } if (info) { info.key = this.generateKey(info); } return info; } }, { key: "getComponentsPath", value: function getComponentsPath(component, parent) { // Get path to the component in the parent component. var path = 'components'; var columnIndex = 0; var tableRowIndex = 0; var tableColumnIndex = 0; var tabIndex = 0; switch (parent.type) { case 'table': tableRowIndex = _lodash["default"].findIndex(parent.rows, function (row) { return row.some(function (column) { return column.components.some(function (comp) { return comp.key === component.key; }); }); }); tableColumnIndex = _lodash["default"].findIndex(parent.rows[tableRowIndex], function (column) { return column.components.some(function (comp) { return comp.key === component.key; }); }); path = "rows[".concat(tableRowIndex, "][").concat(tableColumnIndex, "].components"); break; case 'columns': columnIndex = _lodash["default"].findIndex(parent.columns, function (column) { return column.components.some(function (comp) { return comp.key === component.key; }); }); path = "columns[".concat(columnIndex, "].components"); break; case 'tabs': tabIndex = _lodash["default"].findIndex(parent.components, function (tab) { return tab.components.some(function (comp) { return comp.key === component.key; }); }); path = "components[".concat(tabIndex, "].components"); break; } return path; } /* eslint-disable max-statements */ }, { key: "onDrop", value: function onDrop(element, target, source, sibling) { var _this$groups$group, _this8 = this; if (!target) { return; } // If you try to drop within itself. if (element.contains(target)) { return; } var key = element.getAttribute('data-key'); var type = element.getAttribute('data-type'); var group = element.getAttribute('data-group'); var 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 = _lodash["default"].findIndex(source.formioContainer, { key: element.formioComponent.component.key }); if (index !== -1) { // Grab and remove the component from the source container. info = source.formioContainer.splice(_lodash["default"].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. var compKey = group === 'resource' ? "component-".concat(key) : key; var draggableComponent = ((_this$groups$group = this.groups[group]) === null || _this$groups$group === void 0 ? void 0 : _this$groups$group.components[compKey]) || {}; if (draggableComponent.disableSiblings) { var isCompAlreadyExists = false; (0, _formUtils.eachComponent)(this.webform.components, function (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 ".concat(draggableComponent.key, " component to one page.")); return; } } if (draggableComponent.uniqueComponent) { var _isCompAlreadyExists = false; (0, _formUtils.eachComponent)(this.webform.components, function (component) { if (component.key === draggableComponent.schema.key) { _isCompAlreadyExists = true; return; } }, true); if (_isCompAlreadyExists) { this.webform.redraw(); this.webform.setAlert('danger', "You cannot add more than one ".concat(draggableComponent.title, " component to one page.")); return; } } if (target !== source) { // Ensure the key remains unique in its new container. _builder["default"].uniquify(this.findNamespaceRoot(target.formioComponent), info); } var parent = target.formioComponent; // Insert in the new container. if (target.formioContainer) { if (sibling) { if (!sibling.getAttribute('data-noattach')) { index = _lodash["default"].findIndex(target.formioContainer, { key: _lodash["default"].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 = _lodash["default"].findIndex(_lodash["default"].get(parent.schema, path), { key: info.key }); if (index === -1) { index = 0; } } if (parent && parent.addChildComponent) { parent.addChildComponent(info, element, target, source, sibling); } var componentInDataGrid = parent.type === 'datagrid'; if (isNew && !this.options.noNewEdit && !info.noNewEdit && !(this.options.design && info.type === 'reviewpage')) { this.editComponent(info, target, isNew, null, null, { inDataGrid: componentInDataGrid }); } // Only rebuild the parts needing to be rebuilt. var 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 = _nativePromiseOnly["default"].resolve(); } return rebuild.then(function () { _this8.emit('addComponent', info, parent, path, index, isNew && !_this8.options.noNewEdit && !info.noNewEdit); if (!isNew || _this8.options.noNewEdit || info.noNewEdit) { _this8.emit('change', _this8.form); } }); } }, { key: "setForm", value: function setForm(form) { var _this$options$propert, _this9 = this; if (!form.components) { form.components = []; } if (form && form.properties) { this.options.properties = form.properties; } this.keyboardActionsEnabled = _lodash["default"].get(this.options, 'keyboardBuilder', false) || ((_this$options$propert = this.options.properties) === null || _this$options$propert === void 0 ? void 0 : _this$options$propert.keyboardBuilder); var 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) { var shouldRebuild = !this.webform.form.components || form.components.length !== this.webform.form.components.length; return this.webform.setForm(form, { keepAsReference: tru