UNPKG

formiojs

Version:

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

1,401 lines (1,109 loc) • 75.6 kB
"use strict"; 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); } require("core-js/modules/es.reflect.construct.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.reflect.set.js"); require("core-js/modules/es.symbol.js"); require("core-js/modules/es.symbol.description.js"); require("core-js/modules/es.symbol.iterator.js"); require("core-js/modules/es.string.iterator.js"); require("core-js/modules/es.array.from.js"); require("core-js/modules/es.array.slice.js"); require("core-js/modules/es.function.name.js"); require("core-js/modules/es.object.get-own-property-descriptors.js"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("core-js/modules/es.array.concat.js"); require("core-js/modules/es.regexp.exec.js"); require("core-js/modules/es.string.replace.js"); require("core-js/modules/es.string.split.js"); require("core-js/modules/es.array.find.js"); require("core-js/modules/es.object.to-string.js"); require("core-js/modules/es.string.trim.js"); require("core-js/modules/es.array.map.js"); require("core-js/modules/es.array.join.js"); require("core-js/modules/es.string.match.js"); require("core-js/modules/web.dom-collections.for-each.js"); require("core-js/modules/es.array.sort.js"); require("core-js/modules/es.array.includes.js"); require("core-js/modules/es.string.includes.js"); require("core-js/modules/es.array.filter.js"); require("core-js/modules/es.regexp.to-string.js"); require("core-js/modules/es.array.iterator.js"); require("core-js/modules/web.dom-collections.iterator.js"); require("core-js/modules/es.string.starts-with.js"); require("core-js/modules/es.object.assign.js"); require("core-js/modules/es.object.keys.js"); require("core-js/modules/es.number.constructor.js"); require("core-js/modules/es.number.is-nan.js"); require("core-js/modules/es.number.is-finite.js"); require("core-js/modules/es.array.find-index.js"); require("core-js/modules/es.object.get-prototype-of.js"); var _lodash = _interopRequireDefault(require("lodash")); var _Formio = require("../../Formio"); var _Field2 = _interopRequireDefault(require("../_classes/field/Field")); var _Form = _interopRequireDefault(require("../../Form")); var _nativePromiseOnly = _interopRequireDefault(require("native-promise-only")); var _utils = require("../../utils/utils"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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 _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 _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, 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 set(target, property, value, receiver) { if (typeof Reflect !== "undefined" && Reflect.set) { set = Reflect.set; } else { set = function set(target, property, value, receiver) { var base = _superPropBase(target, property); var desc; if (base) { desc = Object.getOwnPropertyDescriptor(base, property); if (desc.set) { desc.set.call(receiver, value); return true; } else if (!desc.writable) { return false; } } desc = Object.getOwnPropertyDescriptor(receiver, property); if (desc) { if (!desc.writable) { return false; } desc.value = value; Object.defineProperty(receiver, property, desc); } else { _defineProperty(receiver, property, value); } return true; }; } return set(target, property, value, receiver); } function _set(target, property, value, receiver, isStrict) { var s = set(target, property, value, receiver || target); if (!s && isStrict) { throw new Error('failed to set property'); } return value; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } 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 || 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 : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var Choices; if (typeof window !== 'undefined') { Choices = require('../../utils/ChoicesWrapper').default; } var SelectComponent = /*#__PURE__*/function (_Field) { _inherits(SelectComponent, _Field); var _super = _createSuper(SelectComponent); function SelectComponent() { _classCallCheck(this, SelectComponent); return _super.apply(this, arguments); } _createClass(SelectComponent, [{ key: "init", value: function init() { var _this = this; _get(_getPrototypeOf(SelectComponent.prototype), "init", this).call(this); this.templateData = {}; this.validators = this.validators.concat(['select', 'onlyAvailableItems']); // Trigger an update. var updateArgs = []; var triggerUpdate = _lodash.default.debounce(function () { updateArgs = []; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _this.updateItems.apply(_this, args); }, 100); this.triggerUpdate = function () { // Make sure we always resolve the previous promise before reassign it if (typeof _this.itemsLoadedResolve === 'function') { _this.itemsLoadedResolve(); } _this.itemsLoaded = new _nativePromiseOnly.default(function (resolve) { _this.itemsLoadedResolve = resolve; }); for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } if (args.length) { updateArgs = args; } return triggerUpdate.apply(void 0, _toConsumableArray(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 _nativePromiseOnly.default(function (resolve) { _this.itemsLoadedResolve = resolve; }); if (this.isHtmlRenderMode()) { this.activate(); } // Get the template keys for this select component. this.getTemplateKeys(); } }, { key: "dataReady", get: function get() { // 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 _nativePromiseOnly.default.resolve(); } return this.itemsLoaded; } }, { key: "defaultSchema", get: function get() { return SelectComponent.schema(); } }, { key: "emptyValue", get: function get() { 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) { var firstItem = this.component.data.json[0]; var firstValue; if (this.valueProperty) { firstValue = _lodash.default.get(firstItem, this.valueProperty); } else { firstValue = firstItem; } if (firstValue && typeof firstValue === 'string') { return ''; } else { return {}; } } if (this.valueProperty) { return ''; } return {}; } }, { key: "valueProperty", get: function get() { 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 ''; } }, { key: "inputInfo", get: function get() { var info = _get(_getPrototypeOf(SelectComponent.prototype), "elementInfo", this).call(this); info.type = 'select'; info.changeEvent = 'change'; return info; } }, { key: "isSelectResource", get: function get() { return this.component.dataSrc === 'resource'; } }, { key: "isSelectURL", get: function get() { return this.component.dataSrc === 'url'; } }, { key: "itemsFromUrl", get: function get() { return this.isSelectResource || this.isSelectURL; } }, { key: "isInfiniteScrollProvided", get: function get() { return this.itemsFromUrl; } }, { key: "shouldDisabled", get: function get() { return _get(_getPrototypeOf(SelectComponent.prototype), "shouldDisabled", this) || this.parentDisabled; } }, { key: "isEntireObjectDisplay", value: function isEntireObjectDisplay() { return this.component.dataSrc === 'resource' && this.valueProperty === 'data'; } }, { key: "getSelectTemplate", value: function getSelectTemplate(data, value) { if (!this.component.template) { return data.label; } var options = { noeval: this.itemsFromUrl, data: {} }; var template = this.sanitize(this.component.template ? this.interpolate(this.component.template, { item: data }) : data.label, this.shouldSanitizeValue); if (value && !_lodash.default.isObject(value) && 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[value] = options.data.item; } return template; } }, { key: "selectValueAndLabel", value: function selectValueAndLabel(data) { var value = this.getOptionValue(this.itemValue(data)); return { value: value, label: this.itemTemplate(data, value) }; } }, { key: "itemTemplate", value: function itemTemplate(data, value) { if (!_lodash.default.isNumber(data) && _lodash.default.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) { var itemLabel = data.label || data; var _value = typeof itemLabel === 'string' ? this.t(itemLabel, { _userInput: true }) : itemLabel; return this.sanitize(_value, this.shouldSanitizeValue); } if (typeof data === 'string' || typeof data === 'number') { var selectData = this.selectData; if (selectData) { data = selectData; } else { return this.sanitize(this.t(data, { _userInput: true }), this.shouldSanitizeValue); } } if (data.data) { // checking additional fields in the template for the selected Entire Object option var hasNestedFields = /item\.data\.\w*/g.test(this.component.template); data.data = this.isEntireObjectDisplay() && _lodash.default.isObject(data.data) && !hasNestedFields ? JSON.stringify(data.data) : data.data; } var template = this.sanitize(this.getSelectTemplate(data, value), this.shouldSanitizeValue); if (template) { var _this$i18next; var label = template.replace(/<\/?[^>]+(>|$)/g, ''); var hasTranslator = (_this$i18next = this.i18next) === null || _this$i18next === void 0 ? void 0 : _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); } } /** * Adds an option to the select dropdown. * * @param value * @param label */ }, { key: "addOption", value: function addOption(value, label) { var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var id = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : (0, _utils.getRandomComponentId)(); if (_lodash.default.isNil(label)) return; var idPath = this.component.idPath ? this.component.idPath.split('.').reduceRight(function (obj, key) { return _defineProperty({}, key, obj); }, id) : {}; var option = _objectSpread({ value: this.getOptionValue(value), label: label }, idPath); var skipOption = this.component.uniqueOptions ? !!this.selectOptions.find(function (selectOption) { return _lodash.default.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 && _lodash.default.isObject(option.value) && _lodash.default.isEmpty(option.value)) { option.value = ''; } // Add element to option so we can reference it later. var div = document.createElement('div'); div.innerHTML = this.sanitize(this.renderTemplate('selectOption', { selected: _lodash.default.isEqual(this.getOptionValue(this.dataValue), option.value), option: option, attrs: attrs, id: id, useId: this.valueProperty === '' && _lodash.default.isObject(value) && id }), this.shouldSanitizeValue).trim(); option.element = div.firstChild; this.refs.selectContainer.appendChild(option.element); } } }, { key: "addValueOptions", value: function addValueOptions(items) { items = items || []; var added = false; if (!this.selectOptions.length) { // Add the currently selected choices if they don't already exist. var currentChoices = Array.isArray(this.dataValue) ? this.dataValue : [this.dataValue]; added = this.addCurrentChoices(currentChoices, items); if (!added && !this.component.multiple) { this.addPlaceholder(); } } return added; } }, { key: "disableInfiniteScroll", value: function disableInfiniteScroll() { if (!this.downloadedResources) { return; } this.downloadedResources.serverCount = this.downloadedResources.length; this.serverCount = this.downloadedResources.length; } /* eslint-disable max-statements */ }, { key: "setItems", value: function setItems(items, fromSearch) { var _this2 = this, _this$choices, _this$choices$input; // 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 && typeof this.component.onSetItems === 'function') { var newItems = this.component.onSetItems(this, 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 = _lodash.default.get(items, this.component.selectValues, items) || []; } var areItemsEqual; if (this.itemsFromUrl) { areItemsEqual = this.isSelectURL ? _lodash.default.isEqual(items, this.downloadedResources) : false; var areItemsEnded = this.component.limit > items.length; var 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 (!_lodash.default.isEmpty(this.dataValue) && this.component.idPath) { var selectedOptionId = _lodash.default.get(this.dataValue, this.component.idPath, null); var newOptionWithSameId = !_lodash.default.isNil(selectedOptionId) && items.find(function (item) { var itemId = _lodash.default.get(item, _this2.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. _lodash.default.each(items, function (item, index) { // preventing references of the components inside the form to the parent form when building forms if (_this2.root && _this2.root.options.editForm && _this2.root.options.editForm._id && _this2.root.options.editForm._id === item._id) return; var itemValueAndLabel = _this2.selectValueAndLabel(item); _this2.addOption(itemValueAndLabel.value, itemValueAndLabel.label, {}, _lodash.default.get(item, _this2.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; var searching = fromSearch && ((_this$choices = this.choices) === null || _this$choices === void 0 ? void 0 : (_this$choices$input = _this$choices.input) === null || _this$choices$input === void 0 ? void 0 : _this$choices$input.isFocussed); if (!searching) { // If a value is provided, then select it. if (!this.isEmpty()) { this.setValue(this.dataValue, { noUpdateEvent: true }); } else if (this.shouldAddDefaultValue && !this.options.readOnly) { // If a default value is provided then select it. var defaultValue = this.defaultValue; if (!this.isEmpty(defaultValue)) { this.setValue(defaultValue); } } } // Say we are done loading the items. this.itemsLoadedResolve(); } }, { key: "getSingleItemValueForHTMLMode", value: function getSingleItemValueForHTMLMode(data) { var _this$selectOptions; var option = (_this$selectOptions = this.selectOptions) === null || _this$selectOptions === void 0 ? void 0 : _this$selectOptions.find(function (_ref2) { var value = _ref2.value; return _lodash.default.isEqual(value, data); }); if (option) { return option.label || data; } return data; } }, { key: "itemValueForHTMLMode", value: function itemValueForHTMLMode(value) { var _this3 = this; if (!this.isHtmlRenderMode()) { return _get(_getPrototypeOf(SelectComponent.prototype), "itemValueForHTMLMode", this).call(this, value); } if (Array.isArray(value)) { var values = value.map(function (item) { return Array.isArray(item) ? _this3.itemValueForHTMLMode(item) : _this3.getSingleItemValueForHTMLMode(item); }); return values.join(', '); } return this.getSingleItemValueForHTMLMode(value); } /* eslint-enable max-statements */ }, { key: "defaultValue", get: function get() { var defaultValue = _get(_getPrototypeOf(SelectComponent.prototype), "defaultValue", this); if (!defaultValue && (this.component.defaultValue === false || this.component.defaultValue === 0)) { defaultValue = this.component.defaultValue; } return defaultValue; } }, { key: "getTemplateKeys", value: function getTemplateKeys() { var _this4 = this; this.templateKeys = []; if (this.options.readOnly && this.component.template) { var keys = this.component.template.match(/({{\s*(.*?)\s*}})/g); if (keys) { keys.forEach(function (key) { var propKey = key.match(/{{\s*item\.(.*?)\s*}}/); if (propKey && propKey.length > 1) { _this4.templateKeys.push(propKey[1]); } }); } } } }, { key: "loadingError", get: function get() { return !this.component.refreshOn && !this.component.refreshOnBlur && this.networkError; } }, { key: "selectData", get: function get() { var selectData = _lodash.default.get(this.root, 'submission.metadata.selectData', {}); return _lodash.default.get(selectData, this.path); } }, { key: "shouldLoad", get: function get() { if (this.loadingError) { return false; } // Live forms should always load. if (!this.options.readOnly || this.options.display === 'pdf' && 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. var dataValue = this.dataValue; var selectData = this.selectData; return this.templateKeys.reduce(function (shouldLoad, key) { var hasValue = _lodash.default.has(dataValue, key) || _lodash.default.has(selectData, key); return shouldLoad || !hasValue; }, false); } // Return that we should load. return true; } }, { key: "loadItems", value: function loadItems(url, search, headers, options, method, body) { var _this5 = this; 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. var 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; } var limit = this.component.limit || 100; var skip = this.isScrollLoading ? this.selectOptions.length : 0; var query = this.component.disableLimit ? {} : { limit: limit, skip: skip }; // Allow for url interpolation. url = this.interpolate(url, { formioBase: _Formio.GlobalFormio.getBaseUrl(), search: search, limit: limit, skip: skip, page: Math.abs(Math.floor(skip / limit)) }); // Add search capability. if (this.component.searchField && search) { if (Array.isArray(search)) { query["".concat(this.component.searchField)] = search.join(','); } else { query["".concat(this.component.searchField)] = search; } } // 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 (!_lodash.default.isEmpty(query)) { // Add the query string. url += (!url.includes('?') ? '?' : '&') + _Formio.GlobalFormio.serialize(query, function (item) { return _this5.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.GlobalFormio.makeRequest(this.options.formio, 'select', url, method, body, options).then(function (response) { _this5.loading = false; _this5.error = null; _this5.setItems(response, !!search); }).catch(function (err) { if (_this5.itemsFromUrl) { _this5.setItems([]); _this5.disableInfiniteScroll(); } _this5.isScrollLoading = false; _this5.handleLoadingError(err); }); } }, { key: "handleLoadingError", value: function 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 ".concat(this.key)); } /** * Get the request headers for this select dropdown. */ }, { key: "requestHeaders", get: function get() { var _this6 = this; // Create the headers object. var headers = new _Formio.GlobalFormio.Headers(); // Add custom headers to the url. if (this.component.data && this.component.data.headers) { try { _lodash.default.each(this.component.data.headers, function (header) { if (header.key) { headers.set(header.key, _this6.interpolate(header.value)); } }); } catch (err) { console.warn(err.message); } } return headers; } }, { key: "getCustomItems", value: function getCustomItems() { var customItems = this.evaluate(this.component.data.custom, { values: [] }, 'values'); this.asyncValues = (0, _utils.isPromise)(customItems); return customItems; } }, { key: "asyncCustomValues", value: function asyncCustomValues() { if (!_lodash.default.isBoolean(this.asyncValues)) { this.getCustomItems(); } return this.asyncValues; } }, { key: "updateCustomItems", value: function updateCustomItems(forceUpdate) { var _this7 = this; if (this.asyncCustomValues()) { if (!forceUpdate && !this.active) { this.itemsLoadedResolve(); return; } this.loading = true; this.getCustomItems().then(function (items) { _this7.loading = false; _this7.setItems(items || []); }).catch(function (err) { _this7.handleLoadingError(err); }); } else { this.setItems(this.getCustomItems() || []); } } }, { key: "isEmpty", value: function isEmpty() { var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.dataValue; return _get(_getPrototypeOf(SelectComponent.prototype), "isEmpty", this).call(this, value) || value === undefined; } }, { key: "refresh", value: function refresh(value, _ref3) { var instance = _ref3.instance; if (this.component.clearOnRefresh && instance && !instance.pristine) { this.setValue(this.emptyValue); } this.updateItems(null, true); } }, { key: "additionalResourcesAvailable", get: function get() { return _lodash.default.isNil(this.serverCount) || this.serverCount > this.downloadedResources.length; } }, { key: "serverCount", get: function get() { if (this.isFromSearch) { return this.searchServerCount; } return this.defaultServerCount; }, set: function set(value) { if (this.isFromSearch) { this.searchServerCount = value; } else { this.defaultServerCount = value; } } }, { key: "downloadedResources", get: function get() { if (this.isFromSearch) { return this.searchDownloadedResources; } return this.defaultDownloadedResources; }, set: function set(value) { if (this.isFromSearch) { this.searchDownloadedResources = value; } else { this.defaultDownloadedResources = value; } } /* eslint-disable max-statements */ }, { key: "updateItems", value: function updateItems(searchInput, forceUpdate) { var _this8 = this; if (!this.component.data) { console.warn("Select component ".concat(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; } var resourceUrl = this.options.formio ? this.options.formio.formsUrl : "".concat(_Formio.GlobalFormio.getProjectUrl(), "/form"); resourceUrl += "/".concat(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 ".concat(this.key)); } } else { this.setItems(this.downloadedResources); } break; } case 'url': { if (!forceUpdate && !this.active && !this.calculatedValue) { // If we are lazyLoading, wait until activated. this.itemsLoadedResolve(); return; } var url = this.component.data.url; var method; var body; if (url.startsWith('/')) { // if URL starts with '/project', we should use base URL to avoid issues with URL formed like <base_url>/<project_name>/project/<project_id>/... var baseUrl = url.startsWith('/project') ? _Formio.GlobalFormio.getBaseUrl() : _Formio.GlobalFormio.getProjectUrl() || _Formio.GlobalFormio.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; } } var 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) { var request = window.indexedDB.open(this.component.indexeddb.database); request.onupgradeneeded = function (event) { if (_this8.component.customOptions) { var db = event.target.result; var objectStore = db.createObjectStore(_this8.component.indexeddb.table, { keyPath: 'myKey', autoIncrement: true }); objectStore.transaction.oncomplete = function () { var transaction = db.transaction(_this8.component.indexeddb.table, 'readwrite'); _this8.component.customOptions.forEach(function (item) { transaction.objectStore(_this8.component.indexeddb.table).put(item); }); }; } }; request.onerror = function () { window.alert(request.errorCode); }; request.onsuccess = function (event) { var db = event.target.result; var transaction = db.transaction(_this8.component.indexeddb.table, 'readwrite'); var objectStore = transaction.objectStore(_this8.component.indexeddb.table); new _nativePromiseOnly.default(function (resolve) { var responseItems = []; objectStore.getAll().onsuccess = function (event) { event.target.result.forEach(function (item) { responseItems.push(item); }); resolve(responseItems); }; }).then(function (items) { if (!_lodash.default.isEmpty(_this8.component.indexeddb.filter)) { items = _lodash.default.filter(items, _this8.component.indexeddb.filter); } _this8.setItems(items); }); }; } } } } /* eslint-enable max-statements */ }, { key: "addPlaceholder", value: function addPlaceholder() { if (!this.component.placeholder) { return; } this.addOption('', this.component.placeholder, { placeholder: true }); } /** * Activate this select control. */ }, { key: "activate", value: function activate() { if (this.loading || !this.active) { this.setLoadingItem(); } if (this.active) { return; } this.activated = true; this.triggerUpdate(); } }, { key: "setLoadingItem", value: function setLoadingItem() { var addToCurrentList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; if (this.choices) { if (addToCurrentList) { this.choices.setChoices([{ value: "".concat(this.id, "-loading"), label: 'Loading...', disabled: true }], 'value', 'label'); } else { this.choices.setChoices([{ value: '', label: "<i class=\"".concat(this.iconClass('refresh'), "\" style=\"font-size:1.3em;\"></i>"), disabled: true }], 'value', 'label', true); } } else if (this.component.dataSrc === 'url' || this.component.dataSrc === 'resource') { this.addOption('', this.t('loading...')); } } }, { key: "active", get: function get() { return !this.component.lazyLoad || this.activated; } }, { key: "render", value: function render() { var info = this.inputInfo; info.attr = info.attr || {}; info.multiple = this.component.multiple; return _get(_getPrototypeOf(SelectComponent.prototype), "render", this).call(this, this.wrapElement(this.renderTemplate('select', { input: info, selectOptions: '', index: null }))); } }, { key: "wrapElement", value: function wrapElement(element) { return this.component.addResource && !this.options.readOnly ? this.renderTemplate('resourceAdd', { element: element }) : element; } }, { key: "choicesOptions", value: function choicesOptions() { var useSearch = this.component.hasOwnProperty('searchEnabled') ? this.component.searchEnabled : true; var placeholderValue = this.t(this.component.placeholder, { _userInput: true }); var customOptions = this.component.customOptions || {}; if (typeof customOptions == 'string') { try { customOptions = JSON.parse(customOptions); } catch (err) { console.warn(err.message); customOptions = {}; } } var commonFuseOptions = { maxPatternLength: 1000, distance: 1000 }; return _objectSpread({ removeItemButton: this.component.disabled ? false : _lodash.default.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, 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: _lodash.default.get(this, 'component.searchFields', ['label']), shadowRoot: this.root ? this.root.shadowRoot : null, fuseOptions: this.component.useExactSearch ? _objectSpread({ tokenize: true, matchAllTokens: true }, commonFuseOptions) : Object.assign({}, _lodash.default.get(this, 'component.fuseOptions', {}), _objectSpread({ include: 'score', threshold: _lodash.default.get(this, 'component.selectThreshold', 0.3) }, commonFuseOptions)), valueComparer: _lodash.default.isEqual, resetScrollPosition: false }, customOptions); } /* eslint-disable max-statements */ }, { key: "attach", value: function attach(element) { var _this9 = this, _this$choices2, _this$choices2$contai, _this$choices2$contai2; var superAttach = _get(_getPrototypeOf(SelectComponent.prototype), "attach", this).call(this, element); this.loadRefs(element, { selectContainer: 'single', addResource: 'single', autocompleteInput: 'single' }); //enable autocomplete for select var autocompleteInput = this.refs.autocompleteInput; if (autocompleteInput) { this.addEventListener(autocompleteInput, 'change', function (event) { _this9.setValue(event.target.value); }); } var input = this.refs.selectContainer; if (!input) { return; } this.addEventListener(input, this.inputInfo.changeEvent, function () { return _this9.updateValue(null, { modified: true }); }); this.attachRefreshOnBlur(); if (this.component.widget === 'html5') { this.triggerUpdate(null, true); if (this.visible) { this.setItems(this.selectOptions || []); } this.focusableElement = input; this.addEventListener(input, 'focus', function () { return _this9.update(); }); this.addEventListener(input, 'keydown', function (event) { var key = event.key; if (['Backspace', 'Delete'].includes(key)) { _this9.setValue(_this9.emptyValue); } }); return; } var tabIndex = input.tabIndex; this.addPlaceholder(); input.setAttribute('dir', this.i18next.dir()); if ((_this$choices2 = this.choices) !== null && _this$choices2 !== void 0 && (_this$choices2$contai = _this$choices2.containerOuter) !== null && _this$choices2$contai !== void 0 && (_this$choices2$contai2 = _this$choices2$contai.element) !== null && _this$choices2$contai2 !== void 0 && _this$choices2$contai2.parentNode) { this.choices.destroy(); } var 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'); if (choicesOptions.searchEnabled) { this.addEventListener(this.choices.containerOuter.element, 'focus', function () { return _this9.focusableElement.focus(); }); } } if (this.itemsFromUrl) { this.scrollList = this.choices.choiceList.element; this.addEventListener(this.scrollList, 'scroll', function () { return _this9.onScroll(); }); } } 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', function (event) { _this9.isFromSearch = !!event.target.value; if (!event.target.value) { _this9.triggerUpdate(); } else { _this9.serverCount = null; _this9.downloadedResources = []; } }); } this.addEventListener(input, 'choice', function () { if (_this9.component.multiple && _this9.component.dataSrc === 'resource' && _this9.isFromSearch) { _this9.triggerUpdate(); } _this9.isFromSearch = false; }); // avoid spamming the resource/url endpoint when we have server side filtering enabled. var debounceTimeout = this.component.searchField && (this.isSelectResource || this.isSelectURL) ? (this.component.searchDebounce === 0 ? 0 : this.component.searchDebounce || this.defaultSchema.searchDebounce) * 1000 : 0; var updateComponent = function updateComponent(evt) { _this9.triggerUpdate(evt.detail.value); }; this.addEventListener(input, 'search', _lodash.default.debounce(updateComponent, debounceTimeout)); this.addEventListener(input, 'stopSearch', function () { return _this9.triggerUpdate(); }); this.addEventListener(input, 'hideDropdown', function () { if (_this9.choices && _this9.choices.input && _this9.choices.input.element) { _this9.choices.input.element.value = ''; } _this9.updateItems(null, true); }); } this.addEventListener(input, 'showDropdown', function () { return _this9.update(); }); if (this.choices && choicesOptions.placeholderValue && this.choices._isSelectOneElement) { this.addPlaceholderItem(choicesOptions.placeholderValue); this.addEventListener(input, 'removeItem', function () { _this9.addPlaceholderItem(choicesOptio