@formio/js 5.0.0-dev.5633.3b83d8c → 5.0.0-dev.5634.29c714c

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.
Files changed (36) hide show
  1. package/Changelog.md +2 -0
  2. package/dist/formio.builder.css +0 -4
  3. package/dist/formio.builder.min.css +1 -1
  4. package/dist/formio.form.css +0 -4
  5. package/dist/formio.form.js +6 -6
  6. package/dist/formio.form.min.css +1 -1
  7. package/dist/formio.form.min.js +1 -1
  8. package/dist/formio.full.css +0 -4
  9. package/dist/formio.full.js +7 -7
  10. package/dist/formio.full.min.css +1 -1
  11. package/dist/formio.full.min.js +1 -1
  12. package/dist/formio.utils.js +1 -1
  13. package/dist/formio.utils.min.js +1 -1
  14. package/lib/cjs/Webform.d.ts +0 -6
  15. package/lib/cjs/Webform.js +6 -13
  16. package/lib/cjs/WebformBuilder.js +8 -2
  17. package/lib/cjs/components/_classes/component/Component.d.ts +0 -2
  18. package/lib/cjs/components/_classes/component/Component.js +13 -15
  19. package/lib/cjs/components/form/Form.d.ts +0 -1
  20. package/lib/cjs/components/form/Form.js +4 -6
  21. package/lib/cjs/components/select/Select.js +1 -1
  22. package/lib/cjs/components/signature/Signature.js +1 -1
  23. package/lib/cjs/utils/utils.d.ts +6 -0
  24. package/lib/cjs/utils/utils.js +15 -4
  25. package/lib/mjs/Webform.d.ts +0 -6
  26. package/lib/mjs/Webform.js +6 -13
  27. package/lib/mjs/WebformBuilder.js +8 -2
  28. package/lib/mjs/components/_classes/component/Component.d.ts +0 -2
  29. package/lib/mjs/components/_classes/component/Component.js +13 -23
  30. package/lib/mjs/components/form/Form.d.ts +0 -1
  31. package/lib/mjs/components/form/Form.js +4 -6
  32. package/lib/mjs/components/select/Select.js +2 -2
  33. package/lib/mjs/components/signature/Signature.js +1 -1
  34. package/lib/mjs/utils/utils.d.ts +6 -0
  35. package/lib/mjs/utils/utils.js +12 -2
  36. package/package.json +1 -1
