@formio/js 5.1.0-dev.6086.0b0957a → 5.1.0-dev.6090.1122fcd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,4 +43,4 @@
43
43
 
44
44
  //! moment.js
45
45
 
46
- //! version : 0.5.46
46
+ //! version : 0.5.48
@@ -661,7 +661,9 @@ class Webform extends NestedDataComponent_1.default {
661
661
  const rebuild = this.rebuild() || Promise.resolve();
662
662
  return rebuild.then(() => {
663
663
  this.emit('formLoad', form);
664
- this.triggerCaptcha();
664
+ if (!this.options.server) {
665
+ this.triggerCaptcha();
666
+ }
665
667
  // Make sure to trigger onChange after a render event occurs to speed up form rendering.
666
668
  setTimeout(() => {
667
669
  this.onChange(flags);
@@ -77,6 +77,7 @@ export default class WebformBuilder extends Component {
77
77
  removeComponent(component: any, parent: any, original: any, componentInstance: any): boolean | undefined;
78
78
  replaceDoubleQuotes(data: any, fieldsToRemoveDoubleQuotes?: any[]): any;
79
79
  updateComponent(component: any, changed: any): void;
80
+ originalDefaultValue: any;
80
81
  findRepeatablePaths(): any[];
81
82
  highlightInvalidComponents(): void;
82
83
  /**
@@ -1070,6 +1070,17 @@ class WebformBuilder extends Component_1.default {
1070
1070
  'fields.month.required',
1071
1071
  'fields.year.required',
1072
1072
  ]));
1073
+ if (defaultValueComponent.component.components) {
1074
+ if (!this.originalDefaultValue) {
1075
+ this.originalDefaultValue = (0, utils_1.fastCloneDeep)(defaultValueComponent.component);
1076
+ }
1077
+ (0, formUtils_1.eachComponent)(defaultValueComponent.component.components, (comp => {
1078
+ var _a;
1079
+ if ((_a = comp.validate) === null || _a === void 0 ? void 0 : _a.required) {
1080
+ comp.validate.required = false;
1081
+ }
1082
+ }));
1083
+ }
1073
1084
  const parentComponent = defaultValueComponent.parent;
1074
1085
  let tabIndex = -1;
1075
1086
  let index = -1;
@@ -1161,6 +1172,9 @@ class WebformBuilder extends Component_1.default {
1161
1172
  if (index !== -1) {
1162
1173
  let submissionData = this.editForm.submission.data;
1163
1174
  submissionData = submissionData.componentJson || submissionData;
1175
+ if (submissionData.components && this.originalDefaultValue) {
1176
+ submissionData.components = this.originalDefaultValue.components;
1177
+ }
1164
1178
  const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
1165
1179
  this.replaceDoubleQuotes(submissionData, fieldsToRemoveDoubleQuotes);
1166
1180
  this.hook('beforeSaveComponentSettings', submissionData);
@@ -903,8 +903,9 @@ class SelectComponent extends ListComponent_1.default {
903
903
  });
904
904
  }
905
905
  // Add value options.
906
+ const value = this.undoValueTyping(this.dataValue);
906
907
  this.addValueOptions();
907
- this.setChoicesValue(this.dataValue);
908
+ this.setChoicesValue(value);
908
909
  if (this.isSelectResource && this.refs.addResource) {
909
910
  this.addEventListener(this.refs.addResource, 'click', (event) => {
910
911
  event.preventDefault();
@@ -1283,6 +1284,9 @@ class SelectComponent extends ListComponent_1.default {
1283
1284
  this.lazyLoadInit = true;
1284
1285
  const searchProperty = this.component.searchField || this.component.valueProperty;
1285
1286
  this.triggerUpdate(lodash_1.default.get(value.data || value, searchProperty, value), true);
1287
+ this.itemsLoaded.then(() => {
1288
+ this.setChoicesValue(value, hasPreviousValue, flags);
1289
+ });
1286
1290
  return changed;
1287
1291
  }
1288
1292
  // Add the value options.
@@ -150,6 +150,9 @@ class SelectBoxesComponent extends Radio_1.default {
150
150
  }
151
151
  }
152
152
  }
153
+ else if (lodash_1.default.isEmpty(this.loadedOptions) && !checkedValues.length) {
154
+ value = {};
155
+ }
153
156
  return value;
154
157
  }
155
158
  /**
@@ -102,8 +102,8 @@ class TextFieldComponent extends Input_1.default {
102
102
  if (((_c = this.component.widget) === null || _c === void 0 ? void 0 : _c.type) === 'calendar') {
103
103
  this.component.widget = Object.assign(Object.assign({}, this.component.widget), { readOnly: this.options.readOnly, timezone,
104
104
  displayInTimezone, locale: this.component.widget.locale || this.options.language, saveAs: 'text' });
105
- // update originalComponent to include widget settings after component initialization
106
- // originalComponent is used to restore the component (and widget) after evaluating field logic
105
+ // update originalComponent to include widget settings after component initialization
106
+ // originalComponent is used to restore the component (and widget) after evaluating field logic
107
107
  this.originalComponent = FormioUtils.fastCloneDeep(this.component);
108
108
  }
109
109
  }
@@ -490,6 +490,15 @@ export function getFocusableElements(element: HTMLElement): NodeList<HTMLElement
490
490
  * @returns {Array<string>|null} - The saved types for the component
491
491
  */
492
492
  export function getComponentSavedTypes(fullSchema: import('@formio/core').Component): Array<string> | null;
493
+ /**
494
+ * Checks if a string has timezone information encoded in it
495
+ * Example: 2024-01-01T00:00:00Z -> true
496
+ * Example: 2024-01-01T00:00:00+03:00 -> true
497
+ * Example: 2011-05-03T00:00:00 -> false
498
+ * @param {string} value the string value to check
499
+ * @returns {boolean} if value has encoded timezone
500
+ */
501
+ export function hasEncodedTimezone(value: string): boolean;
493
502
  export * from "./formUtils";
494
503
  /**
495
504
  * Map values through unfold and return first non-nil value.
@@ -19,7 +19,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.firstNonNil = exports.unfold = exports.bootstrapVersion = exports.uniqueKey = exports.iterateKey = exports.delay = exports.fieldData = exports.getCurrencyAffixes = exports.getNumberDecimalLimit = exports.getNumberSeparators = exports.matchInputMask = exports.unmaskValue = exports.getInputMask = exports.convertFormatToMask = exports.convertFormatToMoment = exports.convertFormatToFlatpickr = exports.getLocaleDateFormatInfo = exports.formatOffset = exports.formatDate = exports.momentDate = exports.loadZones = exports.shouldLoadZones = exports.zonesLoaded = exports.offsetDate = exports.currentTimezone = exports.isValidDate = exports.getDateSetting = exports.guid = exports.uniqueName = exports.convertStringToHTMLElement = exports.unescapeHTML = exports.removeHTML = exports.setActionProperty = exports.checkTrigger = exports.checkCondition = exports.checkJsonConditional = exports.checkCustomConditional = exports.getComponentActualValue = exports.checkSimpleConditional = exports.checkCalculated = exports.isMongoId = exports.boolValue = exports.getScriptPlugin = exports.getElementRect = exports.getPropertyValue = exports.getRandomComponentId = exports.evaluate = exports.moment = exports.ConditionOperators = exports.jsonLogic = void 0;
22
- exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.interpolate = exports.Evaluator = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = exports.observeOverload = exports.withSwitch = void 0;
22
+ exports.hasEncodedTimezone = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.interpolate = exports.Evaluator = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = exports.observeOverload = exports.withSwitch = void 0;
23
23
  const lodash_1 = __importDefault(require("lodash"));
24
24
  exports._ = lodash_1.default;
25
25
  const json_logic_js_1 = __importDefault(require("json-logic-js"));
@@ -1646,3 +1646,18 @@ const interpolateErrors = (component, errors, interpolateFn) => {
1646
1646
  });
1647
1647
  };
1648
1648
  exports.interpolateErrors = interpolateErrors;
1649
+ /**
1650
+ * Checks if a string has timezone information encoded in it
1651
+ * Example: 2024-01-01T00:00:00Z -> true
1652
+ * Example: 2024-01-01T00:00:00+03:00 -> true
1653
+ * Example: 2011-05-03T00:00:00 -> false
1654
+ * @param {string} value the string value to check
1655
+ * @returns {boolean} if value has encoded timezone
1656
+ */
1657
+ function hasEncodedTimezone(value) {
1658
+ if (typeof value !== 'string') {
1659
+ return false;
1660
+ }
1661
+ return (value.substring(value.length - 1) === 'z' || value.substring(value.length - 1) === 'Z' || value.match(/[+|-][0-9]{2}:[0-9]{2}$/));
1662
+ }
1663
+ exports.hasEncodedTimezone = hasEncodedTimezone;
@@ -286,6 +286,11 @@ class CalendarWidget extends InputWidget_1.default {
286
286
  value = value ? (0, utils_1.formatDate)(this.timezonesUrl, value, (0, utils_1.convertFormatToMoment)(this.settings.format), this.timezone, (0, utils_1.convertFormatToMoment)(this.valueMomentFormat)) : value;
287
287
  return super.setValue(value);
288
288
  }
289
+ // If the component is a textfield that does not have timezone information included in the string value then skip
290
+ // the timezone offset
291
+ if (this.component.type === 'textfield' && !(0, utils_1.hasEncodedTimezone)(value)) {
292
+ this.settings.skipOffset = true;
293
+ }
289
294
  const zonesLoading = this.loadZones();
290
295
  if (value) {
291
296
  if (!saveAsText && this.settings.readOnly && !zonesLoading) {
@@ -453,7 +458,7 @@ class CalendarWidget extends InputWidget_1.default {
453
458
  return (date, format) => {
454
459
  // Only format this if this is the altFormat and the form is readOnly.
455
460
  if (this.settings.readOnly && (format === this.settings.altFormat)) {
456
- if (!this.settings.enableTime || this.loadZones()) {
461
+ if (!this.settings.enableTime || this.loadZones() || this.settings.skipOffset) {
457
462
  return Flatpickr.formatDate(date, format);
458
463
  }
459
464
  const currentValue = new Date(this.getValue());
@@ -659,7 +659,9 @@ export default class Webform extends NestedDataComponent {
659
659
  const rebuild = this.rebuild() || Promise.resolve();
660
660
  return rebuild.then(() => {
661
661
  this.emit('formLoad', form);
662
- this.triggerCaptcha();
662
+ if (!this.options.server) {
663
+ this.triggerCaptcha();
664
+ }
663
665
  // Make sure to trigger onChange after a render event occurs to speed up form rendering.
664
666
  setTimeout(() => {
665
667
  this.onChange(flags);
@@ -77,6 +77,7 @@ export default class WebformBuilder extends Component {
77
77
  removeComponent(component: any, parent: any, original: any, componentInstance: any): boolean | undefined;
78
78
  replaceDoubleQuotes(data: any, fieldsToRemoveDoubleQuotes?: any[]): any;
79
79
  updateComponent(component: any, changed: any): void;
80
+ originalDefaultValue: any;
80
81
  findRepeatablePaths(): any[];
81
82
  highlightInvalidComponents(): void;
82
83
  /**
@@ -1054,6 +1054,16 @@ export default class WebformBuilder extends Component {
1054
1054
  'fields.month.required',
1055
1055
  'fields.year.required',
1056
1056
  ]));
1057
+ if (defaultValueComponent.component.components) {
1058
+ if (!this.originalDefaultValue) {
1059
+ this.originalDefaultValue = fastCloneDeep(defaultValueComponent.component);
1060
+ }
1061
+ eachComponent(defaultValueComponent.component.components, (comp => {
1062
+ if (comp.validate?.required) {
1063
+ comp.validate.required = false;
1064
+ }
1065
+ }));
1066
+ }
1057
1067
  const parentComponent = defaultValueComponent.parent;
1058
1068
  let tabIndex = -1;
1059
1069
  let index = -1;
@@ -1145,6 +1155,9 @@ export default class WebformBuilder extends Component {
1145
1155
  if (index !== -1) {
1146
1156
  let submissionData = this.editForm.submission.data;
1147
1157
  submissionData = submissionData.componentJson || submissionData;
1158
+ if (submissionData.components && this.originalDefaultValue) {
1159
+ submissionData.components = this.originalDefaultValue.components;
1160
+ }
1148
1161
  const fieldsToRemoveDoubleQuotes = ['label', 'tooltip'];
1149
1162
  this.replaceDoubleQuotes(submissionData, fieldsToRemoveDoubleQuotes);
1150
1163
  this.hook('beforeSaveComponentSettings', submissionData);
@@ -935,8 +935,9 @@ export default class SelectComponent extends ListComponent {
935
935
  });
936
936
  }
937
937
  // Add value options.
938
+ const value = this.undoValueTyping(this.dataValue);
938
939
  this.addValueOptions();
939
- this.setChoicesValue(this.dataValue);
940
+ this.setChoicesValue(value);
940
941
  if (this.isSelectResource && this.refs.addResource) {
941
942
  this.addEventListener(this.refs.addResource, 'click', (event) => {
942
943
  event.preventDefault();
@@ -1312,6 +1313,9 @@ export default class SelectComponent extends ListComponent {
1312
1313
  this.lazyLoadInit = true;
1313
1314
  const searchProperty = this.component.searchField || this.component.valueProperty;
1314
1315
  this.triggerUpdate(_.get(value.data || value, searchProperty, value), true);
1316
+ this.itemsLoaded.then(() => {
1317
+ this.setChoicesValue(value, hasPreviousValue, flags);
1318
+ });
1315
1319
  return changed;
1316
1320
  }
1317
1321
  // Add the value options.
@@ -152,6 +152,9 @@ export default class SelectBoxesComponent extends RadioComponent {
152
152
  }
153
153
  }
154
154
  }
155
+ else if (_.isEmpty(this.loadedOptions) && !checkedValues.length) {
156
+ value = {};
157
+ }
155
158
  return value;
156
159
  }
157
160
  /**
@@ -86,8 +86,8 @@ export default class TextFieldComponent extends Input {
86
86
  locale: this.component.widget.locale || this.options.language,
87
87
  saveAs: 'text'
88
88
  };
89
- // update originalComponent to include widget settings after component initialization
90
- // originalComponent is used to restore the component (and widget) after evaluating field logic
89
+ // update originalComponent to include widget settings after component initialization
90
+ // originalComponent is used to restore the component (and widget) after evaluating field logic
91
91
  this.originalComponent = FormioUtils.fastCloneDeep(this.component);
92
92
  }
93
93
  }
@@ -490,6 +490,15 @@ export function getFocusableElements(element: HTMLElement): NodeList<HTMLElement
490
490
  * @returns {Array<string>|null} - The saved types for the component
491
491
  */
492
492
  export function getComponentSavedTypes(fullSchema: import('@formio/core').Component): Array<string> | null;
493
+ /**
494
+ * Checks if a string has timezone information encoded in it
495
+ * Example: 2024-01-01T00:00:00Z -> true
496
+ * Example: 2024-01-01T00:00:00+03:00 -> true
497
+ * Example: 2011-05-03T00:00:00 -> false
498
+ * @param {string} value the string value to check
499
+ * @returns {boolean} if value has encoded timezone
500
+ */
501
+ export function hasEncodedTimezone(value: string): boolean;
493
502
  export * from "./formUtils";
494
503
  /**
495
504
  * Map values through unfold and return first non-nil value.
@@ -1554,3 +1554,17 @@ export const interpolateErrors = (component, errors, interpolateFn) => {
1554
1554
  return { ...error, message: unescapeHTML(interpolateFn(toInterpolate, context)), context: { ...context } };
1555
1555
  });
1556
1556
  };
1557
+ /**
1558
+ * Checks if a string has timezone information encoded in it
1559
+ * Example: 2024-01-01T00:00:00Z -> true
1560
+ * Example: 2024-01-01T00:00:00+03:00 -> true
1561
+ * Example: 2011-05-03T00:00:00 -> false
1562
+ * @param {string} value the string value to check
1563
+ * @returns {boolean} if value has encoded timezone
1564
+ */
1565
+ export function hasEncodedTimezone(value) {
1566
+ if (typeof value !== 'string') {
1567
+ return false;
1568
+ }
1569
+ return (value.substring(value.length - 1) === 'z' || value.substring(value.length - 1) === 'Z' || value.match(/[+|-][0-9]{2}:[0-9]{2}$/));
1570
+ }
@@ -1,6 +1,6 @@
1
1
  import { Formio } from '../Formio';
2
2
  import InputWidget from './InputWidget';
3
- import { convertFormatToFlatpickr, convertFormatToMask, convertFormatToMoment, formatDate, formatOffset, getBrowserInfo, getDateSetting, getLocaleDateFormatInfo, momentDate, zonesLoaded, shouldLoadZones, loadZones, } from '../utils/utils';
3
+ import { convertFormatToFlatpickr, convertFormatToMask, convertFormatToMoment, formatDate, formatOffset, getBrowserInfo, getDateSetting, getLocaleDateFormatInfo, momentDate, zonesLoaded, shouldLoadZones, loadZones, hasEncodedTimezone, } from '../utils/utils';
4
4
  import moment from 'moment';
5
5
  import _ from 'lodash';
6
6
  const DEFAULT_FORMAT = 'yyyy-MM-dd hh:mm a';
@@ -278,6 +278,11 @@ export default class CalendarWidget extends InputWidget {
278
278
  value = value ? formatDate(this.timezonesUrl, value, convertFormatToMoment(this.settings.format), this.timezone, convertFormatToMoment(this.valueMomentFormat)) : value;
279
279
  return super.setValue(value);
280
280
  }
281
+ // If the component is a textfield that does not have timezone information included in the string value then skip
282
+ // the timezone offset
283
+ if (this.component.type === 'textfield' && !hasEncodedTimezone(value)) {
284
+ this.settings.skipOffset = true;
285
+ }
281
286
  const zonesLoading = this.loadZones();
282
287
  if (value) {
283
288
  if (!saveAsText && this.settings.readOnly && !zonesLoading) {
@@ -443,7 +448,7 @@ export default class CalendarWidget extends InputWidget {
443
448
  return (date, format) => {
444
449
  // Only format this if this is the altFormat and the form is readOnly.
445
450
  if (this.settings.readOnly && (format === this.settings.altFormat)) {
446
- if (!this.settings.enableTime || this.loadZones()) {
451
+ if (!this.settings.enableTime || this.loadZones() || this.settings.skipOffset) {
447
452
  return Flatpickr.formatDate(date, format);
448
453
  }
449
454
  const currentValue = new Date(this.getValue());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/js",
3
- "version": "5.1.0-dev.6086.0b0957a",
3
+ "version": "5.1.0-dev.6090.1122fcd",
4
4
  "description": "JavaScript powered Forms with JSON Form Builder",
5
5
  "main": "lib/cjs/index.js",
6
6
  "exports": {
@@ -108,7 +108,7 @@
108
108
  "jwt-decode": "^3.1.2",
109
109
  "lodash": "^4.17.21",
110
110
  "moment": "^2.29.4",
111
- "moment-timezone": "^0.5.44",
111
+ "moment-timezone": "^0.5.48",
112
112
  "quill": "^2.0.2",
113
113
  "signature_pad": "^4.2.0",
114
114
  "string-hash": "^1.1.3",