@@ -356,12 +356,6 @@ declare class Webform extends NestedDataComponent {
356
356
  * @returns {Object}
357
357
  */
358
358
  get submission(): Object;
359
- /**
360
- * @param submission
361
- * @param flags
362
- * @return {void}
363
- */
364
- onSetSubmission(submission: any, flags?: {}): void;
365
359
  /**
366
360
  * Sets a submission and returns the promise when it is ready.
367
361
  * @param submission
@@ -716,17 +716,6 @@ class Webform extends NestedDataComponent_1.default {
716
716
  set submission(submission) {
717
717
  this.setSubmission(submission);
718
718
  }
719
- /**
720
- * @param submission
721
- * @param flags
722
- * @return {void}
723
- */
724
- onSetSubmission(submission, flags = {}) {
725
- this.submissionSet = true;
726
- this.triggerChange(flags);
727
- this.emit('beforeSetSubmission', submission);
728
- this.setValue(submission, flags);
729
- }
730
719
  /**
731
720
  * Sets a submission and returns the promise when it is ready.
732
721
  * @param submission
@@ -739,7 +728,10 @@ class Webform extends NestedDataComponent_1.default {
739
728
  if (resolveFlags) {
740
729
  flags = Object.assign(Object.assign({}, flags), resolveFlags);
741
730
  }
742
- this.onSetSubmission(submission, flags);
731
+ this.submissionSet = true;
732
+ this.triggerChange(flags);
733
+ this.emit('beforeSetSubmission', submission);
734
+ this.setValue(submission, flags);
743
735
  return this.submissionReadyResolve(submission);
744
736
  }, (err) => this.submissionReadyReject(err)).catch((err) => this.submissionReadyReject(err));
745
737
  }
@@ -795,7 +787,8 @@ class Webform extends NestedDataComponent_1.default {
795
787
  formio.loadSubmissions({
796
788
  params: {
797
789
  state: 'draft',
798
- owner: userId
790
+ owner: userId,
791
+ sort: '-created'
799
792
  }
800
793
  }).then(submissions => {
801
794
  if (submissions.length > 0 && !this.options.skipDraftRestore) {
@@ -986,8 +986,14 @@ class WebformBuilder extends Component_1.default {
986
986
  else if (parent.formioComponent && parent.formioComponent.removeChildComponent) {
987
987
  parent.formioComponent.removeChildComponent(component);
988
988
  }
989
- if (component.input && componentInstance && componentInstance.parent) {
990
- lodash_1.default.unset(componentInstance._data, componentInstance.key);
989
+ if (component.input && componentInstance && parent.formioComponent) {
990
+ const parentDefaultValue = lodash_1.default.get(parent.formioComponent, 'component.defaultValue', null);
991
+ if (Array.isArray(parentDefaultValue)) {
992
+ parentDefaultValue.forEach(v => lodash_1.default.unset(v, componentInstance.key));
993
+ }
994
+ else if (typeof parentDefaultValue === 'object') {
995
+ lodash_1.default.unset(parentDefaultValue, componentInstance.key);
996
+ }
991
997
  }
992
998
  const rebuild = parent.formioComponent.rebuild() || Promise.resolve();
993
999
  rebuild.then(() => {
@@ -327,12 +327,10 @@ declare class Component extends Element {
327
327
  */
328
328
  loadRefs(element: HTMLElement, refs: object, referenceAttributeName?: string | undefined): void;
329
329
  setOpenModalElement(template: any): void;
330
- renderModalPreview(ctx: any): any;
331
330
  getModalPreviewTemplate(): any;
332
331
  build(element: any): Promise<void>;
333
332
  get hasModalSaveButton(): boolean;
334
333
  render(children?: string, topLevel?: boolean): any;
335
- createTooltip(tooltipEl: any, settings?: {}): import("tippy.js").Instance<import("tippy.js").Props>[];
336
334
  attachTooltips(toolTipsRefs: any): void;
337
335
  createComponentModal(element: any, modalShouldBeOpened: any, currentValue: any): ComponentModal;
338
336
  attach(element: any): Promise<void>;
@@ -1029,9 +1029,6 @@ class Component extends Element_1.default {
1029
1029
  setOpenModalElement(template) {
1030
1030
  this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate());
1031
1031
  }
1032
- renderModalPreview(ctx) {
1033
- return this.renderTemplate('modalPreview', ctx || {});
1034
- }
1035
1032
  getModalPreviewTemplate() {
1036
1033
  var _a;
1037
1034
  const dataValue = this.component.type === 'password' ? this.dataValue.replace(/./g, '•') : this.dataValue;
@@ -1039,7 +1036,7 @@ class Component extends Element_1.default {
1039
1036
  if (this.hasInput && ((_a = this.component.validate) === null || _a === void 0 ? void 0 : _a.required) && !this.isPDFReadOnlyMode) {
1040
1037
  modalLabel = { className: 'field-required' };
1041
1038
  }
1042
- return this.renderModalPreview({
1039
+ return this.renderTemplate('modalPreview', {
1043
1040
  previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('Click to set value'),
1044
1041
  messages: '',
1045
1042
  labelInfo: modalLabel,
@@ -1077,17 +1074,21 @@ class Component extends Element_1.default {
1077
1074
  }, topLevel);
1078
1075
  }
1079
1076
  }
1080
- createTooltip(tooltipEl, settings = {}) {
1081
- const tooltipAttribute = tooltipEl.getAttribute('data-tooltip');
1082
- const tooltipDataTitle = tooltipEl.getAttribute('data-title');
1083
- const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)
1084
- .replace(/(?:\r\n|\r|\n)/g, '<br />');
1085
- return (0, tippy_js_1.default)(tooltipEl, Object.assign(Object.assign({ allowHTML: true, trigger: 'mouseenter click focus', placement: 'right', zIndex: 10000, interactive: true }, settings), { content: this.t(this.sanitize(tooltipText), { _userInput: true }) }));
1086
- }
1087
1077
  attachTooltips(toolTipsRefs) {
1088
1078
  toolTipsRefs === null || toolTipsRefs === void 0 ? void 0 : toolTipsRefs.forEach((tooltip, index) => {
1089
1079
  if (tooltip) {
1090
- this.tooltips[index] = this.createTooltip(tooltip);
1080
+ const tooltipAttribute = tooltip.getAttribute('data-tooltip');
1081
+ const tooltipDataTitle = tooltip.getAttribute('data-title');
1082
+ const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)
1083
+ .replace(/(?:\r\n|\r|\n)/g, '<br />');
1084
+ this.tooltips[index] = (0, tippy_js_1.default)(tooltip, {
1085
+ allowHTML: true,
1086
+ trigger: 'mouseenter click focus',
1087
+ placement: 'right',
1088
+ zIndex: 10000,
1089
+ interactive: true,
1090
+ content: this.t(this.sanitize(tooltipText), { _userInput: true }),
1091
+ });
1091
1092
  }
1092
1093
  });
1093
1094
  }
@@ -1849,9 +1850,6 @@ class Component extends Element_1.default {
1849
1850
  messages = lodash_1.default.uniqBy(messages, message => message.message);
1850
1851
  if (this.refs.messageContainer) {
1851
1852
  this.setContent(this.refs.messageContainer, messages.map((message) => {
1852
- if (message.message && typeof message.message === 'string') {
1853
- message.message = message.message.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
1854
- }
1855
1853
  return this.renderTemplate('message', Object.assign({}, message));
1856
1854
  }).join(''));
1857
1855
  }
@@ -79,7 +79,6 @@ export default class FormComponent extends Component {
79
79
  isHidden(): boolean;
80
80
  setValue(submission: any, flags?: {}): boolean;
81
81
  setSubFormValue(submission: any, flags: any): void;
82
- onSetSubFormValue(submission: any, flags: any): void;
83
82
  areAllComponentsEmpty(data: any): boolean;
84
83
  updateSubFormVisibility(): void;
85
84
  /**
@@ -630,9 +630,10 @@ class FormComponent extends Component_1.default {
630
630
  && submission._id
631
631
  && this.subForm.formio
632
632
  && lodash_1.default.isEmpty(submission.data);
633
- if (shouldLoadSubmissionById) {
633
+ const shouldLoadDraftById = this.options.saveDraft && lodash_1.default.isEmpty(submission.data) && lodash_1.default.get(this.subForm, 'submission._id');
634
+ if (shouldLoadSubmissionById || shouldLoadDraftById) {
634
635
  const formId = submission.form || this.formObj.form || this.component.form;
635
- const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id}`;
636
+ const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id || this.subForm.submission._id}`;
636
637
  const options = ((_a = this.root.formio) === null || _a === void 0 ? void 0 : _a.base) && ((_b = this.root.formio) === null || _b === void 0 ? void 0 : _b.projectUrl)
637
638
  ? {
638
639
  base: this.root.formio.base,
@@ -645,12 +646,9 @@ class FormComponent extends Component_1.default {
645
646
  });
646
647
  }
647
648
  else {
648
- this.onSetSubFormValue(submission, flags);
649
+ this.subForm.setValue(submission, flags);
649
650
  }
650
651
  }
651
- onSetSubFormValue(submission, flags) {
652
- this.subForm.setValue(submission, flags);
653
- }
654
652
  isEmpty(value = this.dataValue) {
655
653
  return value === null || lodash_1.default.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value === null || value === void 0 ? void 0 : value.data) && !(value === null || value === void 0 ? void 0 : value._id));
656
654
  }
@@ -1526,7 +1526,7 @@ class SelectComponent extends ListComponent_1.default {
1526
1526
  const getTemplateValue = (v) => {
1527
1527
  const itemTemplate = this.itemTemplate(v);
1528
1528
  return options.csv && itemTemplate
1529
- ? (0, utils_1.unescapeHTML)(itemTemplate)
1529
+ ? (0, utils_1.removeHTML)(itemTemplate)
1530
1530
  : itemTemplate;
1531
1531
  };
1532
1532
  if (Array.isArray(value)) {
@@ -172,7 +172,7 @@ class SignatureComponent extends Input_1.default {
172
172
  return false;
173
173
  }
174
174
  getModalPreviewTemplate() {
175
- return this.renderModalPreview({
175
+ return this.renderTemplate('modalPreview', {
176
176
  previewText: this.dataValue ?
177
177
  `<img src=${this.dataValue} ${this._referenceAttributeName}='openModal' style="width: 100%;height: 100%;" />` :
178
178
  this.t('Click to Sign')
@@ -107,6 +107,12 @@ export function checkCondition(component: any, row: any, data: any, form: any, i
107
107
  */
108
108
  export function checkTrigger(component: any, trigger: any, row: any, data: any, form: any, instance: any): mixed;
109
109
  export function setActionProperty(component: any, action: any, result: any, row: any, data: any, instance: any): any;
110
+ /**
111
+ * Removes HTML tags from string e.g. <div>Hello World</div> => Hello World
112
+ * @param {string} str
113
+ * @returns {string}
114
+ */
115
+ export function removeHTML(str: string): string;
110
116
  /**
111
117
  * Unescape HTML characters like &lt, &gt, &amp and etc.
112
118
  * @param str
@@ -30,8 +30,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
30
30
  return (mod && mod.__esModule) ? mod : { "default": mod };
31
31
  };
32
32
  Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.withSwitch = 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.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;
34
- exports.isSelectResourceWithObjectValue = exports.getItemTemplateKeys = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isInsideScopingComponent = 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 = void 0;
33
+ 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;
34
+ exports.isSelectResourceWithObjectValue = exports.getItemTemplateKeys = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isInsideScopingComponent = 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;
35
35
  const lodash_1 = __importDefault(require("lodash"));
36
36
  exports._ = lodash_1.default;
37
37
  const fetch_ponyfill_1 = __importDefault(require("fetch-ponyfill"));
@@ -448,6 +448,16 @@ function setActionProperty(component, action, result, row, data, instance) {
448
448
  return component;
449
449
  }
450
450
  exports.setActionProperty = setActionProperty;
451
+ /**
452
+ * Removes HTML tags from string e.g. <div>Hello World</div> => Hello World
453
+ * @param {string} str
454
+ * @returns {string}
455
+ */
456
+ function removeHTML(str) {
457
+ const doc = new window.DOMParser().parseFromString(str, 'text/html');
458
+ return (doc.body.textContent || '').trim();
459
+ }
460
+ exports.removeHTML = removeHTML;
451
461
  /**
452
462
  * Unescape HTML characters like &lt, &gt, &amp and etc.
453
463
  * @param str
@@ -457,8 +467,9 @@ function unescapeHTML(str) {
457
467
  if (typeof window === 'undefined' || !('DOMParser' in window)) {
458
468
  return str;
459
469
  }
460
- const doc = new window.DOMParser().parseFromString(str, 'text/html');
461
- return doc.documentElement.textContent;
470
+ const elem = document.createElement('textarea');
471
+ elem.innerHTML = str;
472
+ return elem.value;
462
473
  }
463
474
  exports.unescapeHTML = unescapeHTML;
464
475
  /**
@@ -356,12 +356,6 @@ declare class Webform extends NestedDataComponent {
356
356
  * @returns {Object}
357
357
  */
358
358
  get submission(): Object;
359
- /**
360
- * @param submission
361
- * @param flags
362
- * @return {void}
363
- */
364
- onSetSubmission(submission: any, flags?: {}): void;
365
359
  /**
366
360
  * Sets a submission and returns the promise when it is ready.
367
361
  * @param submission
@@ -714,17 +714,6 @@ export default class Webform extends NestedDataComponent {
714
714
  set submission(submission) {
715
715
  this.setSubmission(submission);
716
716
  }
717
- /**
718
- * @param submission
719
- * @param flags
720
- * @return {void}
721
- */
722
- onSetSubmission(submission, flags = {}) {
723
- this.submissionSet = true;
724
- this.triggerChange(flags);
725
- this.emit('beforeSetSubmission', submission);
726
- this.setValue(submission, flags);
727
- }
728
717
  /**
729
718
  * Sets a submission and returns the promise when it is ready.
730
719
  * @param submission
@@ -743,7 +732,10 @@ export default class Webform extends NestedDataComponent {
743
732
  ...resolveFlags
744
733
  };
745
734
  }
746
- this.onSetSubmission(submission, flags);
735
+ this.submissionSet = true;
736
+ this.triggerChange(flags);
737
+ this.emit('beforeSetSubmission', submission);
738
+ this.setValue(submission, flags);
747
739
  return this.submissionReadyResolve(submission);
748
740
  }, (err) => this.submissionReadyReject(err)).catch((err) => this.submissionReadyReject(err));
749
741
  }
@@ -799,7 +791,8 @@ export default class Webform extends NestedDataComponent {
799
791
  formio.loadSubmissions({
800
792
  params: {
801
793
  state: 'draft',
802
- owner: userId
794
+ owner: userId,
795
+ sort: '-created'
803
796
  }
804
797
  }).then(submissions => {
805
798
  if (submissions.length > 0 && !this.options.skipDraftRestore) {
@@ -970,8 +970,14 @@ export default class WebformBuilder extends Component {
970
970
  else if (parent.formioComponent && parent.formioComponent.removeChildComponent) {
971
971
  parent.formioComponent.removeChildComponent(component);
972
972
  }
973
- if (component.input && componentInstance && componentInstance.parent) {
974
- _.unset(componentInstance._data, componentInstance.key);
973
+ if (component.input && componentInstance && parent.formioComponent) {
974
+ const parentDefaultValue = _.get(parent.formioComponent, 'component.defaultValue', null);
975
+ if (Array.isArray(parentDefaultValue)) {
976
+ parentDefaultValue.forEach(v => _.unset(v, componentInstance.key));
977
+ }
978
+ else if (typeof parentDefaultValue === 'object') {
979
+ _.unset(parentDefaultValue, componentInstance.key);
980
+ }
975
981
  }
976
982
  const rebuild = parent.formioComponent.rebuild() || Promise.resolve();
977
983
  rebuild.then(() => {
@@ -327,12 +327,10 @@ declare class Component extends Element {
327
327
  */
328
328
  loadRefs(element: HTMLElement, refs: object, referenceAttributeName?: string | undefined): void;
329
329
  setOpenModalElement(template: any): void;
330
- renderModalPreview(ctx: any): any;
331
330
  getModalPreviewTemplate(): any;
332
331
  build(element: any): Promise<void>;
333
332
  get hasModalSaveButton(): boolean;
334
333
  render(children?: string, topLevel?: boolean): any;
335
- createTooltip(tooltipEl: any, settings?: {}): import("tippy.js").Instance<import("tippy.js").Props>[];
336
334
  attachTooltips(toolTipsRefs: any): void;
337
335
  createComponentModal(element: any, modalShouldBeOpened: any, currentValue: any): ComponentModal;
338
336
  attach(element: any): Promise<void>;
@@ -996,16 +996,13 @@ export default class Component extends Element {
996
996
  setOpenModalElement(template) {
997
997
  this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate());
998
998
  }
999
- renderModalPreview(ctx) {
1000
- return this.renderTemplate('modalPreview', ctx || {});
1001
- }
1002
999
  getModalPreviewTemplate() {
1003
1000
  const dataValue = this.component.type === 'password' ? this.dataValue.replace(/./g, '•') : this.dataValue;
1004
1001
  let modalLabel;
1005
1002
  if (this.hasInput && this.component.validate?.required && !this.isPDFReadOnlyMode) {
1006
1003
  modalLabel = { className: 'field-required' };
1007
1004
  }
1008
- return this.renderModalPreview({
1005
+ return this.renderTemplate('modalPreview', {
1009
1006
  previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('Click to set value'),
1010
1007
  messages: '',
1011
1008
  labelInfo: modalLabel,
@@ -1043,25 +1040,21 @@ export default class Component extends Element {
1043
1040
  }, topLevel);
1044
1041
  }
1045
1042
  }
1046
- createTooltip(tooltipEl, settings = {}) {
1047
- const tooltipAttribute = tooltipEl.getAttribute('data-tooltip');
1048
- const tooltipDataTitle = tooltipEl.getAttribute('data-title');
1049
- const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)
1050
- .replace(/(?:\r\n|\r|\n)/g, '<br />');
1051
- return tippy(tooltipEl, {
1052
- allowHTML: true,
1053
- trigger: 'mouseenter click focus',
1054
- placement: 'right',
1055
- zIndex: 10000,
1056
- interactive: true,
1057
- ...settings,
1058
- content: this.t(this.sanitize(tooltipText), { _userInput: true }),
1059
- });
1060
- }
1061
1043
  attachTooltips(toolTipsRefs) {
1062
1044
  toolTipsRefs?.forEach((tooltip, index) => {
1063
1045
  if (tooltip) {
1064
- this.tooltips[index] = this.createTooltip(tooltip);
1046
+ const tooltipAttribute = tooltip.getAttribute('data-tooltip');
1047
+ const tooltipDataTitle = tooltip.getAttribute('data-title');
1048
+ const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)
1049
+ .replace(/(?:\r\n|\r|\n)/g, '<br />');
1050
+ this.tooltips[index] = tippy(tooltip, {
1051
+ allowHTML: true,
1052
+ trigger: 'mouseenter click focus',
1053
+ placement: 'right',
1054
+ zIndex: 10000,
1055
+ interactive: true,
1056
+ content: this.t(this.sanitize(tooltipText), { _userInput: true }),
1057
+ });
1065
1058
  }
1066
1059
  });
1067
1060
  }
@@ -1821,9 +1814,6 @@ export default class Component extends Element {
1821
1814
  messages = _.uniqBy(messages, message => message.message);
1822
1815
  if (this.refs.messageContainer) {
1823
1816
  this.setContent(this.refs.messageContainer, messages.map((message) => {
1824
- if (message.message && typeof message.message === 'string') {
1825
- message.message = message.message.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
1826
- }
1827
1817
  return this.renderTemplate('message', { ...message });
1828
1818
  }).join(''));
1829
1819
  }
@@ -79,7 +79,6 @@ export default class FormComponent extends Component {
79
79
  isHidden(): boolean;
80
80
  setValue(submission: any, flags?: {}): boolean;
81
81
  setSubFormValue(submission: any, flags: any): void;
82
- onSetSubFormValue(submission: any, flags: any): void;
83
82
  areAllComponentsEmpty(data: any): boolean;
84
83
  updateSubFormVisibility(): void;
85
84
  /**
@@ -620,9 +620,10 @@ export default class FormComponent extends Component {
620
620
  && submission._id
621
621
  && this.subForm.formio
622
622
  && _.isEmpty(submission.data);
623
- if (shouldLoadSubmissionById) {
623
+ const shouldLoadDraftById = this.options.saveDraft && _.isEmpty(submission.data) && _.get(this.subForm, 'submission._id');
624
+ if (shouldLoadSubmissionById || shouldLoadDraftById) {
624
625
  const formId = submission.form || this.formObj.form || this.component.form;
625
- const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id}`;
626
+ const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id || this.subForm.submission._id}`;
626
627
  const options = this.root.formio?.base && this.root.formio?.projectUrl
627
628
  ? {
628
629
  base: this.root.formio.base,
@@ -635,12 +636,9 @@ export default class FormComponent extends Component {
635
636
  });
636
637
  }
637
638
  else {
638
- this.onSetSubFormValue(submission, flags);
639
+ this.subForm.setValue(submission, flags);
639
640
  }
640
641
  }
641
- onSetSubFormValue(submission, flags) {
642
- this.subForm.setValue(submission, flags);
643
- }
644
642
  isEmpty(value = this.dataValue) {
645
643
  return value === null || _.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value?.data) && !value?._id);
646
644
  }
@@ -3,7 +3,7 @@ import { Formio } from '../../Formio';
3
3
  import ListComponent from '../_classes/list/ListComponent';
4
4
  import Input from '../_classes/input/Input';
5
5
  import Form from '../../Form';
6
- import { getRandomComponentId, boolValue, isPromise, componentValueTypes, getComponentSavedTypes, unescapeHTML, isSelectResourceWithObjectValue } from '../../utils/utils';
6
+ import { getRandomComponentId, boolValue, isPromise, componentValueTypes, getComponentSavedTypes, unescapeHTML, isSelectResourceWithObjectValue, removeHTML } from '../../utils/utils';
7
7
  import Choices from '../../utils/ChoicesWrapper';
8
8
  export default class SelectComponent extends ListComponent {
9
9
  static schema(...extend) {
@@ -1551,7 +1551,7 @@ export default class SelectComponent extends ListComponent {
1551
1551
  const getTemplateValue = (v) => {
1552
1552
  const itemTemplate = this.itemTemplate(v);
1553
1553
  return options.csv && itemTemplate
1554
- ? unescapeHTML(itemTemplate)
1554
+ ? removeHTML(itemTemplate)
1555
1555
  : itemTemplate;
1556
1556
  };
1557
1557
  if (Array.isArray(value)) {
@@ -169,7 +169,7 @@ export default class SignatureComponent extends Input {
169
169
  return false;
170
170
  }
171
171
  getModalPreviewTemplate() {
172
- return this.renderModalPreview({
172
+ return this.renderTemplate('modalPreview', {
173
173
  previewText: this.dataValue ?
174
174
  `<img src=${this.dataValue} ${this._referenceAttributeName}='openModal' style="width: 100%;height: 100%;" />` :
175
175
  this.t('Click to Sign')
@@ -107,6 +107,12 @@ export function checkCondition(component: any, row: any, data: any, form: any, i
107
107
  */
108
108
  export function checkTrigger(component: any, trigger: any, row: any, data: any, form: any, instance: any): mixed;
109
109
  export function setActionProperty(component: any, action: any, result: any, row: any, data: any, instance: any): any;
110
+ /**
111
+ * Removes HTML tags from string e.g. <div>Hello World</div> => Hello World
112
+ * @param {string} str
113
+ * @returns {string}
114
+ */
115
+ export function removeHTML(str: string): string;
110
116
  /**
111
117
  * Unescape HTML characters like &lt, &gt, &amp and etc.
112
118
  * @param str
@@ -395,6 +395,15 @@ export function setActionProperty(component, action, result, row, data, instance
395
395
  }
396
396
  return component;
397
397
  }
398
+ /**
399
+ * Removes HTML tags from string e.g. <div>Hello World</div> => Hello World
400
+ * @param {string} str
401
+ * @returns {string}
402
+ */
403
+ export function removeHTML(str) {
404
+ const doc = new window.DOMParser().parseFromString(str, 'text/html');
405
+ return (doc.body.textContent || '').trim();
406
+ }
398
407
  /**
399
408
  * Unescape HTML characters like &lt, &gt, &amp and etc.
400
409
  * @param str
@@ -404,8 +413,9 @@ export function unescapeHTML(str) {
404
413
  if (typeof window === 'undefined' || !('DOMParser' in window)) {
405
414
  return str;
406
415
  }
407
- const doc = new window.DOMParser().parseFromString(str, 'text/html');
408
- return doc.documentElement.textContent;
416
+ const elem = document.createElement('textarea');
417
+ elem.innerHTML = str;
418
+ return elem.value;
409
419
  }
410
420
  /**
411
421
  * Make HTML element from string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/js",
3
- "version": "5.0.0-dev.5633.3b83d8c",
3
+ "version": "5.0.0-dev.5634.29c714c",
4
4
  "description": "JavaScript powered Forms with JSON Form Builder",
5
5
  "main": "lib/cjs/index.js",
6
6
  "exports": {