@3t-transform/threeteeui 1.9.101 → 1.9.103
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.
- package/dist/cjs/{auto-be8ad100.js → auto-356ad09b.js} +177 -177
- package/dist/cjs/{domsanitiser.options-55ce2d65.js → domsanitiser.options-065dbed8.js} +12 -12
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{tttx-action-dropdown_1_9_101.cjs.entry.js → tttx-action-dropdown_1_9_103.cjs.entry.js} +51 -51
- package/dist/cjs/{tttx-button-v2_1_9_101.cjs.entry.js → tttx-button-v2_1_9_103.cjs.entry.js} +147 -147
- package/dist/cjs/{tttx-button_1_9_101.cjs.entry.js → tttx-button_1_9_103.cjs.entry.js} +26 -26
- package/dist/cjs/{tttx-chart_1_9_101.cjs.entry.js → tttx-chart_1_9_103.cjs.entry.js} +524 -524
- package/dist/cjs/{tttx-checkbox-group-caption_1_9_101.cjs.entry.js → tttx-checkbox-group-caption_1_9_103.cjs.entry.js} +9 -9
- package/dist/cjs/{tttx-checkbox-group-heading_1_9_101.cjs.entry.js → tttx-checkbox-group-heading_1_9_103.cjs.entry.js} +9 -9
- package/dist/cjs/{tttx-checkbox-group_1_9_101.cjs.entry.js → tttx-checkbox-group_1_9_103.cjs.entry.js} +9 -9
- package/dist/cjs/{tttx-checkbox_1_9_101.cjs.entry.js → tttx-checkbox_1_9_103.cjs.entry.js} +33 -33
- package/dist/cjs/{tttx-comments_1_9_101.cjs.entry.js → tttx-comments_1_9_103.cjs.entry.js} +204 -204
- package/dist/cjs/{tttx-data-pattern_1_9_101.cjs.entry.js → tttx-data-pattern_1_9_103.cjs.entry.js} +20 -20
- package/dist/cjs/{tttx-datacard_1_9_101.cjs.entry.js → tttx-datacard_1_9_103.cjs.entry.js} +43 -43
- package/dist/cjs/tttx-date-range-picker.cjs.entry.js +212 -212
- package/dist/cjs/{tttx-dialog-box_1_9_101.cjs.entry.js → tttx-dialog-box_1_9_103.cjs.entry.js} +94 -94
- package/dist/cjs/{tttx-dialog_1_9_101.cjs.entry.js → tttx-dialog_1_9_103.cjs.entry.js} +69 -69
- package/dist/cjs/{tttx-expander_1_9_101.cjs.entry.js → tttx-expander_1_9_103.cjs.entry.js} +28 -28
- package/dist/cjs/{tttx-filter_1_9_101_4.cjs.entry.js → tttx-filter_1_9_103_4.cjs.entry.js} +386 -386
- package/dist/cjs/{tttx-form_1_9_101.cjs.entry.js → tttx-form_1_9_103.cjs.entry.js} +985 -985
- package/dist/cjs/{tttx-graph_1_9_101.cjs.entry.js → tttx-graph_1_9_103.cjs.entry.js} +124 -124
- package/dist/cjs/{tttx-icon_1_9_101.cjs.entry.js → tttx-icon_1_9_103.cjs.entry.js} +24 -24
- package/dist/cjs/{tttx-keyvalue-block_1_9_101.cjs.entry.js → tttx-keyvalue-block_1_9_103.cjs.entry.js} +62 -62
- package/dist/cjs/{tttx-loading-spinner_1_9_101_3.cjs.entry.js → tttx-loading-spinner_1_9_103_3.cjs.entry.js} +172 -172
- package/dist/cjs/{tttx-multiselect-box_1_9_101.cjs.entry.js → tttx-multiselect-box_1_9_103.cjs.entry.js} +175 -175
- package/dist/cjs/{tttx-percentage-bar_1_9_101.cjs.entry.js → tttx-percentage-bar_1_9_103.cjs.entry.js} +56 -56
- package/dist/cjs/{tttx-qrcode_1_9_101.cjs.entry.js → tttx-qrcode_1_9_103.cjs.entry.js} +28 -28
- package/dist/cjs/{tttx-range-slider_1_9_101.cjs.entry.js → tttx-range-slider_1_9_103.cjs.entry.js} +185 -185
- package/dist/cjs/{tttx-select-box_1_9_101.cjs.entry.js → tttx-select-box_1_9_103.cjs.entry.js} +239 -239
- package/dist/cjs/{tttx-skeleton_loader_1_9_101.cjs.entry.js → tttx-skeleton_loader_1_9_103.cjs.entry.js} +30 -30
- package/dist/cjs/{tttx-table_1_9_101.cjs.entry.js → tttx-table_1_9_103.cjs.entry.js} +72 -72
- package/dist/cjs/{tttx-tabs_1_9_101.cjs.entry.js → tttx-tabs_1_9_103.cjs.entry.js} +103 -103
- package/dist/cjs/{tttx-tag-v2_1_9_101.cjs.entry.js → tttx-tag-v2_1_9_103.cjs.entry.js} +72 -72
- package/dist/cjs/{tttx-textarea_1_9_101.cjs.entry.js → tttx-textarea_1_9_103.cjs.entry.js} +50 -50
- package/dist/cjs/{tttx-toggle_1_9_101.cjs.entry.js → tttx-toggle_1_9_103.cjs.entry.js} +30 -30
- package/dist/cjs/{tttx-tooltip_1_9_101.cjs.entry.js → tttx-tooltip_1_9_103.cjs.entry.js} +87 -87
- package/dist/cjs/{tttx-tree-view_1_9_101.cjs.entry.js → tttx-tree-view_1_9_103.cjs.entry.js} +342 -342
- package/dist/cjs/tttx.cjs.js +1 -1
- package/dist/collection/components/atoms/tttx-button/tttx-button.js +129 -129
- package/dist/collection/components/atoms/tttx-button/tttx-button.stories.js +40 -40
- package/dist/collection/components/atoms/tttx-button-v2/tttx-button-v2.css +1 -1
- package/dist/collection/components/atoms/tttx-button-v2/tttx-button-v2.js +436 -436
- package/dist/collection/components/atoms/tttx-button-v2/tttx-button-v2.stories.js +143 -143
- package/dist/collection/components/atoms/tttx-checkbox/tttx-checkbox.js +154 -154
- package/dist/collection/components/atoms/tttx-checkbox/tttx-checkbox.stories.js +58 -58
- package/dist/collection/components/atoms/tttx-datacard/tttx-datacard.js +186 -186
- package/dist/collection/components/atoms/tttx-datacard/tttx-datacard.stories.js +92 -92
- package/dist/collection/components/atoms/tttx-icon/tttx-icon.js +92 -92
- package/dist/collection/components/atoms/tttx-icon/tttx-icon.stories.js +26 -26
- package/dist/collection/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.js +137 -137
- package/dist/collection/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.stories.js +94 -94
- package/dist/collection/components/atoms/tttx-loading-spinner/tttx-loading-spinner.js +194 -194
- package/dist/collection/components/atoms/tttx-loading-spinner/tttx-loading-spinner.stories.js +53 -53
- package/dist/collection/components/atoms/tttx-percentage-bar/tttx-percentage-bar.js +168 -168
- package/dist/collection/components/atoms/tttx-percentage-bar/tttx-percentage-bar.stories.js +52 -52
- package/dist/collection/components/atoms/tttx-qrcode/tttx-qrcode.js +81 -81
- package/dist/collection/components/atoms/tttx-qrcode/tttx-qrcode.stories.js +22 -22
- package/dist/collection/components/atoms/tttx-skeleton-loader/tttx-skeleton-loader.js +225 -225
- package/dist/collection/components/atoms/tttx-skeleton-loader/tttx-skeleton-loader.stories.js +44 -44
- package/dist/collection/components/atoms/tttx-tag/tttx-tag.js +157 -157
- package/dist/collection/components/atoms/tttx-tag/tttx-tag.stories.js +53 -53
- package/dist/collection/components/atoms/tttx-tag-v2/tttx-tag-v2.js +281 -281
- package/dist/collection/components/atoms/tttx-tag-v2/tttx-tag-v2.stories.js +84 -84
- package/dist/collection/components/atoms/tttx-toggle/tttx-toggle.js +84 -84
- package/dist/collection/components/atoms/tttx-toggle/tttx-toggle.stories.js +8 -8
- package/dist/collection/components/domsanitiser.options.js +14 -14
- package/dist/collection/components/molecules/tttx-action-dropdown/tttx-action-dropdown.js +213 -213
- package/dist/collection/components/molecules/tttx-action-dropdown/tttx-action-dropdown.stories.js +55 -55
- package/dist/collection/components/molecules/tttx-chart/tttx-chart.js +793 -793
- package/dist/collection/components/molecules/tttx-chart/tttx-chart.stories.js +209 -209
- package/dist/collection/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-caption.js +17 -17
- package/dist/collection/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-heading.js +17 -17
- package/dist/collection/components/molecules/tttx-checkbox-group/tttx-checkbox-group.js +18 -18
- package/dist/collection/components/molecules/tttx-checkbox-group/tttx-checkbox-group.stories.js +62 -62
- package/dist/collection/components/molecules/tttx-comments/tttx-comments.js +536 -536
- package/dist/collection/components/molecules/tttx-comments/tttx-comments.stories.js +151 -151
- package/dist/collection/components/molecules/tttx-date-range-picker/tttx-date-range-picker.js +292 -292
- package/dist/collection/components/molecules/tttx-date-range-picker/tttx-date-range-picker.stories.js +48 -48
- package/dist/collection/components/molecules/tttx-dialog/icon-types.js +6 -6
- package/dist/collection/components/molecules/tttx-dialog/tttx-dialog.js +218 -218
- package/dist/collection/components/molecules/tttx-dialog/tttx-dialog.stories.js +50 -50
- package/dist/collection/components/molecules/tttx-dialog-box/tttx-dialog-box.js +246 -246
- package/dist/collection/components/molecules/tttx-dialog-box/tttx-dialog-box.stories.js +314 -314
- package/dist/collection/components/molecules/tttx-expander/tttx-expander.js +134 -134
- package/dist/collection/components/molecules/tttx-expander/tttx-expander.stories.js +46 -46
- package/dist/collection/components/molecules/tttx-filter/tttx-filter.js +416 -416
- package/dist/collection/components/molecules/tttx-filter/tttx-filter.stories.js +81 -81
- package/dist/collection/components/molecules/tttx-form/lib/setErrorState.js +49 -49
- package/dist/collection/components/molecules/tttx-form/lib/timecomparatorChecks.js +64 -64
- package/dist/collection/components/molecules/tttx-form/lib/validityCheck.js +76 -76
- package/dist/collection/components/molecules/tttx-form/tttx-form.js +1267 -1267
- package/dist/collection/components/molecules/tttx-form/tttx-form.stories.js +595 -595
- package/dist/collection/components/molecules/tttx-graph/gauge-label-plugin.js +14 -14
- package/dist/collection/components/molecules/tttx-graph/tttx-graph.js +184 -184
- package/dist/collection/components/molecules/tttx-graph/tttx-graph.stories.js +32 -32
- package/dist/collection/components/molecules/tttx-list/tttx-list.js +165 -165
- package/dist/collection/components/molecules/tttx-list/tttx-list.stories.js +134 -134
- package/dist/collection/components/molecules/tttx-multiselect-box/tttx-multiselect-box.js +499 -499
- package/dist/collection/components/molecules/tttx-multiselect-box/tttx-multiselect-box.stories.js +151 -151
- package/dist/collection/components/molecules/tttx-range-slider/tttx-range-slider.js +304 -304
- package/dist/collection/components/molecules/tttx-range-slider/tttx-range-slider.stories.js +22 -22
- package/dist/collection/components/molecules/tttx-select-box/tttx-select-box.js +671 -671
- package/dist/collection/components/molecules/tttx-select-box/tttx-select-box.stories.js +140 -140
- package/dist/collection/components/molecules/tttx-sorter/tttx-sorter.js +253 -253
- package/dist/collection/components/molecules/tttx-sorter/tttx-sorter.stories.js +43 -43
- package/dist/collection/components/molecules/tttx-standalone-input/tttx-standalone-input.js +764 -764
- package/dist/collection/components/molecules/tttx-standalone-input/tttx-standalone-input.stories.js +191 -191
- package/dist/collection/components/molecules/tttx-table/tttx-table.css +1 -1
- package/dist/collection/components/molecules/tttx-table/tttx-table.js +318 -318
- package/dist/collection/components/molecules/tttx-table/tttx-table.stories.js +191 -191
- package/dist/collection/components/molecules/tttx-table/tttx-table.types.js +1 -1
- package/dist/collection/components/molecules/tttx-tabs/tttx-tabs.js +253 -253
- package/dist/collection/components/molecules/tttx-tabs/tttx-tabs.stories.js +82 -82
- package/dist/collection/components/molecules/tttx-textarea/tttx-textarea.js +420 -420
- package/dist/collection/components/molecules/tttx-textarea/tttx-textarea.stories.js +81 -81
- package/dist/collection/components/molecules/tttx-toolbar/tttx-toolbar.js +73 -73
- package/dist/collection/components/molecules/tttx-toolbar/tttx-toolbar.stories.js +97 -97
- package/dist/collection/components/molecules/tttx-tooltip/tttx-tooltip.js +253 -253
- package/dist/collection/components/molecules/tttx-tooltip/tttx-tootip.stories.js +117 -117
- package/dist/collection/components/molecules/tttx-tree-view/helper/helper.js +1 -1
- package/dist/collection/components/molecules/tttx-tree-view/tttx-tree-view.css +1 -1
- package/dist/collection/components/molecules/tttx-tree-view/tttx-tree-view.js +463 -463
- package/dist/collection/components/molecules/tttx-tree-view/tttx-tree-view.stories.js +402 -402
- package/dist/collection/components/organisms/tttx-data-pattern/tttx-data-pattern.js +176 -176
- package/dist/collection/components/organisms/tttx-data-pattern/tttx-data-pattern.stories.js +28 -28
- package/dist/collection/components/palette.stories.js +7 -7
- package/dist/collection/icons.js +2838 -2838
- package/dist/collection/index.js +1 -1
- package/dist/collection/shared/domsanitiser.options.js +14 -14
- package/dist/components/auto.js +177 -177
- package/dist/components/domsanitiser.options.js +12 -12
- package/dist/components/index.d.ts +38 -38
- package/dist/components/index.js +38 -38
- package/dist/components/tttx-action-dropdown_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-action-dropdown_1_9_101.js → tttx-action-dropdown_1_9_103.js} +81 -81
- package/dist/components/tttx-button-v2.js +182 -182
- package/dist/components/tttx-button-v2_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-button-v2_1_9_101.js → tttx-button-v2_1_9_103.js} +2 -2
- package/dist/components/tttx-button.js +51 -51
- package/dist/components/{tttx-dialog_1_9_101.d.ts → tttx-button_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-button_1_9_101.js → tttx-button_1_9_103.js} +2 -2
- package/dist/components/{tttx-table_1_9_101.d.ts → tttx-chart_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-chart_1_9_101.js → tttx-chart_1_9_103.js} +574 -574
- package/dist/components/tttx-checkbox-group-caption_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-checkbox-group-caption_1_9_101.js → tttx-checkbox-group-caption_1_9_103.js} +24 -24
- package/dist/components/tttx-checkbox-group-heading_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-checkbox-group-heading_1_9_101.js → tttx-checkbox-group-heading_1_9_103.js} +24 -24
- package/dist/components/tttx-checkbox-group_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-checkbox-group_1_9_101.js → tttx-checkbox-group_1_9_103.js} +25 -25
- package/dist/components/tttx-checkbox_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-checkbox_1_9_101.js → tttx-checkbox_1_9_103.js} +59 -59
- package/dist/components/tttx-comments_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-comments_1_9_101.js → tttx-comments_1_9_103.js} +241 -241
- package/dist/components/tttx-data-pattern_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-data-pattern_1_9_101.js → tttx-data-pattern_1_9_103.js} +80 -80
- package/dist/components/tttx-datacard_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-datacard_1_9_101.js → tttx-datacard_1_9_103.js} +79 -79
- package/dist/components/tttx-date-range-picker.js +242 -242
- package/dist/components/tttx-dialog-box_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-dialog-box_1_9_101.js → tttx-dialog-box_1_9_103.js} +125 -125
- package/dist/components/{tttx-filter_1_9_101.d.ts → tttx-dialog_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-dialog_1_9_101.js → tttx-dialog_1_9_103.js} +103 -103
- package/dist/components/tttx-expander_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-expander_1_9_101.js → tttx-expander_1_9_103.js} +55 -55
- package/dist/components/tttx-filter.js +217 -217
- package/dist/components/{tttx-button_1_9_101.d.ts → tttx-filter_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-filter_1_9_101.js → tttx-filter_1_9_103.js} +2 -2
- package/dist/components/{tttx-form_1_9_101.d.ts → tttx-form_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-form_1_9_101.js → tttx-form_1_9_103.js} +1039 -1039
- package/dist/components/tttx-graph.js +143 -143
- package/dist/components/{tttx-graph_1_9_101.d.ts → tttx-graph_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-graph_1_9_101.js → tttx-graph_1_9_103.js} +2 -2
- package/dist/components/tttx-icon.js +42 -42
- package/dist/components/{tttx-list_1_9_101.d.ts → tttx-icon_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-icon_1_9_101.js → tttx-icon_1_9_103.js} +2 -2
- package/dist/components/tttx-keyvalue-block_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-keyvalue-block_1_9_101.js → tttx-keyvalue-block_1_9_103.js} +83 -83
- package/dist/components/tttx-list.js +92 -92
- package/dist/components/{tttx-tabs_1_9_101.d.ts → tttx-list_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-list_1_9_101.js → tttx-list_1_9_103.js} +2 -2
- package/dist/components/tttx-loading-spinner.js +92 -92
- package/dist/components/tttx-loading-spinner_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-loading-spinner_1_9_101.js → tttx-loading-spinner_1_9_103.js} +2 -2
- package/dist/components/tttx-multiselect-box_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-multiselect-box_1_9_101.js → tttx-multiselect-box_1_9_103.js} +231 -231
- package/dist/components/tttx-percentage-bar_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-percentage-bar_1_9_101.js → tttx-percentage-bar_1_9_103.js} +80 -80
- package/dist/components/tttx-qrcode_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-qrcode_1_9_101.js → tttx-qrcode_1_9_103.js} +47 -47
- package/dist/components/tttx-range-slider_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-range-slider_1_9_101.js → tttx-range-slider_1_9_103.js} +208 -208
- package/dist/components/tttx-select-box.js +295 -295
- package/dist/components/tttx-select-box_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-select-box_1_9_101.js → tttx-select-box_1_9_103.js} +2 -2
- package/dist/components/tttx-skeleton_loader_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-skeleton_loader_1_9_101.js → tttx-skeleton_loader_1_9_103.js} +57 -57
- package/dist/components/tttx-sorter.js +136 -136
- package/dist/components/tttx-sorter_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-sorter_1_9_101.js → tttx-sorter_1_9_103.js} +2 -2
- package/dist/components/tttx-standalone-input.js +136 -136
- package/dist/components/tttx-standalone-input_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-standalone-input_1_9_101.js → tttx-standalone-input_1_9_103.js} +2 -2
- package/dist/components/{tttx-chart_1_9_101.d.ts → tttx-table_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-table_1_9_101.js → tttx-table_1_9_103.js} +109 -109
- package/dist/components/{tttx-icon_1_9_101.d.ts → tttx-tabs_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-tabs_1_9_101.js → tttx-tabs_1_9_103.js} +128 -128
- package/dist/components/{tttx-tag-v2_1_9_101.d.ts → tttx-tag-v2_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-tag-v2_1_9_101.js → tttx-tag-v2_1_9_103.js} +105 -105
- package/dist/components/tttx-tag.js +44 -44
- package/dist/components/{tttx-tag_1_9_101.d.ts → tttx-tag_1_9_103.d.ts} +4 -4
- package/dist/components/{tttx-tag_1_9_101.js → tttx-tag_1_9_103.js} +2 -2
- package/dist/components/tttx-textarea_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-textarea_1_9_101.js → tttx-textarea_1_9_103.js} +83 -83
- package/dist/components/tttx-toggle_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-toggle_1_9_101.js → tttx-toggle_1_9_103.js} +49 -49
- package/dist/components/tttx-toolbar.js +42 -42
- package/dist/components/tttx-toolbar_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-toolbar_1_9_101.js → tttx-toolbar_1_9_103.js} +2 -2
- package/dist/components/tttx-tooltip_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-tooltip_1_9_101.js → tttx-tooltip_1_9_103.js} +114 -114
- package/dist/components/tttx-tree-view_1_9_103.d.ts +11 -0
- package/dist/components/{tttx-tree-view_1_9_101.js → tttx-tree-view_1_9_103.js} +371 -371
- package/dist/esm/{auto-421f2656.js → auto-a07ee1b1.js} +177 -177
- package/dist/esm/{domsanitiser.options-38a67458.js → domsanitiser.options-2c1ef894.js} +12 -12
- package/dist/esm/loader.js +1 -1
- package/dist/esm/polyfills/core-js.js +0 -0
- package/dist/esm/polyfills/dom.js +0 -0
- package/dist/esm/polyfills/es5-html-element.js +0 -0
- package/dist/esm/polyfills/index.js +0 -0
- package/dist/esm/polyfills/system.js +0 -0
- package/dist/esm/{tttx-action-dropdown_1_9_101.entry.js → tttx-action-dropdown_1_9_103.entry.js} +51 -51
- package/dist/esm/{tttx-button-v2_1_9_101.entry.js → tttx-button-v2_1_9_103.entry.js} +147 -147
- package/dist/esm/{tttx-button_1_9_101.entry.js → tttx-button_1_9_103.entry.js} +26 -26
- package/dist/esm/{tttx-chart_1_9_101.entry.js → tttx-chart_1_9_103.entry.js} +524 -524
- package/dist/esm/{tttx-checkbox-group-caption_1_9_101.entry.js → tttx-checkbox-group-caption_1_9_103.entry.js} +9 -9
- package/dist/esm/{tttx-checkbox-group-heading_1_9_101.entry.js → tttx-checkbox-group-heading_1_9_103.entry.js} +9 -9
- package/dist/esm/{tttx-checkbox-group_1_9_101.entry.js → tttx-checkbox-group_1_9_103.entry.js} +9 -9
- package/dist/esm/{tttx-checkbox_1_9_101.entry.js → tttx-checkbox_1_9_103.entry.js} +33 -33
- package/dist/esm/{tttx-comments_1_9_101.entry.js → tttx-comments_1_9_103.entry.js} +204 -204
- package/dist/esm/{tttx-data-pattern_1_9_101.entry.js → tttx-data-pattern_1_9_103.entry.js} +20 -20
- package/dist/esm/{tttx-datacard_1_9_101.entry.js → tttx-datacard_1_9_103.entry.js} +43 -43
- package/dist/esm/tttx-date-range-picker.entry.js +212 -212
- package/dist/esm/{tttx-dialog-box_1_9_101.entry.js → tttx-dialog-box_1_9_103.entry.js} +94 -94
- package/dist/esm/{tttx-dialog_1_9_101.entry.js → tttx-dialog_1_9_103.entry.js} +69 -69
- package/dist/esm/{tttx-expander_1_9_101.entry.js → tttx-expander_1_9_103.entry.js} +28 -28
- package/dist/esm/{tttx-filter_1_9_101_4.entry.js → tttx-filter_1_9_103_4.entry.js} +383 -383
- package/dist/esm/{tttx-form_1_9_101.entry.js → tttx-form_1_9_103.entry.js} +985 -985
- package/dist/esm/{tttx-graph_1_9_101.entry.js → tttx-graph_1_9_103.entry.js} +124 -124
- package/dist/esm/{tttx-icon_1_9_101.entry.js → tttx-icon_1_9_103.entry.js} +24 -24
- package/dist/esm/{tttx-keyvalue-block_1_9_101.entry.js → tttx-keyvalue-block_1_9_103.entry.js} +62 -62
- package/dist/esm/{tttx-loading-spinner_1_9_101_3.entry.js → tttx-loading-spinner_1_9_103_3.entry.js} +170 -170
- package/dist/esm/{tttx-multiselect-box_1_9_101.entry.js → tttx-multiselect-box_1_9_103.entry.js} +175 -175
- package/dist/esm/{tttx-percentage-bar_1_9_101.entry.js → tttx-percentage-bar_1_9_103.entry.js} +56 -56
- package/dist/esm/{tttx-qrcode_1_9_101.entry.js → tttx-qrcode_1_9_103.entry.js} +28 -28
- package/dist/esm/{tttx-range-slider_1_9_101.entry.js → tttx-range-slider_1_9_103.entry.js} +185 -185
- package/dist/esm/{tttx-select-box_1_9_101.entry.js → tttx-select-box_1_9_103.entry.js} +239 -239
- package/dist/esm/{tttx-skeleton_loader_1_9_101.entry.js → tttx-skeleton_loader_1_9_103.entry.js} +30 -30
- package/dist/esm/{tttx-table_1_9_101.entry.js → tttx-table_1_9_103.entry.js} +72 -72
- package/dist/esm/{tttx-tabs_1_9_101.entry.js → tttx-tabs_1_9_103.entry.js} +103 -103
- package/dist/esm/{tttx-tag-v2_1_9_101.entry.js → tttx-tag-v2_1_9_103.entry.js} +72 -72
- package/dist/esm/{tttx-textarea_1_9_101.entry.js → tttx-textarea_1_9_103.entry.js} +50 -50
- package/dist/esm/{tttx-toggle_1_9_101.entry.js → tttx-toggle_1_9_103.entry.js} +30 -30
- package/dist/esm/{tttx-tooltip_1_9_101.entry.js → tttx-tooltip_1_9_103.entry.js} +87 -87
- package/dist/esm/{tttx-tree-view_1_9_101.entry.js → tttx-tree-view_1_9_103.entry.js} +342 -342
- package/dist/esm/tttx.js +1 -1
- package/dist/tttx/{p-b3f49d83.entry.js → p-0c5bc253.entry.js} +1 -1
- package/dist/tttx/{p-82b4e575.entry.js → p-10d2d044.entry.js} +1 -1
- package/dist/tttx/p-1623f3cf.entry.js +1 -1
- package/dist/tttx/{p-b161205b.entry.js → p-16aa3f67.entry.js} +1 -1
- package/dist/tttx/p-21707b8d.entry.js +1 -1
- package/dist/tttx/p-2251ab85.entry.js +1 -1
- package/dist/tttx/p-2d19c46c.entry.js +1 -1
- package/dist/tttx/p-358eaa44.entry.js +1 -1
- package/dist/tttx/p-362999b3.entry.js +1 -1
- package/dist/tttx/p-3ec67d75.entry.js +1 -1
- package/dist/tttx/p-44f0af69.entry.js +1 -1
- package/dist/tttx/p-4664d065.entry.js +1 -1
- package/dist/tttx/{p-00a849cf.entry.js → p-486ca932.entry.js} +1 -1
- package/dist/tttx/{p-e21e3a9c.entry.js → p-59115c8f.entry.js} +1 -1
- package/dist/tttx/p-5d289334.entry.js +1 -1
- package/dist/tttx/p-6ec18b4a.entry.js +1 -1
- package/dist/tttx/{p-a59ad197.entry.js → p-700c2816.entry.js} +1 -1
- package/dist/tttx/p-7b5b0670.entry.js +1 -1
- package/dist/tttx/p-7d1712fe.entry.js +1 -1
- package/dist/tttx/{p-41b69e01.entry.js → p-8f85ab3e.entry.js} +1 -1
- package/dist/tttx/p-a1b8ecda.entry.js +1 -1
- package/dist/tttx/p-a43e2c5e.entry.js +1 -1
- package/dist/tttx/p-b8cc0cb2.entry.js +1 -1
- package/dist/tttx/p-b9003a76.entry.js +1 -1
- package/dist/tttx/p-bb59054f.entry.js +1 -1
- package/dist/tttx/p-c66bc14c.entry.js +1 -1
- package/dist/tttx/p-c8051143.entry.js +1 -1
- package/dist/tttx/p-ca93f786.entry.js +1 -1
- package/dist/tttx/p-d21b0507.entry.js +1 -1
- package/dist/tttx/p-d945d492.entry.js +1 -1
- package/dist/tttx/{p-34e0e487.entry.js → p-df708b75.entry.js} +2 -2
- package/dist/tttx/p-f0c1380f.entry.js +1 -1
- package/dist/tttx/{p-0bb158ce.js → p-f411d1e5.js} +2 -2
- package/dist/tttx/{p-d4c4edbd.entry.js → p-fa25ee03.entry.js} +1 -1
- package/dist/tttx/{p-41f0bf7f.entry.js → p-fbdd1046.entry.js} +1 -1
- package/dist/tttx/tttx.esm.js +1 -1
- package/dist/types/components/atoms/tttx-button/tttx-button.d.ts +11 -11
- package/dist/types/components/atoms/tttx-button/tttx-button.stories.d.ts +11 -11
- package/dist/types/components/atoms/tttx-button-v2/tttx-button-v2.d.ts +36 -36
- package/dist/types/components/atoms/tttx-button-v2/tttx-button-v2.stories.d.ts +68 -68
- package/dist/types/components/atoms/tttx-checkbox/tttx-checkbox.d.ts +17 -17
- package/dist/types/components/atoms/tttx-datacard/tttx-datacard.d.ts +21 -21
- package/dist/types/components/atoms/tttx-datacard/tttx-datacard.stories.d.ts +44 -44
- package/dist/types/components/atoms/tttx-icon/tttx-icon.d.ts +9 -9
- package/dist/types/components/atoms/tttx-icon/tttx-icon.stories.d.ts +25 -25
- package/dist/types/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.d.ts +13 -13
- package/dist/types/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.stories.d.ts +11 -11
- package/dist/types/components/atoms/tttx-loading-spinner/tttx-loading-spinner.d.ts +23 -23
- package/dist/types/components/atoms/tttx-loading-spinner/tttx-loading-spinner.stories.d.ts +47 -47
- package/dist/types/components/atoms/tttx-percentage-bar/tttx-percentage-bar.d.ts +22 -22
- package/dist/types/components/atoms/tttx-percentage-bar/tttx-percentage-bar.stories.d.ts +10 -10
- package/dist/types/components/atoms/tttx-qrcode/tttx-qrcode.d.ts +8 -8
- package/dist/types/components/atoms/tttx-qrcode/tttx-qrcode.stories.d.ts +23 -23
- package/dist/types/components/atoms/tttx-skeleton-loader/tttx-skeleton-loader.d.ts +14 -14
- package/dist/types/components/atoms/tttx-tag/tttx-tag.d.ts +10 -10
- package/dist/types/components/atoms/tttx-tag/tttx-tag.stories.d.ts +51 -51
- package/dist/types/components/atoms/tttx-tag-v2/tttx-tag-v2.d.ts +15 -15
- package/dist/types/components/atoms/tttx-tag-v2/tttx-tag-v2.stories.d.ts +48 -48
- package/dist/types/components/atoms/tttx-toggle/tttx-toggle.d.ts +11 -11
- package/dist/types/components/atoms/tttx-toggle/tttx-toggle.stories.d.ts +6 -6
- package/dist/types/components/domsanitiser.options.d.ts +10 -10
- package/dist/types/components/molecules/tttx-action-dropdown/tttx-action-dropdown.d.ts +21 -21
- package/dist/types/components/molecules/tttx-chart/tttx-chart.d.ts +60 -60
- package/dist/types/components/molecules/tttx-chart/tttx-chart.stories.d.ts +38 -38
- package/dist/types/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-caption.d.ts +3 -3
- package/dist/types/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-heading.d.ts +3 -3
- package/dist/types/components/molecules/tttx-checkbox-group/tttx-checkbox-group.d.ts +3 -3
- package/dist/types/components/molecules/tttx-checkbox-group/tttx-checkbox-group.stories.d.ts +15 -15
- package/dist/types/components/molecules/tttx-comments/tttx-comments.d.ts +68 -68
- package/dist/types/components/molecules/tttx-date-range-picker/tttx-date-range-picker.d.ts +42 -42
- package/dist/types/components/molecules/tttx-dialog/icon-types.d.ts +18 -18
- package/dist/types/components/molecules/tttx-dialog/tttx-dialog.d.ts +27 -27
- package/dist/types/components/molecules/tttx-dialog-box/tttx-dialog-box.d.ts +26 -26
- package/dist/types/components/molecules/tttx-dialog-box/tttx-dialog-box.stories.d.ts +24 -24
- package/dist/types/components/molecules/tttx-expander/tttx-expander.d.ts +16 -16
- package/dist/types/components/molecules/tttx-filter/tttx-filter.d.ts +44 -44
- package/dist/types/components/molecules/tttx-form/lib/setErrorState.d.ts +14 -14
- package/dist/types/components/molecules/tttx-form/lib/timecomparatorChecks.d.ts +4 -4
- package/dist/types/components/molecules/tttx-form/lib/validityCheck.d.ts +15 -15
- package/dist/types/components/molecules/tttx-form/tttx-form.d.ts +297 -297
- package/dist/types/components/molecules/tttx-graph/gauge-label-plugin.d.ts +4 -4
- package/dist/types/components/molecules/tttx-graph/tttx-graph.d.ts +13 -13
- package/dist/types/components/molecules/tttx-graph/tttx-graph.stories.d.ts +26 -26
- package/dist/types/components/molecules/tttx-list/tttx-list.d.ts +23 -23
- package/dist/types/components/molecules/tttx-multiselect-box/tttx-multiselect-box.d.ts +50 -50
- package/dist/types/components/molecules/tttx-range-slider/tttx-range-slider.d.ts +45 -45
- package/dist/types/components/molecules/tttx-range-slider/tttx-range-slider.stories.d.ts +7 -7
- package/dist/types/components/molecules/tttx-select-box/tttx-select-box.d.ts +55 -55
- package/dist/types/components/molecules/tttx-select-box/tttx-select-box.stories.d.ts +28 -28
- package/dist/types/components/molecules/tttx-sorter/tttx-sorter.d.ts +21 -21
- package/dist/types/components/molecules/tttx-standalone-input/tttx-standalone-input.d.ts +69 -69
- package/dist/types/components/molecules/tttx-table/tttx-table.d.ts +32 -32
- package/dist/types/components/molecules/tttx-table/tttx-table.types.d.ts +6 -6
- package/dist/types/components/molecules/tttx-tabs/tttx-tabs.d.ts +25 -25
- package/dist/types/components/molecules/tttx-textarea/tttx-textarea.d.ts +42 -42
- package/dist/types/components/molecules/tttx-textarea/tttx-textarea.stories.d.ts +89 -89
- package/dist/types/components/molecules/tttx-toolbar/tttx-toolbar.d.ts +8 -8
- package/dist/types/components/molecules/tttx-toolbar/tttx-toolbar.stories.d.ts +19 -19
- package/dist/types/components/molecules/tttx-tooltip/tttx-tooltip.d.ts +37 -37
- package/dist/types/components/molecules/tttx-tooltip/tttx-tootip.stories.d.ts +12 -12
- package/dist/types/components/molecules/tttx-tree-view/helper/helper.d.ts +24 -24
- package/dist/types/components/molecules/tttx-tree-view/tttx-tree-view.d.ts +57 -57
- package/dist/types/components/organisms/tttx-data-pattern/tttx-data-pattern.d.ts +11 -11
- package/dist/types/components/organisms/tttx-data-pattern/tttx-data-pattern.stories.d.ts +13 -13
- package/dist/types/components/palette.stories.d.ts +6 -6
- package/dist/types/components.d.ts +451 -451
- package/dist/types/icons.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/shared/domsanitiser.options.d.ts +10 -10
- package/package.json +1 -1
- package/dist/components/tttx-action-dropdown_1_9_101.d.ts +0 -11
- package/dist/components/tttx-button-v2_1_9_101.d.ts +0 -11
- package/dist/components/tttx-checkbox-group-caption_1_9_101.d.ts +0 -11
- package/dist/components/tttx-checkbox-group-heading_1_9_101.d.ts +0 -11
- package/dist/components/tttx-checkbox-group_1_9_101.d.ts +0 -11
- package/dist/components/tttx-checkbox_1_9_101.d.ts +0 -11
- package/dist/components/tttx-comments_1_9_101.d.ts +0 -11
- package/dist/components/tttx-data-pattern_1_9_101.d.ts +0 -11
- package/dist/components/tttx-datacard_1_9_101.d.ts +0 -11
- package/dist/components/tttx-dialog-box_1_9_101.d.ts +0 -11
- package/dist/components/tttx-expander_1_9_101.d.ts +0 -11
- package/dist/components/tttx-keyvalue-block_1_9_101.d.ts +0 -11
- package/dist/components/tttx-loading-spinner_1_9_101.d.ts +0 -11
- package/dist/components/tttx-multiselect-box_1_9_101.d.ts +0 -11
- package/dist/components/tttx-percentage-bar_1_9_101.d.ts +0 -11
- package/dist/components/tttx-qrcode_1_9_101.d.ts +0 -11
- package/dist/components/tttx-range-slider_1_9_101.d.ts +0 -11
- package/dist/components/tttx-select-box_1_9_101.d.ts +0 -11
- package/dist/components/tttx-skeleton_loader_1_9_101.d.ts +0 -11
- package/dist/components/tttx-sorter_1_9_101.d.ts +0 -11
- package/dist/components/tttx-standalone-input_1_9_101.d.ts +0 -11
- package/dist/components/tttx-textarea_1_9_101.d.ts +0 -11
- package/dist/components/tttx-toggle_1_9_101.d.ts +0 -11
- package/dist/components/tttx-toolbar_1_9_101.d.ts +0 -11
- package/dist/components/tttx-tooltip_1_9_101.d.ts +0 -11
- package/dist/components/tttx-tree-view_1_9_101.d.ts +0 -11
- package/dist/types/components/atoms/tttx-checkbox/tttx-checkbox.stories.d.ts +0 -47
- package/dist/types/components/atoms/tttx-skeleton-loader/tttx-skeleton-loader.stories.d.ts +0 -58
- package/dist/types/components/molecules/tttx-action-dropdown/tttx-action-dropdown.stories.d.ts +0 -36
- package/dist/types/components/molecules/tttx-comments/tttx-comments.stories.d.ts +0 -8
- package/dist/types/components/molecules/tttx-date-range-picker/tttx-date-range-picker.stories.d.ts +0 -28
- package/dist/types/components/molecules/tttx-dialog/tttx-dialog.stories.d.ts +0 -42
- package/dist/types/components/molecules/tttx-expander/tttx-expander.stories.d.ts +0 -27
- package/dist/types/components/molecules/tttx-filter/tttx-filter.stories.d.ts +0 -76
- package/dist/types/components/molecules/tttx-form/tttx-form.stories.d.ts +0 -718
- package/dist/types/components/molecules/tttx-list/tttx-list.stories.d.ts +0 -15
- package/dist/types/components/molecules/tttx-multiselect-box/tttx-multiselect-box.stories.d.ts +0 -17
- package/dist/types/components/molecules/tttx-sorter/tttx-sorter.stories.d.ts +0 -30
- package/dist/types/components/molecules/tttx-standalone-input/tttx-standalone-input.stories.d.ts +0 -150
- package/dist/types/components/molecules/tttx-table/tttx-table.stories.d.ts +0 -79
- package/dist/types/components/molecules/tttx-tabs/tttx-tabs.stories.d.ts +0 -13
- package/dist/types/components/molecules/tttx-tree-view/tttx-tree-view.stories.d.ts +0 -15
- /package/dist/tttx/{p-55799798.js → p-62d92a44.js} +0 -0
|
@@ -6,1054 +6,1054 @@ import { d as defineCustomElement$4 } from './tttx-select-box.js';
|
|
|
6
6
|
import { d as defineCustomElement$3 } from './tttx-standalone-input.js';
|
|
7
7
|
import { d as defineCustomElement$2 } from './tttx-tag.js';
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* Validates the input field on focusout event by checking its validity state,
|
|
11
|
-
* sets an error message if there's an issue, and emits a "dataChanged" event to
|
|
12
|
-
* the parent component with the field name and its new value.
|
|
13
|
-
*
|
|
14
|
-
* @param {Event | FocusEvent} event - The focusout event triggered by the input field.
|
|
15
|
-
* @return {{ target: FormField; hasError: boolean; errorMessage: string; }}
|
|
16
|
-
*/
|
|
17
|
-
function validityCheck(event) {
|
|
18
|
-
var _a, _b, _c, _d;
|
|
19
|
-
if (event.preventDefault) {
|
|
20
|
-
event.preventDefault();
|
|
21
|
-
}
|
|
22
|
-
const target = event.target;
|
|
23
|
-
let hasError = true;
|
|
24
|
-
let errorMessage = '';
|
|
25
|
-
// validity object on HTML5 inputs has the following options
|
|
26
|
-
/*
|
|
27
|
-
badInput
|
|
28
|
-
customError
|
|
29
|
-
patternMismatch
|
|
30
|
-
rangeOverflow
|
|
31
|
-
rangeUnderflow
|
|
32
|
-
stepMismatch
|
|
33
|
-
tooLong
|
|
34
|
-
tooShort
|
|
35
|
-
typeMismatch
|
|
36
|
-
valid
|
|
37
|
-
valueMissing
|
|
38
|
-
*/
|
|
39
|
-
// customErrors can be set with
|
|
40
|
-
// target.setCustomValidity('custom error!');
|
|
41
|
-
// and cleared with
|
|
42
|
-
// target.setCustomValidity('');
|
|
43
|
-
//handle whitespace-only input
|
|
44
|
-
if (!target.hasAttribute('custom-validation-set')) {
|
|
45
|
-
if (target.value.length && !target.value.replace(/\s/g, '').length) {
|
|
46
|
-
errorMessage = 'This field cannot be left blank';
|
|
47
|
-
target.setCustomValidity(errorMessage);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
if (target.setCustomValidity) // tests are dumb as a brick
|
|
51
|
-
target.setCustomValidity('');
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
// Check the validity of the input field and set an error message if needed
|
|
55
|
-
switch (true) {
|
|
56
|
-
// The field is required, but has no value
|
|
57
|
-
case target.validity.valueMissing:
|
|
58
|
-
errorMessage = (_a = target.dataset.required) !== null && _a !== void 0 ? _a : 'This field is required';
|
|
59
|
-
break;
|
|
60
|
-
// The field's value does not match the expected pattern
|
|
61
|
-
case target.validity.patternMismatch:
|
|
62
|
-
errorMessage = (_b = target.dataset.pattern) !== null && _b !== void 0 ? _b : 'Incorrect format';
|
|
63
|
-
break;
|
|
64
|
-
// The field's value is not of the correct input type
|
|
65
|
-
case target.validity.badInput:
|
|
66
|
-
// IE string in a number field
|
|
67
|
-
errorMessage = (_c = target.dataset.badinput) !== null && _c !== void 0 ? _c : 'Wrong input type';
|
|
68
|
-
break;
|
|
69
|
-
// The field's value is above or below the range set in the "min" and "max" attributes
|
|
70
|
-
case target.validity.rangeOverflow || target.validity.rangeUnderflow:
|
|
71
|
-
// IE date or number is above or below value set in min or max tags
|
|
72
|
-
errorMessage = (_d = target.dataset.range) !== null && _d !== void 0 ? _d : 'Invalid value';
|
|
73
|
-
break;
|
|
74
|
-
case target.validity.customError:
|
|
75
|
-
errorMessage = target.validationMessage;
|
|
76
|
-
break;
|
|
77
|
-
// No error detected
|
|
78
|
-
default:
|
|
79
|
-
hasError = false;
|
|
80
|
-
}
|
|
81
|
-
// Return the error state
|
|
82
|
-
return { target, hasError, errorMessage };
|
|
9
|
+
/**
|
|
10
|
+
* Validates the input field on focusout event by checking its validity state,
|
|
11
|
+
* sets an error message if there's an issue, and emits a "dataChanged" event to
|
|
12
|
+
* the parent component with the field name and its new value.
|
|
13
|
+
*
|
|
14
|
+
* @param {Event | FocusEvent} event - The focusout event triggered by the input field.
|
|
15
|
+
* @return {{ target: FormField; hasError: boolean; errorMessage: string; }}
|
|
16
|
+
*/
|
|
17
|
+
function validityCheck(event) {
|
|
18
|
+
var _a, _b, _c, _d;
|
|
19
|
+
if (event.preventDefault) {
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
}
|
|
22
|
+
const target = event.target;
|
|
23
|
+
let hasError = true;
|
|
24
|
+
let errorMessage = '';
|
|
25
|
+
// validity object on HTML5 inputs has the following options
|
|
26
|
+
/*
|
|
27
|
+
badInput
|
|
28
|
+
customError
|
|
29
|
+
patternMismatch
|
|
30
|
+
rangeOverflow
|
|
31
|
+
rangeUnderflow
|
|
32
|
+
stepMismatch
|
|
33
|
+
tooLong
|
|
34
|
+
tooShort
|
|
35
|
+
typeMismatch
|
|
36
|
+
valid
|
|
37
|
+
valueMissing
|
|
38
|
+
*/
|
|
39
|
+
// customErrors can be set with
|
|
40
|
+
// target.setCustomValidity('custom error!');
|
|
41
|
+
// and cleared with
|
|
42
|
+
// target.setCustomValidity('');
|
|
43
|
+
//handle whitespace-only input
|
|
44
|
+
if (!target.hasAttribute('custom-validation-set')) {
|
|
45
|
+
if (target.value.length && !target.value.replace(/\s/g, '').length) {
|
|
46
|
+
errorMessage = 'This field cannot be left blank';
|
|
47
|
+
target.setCustomValidity(errorMessage);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (target.setCustomValidity) // tests are dumb as a brick
|
|
51
|
+
target.setCustomValidity('');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Check the validity of the input field and set an error message if needed
|
|
55
|
+
switch (true) {
|
|
56
|
+
// The field is required, but has no value
|
|
57
|
+
case target.validity.valueMissing:
|
|
58
|
+
errorMessage = (_a = target.dataset.required) !== null && _a !== void 0 ? _a : 'This field is required';
|
|
59
|
+
break;
|
|
60
|
+
// The field's value does not match the expected pattern
|
|
61
|
+
case target.validity.patternMismatch:
|
|
62
|
+
errorMessage = (_b = target.dataset.pattern) !== null && _b !== void 0 ? _b : 'Incorrect format';
|
|
63
|
+
break;
|
|
64
|
+
// The field's value is not of the correct input type
|
|
65
|
+
case target.validity.badInput:
|
|
66
|
+
// IE string in a number field
|
|
67
|
+
errorMessage = (_c = target.dataset.badinput) !== null && _c !== void 0 ? _c : 'Wrong input type';
|
|
68
|
+
break;
|
|
69
|
+
// The field's value is above or below the range set in the "min" and "max" attributes
|
|
70
|
+
case target.validity.rangeOverflow || target.validity.rangeUnderflow:
|
|
71
|
+
// IE date or number is above or below value set in min or max tags
|
|
72
|
+
errorMessage = (_d = target.dataset.range) !== null && _d !== void 0 ? _d : 'Invalid value';
|
|
73
|
+
break;
|
|
74
|
+
case target.validity.customError:
|
|
75
|
+
errorMessage = target.validationMessage;
|
|
76
|
+
break;
|
|
77
|
+
// No error detected
|
|
78
|
+
default:
|
|
79
|
+
hasError = false;
|
|
80
|
+
}
|
|
81
|
+
// Return the error state
|
|
82
|
+
return { target, hasError, errorMessage };
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
/**
|
|
86
|
-
* Sets the error state of an input field by updating its class and error message.
|
|
87
|
-
* If an error was detected, it sets the input field's class to "invalid" and
|
|
88
|
-
* displays the error message in an error bubble. If no error was detected,
|
|
89
|
-
* it removes the "invalid" class from the input field and clears the error bubble.
|
|
90
|
-
*
|
|
91
|
-
* @param {FormField} target - The input field to update.
|
|
92
|
-
* @param {boolean} hasError - Whether an error was detected in the field.
|
|
93
|
-
* @param {string} errorMessage - The error message to display (if any).
|
|
94
|
-
* @return {void}
|
|
95
|
-
*/
|
|
96
|
-
function setErrorState(target, hasError, errorMessage, parent = undefined) {
|
|
97
|
-
// Find the error bubble element for the input field
|
|
98
|
-
let errorBubble;
|
|
99
|
-
if (parent !== undefined) {
|
|
100
|
-
errorBubble = parent.querySelector('.errorBubble');
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
if (target.parentElement.nodeName.toLowerCase() === 'label') {
|
|
104
|
-
errorBubble = target.parentElement.querySelector('.errorBubble');
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
errorBubble = target.parentElement.parentElement.querySelector('.errorBubble');
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (!errorBubble)
|
|
111
|
-
return;
|
|
112
|
-
// If an error was detected, set the input field's class to "invalid" and display the error message in the error bubble
|
|
113
|
-
if (hasError) {
|
|
114
|
-
target.classList.add('invalid');
|
|
115
|
-
errorBubble.classList.add('visible');
|
|
116
|
-
const errorIcon = document.createElement('span');
|
|
117
|
-
// Set the class of the error icon to a pre-defined CSS class that specifies the icon's appearance
|
|
118
|
-
errorIcon.className = 'material-symbols-rounded';
|
|
119
|
-
// Set the text content of the error icon to the word "warning"
|
|
120
|
-
errorIcon.textContent = 'warning';
|
|
121
|
-
// errorBubble.replaceChildren cannot be used here because the tests don't support this new feature :(
|
|
122
|
-
errorBubble.innerHTML = '';
|
|
123
|
-
errorBubble.append(errorIcon);
|
|
124
|
-
errorBubble.append(errorMessage);
|
|
125
|
-
}
|
|
126
|
-
// If no error was detected, remove the "invalid" class from the input field and clear the error bubble
|
|
127
|
-
else {
|
|
128
|
-
errorBubble.classList.remove('visible');
|
|
129
|
-
target.classList.remove('invalid');
|
|
130
|
-
errorBubble.innerHTML = '';
|
|
131
|
-
}
|
|
85
|
+
/**
|
|
86
|
+
* Sets the error state of an input field by updating its class and error message.
|
|
87
|
+
* If an error was detected, it sets the input field's class to "invalid" and
|
|
88
|
+
* displays the error message in an error bubble. If no error was detected,
|
|
89
|
+
* it removes the "invalid" class from the input field and clears the error bubble.
|
|
90
|
+
*
|
|
91
|
+
* @param {FormField} target - The input field to update.
|
|
92
|
+
* @param {boolean} hasError - Whether an error was detected in the field.
|
|
93
|
+
* @param {string} errorMessage - The error message to display (if any).
|
|
94
|
+
* @return {void}
|
|
95
|
+
*/
|
|
96
|
+
function setErrorState(target, hasError, errorMessage, parent = undefined) {
|
|
97
|
+
// Find the error bubble element for the input field
|
|
98
|
+
let errorBubble;
|
|
99
|
+
if (parent !== undefined) {
|
|
100
|
+
errorBubble = parent.querySelector('.errorBubble');
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
if (target.parentElement.nodeName.toLowerCase() === 'label') {
|
|
104
|
+
errorBubble = target.parentElement.querySelector('.errorBubble');
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
errorBubble = target.parentElement.parentElement.querySelector('.errorBubble');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (!errorBubble)
|
|
111
|
+
return;
|
|
112
|
+
// If an error was detected, set the input field's class to "invalid" and display the error message in the error bubble
|
|
113
|
+
if (hasError) {
|
|
114
|
+
target.classList.add('invalid');
|
|
115
|
+
errorBubble.classList.add('visible');
|
|
116
|
+
const errorIcon = document.createElement('span');
|
|
117
|
+
// Set the class of the error icon to a pre-defined CSS class that specifies the icon's appearance
|
|
118
|
+
errorIcon.className = 'material-symbols-rounded';
|
|
119
|
+
// Set the text content of the error icon to the word "warning"
|
|
120
|
+
errorIcon.textContent = 'warning';
|
|
121
|
+
// errorBubble.replaceChildren cannot be used here because the tests don't support this new feature :(
|
|
122
|
+
errorBubble.innerHTML = '';
|
|
123
|
+
errorBubble.append(errorIcon);
|
|
124
|
+
errorBubble.append(errorMessage);
|
|
125
|
+
}
|
|
126
|
+
// If no error was detected, remove the "invalid" class from the input field and clear the error bubble
|
|
127
|
+
else {
|
|
128
|
+
errorBubble.classList.remove('visible');
|
|
129
|
+
target.classList.remove('invalid');
|
|
130
|
+
errorBubble.innerHTML = '';
|
|
131
|
+
}
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
function startEndTimeComparator(event) {
|
|
135
|
-
var _a, _b;
|
|
136
|
-
const target = event.target;
|
|
137
|
-
const formKey = target.getAttribute('data-formkey');
|
|
138
|
-
const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[data-formkey=${formKey}]`));
|
|
139
|
-
if (timeFields.length === 4) {
|
|
140
|
-
const startTime = timeFields.find(t => t.name.endsWith('starttime'));
|
|
141
|
-
const endTime = timeFields.find(t => t.name.endsWith('endtime'));
|
|
142
|
-
const startDate = timeFields.find(t => t.name.endsWith('startdate'));
|
|
143
|
-
const endDate = timeFields.find(t => t.name.endsWith('enddate'));
|
|
144
|
-
if (startTime.valueAsNumber >= endTime.valueAsNumber && ((_a = startDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) === ((_b = endDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
|
|
145
|
-
setErrorState(endTime, true, 'End time cannot be the same or before the start time');
|
|
146
|
-
if (target.name.endsWith('starttime')) {
|
|
147
|
-
this.validityCheckWrapper(event);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
// clear any end time comparitor errors and perform the standard validity check on the event
|
|
152
|
-
endTime.setCustomValidity('');
|
|
153
|
-
setErrorState(endTime, false, null);
|
|
154
|
-
this.validityCheckWrapper(event);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
function clearTimeComparator(event) {
|
|
159
|
-
const target = event.target;
|
|
160
|
-
const formKey = target.getAttribute('data-formkey');
|
|
161
|
-
const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[type=time][data-formkey=${formKey}]`));
|
|
162
|
-
if (timeFields.length) {
|
|
163
|
-
const endTime = timeFields.find(t => t.name.endsWith('endtime'));
|
|
164
|
-
endTime.setCustomValidity('');
|
|
165
|
-
setErrorState(endTime, false, null);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
function endDateComparisonValidator(event, triggeredByStartDate = false) {
|
|
169
|
-
var _a, _b, _c, _d;
|
|
170
|
-
const endDate = event.target;
|
|
171
|
-
if (!endDate.value && triggeredByStartDate) {
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
const compareWithName = endDate.getAttribute('data-compare-with');
|
|
175
|
-
const startDate = endDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareWithName}]`);
|
|
176
|
-
if (((_a = endDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) < ((_b = startDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
|
|
177
|
-
endDate.setCustomValidity(endDate.getAttribute('data-compare'));
|
|
178
|
-
setErrorState(endDate, true, endDate.getAttribute('data-compare'));
|
|
179
|
-
}
|
|
180
|
-
else if (((_c = endDate.valueAsDate) === null || _c === void 0 ? void 0 : _c.valueOf()) === ((_d = startDate.valueAsDate) === null || _d === void 0 ? void 0 : _d.valueOf())) {
|
|
181
|
-
endDate.setCustomValidity('');
|
|
182
|
-
this.validityCheckWrapper(event);
|
|
183
|
-
startEndTimeComparator.bind(this)(event);
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
clearTimeComparator.bind(this)(event);
|
|
187
|
-
this.validityCheckWrapper(event);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
function startDateComparisonValidator(event) {
|
|
191
|
-
const startDate = event.target;
|
|
192
|
-
const compareToName = startDate.getAttribute('data-compare-to');
|
|
193
|
-
const endDate = startDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareToName}]`);
|
|
194
|
-
endDateComparisonValidator.bind(this)({ target: endDate }, true);
|
|
195
|
-
this.validityCheckWrapper(event);
|
|
134
|
+
function startEndTimeComparator(event) {
|
|
135
|
+
var _a, _b;
|
|
136
|
+
const target = event.target;
|
|
137
|
+
const formKey = target.getAttribute('data-formkey');
|
|
138
|
+
const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[data-formkey=${formKey}]`));
|
|
139
|
+
if (timeFields.length === 4) {
|
|
140
|
+
const startTime = timeFields.find(t => t.name.endsWith('starttime'));
|
|
141
|
+
const endTime = timeFields.find(t => t.name.endsWith('endtime'));
|
|
142
|
+
const startDate = timeFields.find(t => t.name.endsWith('startdate'));
|
|
143
|
+
const endDate = timeFields.find(t => t.name.endsWith('enddate'));
|
|
144
|
+
if (startTime.valueAsNumber >= endTime.valueAsNumber && ((_a = startDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) === ((_b = endDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
|
|
145
|
+
setErrorState(endTime, true, 'End time cannot be the same or before the start time');
|
|
146
|
+
if (target.name.endsWith('starttime')) {
|
|
147
|
+
this.validityCheckWrapper(event);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// clear any end time comparitor errors and perform the standard validity check on the event
|
|
152
|
+
endTime.setCustomValidity('');
|
|
153
|
+
setErrorState(endTime, false, null);
|
|
154
|
+
this.validityCheckWrapper(event);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function clearTimeComparator(event) {
|
|
159
|
+
const target = event.target;
|
|
160
|
+
const formKey = target.getAttribute('data-formkey');
|
|
161
|
+
const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[type=time][data-formkey=${formKey}]`));
|
|
162
|
+
if (timeFields.length) {
|
|
163
|
+
const endTime = timeFields.find(t => t.name.endsWith('endtime'));
|
|
164
|
+
endTime.setCustomValidity('');
|
|
165
|
+
setErrorState(endTime, false, null);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function endDateComparisonValidator(event, triggeredByStartDate = false) {
|
|
169
|
+
var _a, _b, _c, _d;
|
|
170
|
+
const endDate = event.target;
|
|
171
|
+
if (!endDate.value && triggeredByStartDate) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const compareWithName = endDate.getAttribute('data-compare-with');
|
|
175
|
+
const startDate = endDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareWithName}]`);
|
|
176
|
+
if (((_a = endDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) < ((_b = startDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
|
|
177
|
+
endDate.setCustomValidity(endDate.getAttribute('data-compare'));
|
|
178
|
+
setErrorState(endDate, true, endDate.getAttribute('data-compare'));
|
|
179
|
+
}
|
|
180
|
+
else if (((_c = endDate.valueAsDate) === null || _c === void 0 ? void 0 : _c.valueOf()) === ((_d = startDate.valueAsDate) === null || _d === void 0 ? void 0 : _d.valueOf())) {
|
|
181
|
+
endDate.setCustomValidity('');
|
|
182
|
+
this.validityCheckWrapper(event);
|
|
183
|
+
startEndTimeComparator.bind(this)(event);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
clearTimeComparator.bind(this)(event);
|
|
187
|
+
this.validityCheckWrapper(event);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function startDateComparisonValidator(event) {
|
|
191
|
+
const startDate = event.target;
|
|
192
|
+
const compareToName = startDate.getAttribute('data-compare-to');
|
|
193
|
+
const endDate = startDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareToName}]`);
|
|
194
|
+
endDateComparisonValidator.bind(this)({ target: endDate }, true);
|
|
195
|
+
this.validityCheckWrapper(event);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
const tttxFormCss = ".material-symbols-rounded{font-variation-settings:\"FILL\" 1, \"wght\" 400, \"GRAD\" 0, \"opsz\" 24}.material-symbols-rounded{font-variation-settings:\"FILL\" 1, \"wght\" 400, \"GRAD\" 0, \"opsz\" 24}label{font-weight:500;font-size:16px;line-height:18.752px;color:#212121}label .optional{color:#757575;font-weight:normal}label .outer-container{position:relative}label .outer-container .left-icons,label .outer-container .right-icons{display:flex;position:absolute;height:24px;gap:8px}label .outer-container .left-icons tttx-icon,label .outer-container .right-icons tttx-icon{height:24px;width:24px}label .outer-container .left-icons{left:8px}label .outer-container .right-icons{right:8px}label .outer-container input,label .outer-container textarea{color:#212121;box-sizing:border-box;border:1px solid #d5d5d5;border-radius:4px;margin-top:4px;padding:0;padding-left:16px;padding-right:16px;}label .outer-container input.has-input-icon,label .outer-container textarea.has-input-icon{padding-left:40px}label .outer-container input.has-input-icon.has-left-icon,label .outer-container textarea.has-input-icon.has-left-icon{padding-left:72px}label .outer-container input.has-left-icon,label .outer-container textarea.has-left-icon{padding-left:40px}label .outer-container input.has-right-icon,label .outer-container textarea.has-right-icon{padding-right:40px}label .outer-container input.invalid,label .outer-container textarea.invalid{border:1px solid #dc0000}label .outer-container input:not([type=submit]),label .outer-container textarea:not([type=submit]){font-family:\"Roboto\", serif;width:100%;height:36px;font-size:16px;line-height:18.752px}label .outer-container input[type=radio],label .outer-container textarea[type=radio]{width:20px;height:20px}label .outer-container input[type=date],label .outer-container textarea[type=date]{background:white;display:block;min-width:calc(100% - 18px);line-height:37px}label .outer-container input[readonly],label .outer-container textarea[readonly]{cursor:default;pointer-events:none;user-select:none;color:gray}label .outer-container input:focus,label .outer-container textarea:focus{border-color:#1479c6}label .outer-container input:focus-visible,label .outer-container textarea:focus-visible{outline:none}label .outer-container textarea{padding:8px;height:auto;min-height:100px;resize:vertical}label .outer-container textarea.resize-none{resize:none}label .outer-container.inputBlock{display:flex;align-items:center;line-height:21px}label .outer-container.inputBlock .left-icons,label .outer-container.inputBlock .right-icons{margin-top:4px}label .outer-container.inputBlock.readonly{pointer-events:none;user-select:none;color:gray}label .outer-container.inputBlock.radioBlock{display:block}label .outer-container.inputInline{display:flex;white-space:nowrap;align-items:center;margin:0}label .outer-container.inputInline input{margin-top:0}label .secondarylabel{color:#757575;font-size:14px;line-height:16.408px;font-weight:normal;display:flex;margin-top:4px}label .errorBubble{position:relative;font-size:14px;line-height:16.408px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;display:flex;align-content:center;align-items:center;justify-items:center;margin-top:4px}label .errorBubble:not(.visible){display:none}label .errorBubble span{color:#dc0000;font-size:16px;margin-right:4px}.material-symbols-rounded{font-family:\"Material Symbols Rounded\", sans-serif;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:#9e9e9e}button{cursor:pointer}.button{font-family:Roboto, serif;box-sizing:border-box;height:36px;min-width:36px;padding:0;margin:0;background:transparent;color:#212121;border:1px solid #c8c8c8;border-radius:4px;text-transform:uppercase;display:flex;justify-content:left;align-items:center;font-size:14px;font-weight:500}.button-content{display:block;padding:0 16px}.icon-left,.icon-right{margin-top:4px}.iconleft{padding-left:8px}.iconleft .button-content{padding-left:4px}.iconright{padding-right:8px}.iconright .button-content{padding-right:4px}.notext{padding:0 6px}.button:active{background:rgba(17, 17, 17, 0.2);border:1px solid #d5d5d5}.blackout{background:#363636;border:1px solid #363636;color:white}.blackout:active{background:#212121;border:1px solid #212121}.primary{background:#1479c6;border:1px solid #1479c6;color:white}.primary:active{background:#1464a2;border:1px solid #1464a2}.borderless{background:transparent;border:none;color:#212121}.borderless:active{background:rgba(17, 17, 17, 0.2);border:none}.borderless-circle{background:transparent;border:none;color:#212121;border-radius:50%}.borderless-circle:active{border:none}.borderless-circle:focus{border-color:transparent}.danger{background:#dc0000;border:1px solid #dc0000;color:white}.danger:active{background:#b00000;border:1px solid #b00000}.disabled{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}.disabled:active{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}@media (hover: hover){.button:hover{background:rgba(17, 17, 17, 0.1);border:1px solid #d5d5d5}.primary:hover{background:#146eb3;border:1px solid #146eb3}.borderless:hover{background:rgba(17, 17, 17, 0.1);border:none}.borderless-circle:hover{background:rgba(17, 17, 17, 0.1);border:none}.danger:hover{background:#c60000;border:1px solid #c60000}.disabled:hover{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}.blackout:hover{background:#212121;border:1px solid #212121}}:host{display:block}fieldset{margin:0;padding:0;border:none}label{display:block;position:relative;margin-bottom:16px}.inlineLabel{font-weight:400;display:inline-block;vertical-align:top;padding-top:4px}input[type=checkbox]{width:18px;height:18px}input~label{font-weight:400}select{font-family:\"Roboto\", serif;box-sizing:border-box;width:100%;height:36px;padding:0 16px;font-size:16px;border:1px solid #d5d5d5;border-radius:4px;margin-top:4px}.placeholder{color:#9e9e9e}.placeholder option{color:initial}select.invalid:invalid{border:1px solid #dc0000}select~.errorBubble{position:relative;font-size:14px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;display:flex;align-content:center;align-items:center;justify-items:center}select~.errorBubble:not(.visible){visibility:hidden}select~.errorBubble span{color:#dc0000;font-size:16px;margin-right:4px;height:16px}select.invalid:invalid~.errorBubble{position:relative;font-size:14px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;visibility:visible}select:focus{border-color:#1479c6}select:focus-visible{outline:none}.button{padding:0 16px}.footer{display:flex;gap:16px;flex-direction:row-reverse}label.flex-label{display:flex;flex-direction:column;width:346px;box-sizing:border-box}label>.outer-container>input[type=date]{min-width:0;width:200px}label.flex-label input[type=time]{min-width:auto;text-align:center;width:130px;margin-left:16px}label>.outer-container>input[type=date],label.flex-label input[type=time]{line-height:36px}input[type=radio]~span{transform:translateY(-17%);display:inline-block;margin-left:5px}";
|
|
199
199
|
|
|
200
|
-
const TttxForm = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
201
|
-
constructor() {
|
|
202
|
-
super();
|
|
203
|
-
this.__registerHost();
|
|
204
|
-
this.__attachShadow();
|
|
205
|
-
this.dataSubmitted = createEvent(this, "dataSubmitted", 7);
|
|
206
|
-
this.dataChanged = createEvent(this, "dataChanged", 7);
|
|
207
|
-
this.searchTermChanged = createEvent(this, "searchTermChanged", 7);
|
|
208
|
-
this.selectToggleOpen = createEvent(this, "selectToggleOpen", 7);
|
|
209
|
-
// Create a new template element using the HTMLTemplateElement interface.
|
|
210
|
-
this.template = document.createElement('template');
|
|
211
|
-
this.formschema = undefined;
|
|
212
|
-
this.data = undefined;
|
|
213
|
-
}
|
|
214
|
-
// This method is called whenever the "formschema" property changes
|
|
215
|
-
onFormSchemaChange(newValue) {
|
|
216
|
-
// Check if the new value is a string, indicating that it needs to be parsed
|
|
217
|
-
if (typeof newValue === 'string') {
|
|
218
|
-
// Parse the string and set the "_formSchema" property
|
|
219
|
-
this._formSchema = JSON.parse(newValue);
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
// If the new value is already an object, set the "_formSchema" property directly
|
|
223
|
-
this._formSchema = newValue;
|
|
224
|
-
}
|
|
225
|
-
return this._formSchema;
|
|
226
|
-
}
|
|
227
|
-
onDataChange(newValue) {
|
|
228
|
-
if (typeof newValue === 'string') {
|
|
229
|
-
this._data = JSON.parse(newValue);
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
this._data = newValue;
|
|
233
|
-
}
|
|
234
|
-
return this._data;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Handles the focus event for a form field and emits a "dataChanged" event
|
|
238
|
-
* to the parent component with the field name and its new value.
|
|
239
|
-
*
|
|
240
|
-
* @param {KeyboardEvent | Event} event - The focus event triggered by the field.
|
|
241
|
-
* @return {void}
|
|
242
|
-
*/
|
|
243
|
-
fieldChanged(event) {
|
|
244
|
-
// Extract the name and value of the field from the event
|
|
245
|
-
const target = event.target;
|
|
246
|
-
const fieldName = target.name;
|
|
247
|
-
let fieldValue = target.value;
|
|
248
|
-
if (target.type === 'checkbox') {
|
|
249
|
-
fieldValue = target.checked ? 'on' : 'off';
|
|
250
|
-
}
|
|
251
|
-
// Emit an event to signal that the field's data has changed
|
|
252
|
-
this.dataChanged.emit({ name: fieldName, value: fieldValue });
|
|
253
|
-
}
|
|
254
|
-
async submit() {
|
|
255
|
-
this.submitButton.click();
|
|
256
|
-
}
|
|
257
|
-
async showLoadingSpinner(fieldname, value) {
|
|
258
|
-
const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
|
|
259
|
-
tttxSelect.isLoading = value;
|
|
260
|
-
}
|
|
261
|
-
async setSelectedItem(fieldname, id) {
|
|
262
|
-
const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
|
|
263
|
-
// select option with id
|
|
264
|
-
await tttxSelect.setSelectedItem(id);
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Replace all children in a given select list with a list of new options
|
|
268
|
-
* @param { string } fieldname the form name of the given field
|
|
269
|
-
* @param { {label: string, value: string}[] } options a list of option values and labels
|
|
270
|
-
*/
|
|
271
|
-
async setSelectOptions(fieldname, options, skipDefultSelection) {
|
|
272
|
-
const select = this.fieldset.querySelector(`[name=${fieldname}]`);
|
|
273
|
-
const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
|
|
274
|
-
const fragment = new DocumentFragment();
|
|
275
|
-
for (const option of options) {
|
|
276
|
-
const o = document.createElement('option');
|
|
277
|
-
o.innerText = option.label;
|
|
278
|
-
o.value = option.value;
|
|
279
|
-
if (option.disabled) {
|
|
280
|
-
o.disabled = true;
|
|
281
|
-
}
|
|
282
|
-
fragment.appendChild(o);
|
|
283
|
-
}
|
|
284
|
-
select.replaceChildren(fragment);
|
|
285
|
-
tttxSelect.optionsData = options;
|
|
286
|
-
// skip the first option selection if skipDefultSelection is true.
|
|
287
|
-
if (!skipDefultSelection) {
|
|
288
|
-
await tttxSelect.setSelectedItem(options.length > 0 ? options[0].value : undefined);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
async isValid() {
|
|
292
|
-
const valid = this.form.checkValidity();
|
|
293
|
-
const allElements = this.fieldset.querySelectorAll('[custom-validation-set=true]');
|
|
294
|
-
if (allElements.length || !valid) {
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
return true;
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Submits the form data to the server.
|
|
301
|
-
*
|
|
302
|
-
* @param {SubmitEvent} event - The event object for the form submission.
|
|
303
|
-
* @returns {void}
|
|
304
|
-
*/
|
|
305
|
-
doSubmit(event) {
|
|
306
|
-
// prevent the form from submitting normally
|
|
307
|
-
event.preventDefault();
|
|
308
|
-
const allElements = this.fieldset.querySelectorAll('[custom-validation-set=true]');
|
|
309
|
-
if (allElements.length) {
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
// create a new FormData object with the form data
|
|
313
|
-
const formData = new FormData(event.target);
|
|
314
|
-
// get a list of checkboxes, if any, so we can manually set unchecked box data
|
|
315
|
-
const formProperties = this._formSchema.properties;
|
|
316
|
-
for (const formKey of Object.keys(formProperties)) {
|
|
317
|
-
if (formProperties[formKey].form.type === 'checkbox' && !formData.has(formKey)) {
|
|
318
|
-
formData.append(formKey, 'off');
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
// emit the form data through the `dataSubmitted` event
|
|
322
|
-
this.dataSubmitted.emit(formData);
|
|
323
|
-
}
|
|
324
|
-
// This method is called before the component is loaded into the DOM
|
|
325
|
-
componentWillLoad() {
|
|
326
|
-
// Initialize the form schema by calling the "onFormSchemaChange" method with the current "formschema" property
|
|
327
|
-
this.onFormSchemaChange(this.formschema);
|
|
328
|
-
if (this.data) {
|
|
329
|
-
this.onDataChange(this.data);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
// This method is called before the component is rendered
|
|
333
|
-
componentWillRender() {
|
|
334
|
-
// Clear the template to account for a potential re-render scenario
|
|
335
|
-
this.template = document.createElement('template');
|
|
336
|
-
// Populate the form from the form schema
|
|
337
|
-
this.populateFormFromSchema();
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Creates a new HTMLSelectElement with a set of options.
|
|
341
|
-
*
|
|
342
|
-
* @param {string} formKey - The name of the dropdown field, as specified in the form schema.
|
|
343
|
-
* @param {object} formProperties - An object containing additional properties, such as the field type and options properties.
|
|
344
|
-
* @param {'select'} formProperties.type - The type of form field. In this case, it will always be "select".
|
|
345
|
-
* @param {object} formProperties.validation - A set of validation rules for the field.
|
|
346
|
-
* @param {Array<{label:string, value:string, placeholder?:boolean}>} formProperties.options - A list of properties to pass to the select options.
|
|
347
|
-
* @param {string} formProperties.options[].label - The visible value of the option.
|
|
348
|
-
* @param {string} formProperties.options[].value - The actual value of the option.
|
|
349
|
-
* @param {boolean} [formProperties.options[].placeholder]
|
|
350
|
-
*/
|
|
351
|
-
createSelect(formKey, formProperties) {
|
|
352
|
-
var _a, _b, _c, _d, _e, _f;
|
|
353
|
-
const select = document.createElement('select');
|
|
354
|
-
select.setAttribute('name', formKey);
|
|
355
|
-
(_a = formProperties.options) === null || _a === void 0 ? void 0 : _a.forEach(optionProperties => {
|
|
356
|
-
this.appendOption(select, optionProperties);
|
|
357
|
-
});
|
|
358
|
-
if ((_b = this._data) === null || _b === void 0 ? void 0 : _b[formKey]) {
|
|
359
|
-
select.classList.remove('placeholder');
|
|
360
|
-
}
|
|
361
|
-
const tttxSelect = document.createElement('tttx-select-
|
|
362
|
-
tttxSelect.optionsData = (_c = formProperties.options) === null || _c === void 0 ? void 0 : _c.filter(o => !o.placeholder);
|
|
363
|
-
tttxSelect.placeholder = (_e = (_d = formProperties.options) === null || _d === void 0 ? void 0 : _d.filter(o => o.placeholder)[0]) === null || _e === void 0 ? void 0 : _e.label;
|
|
364
|
-
tttxSelect.inline = false;
|
|
365
|
-
tttxSelect.searchEnabled = true;
|
|
366
|
-
tttxSelect.useExternalFiltering = formProperties.useExternalFiltering || false;
|
|
367
|
-
tttxSelect.style.width = '100%';
|
|
368
|
-
tttxSelect.style.marginTop = '6px';
|
|
369
|
-
tttxSelect.isLoading = formProperties.isLoading || false;
|
|
370
|
-
tttxSelect.readOnly = (_f = formProperties.readOnly) !== null && _f !== void 0 ? _f : false;
|
|
371
|
-
tttxSelect.setAttribute('name', 'overlay-' + formKey);
|
|
372
|
-
const fragment = document.createDocumentFragment();
|
|
373
|
-
fragment.append(tttxSelect);
|
|
374
|
-
select.style.display = 'none';
|
|
375
|
-
tttxSelect.addEventListener('selectItemEvent', this.selectItemEventCallback.bind(select));
|
|
376
|
-
// emit the event for searchTermChanged.
|
|
377
|
-
tttxSelect.addEventListener('multiselectSearchUpdated', (ev) => this.searchTermChanged.emit({
|
|
378
|
-
name: formKey,
|
|
379
|
-
value: ev.detail,
|
|
380
|
-
type: 'SearchTermChanged'
|
|
381
|
-
}));
|
|
382
|
-
tttxSelect.addEventListener('toggleOpen', (ev) => this.selectToggleOpen.emit({
|
|
383
|
-
name: formKey,
|
|
384
|
-
value: ev.detail,
|
|
385
|
-
type: 'ToggleOpen'
|
|
386
|
-
}));
|
|
387
|
-
return { input: select, overlay: fragment };
|
|
388
|
-
}
|
|
389
|
-
selectItemEventCallback(ev) {
|
|
390
|
-
// this function MUST be bound to a HTMLSelectElement
|
|
391
|
-
// 'this' will be the select element
|
|
392
|
-
// the function was split out for testing
|
|
393
|
-
const select = this;
|
|
394
|
-
select.value = ev.detail.value;
|
|
395
|
-
select.onblur({ target: select }); // triggers validator
|
|
396
|
-
select.onchange({ target: select }); // triggers dataChanged event
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Appends an option to a select element
|
|
400
|
-
*
|
|
401
|
-
* @param {HTMLSelectElement} select - The select elements to attach the option to.
|
|
402
|
-
* @param {Object} optionProperties
|
|
403
|
-
* @param {string} optionProperties.value - The value of the option.
|
|
404
|
-
* @param {string} optionProperties.label - The label which will be displayed on the form for the option.
|
|
405
|
-
* @param {boolean} [optionProperties.placeholder]
|
|
406
|
-
*/
|
|
407
|
-
appendOption(select, optionProperties) {
|
|
408
|
-
const option = document.createElement('option');
|
|
409
|
-
option.setAttribute('value', optionProperties.value);
|
|
410
|
-
if (optionProperties.placeholder) {
|
|
411
|
-
option.setAttribute('disabled', (optionProperties.disabled) ? 'true' : '');
|
|
412
|
-
option.setAttribute('selected', '');
|
|
413
|
-
option.setAttribute('hidden', '');
|
|
414
|
-
select.classList.add('placeholder');
|
|
415
|
-
}
|
|
416
|
-
if (optionProperties.label)
|
|
417
|
-
option.innerHTML = purify.sanitize(optionProperties.label, domSanitiserOptions);
|
|
418
|
-
select.appendChild(option);
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Creates a new HTMLInputElement with the specified name, type, and placeholder (if any),
|
|
422
|
-
* and sets its autocomplete and autocapitalization properties to off.
|
|
423
|
-
*
|
|
424
|
-
* @param {string} formKey - The name of the input field, as specified in the form schema.
|
|
425
|
-
* @param {Record<string, any>} formProperties - An object containing additional properties for the input field, such as its type and placeholder value.
|
|
426
|
-
* @param {string} formProperties.type - The type of the input field (e.g., "text", "email", "number", etc.).
|
|
427
|
-
* @param {string} [formProperties.placeholder] - An optional placeholder value to display in the input field.
|
|
428
|
-
* @return {HTMLInputElement} - The new input element.
|
|
429
|
-
*/
|
|
430
|
-
createInput(formKey, formProperties) {
|
|
431
|
-
var _a;
|
|
432
|
-
// Create a new <input> element with the specified name and type
|
|
433
|
-
const input = document.createElement('input');
|
|
434
|
-
input.type = formProperties.type;
|
|
435
|
-
input.name = formKey;
|
|
436
|
-
// Set the placeholder attribute to the specified value (if any)
|
|
437
|
-
input.placeholder = (_a = formProperties.placeholder) !== null && _a !== void 0 ? _a : '';
|
|
438
|
-
// Disable autocomplete and autocapitalization
|
|
439
|
-
input.autocomplete = 'off';
|
|
440
|
-
input.autocapitalize = 'off';
|
|
441
|
-
if (formProperties.readonly) {
|
|
442
|
-
input.readOnly = true;
|
|
443
|
-
}
|
|
444
|
-
if (formProperties.maskedValue) {
|
|
445
|
-
// Clear input on focus
|
|
446
|
-
input.onfocus = () => {
|
|
447
|
-
if (input.value === formProperties.maskedValue) {
|
|
448
|
-
input.value = '';
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
|
-
// Restore value or update it on blur
|
|
452
|
-
input.addEventListener('blur', () => {
|
|
453
|
-
if (input.value.trim() === '') {
|
|
454
|
-
input.value = formProperties.maskedValue;
|
|
455
|
-
}
|
|
456
|
-
else {
|
|
457
|
-
formProperties.value = input.value;
|
|
458
|
-
}
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
// Return the input element
|
|
462
|
-
return input;
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* Creates a new HTMLTextAreaElement with the specified name and placeholder (if any),
|
|
466
|
-
* and sets its autocomplete and autocapitalization properties to off.
|
|
467
|
-
*
|
|
468
|
-
* @param {string} formKey - The name of the input field, as specified in the form schema.
|
|
469
|
-
* @param {Record<string, any>} formProperties - An object containing additional properties for the input field, such as its type and placeholder value.
|
|
470
|
-
* @param {string} [formProperties.placeholder] - An optional placeholder value to display in the input field.
|
|
471
|
-
* @return {HTMLTextAreaElement} - The new input element.
|
|
472
|
-
*/
|
|
473
|
-
createTextArea(formKey, formProperties) {
|
|
474
|
-
var _a;
|
|
475
|
-
const input = document.createElement('textarea');
|
|
476
|
-
input.name = formKey;
|
|
477
|
-
// Set the placeholder attribute to the specified value (if any)
|
|
478
|
-
input.placeholder = (_a = formProperties.placeholder) !== null && _a !== void 0 ? _a : '';
|
|
479
|
-
// Disable autocomplete and autocapitalization
|
|
480
|
-
input.autocomplete = 'off';
|
|
481
|
-
input.autocapitalize = 'off';
|
|
482
|
-
if (formProperties.readonly) {
|
|
483
|
-
input.readOnly = true;
|
|
484
|
-
}
|
|
485
|
-
if (formProperties.resize === 'none') {
|
|
486
|
-
input.classList.add('resize-none');
|
|
487
|
-
}
|
|
488
|
-
// Return the input element
|
|
489
|
-
return input;
|
|
490
|
-
}
|
|
491
|
-
createStartEndDateComponent(formKey, formProperties) {
|
|
492
|
-
var _a, _b, _c, _d;
|
|
493
|
-
const startDate = document.createElement('input');
|
|
494
|
-
const endDate = document.createElement('input');
|
|
495
|
-
startDate.type = endDate.type = 'date';
|
|
496
|
-
startDate.name = `${formKey}-startdate`;
|
|
497
|
-
endDate.name = `${formKey}-enddate`;
|
|
498
|
-
startDate.setAttribute('data-formkey', formKey);
|
|
499
|
-
endDate.setAttribute('data-formkey', formKey);
|
|
500
|
-
if (formProperties.readonly) {
|
|
501
|
-
startDate.readOnly = true;
|
|
502
|
-
endDate.readOnly = true;
|
|
503
|
-
}
|
|
504
|
-
this.applyValidation(startDate, Object.assign({ required: { message: 'Please enter a start date' }, dateCompare: { to: endDate.name } }, (_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.startDate));
|
|
505
|
-
this.applyValidation(endDate, Object.assign({ required: { message: 'Please enter an end date' }, dateCompare: { with: startDate.name, message: 'End date cannot be before the start date' } }, (_b = formProperties.validation) === null || _b === void 0 ? void 0 : _b.endDate));
|
|
506
|
-
let startTime;
|
|
507
|
-
let endTime;
|
|
508
|
-
if (formProperties.includeTime) {
|
|
509
|
-
startTime = document.createElement('input');
|
|
510
|
-
endTime = document.createElement('input');
|
|
511
|
-
startTime.type = endTime.type = 'time';
|
|
512
|
-
startTime.name = `${formKey}-starttime`;
|
|
513
|
-
endTime.name = `${formKey}-endtime`;
|
|
514
|
-
startTime.setAttribute('data-formkey', formKey);
|
|
515
|
-
endTime.setAttribute('data-formkey', formKey);
|
|
516
|
-
if (formProperties.readonly) {
|
|
517
|
-
startTime.readOnly = true;
|
|
518
|
-
endTime.readOnly = true;
|
|
519
|
-
}
|
|
520
|
-
this.applyValidation(startTime, Object.assign({ required: { message: 'Please enter a start time' } }, (_c = formProperties.validation) === null || _c === void 0 ? void 0 : _c.startTime));
|
|
521
|
-
this.applyValidation(endTime, Object.assign({ required: { message: 'Please enter an end time' } }, (_d = formProperties.validation) === null || _d === void 0 ? void 0 : _d.endTime));
|
|
522
|
-
}
|
|
523
|
-
const startLabel = document.createElement('label');
|
|
524
|
-
startLabel.innerText = 'Start date';
|
|
525
|
-
const endLabel = document.createElement('label');
|
|
526
|
-
endLabel.innerText = 'End date';
|
|
527
|
-
const startContainer = document.createElement('div');
|
|
528
|
-
const endContainer = document.createElement('div');
|
|
529
|
-
startContainer.className = endContainer.className = 'outer-container inputBlock';
|
|
530
|
-
startLabel.className = endLabel.className = 'flex-label';
|
|
531
|
-
startContainer.append(startDate);
|
|
532
|
-
if (startTime) {
|
|
533
|
-
startContainer.append(startTime);
|
|
534
|
-
}
|
|
535
|
-
startLabel.append(startContainer);
|
|
536
|
-
startLabel.append(this.createErrorBubble());
|
|
537
|
-
endContainer.append(endDate);
|
|
538
|
-
if (endTime) {
|
|
539
|
-
endContainer.append(endTime);
|
|
540
|
-
}
|
|
541
|
-
endLabel.append(endContainer);
|
|
542
|
-
endLabel.append(this.createErrorBubble());
|
|
543
|
-
return { start: startLabel, end: endLabel };
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Applies validation attributes to an input element based on the specified validation object.
|
|
547
|
-
* If a certain property is present in the object, it will set the corresponding attribute on
|
|
548
|
-
* the input element (e.g., "required" will set the "required" and "data-required" attributes,
|
|
549
|
-
* "pattern" will set the "pattern" and "data-pattern" attributes, etc.).
|
|
550
|
-
*
|
|
551
|
-
* @param {FormField} input - The input element to apply validation attributes to.
|
|
552
|
-
* @param {object} validation - An object containing the validation rules for the input field.
|
|
553
|
-
* @param {object} [validation.required] - An object containing a "message" property to display if the field is required.
|
|
554
|
-
* @param {string} [validation.required.message]
|
|
555
|
-
* @param {object} [validation.pattern] - An object containing a "pattern" property to match against the field value, and a "message" property to display if the pattern doesn't match.
|
|
556
|
-
* @param {string} [validation.pattern.pattern]
|
|
557
|
-
* @param {string} [validation.pattern.message]
|
|
558
|
-
* @param {object} [validation.badInput] - An object containing a "message" property to display if the field value is invalid.
|
|
559
|
-
* @param {string} [validation.badInput.message]
|
|
560
|
-
* @param {object} [validation.minmax] - An object containing "min" and "max" properties to validate the field value against, and a "message" property to display if the value is out of range.
|
|
561
|
-
* @param {string} [validation.minmax.min]
|
|
562
|
-
* @param {string} [validation.minmax.max]
|
|
563
|
-
* @param {string} [validation.minmax.message]
|
|
564
|
-
* @param {string} [validation.maxlength] - The maximum length of the input field.
|
|
565
|
-
* @param {string} [validation.datecompare] - To compare start and end date fields.
|
|
566
|
-
* @return {void}
|
|
567
|
-
*/
|
|
568
|
-
applyValidation(input, validation) {
|
|
569
|
-
var _a, _b;
|
|
570
|
-
// If the "required" property is present, add the "required" attribute to the input element and
|
|
571
|
-
// set its "data-required" attribute to the specified message (if any)
|
|
572
|
-
if (validation.required) {
|
|
573
|
-
input.setAttribute('required', '');
|
|
574
|
-
input.setAttribute('data-required', (_a = validation.required.message) !== null && _a !== void 0 ? _a : '');
|
|
575
|
-
}
|
|
576
|
-
// If the "pattern" property is present, add the "pattern" attribute to the input element and set
|
|
577
|
-
// its "data-pattern" attribute to the specified message (if any)
|
|
578
|
-
if (validation.pattern) {
|
|
579
|
-
input.setAttribute('pattern', validation.pattern.pattern);
|
|
580
|
-
input.setAttribute('data-pattern', (_b = validation.pattern.message) !== null && _b !== void 0 ? _b : '');
|
|
581
|
-
}
|
|
582
|
-
// If the "badInput" property is present, set the input element's "data-badinput" attribute to
|
|
583
|
-
// the specified message
|
|
584
|
-
if (validation.badInput) {
|
|
585
|
-
input.setAttribute('data-badinput', validation.badInput.message);
|
|
586
|
-
}
|
|
587
|
-
// If the "minmax" property is present, add the "min" and "max" attributes to the input element
|
|
588
|
-
// and set its "data-range" attribute to the specified message (if any)
|
|
589
|
-
if (validation.minmax) {
|
|
590
|
-
input.setAttribute('min', validation.minmax.min);
|
|
591
|
-
input.setAttribute('max', validation.minmax.max);
|
|
592
|
-
input.setAttribute('data-range', validation.minmax.message);
|
|
593
|
-
}
|
|
594
|
-
// If the "maxlength" property is present, add the "maxlength" attribute to the input element
|
|
595
|
-
if (validation.maxlength) {
|
|
596
|
-
input.setAttribute('maxlength', validation.maxlength);
|
|
597
|
-
}
|
|
598
|
-
// Custom validation parameters for start date and end date comparison
|
|
599
|
-
if (validation.dateCompare) {
|
|
600
|
-
if (validation.dateCompare.message && validation.dateCompare.with) {
|
|
601
|
-
input.setAttribute('data-compare', validation.dateCompare.message);
|
|
602
|
-
input.setAttribute('data-compare-with', validation.dateCompare.with);
|
|
603
|
-
}
|
|
604
|
-
if (validation.dateCompare.to) {
|
|
605
|
-
input.setAttribute('data-compare-to', validation.dateCompare.to);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
// Create a new error bubble element
|
|
610
|
-
createErrorBubble() {
|
|
611
|
-
// Create a new <div> element with the "errorBubble" class
|
|
612
|
-
const errorBubble = document.createElement('div');
|
|
613
|
-
errorBubble.className = 'errorBubble';
|
|
614
|
-
// Return the error bubble element
|
|
615
|
-
return errorBubble;
|
|
616
|
-
}
|
|
617
|
-
/**
|
|
618
|
-
*
|
|
619
|
-
* @param {Record<string, any>} formProperties
|
|
620
|
-
* @param {HTMLInputElement | HTMLSelectElement} input
|
|
621
|
-
* @param {HTMLLabelElement} label
|
|
622
|
-
* @returns {void}
|
|
623
|
-
*/
|
|
624
|
-
appendCheckboxInput(formProperties, input, label) {
|
|
625
|
-
if (formProperties.label) {
|
|
626
|
-
const lineBreak = document.createElement('br');
|
|
627
|
-
label.appendChild(lineBreak);
|
|
628
|
-
}
|
|
629
|
-
// Append the input element and error bubble element to the label
|
|
630
|
-
label.appendChild(input);
|
|
631
|
-
if (!formProperties.inlineLabel)
|
|
632
|
-
return;
|
|
633
|
-
const inlineLabel = document.createElement('span');
|
|
634
|
-
inlineLabel.className = 'inlineLabel';
|
|
635
|
-
inlineLabel.textContent = formProperties.inlineLabel;
|
|
636
|
-
label.appendChild(inlineLabel);
|
|
637
|
-
}
|
|
638
|
-
/**
|
|
639
|
-
* Creates a new <label> element with the "inputBlock" class and the specified label text,
|
|
640
|
-
* and appends the input element and error bubble element to it. If the form property has
|
|
641
|
-
* no validation object, it adds an "optional" span element to the label.
|
|
642
|
-
*
|
|
643
|
-
* @param {Record<string, any>} formProperties - An object containing properties for the form field, including its label text and validation rules.
|
|
644
|
-
* @param {HTMLInputElement | HTMLSelectElement} input - The input element to associate with the label.
|
|
645
|
-
* @param {never} overlay - The Child Element which will be rendered atop the standard HTML5 element
|
|
646
|
-
* @param {HTMLDivElement} errorBubble - The error bubble element to display error messages in.
|
|
647
|
-
* @return {HTMLLabelElement} - The new label element.
|
|
648
|
-
*/
|
|
649
|
-
createLabel(formProperties, input, overlay = null, errorBubble) {
|
|
650
|
-
var _a;
|
|
651
|
-
const outerContainer = document.createElement('div');
|
|
652
|
-
let outerContainerClassName = 'outer-container inputBlock';
|
|
653
|
-
// Create a new <label> element with the "inputBlock" class and the specified text
|
|
654
|
-
const label = document.createElement('label');
|
|
655
|
-
label.innerText = formProperties.label;
|
|
656
|
-
// If the form property has no validation object, add an "optional" span element to the label
|
|
657
|
-
if (!((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.required) && formProperties.label) {
|
|
658
|
-
const optionalSpan = document.createElement('span');
|
|
659
|
-
optionalSpan.className = 'optional';
|
|
660
|
-
optionalSpan.innerHTML = ' (optional)';
|
|
661
|
-
label.appendChild(optionalSpan);
|
|
662
|
-
}
|
|
663
|
-
if (formProperties.type === 'radio') {
|
|
664
|
-
outerContainerClassName += ' radioBlock';
|
|
665
|
-
}
|
|
666
|
-
outerContainer.className = outerContainerClassName;
|
|
667
|
-
if (formProperties.readonly) {
|
|
668
|
-
label.classList.add('readonly');
|
|
669
|
-
}
|
|
670
|
-
if (formProperties.type === 'checkbox') {
|
|
671
|
-
this.appendCheckboxInput(formProperties, input, label);
|
|
672
|
-
}
|
|
673
|
-
else {
|
|
674
|
-
// Append the input element and error bubble element to the outerContainer
|
|
675
|
-
if (overlay) {
|
|
676
|
-
outerContainer.appendChild(overlay);
|
|
677
|
-
}
|
|
678
|
-
outerContainer.appendChild(input);
|
|
679
|
-
}
|
|
680
|
-
if (formProperties.type !== 'checkbox') {
|
|
681
|
-
label.appendChild(outerContainer);
|
|
682
|
-
}
|
|
683
|
-
label.appendChild(errorBubble);
|
|
684
|
-
// Return the label element
|
|
685
|
-
return label;
|
|
686
|
-
}
|
|
687
|
-
/**
|
|
688
|
-
* Creates a new radio input with a set of options.
|
|
689
|
-
*
|
|
690
|
-
* @param {string} formKey - The name of the dropdown field, as specified in the form schema.
|
|
691
|
-
* @param {Object} formProperties - An object containing additional properties, such as the field type and options properties.
|
|
692
|
-
* @param {'radio'} formProperties.type - The type of form field. In this case, it will always be "radio".
|
|
693
|
-
* @param {Object} formProperties.validation - A set of validation rules for the field.
|
|
694
|
-
* @param {Object[]} formProperties.options - A list of properties to pass to the select options.
|
|
695
|
-
* @param {string} formProperties.options.label - The visible value of the option.
|
|
696
|
-
* @param {string} formProperties.options.value - The actual value of the option.
|
|
697
|
-
*/
|
|
698
|
-
createRadio(formKey, formProperties) {
|
|
699
|
-
var _a, _b;
|
|
700
|
-
const fragment = document.createDocumentFragment();
|
|
701
|
-
for (const optionProperties of formProperties.options) {
|
|
702
|
-
// Create a new <input> element with the specified name and type
|
|
703
|
-
const input = document.createElement('input');
|
|
704
|
-
input.type = 'radio';
|
|
705
|
-
input.name = formKey;
|
|
706
|
-
input.value = optionProperties.value;
|
|
707
|
-
if ((_a = formProperties === null || formProperties === void 0 ? void 0 : formProperties.validation) === null || _a === void 0 ? void 0 : _a.required) {
|
|
708
|
-
input.setAttribute('required', 'required');
|
|
709
|
-
input.setAttribute('data-required', (_b = formProperties.validation.required.message) !== null && _b !== void 0 ? _b : '');
|
|
710
|
-
}
|
|
711
|
-
const span = document.createElement('span');
|
|
712
|
-
span.innerText = optionProperties.label;
|
|
713
|
-
fragment.appendChild(input);
|
|
714
|
-
fragment.appendChild(span);
|
|
715
|
-
fragment.appendChild(document.createElement('br'));
|
|
716
|
-
}
|
|
717
|
-
return fragment;
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Populates the form template with input fields and labels based on the properties of the
|
|
721
|
-
* current form schema. For each property in the schema, it creates an input element, applies
|
|
722
|
-
* any validation rules to it, creates an error bubble and label element, and appends them
|
|
723
|
-
* to the form template. Finally, it creates and appends a submit button element to the form.
|
|
724
|
-
*
|
|
725
|
-
* @return {void}
|
|
726
|
-
*/
|
|
727
|
-
populateFormFromSchema() {
|
|
728
|
-
var _a;
|
|
729
|
-
// If there is no form schema, return early
|
|
730
|
-
if (!this._formSchema) {
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
// Get the properties of the form schema and their keys
|
|
734
|
-
const properties = this._formSchema.properties;
|
|
735
|
-
const propertyKeys = Object.keys(properties);
|
|
736
|
-
// Loop through each property key and create an input, label, and error bubble for it
|
|
737
|
-
for (const formKey of propertyKeys) {
|
|
738
|
-
const formItem = properties[formKey];
|
|
739
|
-
const formProperties = formItem.form;
|
|
740
|
-
// complex form types which require
|
|
741
|
-
// custom HTML should be done here
|
|
742
|
-
if (formProperties.type === 'startenddate') {
|
|
743
|
-
const { start, end } = this.createStartEndDateComponent(formKey, formProperties);
|
|
744
|
-
this.template.content.append(start);
|
|
745
|
-
this.template.content.append(end);
|
|
746
|
-
continue;
|
|
747
|
-
}
|
|
748
|
-
let fragments = {};
|
|
749
|
-
switch (formProperties.type) {
|
|
750
|
-
case 'select':
|
|
751
|
-
fragments = this.createSelect(formKey, formProperties);
|
|
752
|
-
break;
|
|
753
|
-
case 'radio':
|
|
754
|
-
fragments.input = this.createRadio(formKey, formProperties);
|
|
755
|
-
break;
|
|
756
|
-
case 'textarea':
|
|
757
|
-
fragments.input = this.createTextArea(formKey, formProperties);
|
|
758
|
-
break;
|
|
759
|
-
default:
|
|
760
|
-
fragments.input = this.createInput(formKey, formProperties);
|
|
761
|
-
}
|
|
762
|
-
// If the form property has validation, apply it to the input
|
|
763
|
-
if (formProperties.validation &&
|
|
764
|
-
formProperties.type !== 'radio') {
|
|
765
|
-
this.applyValidation(fragments.input, formProperties.validation);
|
|
766
|
-
}
|
|
767
|
-
// Create an error bubble and label element for the input
|
|
768
|
-
const errorBubble = this.createErrorBubble();
|
|
769
|
-
const label = this.createLabel(formProperties, fragments.input, fragments.overlay, errorBubble);
|
|
770
|
-
// If explicitly setting input as invalid, set invalid state and error message on render
|
|
771
|
-
if ((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.invalid) {
|
|
772
|
-
const errorMessage = formProperties.validation.invalid.message;
|
|
773
|
-
fragments.input.setCustomValidity(errorMessage); // Prevents the invalid styling from resetting on blur
|
|
774
|
-
setErrorState(fragments.input, true, errorMessage);
|
|
775
|
-
}
|
|
776
|
-
// Append the label element to the form template
|
|
777
|
-
this.template.content.append(label);
|
|
778
|
-
if (formProperties.disabled) {
|
|
779
|
-
this.toggleFormField(fragments.input, true);
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
/**
|
|
784
|
-
* Clones the form template and binds event listeners to its input elements. First, it checks if
|
|
785
|
-
* there is a form schema present. If so, it clones the template's content, binds events to form
|
|
786
|
-
* input elements, and appends the cloned form elements to the fieldset. The event listeners include
|
|
787
|
-
* "oninvalid" (to check input validity on submit), "onblur" (to check input validity on blur),
|
|
788
|
-
* "onkeyup" (to handle changes in input fields), and "onchange" (to handle changes in select fields).
|
|
789
|
-
*
|
|
790
|
-
* @return {void}
|
|
791
|
-
*/
|
|
792
|
-
componentDidRender() {
|
|
793
|
-
// If there's no form schema, return
|
|
794
|
-
if (!this._formSchema) {
|
|
795
|
-
return;
|
|
796
|
-
}
|
|
797
|
-
// Clone the template's content and store it in a variable
|
|
798
|
-
const formItems = this.template.content;
|
|
799
|
-
// Bind event listeners to form elements
|
|
800
|
-
const properties = this._formSchema.properties;
|
|
801
|
-
const propertyKeys = Object.keys(properties);
|
|
802
|
-
for (const formKey of propertyKeys) {
|
|
803
|
-
this.applyValidationFunctionsToFormElement(formItems, formKey, properties);
|
|
804
|
-
}
|
|
805
|
-
// populate with existing form data if available
|
|
806
|
-
if ((this._data && Object.keys(this._data).length > 0)) {
|
|
807
|
-
this.populateFormWithExistingData(formItems);
|
|
808
|
-
}
|
|
809
|
-
// Append the cloned form elements to the fieldset
|
|
810
|
-
this.fieldset.replaceChildren(formItems);
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* Assign validation events to a given form item
|
|
814
|
-
* @param formItems The document fragment template of form items to be rendered
|
|
815
|
-
* @param formKey The key of the form item to bind events too
|
|
816
|
-
* @param properties The form item's properties, such as type and name
|
|
817
|
-
*/
|
|
818
|
-
applyValidationFunctionsToFormElement(formItems, formKey, properties) {
|
|
819
|
-
const formItemsByKey = formItems.querySelectorAll(`[name^=${formKey}]`);
|
|
820
|
-
for (const formInput of formItemsByKey) {
|
|
821
|
-
// Bind events to form input elements
|
|
822
|
-
formInput.oninvalid = this.validityCheckWrapper.bind(this);
|
|
823
|
-
formInput.onblur = this.validityCheckWrapper.bind(this);
|
|
824
|
-
formInput.onkeyup = this.fieldChanged.bind(this);
|
|
825
|
-
formInput.onchange = this.fieldChanged.bind(this);
|
|
826
|
-
if (properties[formKey].form.type === 'select' && formInput.classList.contains('placeholder')) {
|
|
827
|
-
formInput.addEventListener('change', this.selectRemovePlaceholderCallback.bind(formInput));
|
|
828
|
-
}
|
|
829
|
-
if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-with')) {
|
|
830
|
-
formInput.oninvalid = endDateComparisonValidator.bind(this);
|
|
831
|
-
formInput.onblur = endDateComparisonValidator.bind(this);
|
|
832
|
-
}
|
|
833
|
-
if (properties[formKey].form.type === 'startenddate' && formInput.type === 'time') {
|
|
834
|
-
formInput.oninvalid = startEndTimeComparator.bind(this);
|
|
835
|
-
formInput.onblur = startEndTimeComparator.bind(this);
|
|
836
|
-
}
|
|
837
|
-
if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-to')) {
|
|
838
|
-
formInput.oninvalid = startDateComparisonValidator.bind(this);
|
|
839
|
-
formInput.onblur = startDateComparisonValidator.bind(this);
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
/**
|
|
844
|
-
* If data exists, set form input values before rendering
|
|
845
|
-
* @param formItems The document fragment template of form items to be rendered
|
|
846
|
-
*/
|
|
847
|
-
populateFormWithExistingData(formItems) {
|
|
848
|
-
var _a;
|
|
849
|
-
const dataKeys = Object.keys(this._data);
|
|
850
|
-
for (const key of dataKeys) {
|
|
851
|
-
const formItemsByKey = formItems.querySelectorAll(`[name=${key}]`);
|
|
852
|
-
for (const formItem of formItemsByKey) {
|
|
853
|
-
switch (formItem.type) {
|
|
854
|
-
case 'checkbox':
|
|
855
|
-
if (this._data[key] === 'on') {
|
|
856
|
-
formItem.checked = true;
|
|
857
|
-
}
|
|
858
|
-
break;
|
|
859
|
-
case 'radio':
|
|
860
|
-
if (formItem.value === this._data[key]) {
|
|
861
|
-
formItem.checked = true;
|
|
862
|
-
}
|
|
863
|
-
break;
|
|
864
|
-
case 'select':
|
|
865
|
-
case 'select-one':
|
|
866
|
-
formItems.querySelector(`[name=overlay-${key}]`)['selectedValue'] = this._data[key];
|
|
867
|
-
formItem.value = this._data[key];
|
|
868
|
-
break;
|
|
869
|
-
case 'date':
|
|
870
|
-
formItem.value = (_a = this._data[key]) === null || _a === void 0 ? void 0 : _a.split('T')[0];
|
|
871
|
-
break;
|
|
872
|
-
default:
|
|
873
|
-
formItem.value = this._data[key];
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
/**
|
|
879
|
-
* Remove the placeholder class on the bound THIS select element
|
|
880
|
-
*/
|
|
881
|
-
selectRemovePlaceholderCallback() {
|
|
882
|
-
const select = this;
|
|
883
|
-
select.classList.remove('placeholder');
|
|
884
|
-
}
|
|
885
|
-
/**
|
|
886
|
-
* A wrapper around validity check and set error state
|
|
887
|
-
*/
|
|
888
|
-
validityCheckWrapper(event) {
|
|
889
|
-
const { target, hasError, errorMessage } = validityCheck(event);
|
|
890
|
-
setErrorState(target, hasError, errorMessage);
|
|
891
|
-
}
|
|
892
|
-
assignFieldsetReference(el) {
|
|
893
|
-
this.fieldset = el;
|
|
894
|
-
}
|
|
895
|
-
assignButtonReference(el) {
|
|
896
|
-
this.submitButton = el;
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
* An external validation trigger to apply to a form field
|
|
900
|
-
* @param { string } fieldName The form field name to apply the validation too
|
|
901
|
-
* @param { string } message The validation message to display under the form field
|
|
902
|
-
*/
|
|
903
|
-
async setValidationFor(fieldName, message) {
|
|
904
|
-
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
905
|
-
if (formField.disabled) {
|
|
906
|
-
return;
|
|
907
|
-
}
|
|
908
|
-
formField.setCustomValidity(message);
|
|
909
|
-
formField.setAttribute('custom-validation-set', 'true');
|
|
910
|
-
setErrorState(formField, true, message);
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
* Clear the validation message on a given form field
|
|
914
|
-
* @param { string } fieldName The form field name to clear the validation of
|
|
915
|
-
*/
|
|
916
|
-
async clearValidationFor(fieldName) {
|
|
917
|
-
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
918
|
-
formField.setCustomValidity('');
|
|
919
|
-
formField.removeAttribute('custom-validation-set');
|
|
920
|
-
setErrorState(formField, false, '');
|
|
921
|
-
}
|
|
922
|
-
toggleFormField(formField, disabled) {
|
|
923
|
-
formField.disabled = disabled;
|
|
924
|
-
let parent = formField.parentElement;
|
|
925
|
-
if (parent) {
|
|
926
|
-
do {
|
|
927
|
-
if (parent.nodeName !== 'LABEL') {
|
|
928
|
-
parent = parent.parentElement;
|
|
929
|
-
}
|
|
930
|
-
} while (parent && parent.nodeName !== 'LABEL');
|
|
931
|
-
if (parent) {
|
|
932
|
-
parent.style.display = (disabled) ? 'none' : 'block';
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
/**
|
|
937
|
-
* Disable a form field and visually remove it from the form.
|
|
938
|
-
* If custom validation is set, this function will return without affecting the form field.
|
|
939
|
-
* @param { string } fieldName The form field name to disable
|
|
940
|
-
*/
|
|
941
|
-
async disableFormField(fieldName) {
|
|
942
|
-
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
943
|
-
if (formField.hasAttribute('custom-validation-set')) {
|
|
944
|
-
return;
|
|
945
|
-
}
|
|
946
|
-
this.toggleFormField(formField, true);
|
|
947
|
-
}
|
|
948
|
-
/**
|
|
949
|
-
* Enable a form field and visually add it back to the form.
|
|
950
|
-
* @param { string } fieldName The form field name to enable
|
|
951
|
-
*/
|
|
952
|
-
async enableFormField(fieldName) {
|
|
953
|
-
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
954
|
-
this.toggleFormField(formField, false);
|
|
955
|
-
}
|
|
956
|
-
/**
|
|
957
|
-
* Set the value of a form field progromatically
|
|
958
|
-
* @param { string } fieldName The form field name having it's value set
|
|
959
|
-
* @param { string } fieldValue The form field value to set
|
|
960
|
-
*/
|
|
961
|
-
async setInputFieldValue(fieldName, fieldValue) {
|
|
962
|
-
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
963
|
-
formField.value = fieldValue;
|
|
964
|
-
}
|
|
965
|
-
/**
|
|
966
|
-
* Change the readonly property on an input field. If set to 'true' any validation will also be cleared.
|
|
967
|
-
* @param { string } fieldName The form field name to set
|
|
968
|
-
* @param { boolean } readonly The state of the read-only attribute
|
|
969
|
-
*/
|
|
970
|
-
async setFieldReadOnlyMode(fieldName, readonly) {
|
|
971
|
-
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
972
|
-
if (formField && formField.nodeName === 'SELECT') {
|
|
973
|
-
const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldName}]`);
|
|
974
|
-
tttxSelect.readOnly = readonly;
|
|
975
|
-
formField.disabled = readonly;
|
|
976
|
-
}
|
|
977
|
-
else {
|
|
978
|
-
formField.readOnly = readonly;
|
|
979
|
-
}
|
|
980
|
-
if (readonly) {
|
|
981
|
-
await this.clearValidationFor(fieldName);
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
/**
|
|
985
|
-
* Renders the component's template as a form element with a fieldset container. The form's
|
|
986
|
-
* "onSubmit" event is bound to the "doSubmit" function, which handles the form submission
|
|
987
|
-
* and emits a "dataSubmitted" event with the form data. The fieldset element is assigned
|
|
988
|
-
* to the "fieldset" instance variable using a ref, so it can be populated with form elements
|
|
989
|
-
* later on.
|
|
990
|
-
*/
|
|
991
|
-
render() {
|
|
992
|
-
//react rendering so we can't JEST it
|
|
993
|
-
//ignore so it doesn't ruin coverage
|
|
994
|
-
/*istanbul ignore next*/
|
|
995
|
-
return (h(Host, null, h("form", { onSubmit: this.doSubmit.bind(this), ref: frm => this.form = frm }, h("fieldset", { ref: this.assignFieldsetReference.bind(this) }), h("input", { type: "submit", ref: this.assignButtonReference.bind(this), style: { display: 'none' } }))));
|
|
996
|
-
}
|
|
997
|
-
static get watchers() { return {
|
|
998
|
-
"formschema": ["onFormSchemaChange"],
|
|
999
|
-
"data": ["onDataChange"]
|
|
1000
|
-
}; }
|
|
1001
|
-
static get style() { return tttxFormCss; }
|
|
1002
|
-
}, [1, "tttx-
|
|
1003
|
-
"formschema": [1025],
|
|
1004
|
-
"data": [1032],
|
|
1005
|
-
"submit": [64],
|
|
1006
|
-
"showLoadingSpinner": [64],
|
|
1007
|
-
"setSelectedItem": [64],
|
|
1008
|
-
"setSelectOptions": [64],
|
|
1009
|
-
"isValid": [64],
|
|
1010
|
-
"setValidationFor": [64],
|
|
1011
|
-
"clearValidationFor": [64],
|
|
1012
|
-
"disableFormField": [64],
|
|
1013
|
-
"enableFormField": [64],
|
|
1014
|
-
"setInputFieldValue": [64],
|
|
1015
|
-
"setFieldReadOnlyMode": [64]
|
|
1016
|
-
}]);
|
|
1017
|
-
function defineCustomElement$1() {
|
|
1018
|
-
if (typeof customElements === "undefined") {
|
|
1019
|
-
return;
|
|
1020
|
-
}
|
|
1021
|
-
const components = ["tttx-
|
|
1022
|
-
components.forEach(tagName => { switch (tagName) {
|
|
1023
|
-
case "tttx-
|
|
1024
|
-
if (!customElements.get(tagName)) {
|
|
1025
|
-
customElements.define(tagName, TttxForm);
|
|
1026
|
-
}
|
|
1027
|
-
break;
|
|
1028
|
-
case "tttx-
|
|
1029
|
-
if (!customElements.get(tagName)) {
|
|
1030
|
-
defineCustomElement$6();
|
|
1031
|
-
}
|
|
1032
|
-
break;
|
|
1033
|
-
case "tttx-loading-
|
|
1034
|
-
if (!customElements.get(tagName)) {
|
|
1035
|
-
defineCustomElement$5();
|
|
1036
|
-
}
|
|
1037
|
-
break;
|
|
1038
|
-
case "tttx-select-
|
|
1039
|
-
if (!customElements.get(tagName)) {
|
|
1040
|
-
defineCustomElement$4();
|
|
1041
|
-
}
|
|
1042
|
-
break;
|
|
1043
|
-
case "tttx-standalone-
|
|
1044
|
-
if (!customElements.get(tagName)) {
|
|
1045
|
-
defineCustomElement$3();
|
|
1046
|
-
}
|
|
1047
|
-
break;
|
|
1048
|
-
case "tttx-
|
|
1049
|
-
if (!customElements.get(tagName)) {
|
|
1050
|
-
defineCustomElement$2();
|
|
1051
|
-
}
|
|
1052
|
-
break;
|
|
1053
|
-
} });
|
|
200
|
+
const TttxForm = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
201
|
+
constructor() {
|
|
202
|
+
super();
|
|
203
|
+
this.__registerHost();
|
|
204
|
+
this.__attachShadow();
|
|
205
|
+
this.dataSubmitted = createEvent(this, "dataSubmitted", 7);
|
|
206
|
+
this.dataChanged = createEvent(this, "dataChanged", 7);
|
|
207
|
+
this.searchTermChanged = createEvent(this, "searchTermChanged", 7);
|
|
208
|
+
this.selectToggleOpen = createEvent(this, "selectToggleOpen", 7);
|
|
209
|
+
// Create a new template element using the HTMLTemplateElement interface.
|
|
210
|
+
this.template = document.createElement('template');
|
|
211
|
+
this.formschema = undefined;
|
|
212
|
+
this.data = undefined;
|
|
213
|
+
}
|
|
214
|
+
// This method is called whenever the "formschema" property changes
|
|
215
|
+
onFormSchemaChange(newValue) {
|
|
216
|
+
// Check if the new value is a string, indicating that it needs to be parsed
|
|
217
|
+
if (typeof newValue === 'string') {
|
|
218
|
+
// Parse the string and set the "_formSchema" property
|
|
219
|
+
this._formSchema = JSON.parse(newValue);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
// If the new value is already an object, set the "_formSchema" property directly
|
|
223
|
+
this._formSchema = newValue;
|
|
224
|
+
}
|
|
225
|
+
return this._formSchema;
|
|
226
|
+
}
|
|
227
|
+
onDataChange(newValue) {
|
|
228
|
+
if (typeof newValue === 'string') {
|
|
229
|
+
this._data = JSON.parse(newValue);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
this._data = newValue;
|
|
233
|
+
}
|
|
234
|
+
return this._data;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Handles the focus event for a form field and emits a "dataChanged" event
|
|
238
|
+
* to the parent component with the field name and its new value.
|
|
239
|
+
*
|
|
240
|
+
* @param {KeyboardEvent | Event} event - The focus event triggered by the field.
|
|
241
|
+
* @return {void}
|
|
242
|
+
*/
|
|
243
|
+
fieldChanged(event) {
|
|
244
|
+
// Extract the name and value of the field from the event
|
|
245
|
+
const target = event.target;
|
|
246
|
+
const fieldName = target.name;
|
|
247
|
+
let fieldValue = target.value;
|
|
248
|
+
if (target.type === 'checkbox') {
|
|
249
|
+
fieldValue = target.checked ? 'on' : 'off';
|
|
250
|
+
}
|
|
251
|
+
// Emit an event to signal that the field's data has changed
|
|
252
|
+
this.dataChanged.emit({ name: fieldName, value: fieldValue });
|
|
253
|
+
}
|
|
254
|
+
async submit() {
|
|
255
|
+
this.submitButton.click();
|
|
256
|
+
}
|
|
257
|
+
async showLoadingSpinner(fieldname, value) {
|
|
258
|
+
const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
|
|
259
|
+
tttxSelect.isLoading = value;
|
|
260
|
+
}
|
|
261
|
+
async setSelectedItem(fieldname, id) {
|
|
262
|
+
const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
|
|
263
|
+
// select option with id
|
|
264
|
+
await tttxSelect.setSelectedItem(id);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Replace all children in a given select list with a list of new options
|
|
268
|
+
* @param { string } fieldname the form name of the given field
|
|
269
|
+
* @param { {label: string, value: string}[] } options a list of option values and labels
|
|
270
|
+
*/
|
|
271
|
+
async setSelectOptions(fieldname, options, skipDefultSelection) {
|
|
272
|
+
const select = this.fieldset.querySelector(`[name=${fieldname}]`);
|
|
273
|
+
const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldname}]`);
|
|
274
|
+
const fragment = new DocumentFragment();
|
|
275
|
+
for (const option of options) {
|
|
276
|
+
const o = document.createElement('option');
|
|
277
|
+
o.innerText = option.label;
|
|
278
|
+
o.value = option.value;
|
|
279
|
+
if (option.disabled) {
|
|
280
|
+
o.disabled = true;
|
|
281
|
+
}
|
|
282
|
+
fragment.appendChild(o);
|
|
283
|
+
}
|
|
284
|
+
select.replaceChildren(fragment);
|
|
285
|
+
tttxSelect.optionsData = options;
|
|
286
|
+
// skip the first option selection if skipDefultSelection is true.
|
|
287
|
+
if (!skipDefultSelection) {
|
|
288
|
+
await tttxSelect.setSelectedItem(options.length > 0 ? options[0].value : undefined);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
async isValid() {
|
|
292
|
+
const valid = this.form.checkValidity();
|
|
293
|
+
const allElements = this.fieldset.querySelectorAll('[custom-validation-set=true]');
|
|
294
|
+
if (allElements.length || !valid) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Submits the form data to the server.
|
|
301
|
+
*
|
|
302
|
+
* @param {SubmitEvent} event - The event object for the form submission.
|
|
303
|
+
* @returns {void}
|
|
304
|
+
*/
|
|
305
|
+
doSubmit(event) {
|
|
306
|
+
// prevent the form from submitting normally
|
|
307
|
+
event.preventDefault();
|
|
308
|
+
const allElements = this.fieldset.querySelectorAll('[custom-validation-set=true]');
|
|
309
|
+
if (allElements.length) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
// create a new FormData object with the form data
|
|
313
|
+
const formData = new FormData(event.target);
|
|
314
|
+
// get a list of checkboxes, if any, so we can manually set unchecked box data
|
|
315
|
+
const formProperties = this._formSchema.properties;
|
|
316
|
+
for (const formKey of Object.keys(formProperties)) {
|
|
317
|
+
if (formProperties[formKey].form.type === 'checkbox' && !formData.has(formKey)) {
|
|
318
|
+
formData.append(formKey, 'off');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// emit the form data through the `dataSubmitted` event
|
|
322
|
+
this.dataSubmitted.emit(formData);
|
|
323
|
+
}
|
|
324
|
+
// This method is called before the component is loaded into the DOM
|
|
325
|
+
componentWillLoad() {
|
|
326
|
+
// Initialize the form schema by calling the "onFormSchemaChange" method with the current "formschema" property
|
|
327
|
+
this.onFormSchemaChange(this.formschema);
|
|
328
|
+
if (this.data) {
|
|
329
|
+
this.onDataChange(this.data);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// This method is called before the component is rendered
|
|
333
|
+
componentWillRender() {
|
|
334
|
+
// Clear the template to account for a potential re-render scenario
|
|
335
|
+
this.template = document.createElement('template');
|
|
336
|
+
// Populate the form from the form schema
|
|
337
|
+
this.populateFormFromSchema();
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Creates a new HTMLSelectElement with a set of options.
|
|
341
|
+
*
|
|
342
|
+
* @param {string} formKey - The name of the dropdown field, as specified in the form schema.
|
|
343
|
+
* @param {object} formProperties - An object containing additional properties, such as the field type and options properties.
|
|
344
|
+
* @param {'select'} formProperties.type - The type of form field. In this case, it will always be "select".
|
|
345
|
+
* @param {object} formProperties.validation - A set of validation rules for the field.
|
|
346
|
+
* @param {Array<{label:string, value:string, placeholder?:boolean}>} formProperties.options - A list of properties to pass to the select options.
|
|
347
|
+
* @param {string} formProperties.options[].label - The visible value of the option.
|
|
348
|
+
* @param {string} formProperties.options[].value - The actual value of the option.
|
|
349
|
+
* @param {boolean} [formProperties.options[].placeholder]
|
|
350
|
+
*/
|
|
351
|
+
createSelect(formKey, formProperties) {
|
|
352
|
+
var _a, _b, _c, _d, _e, _f;
|
|
353
|
+
const select = document.createElement('select');
|
|
354
|
+
select.setAttribute('name', formKey);
|
|
355
|
+
(_a = formProperties.options) === null || _a === void 0 ? void 0 : _a.forEach(optionProperties => {
|
|
356
|
+
this.appendOption(select, optionProperties);
|
|
357
|
+
});
|
|
358
|
+
if ((_b = this._data) === null || _b === void 0 ? void 0 : _b[formKey]) {
|
|
359
|
+
select.classList.remove('placeholder');
|
|
360
|
+
}
|
|
361
|
+
const tttxSelect = document.createElement('tttx-select-box_1_9_103');
|
|
362
|
+
tttxSelect.optionsData = (_c = formProperties.options) === null || _c === void 0 ? void 0 : _c.filter(o => !o.placeholder);
|
|
363
|
+
tttxSelect.placeholder = (_e = (_d = formProperties.options) === null || _d === void 0 ? void 0 : _d.filter(o => o.placeholder)[0]) === null || _e === void 0 ? void 0 : _e.label;
|
|
364
|
+
tttxSelect.inline = false;
|
|
365
|
+
tttxSelect.searchEnabled = true;
|
|
366
|
+
tttxSelect.useExternalFiltering = formProperties.useExternalFiltering || false;
|
|
367
|
+
tttxSelect.style.width = '100%';
|
|
368
|
+
tttxSelect.style.marginTop = '6px';
|
|
369
|
+
tttxSelect.isLoading = formProperties.isLoading || false;
|
|
370
|
+
tttxSelect.readOnly = (_f = formProperties.readOnly) !== null && _f !== void 0 ? _f : false;
|
|
371
|
+
tttxSelect.setAttribute('name', 'overlay-' + formKey);
|
|
372
|
+
const fragment = document.createDocumentFragment();
|
|
373
|
+
fragment.append(tttxSelect);
|
|
374
|
+
select.style.display = 'none';
|
|
375
|
+
tttxSelect.addEventListener('selectItemEvent', this.selectItemEventCallback.bind(select));
|
|
376
|
+
// emit the event for searchTermChanged.
|
|
377
|
+
tttxSelect.addEventListener('multiselectSearchUpdated', (ev) => this.searchTermChanged.emit({
|
|
378
|
+
name: formKey,
|
|
379
|
+
value: ev.detail,
|
|
380
|
+
type: 'SearchTermChanged'
|
|
381
|
+
}));
|
|
382
|
+
tttxSelect.addEventListener('toggleOpen', (ev) => this.selectToggleOpen.emit({
|
|
383
|
+
name: formKey,
|
|
384
|
+
value: ev.detail,
|
|
385
|
+
type: 'ToggleOpen'
|
|
386
|
+
}));
|
|
387
|
+
return { input: select, overlay: fragment };
|
|
388
|
+
}
|
|
389
|
+
selectItemEventCallback(ev) {
|
|
390
|
+
// this function MUST be bound to a HTMLSelectElement
|
|
391
|
+
// 'this' will be the select element
|
|
392
|
+
// the function was split out for testing
|
|
393
|
+
const select = this;
|
|
394
|
+
select.value = ev.detail.value;
|
|
395
|
+
select.onblur({ target: select }); // triggers validator
|
|
396
|
+
select.onchange({ target: select }); // triggers dataChanged event
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Appends an option to a select element
|
|
400
|
+
*
|
|
401
|
+
* @param {HTMLSelectElement} select - The select elements to attach the option to.
|
|
402
|
+
* @param {Object} optionProperties
|
|
403
|
+
* @param {string} optionProperties.value - The value of the option.
|
|
404
|
+
* @param {string} optionProperties.label - The label which will be displayed on the form for the option.
|
|
405
|
+
* @param {boolean} [optionProperties.placeholder]
|
|
406
|
+
*/
|
|
407
|
+
appendOption(select, optionProperties) {
|
|
408
|
+
const option = document.createElement('option');
|
|
409
|
+
option.setAttribute('value', optionProperties.value);
|
|
410
|
+
if (optionProperties.placeholder) {
|
|
411
|
+
option.setAttribute('disabled', (optionProperties.disabled) ? 'true' : '');
|
|
412
|
+
option.setAttribute('selected', '');
|
|
413
|
+
option.setAttribute('hidden', '');
|
|
414
|
+
select.classList.add('placeholder');
|
|
415
|
+
}
|
|
416
|
+
if (optionProperties.label)
|
|
417
|
+
option.innerHTML = purify.sanitize(optionProperties.label, domSanitiserOptions);
|
|
418
|
+
select.appendChild(option);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Creates a new HTMLInputElement with the specified name, type, and placeholder (if any),
|
|
422
|
+
* and sets its autocomplete and autocapitalization properties to off.
|
|
423
|
+
*
|
|
424
|
+
* @param {string} formKey - The name of the input field, as specified in the form schema.
|
|
425
|
+
* @param {Record<string, any>} formProperties - An object containing additional properties for the input field, such as its type and placeholder value.
|
|
426
|
+
* @param {string} formProperties.type - The type of the input field (e.g., "text", "email", "number", etc.).
|
|
427
|
+
* @param {string} [formProperties.placeholder] - An optional placeholder value to display in the input field.
|
|
428
|
+
* @return {HTMLInputElement} - The new input element.
|
|
429
|
+
*/
|
|
430
|
+
createInput(formKey, formProperties) {
|
|
431
|
+
var _a;
|
|
432
|
+
// Create a new <input> element with the specified name and type
|
|
433
|
+
const input = document.createElement('input');
|
|
434
|
+
input.type = formProperties.type;
|
|
435
|
+
input.name = formKey;
|
|
436
|
+
// Set the placeholder attribute to the specified value (if any)
|
|
437
|
+
input.placeholder = (_a = formProperties.placeholder) !== null && _a !== void 0 ? _a : '';
|
|
438
|
+
// Disable autocomplete and autocapitalization
|
|
439
|
+
input.autocomplete = 'off';
|
|
440
|
+
input.autocapitalize = 'off';
|
|
441
|
+
if (formProperties.readonly) {
|
|
442
|
+
input.readOnly = true;
|
|
443
|
+
}
|
|
444
|
+
if (formProperties.maskedValue) {
|
|
445
|
+
// Clear input on focus
|
|
446
|
+
input.onfocus = () => {
|
|
447
|
+
if (input.value === formProperties.maskedValue) {
|
|
448
|
+
input.value = '';
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
// Restore value or update it on blur
|
|
452
|
+
input.addEventListener('blur', () => {
|
|
453
|
+
if (input.value.trim() === '') {
|
|
454
|
+
input.value = formProperties.maskedValue;
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
formProperties.value = input.value;
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
// Return the input element
|
|
462
|
+
return input;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Creates a new HTMLTextAreaElement with the specified name and placeholder (if any),
|
|
466
|
+
* and sets its autocomplete and autocapitalization properties to off.
|
|
467
|
+
*
|
|
468
|
+
* @param {string} formKey - The name of the input field, as specified in the form schema.
|
|
469
|
+
* @param {Record<string, any>} formProperties - An object containing additional properties for the input field, such as its type and placeholder value.
|
|
470
|
+
* @param {string} [formProperties.placeholder] - An optional placeholder value to display in the input field.
|
|
471
|
+
* @return {HTMLTextAreaElement} - The new input element.
|
|
472
|
+
*/
|
|
473
|
+
createTextArea(formKey, formProperties) {
|
|
474
|
+
var _a;
|
|
475
|
+
const input = document.createElement('textarea');
|
|
476
|
+
input.name = formKey;
|
|
477
|
+
// Set the placeholder attribute to the specified value (if any)
|
|
478
|
+
input.placeholder = (_a = formProperties.placeholder) !== null && _a !== void 0 ? _a : '';
|
|
479
|
+
// Disable autocomplete and autocapitalization
|
|
480
|
+
input.autocomplete = 'off';
|
|
481
|
+
input.autocapitalize = 'off';
|
|
482
|
+
if (formProperties.readonly) {
|
|
483
|
+
input.readOnly = true;
|
|
484
|
+
}
|
|
485
|
+
if (formProperties.resize === 'none') {
|
|
486
|
+
input.classList.add('resize-none');
|
|
487
|
+
}
|
|
488
|
+
// Return the input element
|
|
489
|
+
return input;
|
|
490
|
+
}
|
|
491
|
+
createStartEndDateComponent(formKey, formProperties) {
|
|
492
|
+
var _a, _b, _c, _d;
|
|
493
|
+
const startDate = document.createElement('input');
|
|
494
|
+
const endDate = document.createElement('input');
|
|
495
|
+
startDate.type = endDate.type = 'date';
|
|
496
|
+
startDate.name = `${formKey}-startdate`;
|
|
497
|
+
endDate.name = `${formKey}-enddate`;
|
|
498
|
+
startDate.setAttribute('data-formkey', formKey);
|
|
499
|
+
endDate.setAttribute('data-formkey', formKey);
|
|
500
|
+
if (formProperties.readonly) {
|
|
501
|
+
startDate.readOnly = true;
|
|
502
|
+
endDate.readOnly = true;
|
|
503
|
+
}
|
|
504
|
+
this.applyValidation(startDate, Object.assign({ required: { message: 'Please enter a start date' }, dateCompare: { to: endDate.name } }, (_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.startDate));
|
|
505
|
+
this.applyValidation(endDate, Object.assign({ required: { message: 'Please enter an end date' }, dateCompare: { with: startDate.name, message: 'End date cannot be before the start date' } }, (_b = formProperties.validation) === null || _b === void 0 ? void 0 : _b.endDate));
|
|
506
|
+
let startTime;
|
|
507
|
+
let endTime;
|
|
508
|
+
if (formProperties.includeTime) {
|
|
509
|
+
startTime = document.createElement('input');
|
|
510
|
+
endTime = document.createElement('input');
|
|
511
|
+
startTime.type = endTime.type = 'time';
|
|
512
|
+
startTime.name = `${formKey}-starttime`;
|
|
513
|
+
endTime.name = `${formKey}-endtime`;
|
|
514
|
+
startTime.setAttribute('data-formkey', formKey);
|
|
515
|
+
endTime.setAttribute('data-formkey', formKey);
|
|
516
|
+
if (formProperties.readonly) {
|
|
517
|
+
startTime.readOnly = true;
|
|
518
|
+
endTime.readOnly = true;
|
|
519
|
+
}
|
|
520
|
+
this.applyValidation(startTime, Object.assign({ required: { message: 'Please enter a start time' } }, (_c = formProperties.validation) === null || _c === void 0 ? void 0 : _c.startTime));
|
|
521
|
+
this.applyValidation(endTime, Object.assign({ required: { message: 'Please enter an end time' } }, (_d = formProperties.validation) === null || _d === void 0 ? void 0 : _d.endTime));
|
|
522
|
+
}
|
|
523
|
+
const startLabel = document.createElement('label');
|
|
524
|
+
startLabel.innerText = 'Start date';
|
|
525
|
+
const endLabel = document.createElement('label');
|
|
526
|
+
endLabel.innerText = 'End date';
|
|
527
|
+
const startContainer = document.createElement('div');
|
|
528
|
+
const endContainer = document.createElement('div');
|
|
529
|
+
startContainer.className = endContainer.className = 'outer-container inputBlock';
|
|
530
|
+
startLabel.className = endLabel.className = 'flex-label';
|
|
531
|
+
startContainer.append(startDate);
|
|
532
|
+
if (startTime) {
|
|
533
|
+
startContainer.append(startTime);
|
|
534
|
+
}
|
|
535
|
+
startLabel.append(startContainer);
|
|
536
|
+
startLabel.append(this.createErrorBubble());
|
|
537
|
+
endContainer.append(endDate);
|
|
538
|
+
if (endTime) {
|
|
539
|
+
endContainer.append(endTime);
|
|
540
|
+
}
|
|
541
|
+
endLabel.append(endContainer);
|
|
542
|
+
endLabel.append(this.createErrorBubble());
|
|
543
|
+
return { start: startLabel, end: endLabel };
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Applies validation attributes to an input element based on the specified validation object.
|
|
547
|
+
* If a certain property is present in the object, it will set the corresponding attribute on
|
|
548
|
+
* the input element (e.g., "required" will set the "required" and "data-required" attributes,
|
|
549
|
+
* "pattern" will set the "pattern" and "data-pattern" attributes, etc.).
|
|
550
|
+
*
|
|
551
|
+
* @param {FormField} input - The input element to apply validation attributes to.
|
|
552
|
+
* @param {object} validation - An object containing the validation rules for the input field.
|
|
553
|
+
* @param {object} [validation.required] - An object containing a "message" property to display if the field is required.
|
|
554
|
+
* @param {string} [validation.required.message]
|
|
555
|
+
* @param {object} [validation.pattern] - An object containing a "pattern" property to match against the field value, and a "message" property to display if the pattern doesn't match.
|
|
556
|
+
* @param {string} [validation.pattern.pattern]
|
|
557
|
+
* @param {string} [validation.pattern.message]
|
|
558
|
+
* @param {object} [validation.badInput] - An object containing a "message" property to display if the field value is invalid.
|
|
559
|
+
* @param {string} [validation.badInput.message]
|
|
560
|
+
* @param {object} [validation.minmax] - An object containing "min" and "max" properties to validate the field value against, and a "message" property to display if the value is out of range.
|
|
561
|
+
* @param {string} [validation.minmax.min]
|
|
562
|
+
* @param {string} [validation.minmax.max]
|
|
563
|
+
* @param {string} [validation.minmax.message]
|
|
564
|
+
* @param {string} [validation.maxlength] - The maximum length of the input field.
|
|
565
|
+
* @param {string} [validation.datecompare] - To compare start and end date fields.
|
|
566
|
+
* @return {void}
|
|
567
|
+
*/
|
|
568
|
+
applyValidation(input, validation) {
|
|
569
|
+
var _a, _b;
|
|
570
|
+
// If the "required" property is present, add the "required" attribute to the input element and
|
|
571
|
+
// set its "data-required" attribute to the specified message (if any)
|
|
572
|
+
if (validation.required) {
|
|
573
|
+
input.setAttribute('required', '');
|
|
574
|
+
input.setAttribute('data-required', (_a = validation.required.message) !== null && _a !== void 0 ? _a : '');
|
|
575
|
+
}
|
|
576
|
+
// If the "pattern" property is present, add the "pattern" attribute to the input element and set
|
|
577
|
+
// its "data-pattern" attribute to the specified message (if any)
|
|
578
|
+
if (validation.pattern) {
|
|
579
|
+
input.setAttribute('pattern', validation.pattern.pattern);
|
|
580
|
+
input.setAttribute('data-pattern', (_b = validation.pattern.message) !== null && _b !== void 0 ? _b : '');
|
|
581
|
+
}
|
|
582
|
+
// If the "badInput" property is present, set the input element's "data-badinput" attribute to
|
|
583
|
+
// the specified message
|
|
584
|
+
if (validation.badInput) {
|
|
585
|
+
input.setAttribute('data-badinput', validation.badInput.message);
|
|
586
|
+
}
|
|
587
|
+
// If the "minmax" property is present, add the "min" and "max" attributes to the input element
|
|
588
|
+
// and set its "data-range" attribute to the specified message (if any)
|
|
589
|
+
if (validation.minmax) {
|
|
590
|
+
input.setAttribute('min', validation.minmax.min);
|
|
591
|
+
input.setAttribute('max', validation.minmax.max);
|
|
592
|
+
input.setAttribute('data-range', validation.minmax.message);
|
|
593
|
+
}
|
|
594
|
+
// If the "maxlength" property is present, add the "maxlength" attribute to the input element
|
|
595
|
+
if (validation.maxlength) {
|
|
596
|
+
input.setAttribute('maxlength', validation.maxlength);
|
|
597
|
+
}
|
|
598
|
+
// Custom validation parameters for start date and end date comparison
|
|
599
|
+
if (validation.dateCompare) {
|
|
600
|
+
if (validation.dateCompare.message && validation.dateCompare.with) {
|
|
601
|
+
input.setAttribute('data-compare', validation.dateCompare.message);
|
|
602
|
+
input.setAttribute('data-compare-with', validation.dateCompare.with);
|
|
603
|
+
}
|
|
604
|
+
if (validation.dateCompare.to) {
|
|
605
|
+
input.setAttribute('data-compare-to', validation.dateCompare.to);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
// Create a new error bubble element
|
|
610
|
+
createErrorBubble() {
|
|
611
|
+
// Create a new <div> element with the "errorBubble" class
|
|
612
|
+
const errorBubble = document.createElement('div');
|
|
613
|
+
errorBubble.className = 'errorBubble';
|
|
614
|
+
// Return the error bubble element
|
|
615
|
+
return errorBubble;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
*
|
|
619
|
+
* @param {Record<string, any>} formProperties
|
|
620
|
+
* @param {HTMLInputElement | HTMLSelectElement} input
|
|
621
|
+
* @param {HTMLLabelElement} label
|
|
622
|
+
* @returns {void}
|
|
623
|
+
*/
|
|
624
|
+
appendCheckboxInput(formProperties, input, label) {
|
|
625
|
+
if (formProperties.label) {
|
|
626
|
+
const lineBreak = document.createElement('br');
|
|
627
|
+
label.appendChild(lineBreak);
|
|
628
|
+
}
|
|
629
|
+
// Append the input element and error bubble element to the label
|
|
630
|
+
label.appendChild(input);
|
|
631
|
+
if (!formProperties.inlineLabel)
|
|
632
|
+
return;
|
|
633
|
+
const inlineLabel = document.createElement('span');
|
|
634
|
+
inlineLabel.className = 'inlineLabel';
|
|
635
|
+
inlineLabel.textContent = formProperties.inlineLabel;
|
|
636
|
+
label.appendChild(inlineLabel);
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Creates a new <label> element with the "inputBlock" class and the specified label text,
|
|
640
|
+
* and appends the input element and error bubble element to it. If the form property has
|
|
641
|
+
* no validation object, it adds an "optional" span element to the label.
|
|
642
|
+
*
|
|
643
|
+
* @param {Record<string, any>} formProperties - An object containing properties for the form field, including its label text and validation rules.
|
|
644
|
+
* @param {HTMLInputElement | HTMLSelectElement} input - The input element to associate with the label.
|
|
645
|
+
* @param {never} overlay - The Child Element which will be rendered atop the standard HTML5 element
|
|
646
|
+
* @param {HTMLDivElement} errorBubble - The error bubble element to display error messages in.
|
|
647
|
+
* @return {HTMLLabelElement} - The new label element.
|
|
648
|
+
*/
|
|
649
|
+
createLabel(formProperties, input, overlay = null, errorBubble) {
|
|
650
|
+
var _a;
|
|
651
|
+
const outerContainer = document.createElement('div');
|
|
652
|
+
let outerContainerClassName = 'outer-container inputBlock';
|
|
653
|
+
// Create a new <label> element with the "inputBlock" class and the specified text
|
|
654
|
+
const label = document.createElement('label');
|
|
655
|
+
label.innerText = formProperties.label;
|
|
656
|
+
// If the form property has no validation object, add an "optional" span element to the label
|
|
657
|
+
if (!((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.required) && formProperties.label) {
|
|
658
|
+
const optionalSpan = document.createElement('span');
|
|
659
|
+
optionalSpan.className = 'optional';
|
|
660
|
+
optionalSpan.innerHTML = ' (optional)';
|
|
661
|
+
label.appendChild(optionalSpan);
|
|
662
|
+
}
|
|
663
|
+
if (formProperties.type === 'radio') {
|
|
664
|
+
outerContainerClassName += ' radioBlock';
|
|
665
|
+
}
|
|
666
|
+
outerContainer.className = outerContainerClassName;
|
|
667
|
+
if (formProperties.readonly) {
|
|
668
|
+
label.classList.add('readonly');
|
|
669
|
+
}
|
|
670
|
+
if (formProperties.type === 'checkbox') {
|
|
671
|
+
this.appendCheckboxInput(formProperties, input, label);
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
// Append the input element and error bubble element to the outerContainer
|
|
675
|
+
if (overlay) {
|
|
676
|
+
outerContainer.appendChild(overlay);
|
|
677
|
+
}
|
|
678
|
+
outerContainer.appendChild(input);
|
|
679
|
+
}
|
|
680
|
+
if (formProperties.type !== 'checkbox') {
|
|
681
|
+
label.appendChild(outerContainer);
|
|
682
|
+
}
|
|
683
|
+
label.appendChild(errorBubble);
|
|
684
|
+
// Return the label element
|
|
685
|
+
return label;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Creates a new radio input with a set of options.
|
|
689
|
+
*
|
|
690
|
+
* @param {string} formKey - The name of the dropdown field, as specified in the form schema.
|
|
691
|
+
* @param {Object} formProperties - An object containing additional properties, such as the field type and options properties.
|
|
692
|
+
* @param {'radio'} formProperties.type - The type of form field. In this case, it will always be "radio".
|
|
693
|
+
* @param {Object} formProperties.validation - A set of validation rules for the field.
|
|
694
|
+
* @param {Object[]} formProperties.options - A list of properties to pass to the select options.
|
|
695
|
+
* @param {string} formProperties.options.label - The visible value of the option.
|
|
696
|
+
* @param {string} formProperties.options.value - The actual value of the option.
|
|
697
|
+
*/
|
|
698
|
+
createRadio(formKey, formProperties) {
|
|
699
|
+
var _a, _b;
|
|
700
|
+
const fragment = document.createDocumentFragment();
|
|
701
|
+
for (const optionProperties of formProperties.options) {
|
|
702
|
+
// Create a new <input> element with the specified name and type
|
|
703
|
+
const input = document.createElement('input');
|
|
704
|
+
input.type = 'radio';
|
|
705
|
+
input.name = formKey;
|
|
706
|
+
input.value = optionProperties.value;
|
|
707
|
+
if ((_a = formProperties === null || formProperties === void 0 ? void 0 : formProperties.validation) === null || _a === void 0 ? void 0 : _a.required) {
|
|
708
|
+
input.setAttribute('required', 'required');
|
|
709
|
+
input.setAttribute('data-required', (_b = formProperties.validation.required.message) !== null && _b !== void 0 ? _b : '');
|
|
710
|
+
}
|
|
711
|
+
const span = document.createElement('span');
|
|
712
|
+
span.innerText = optionProperties.label;
|
|
713
|
+
fragment.appendChild(input);
|
|
714
|
+
fragment.appendChild(span);
|
|
715
|
+
fragment.appendChild(document.createElement('br'));
|
|
716
|
+
}
|
|
717
|
+
return fragment;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Populates the form template with input fields and labels based on the properties of the
|
|
721
|
+
* current form schema. For each property in the schema, it creates an input element, applies
|
|
722
|
+
* any validation rules to it, creates an error bubble and label element, and appends them
|
|
723
|
+
* to the form template. Finally, it creates and appends a submit button element to the form.
|
|
724
|
+
*
|
|
725
|
+
* @return {void}
|
|
726
|
+
*/
|
|
727
|
+
populateFormFromSchema() {
|
|
728
|
+
var _a;
|
|
729
|
+
// If there is no form schema, return early
|
|
730
|
+
if (!this._formSchema) {
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
// Get the properties of the form schema and their keys
|
|
734
|
+
const properties = this._formSchema.properties;
|
|
735
|
+
const propertyKeys = Object.keys(properties);
|
|
736
|
+
// Loop through each property key and create an input, label, and error bubble for it
|
|
737
|
+
for (const formKey of propertyKeys) {
|
|
738
|
+
const formItem = properties[formKey];
|
|
739
|
+
const formProperties = formItem.form;
|
|
740
|
+
// complex form types which require
|
|
741
|
+
// custom HTML should be done here
|
|
742
|
+
if (formProperties.type === 'startenddate') {
|
|
743
|
+
const { start, end } = this.createStartEndDateComponent(formKey, formProperties);
|
|
744
|
+
this.template.content.append(start);
|
|
745
|
+
this.template.content.append(end);
|
|
746
|
+
continue;
|
|
747
|
+
}
|
|
748
|
+
let fragments = {};
|
|
749
|
+
switch (formProperties.type) {
|
|
750
|
+
case 'select':
|
|
751
|
+
fragments = this.createSelect(formKey, formProperties);
|
|
752
|
+
break;
|
|
753
|
+
case 'radio':
|
|
754
|
+
fragments.input = this.createRadio(formKey, formProperties);
|
|
755
|
+
break;
|
|
756
|
+
case 'textarea':
|
|
757
|
+
fragments.input = this.createTextArea(formKey, formProperties);
|
|
758
|
+
break;
|
|
759
|
+
default:
|
|
760
|
+
fragments.input = this.createInput(formKey, formProperties);
|
|
761
|
+
}
|
|
762
|
+
// If the form property has validation, apply it to the input
|
|
763
|
+
if (formProperties.validation &&
|
|
764
|
+
formProperties.type !== 'radio') {
|
|
765
|
+
this.applyValidation(fragments.input, formProperties.validation);
|
|
766
|
+
}
|
|
767
|
+
// Create an error bubble and label element for the input
|
|
768
|
+
const errorBubble = this.createErrorBubble();
|
|
769
|
+
const label = this.createLabel(formProperties, fragments.input, fragments.overlay, errorBubble);
|
|
770
|
+
// If explicitly setting input as invalid, set invalid state and error message on render
|
|
771
|
+
if ((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.invalid) {
|
|
772
|
+
const errorMessage = formProperties.validation.invalid.message;
|
|
773
|
+
fragments.input.setCustomValidity(errorMessage); // Prevents the invalid styling from resetting on blur
|
|
774
|
+
setErrorState(fragments.input, true, errorMessage);
|
|
775
|
+
}
|
|
776
|
+
// Append the label element to the form template
|
|
777
|
+
this.template.content.append(label);
|
|
778
|
+
if (formProperties.disabled) {
|
|
779
|
+
this.toggleFormField(fragments.input, true);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Clones the form template and binds event listeners to its input elements. First, it checks if
|
|
785
|
+
* there is a form schema present. If so, it clones the template's content, binds events to form
|
|
786
|
+
* input elements, and appends the cloned form elements to the fieldset. The event listeners include
|
|
787
|
+
* "oninvalid" (to check input validity on submit), "onblur" (to check input validity on blur),
|
|
788
|
+
* "onkeyup" (to handle changes in input fields), and "onchange" (to handle changes in select fields).
|
|
789
|
+
*
|
|
790
|
+
* @return {void}
|
|
791
|
+
*/
|
|
792
|
+
componentDidRender() {
|
|
793
|
+
// If there's no form schema, return
|
|
794
|
+
if (!this._formSchema) {
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
// Clone the template's content and store it in a variable
|
|
798
|
+
const formItems = this.template.content;
|
|
799
|
+
// Bind event listeners to form elements
|
|
800
|
+
const properties = this._formSchema.properties;
|
|
801
|
+
const propertyKeys = Object.keys(properties);
|
|
802
|
+
for (const formKey of propertyKeys) {
|
|
803
|
+
this.applyValidationFunctionsToFormElement(formItems, formKey, properties);
|
|
804
|
+
}
|
|
805
|
+
// populate with existing form data if available
|
|
806
|
+
if ((this._data && Object.keys(this._data).length > 0)) {
|
|
807
|
+
this.populateFormWithExistingData(formItems);
|
|
808
|
+
}
|
|
809
|
+
// Append the cloned form elements to the fieldset
|
|
810
|
+
this.fieldset.replaceChildren(formItems);
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Assign validation events to a given form item
|
|
814
|
+
* @param formItems The document fragment template of form items to be rendered
|
|
815
|
+
* @param formKey The key of the form item to bind events too
|
|
816
|
+
* @param properties The form item's properties, such as type and name
|
|
817
|
+
*/
|
|
818
|
+
applyValidationFunctionsToFormElement(formItems, formKey, properties) {
|
|
819
|
+
const formItemsByKey = formItems.querySelectorAll(`[name^=${formKey}]`);
|
|
820
|
+
for (const formInput of formItemsByKey) {
|
|
821
|
+
// Bind events to form input elements
|
|
822
|
+
formInput.oninvalid = this.validityCheckWrapper.bind(this);
|
|
823
|
+
formInput.onblur = this.validityCheckWrapper.bind(this);
|
|
824
|
+
formInput.onkeyup = this.fieldChanged.bind(this);
|
|
825
|
+
formInput.onchange = this.fieldChanged.bind(this);
|
|
826
|
+
if (properties[formKey].form.type === 'select' && formInput.classList.contains('placeholder')) {
|
|
827
|
+
formInput.addEventListener('change', this.selectRemovePlaceholderCallback.bind(formInput));
|
|
828
|
+
}
|
|
829
|
+
if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-with')) {
|
|
830
|
+
formInput.oninvalid = endDateComparisonValidator.bind(this);
|
|
831
|
+
formInput.onblur = endDateComparisonValidator.bind(this);
|
|
832
|
+
}
|
|
833
|
+
if (properties[formKey].form.type === 'startenddate' && formInput.type === 'time') {
|
|
834
|
+
formInput.oninvalid = startEndTimeComparator.bind(this);
|
|
835
|
+
formInput.onblur = startEndTimeComparator.bind(this);
|
|
836
|
+
}
|
|
837
|
+
if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-to')) {
|
|
838
|
+
formInput.oninvalid = startDateComparisonValidator.bind(this);
|
|
839
|
+
formInput.onblur = startDateComparisonValidator.bind(this);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* If data exists, set form input values before rendering
|
|
845
|
+
* @param formItems The document fragment template of form items to be rendered
|
|
846
|
+
*/
|
|
847
|
+
populateFormWithExistingData(formItems) {
|
|
848
|
+
var _a;
|
|
849
|
+
const dataKeys = Object.keys(this._data);
|
|
850
|
+
for (const key of dataKeys) {
|
|
851
|
+
const formItemsByKey = formItems.querySelectorAll(`[name=${key}]`);
|
|
852
|
+
for (const formItem of formItemsByKey) {
|
|
853
|
+
switch (formItem.type) {
|
|
854
|
+
case 'checkbox':
|
|
855
|
+
if (this._data[key] === 'on') {
|
|
856
|
+
formItem.checked = true;
|
|
857
|
+
}
|
|
858
|
+
break;
|
|
859
|
+
case 'radio':
|
|
860
|
+
if (formItem.value === this._data[key]) {
|
|
861
|
+
formItem.checked = true;
|
|
862
|
+
}
|
|
863
|
+
break;
|
|
864
|
+
case 'select':
|
|
865
|
+
case 'select-one':
|
|
866
|
+
formItems.querySelector(`[name=overlay-${key}]`)['selectedValue'] = this._data[key];
|
|
867
|
+
formItem.value = this._data[key];
|
|
868
|
+
break;
|
|
869
|
+
case 'date':
|
|
870
|
+
formItem.value = (_a = this._data[key]) === null || _a === void 0 ? void 0 : _a.split('T')[0];
|
|
871
|
+
break;
|
|
872
|
+
default:
|
|
873
|
+
formItem.value = this._data[key];
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Remove the placeholder class on the bound THIS select element
|
|
880
|
+
*/
|
|
881
|
+
selectRemovePlaceholderCallback() {
|
|
882
|
+
const select = this;
|
|
883
|
+
select.classList.remove('placeholder');
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* A wrapper around validity check and set error state
|
|
887
|
+
*/
|
|
888
|
+
validityCheckWrapper(event) {
|
|
889
|
+
const { target, hasError, errorMessage } = validityCheck(event);
|
|
890
|
+
setErrorState(target, hasError, errorMessage);
|
|
891
|
+
}
|
|
892
|
+
assignFieldsetReference(el) {
|
|
893
|
+
this.fieldset = el;
|
|
894
|
+
}
|
|
895
|
+
assignButtonReference(el) {
|
|
896
|
+
this.submitButton = el;
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* An external validation trigger to apply to a form field
|
|
900
|
+
* @param { string } fieldName The form field name to apply the validation too
|
|
901
|
+
* @param { string } message The validation message to display under the form field
|
|
902
|
+
*/
|
|
903
|
+
async setValidationFor(fieldName, message) {
|
|
904
|
+
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
905
|
+
if (formField.disabled) {
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
formField.setCustomValidity(message);
|
|
909
|
+
formField.setAttribute('custom-validation-set', 'true');
|
|
910
|
+
setErrorState(formField, true, message);
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Clear the validation message on a given form field
|
|
914
|
+
* @param { string } fieldName The form field name to clear the validation of
|
|
915
|
+
*/
|
|
916
|
+
async clearValidationFor(fieldName) {
|
|
917
|
+
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
918
|
+
formField.setCustomValidity('');
|
|
919
|
+
formField.removeAttribute('custom-validation-set');
|
|
920
|
+
setErrorState(formField, false, '');
|
|
921
|
+
}
|
|
922
|
+
toggleFormField(formField, disabled) {
|
|
923
|
+
formField.disabled = disabled;
|
|
924
|
+
let parent = formField.parentElement;
|
|
925
|
+
if (parent) {
|
|
926
|
+
do {
|
|
927
|
+
if (parent.nodeName !== 'LABEL') {
|
|
928
|
+
parent = parent.parentElement;
|
|
929
|
+
}
|
|
930
|
+
} while (parent && parent.nodeName !== 'LABEL');
|
|
931
|
+
if (parent) {
|
|
932
|
+
parent.style.display = (disabled) ? 'none' : 'block';
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Disable a form field and visually remove it from the form.
|
|
938
|
+
* If custom validation is set, this function will return without affecting the form field.
|
|
939
|
+
* @param { string } fieldName The form field name to disable
|
|
940
|
+
*/
|
|
941
|
+
async disableFormField(fieldName) {
|
|
942
|
+
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
943
|
+
if (formField.hasAttribute('custom-validation-set')) {
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
this.toggleFormField(formField, true);
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Enable a form field and visually add it back to the form.
|
|
950
|
+
* @param { string } fieldName The form field name to enable
|
|
951
|
+
*/
|
|
952
|
+
async enableFormField(fieldName) {
|
|
953
|
+
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
954
|
+
this.toggleFormField(formField, false);
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Set the value of a form field progromatically
|
|
958
|
+
* @param { string } fieldName The form field name having it's value set
|
|
959
|
+
* @param { string } fieldValue The form field value to set
|
|
960
|
+
*/
|
|
961
|
+
async setInputFieldValue(fieldName, fieldValue) {
|
|
962
|
+
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
963
|
+
formField.value = fieldValue;
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Change the readonly property on an input field. If set to 'true' any validation will also be cleared.
|
|
967
|
+
* @param { string } fieldName The form field name to set
|
|
968
|
+
* @param { boolean } readonly The state of the read-only attribute
|
|
969
|
+
*/
|
|
970
|
+
async setFieldReadOnlyMode(fieldName, readonly) {
|
|
971
|
+
const formField = this.fieldset.querySelector(`[name=${fieldName}]`);
|
|
972
|
+
if (formField && formField.nodeName === 'SELECT') {
|
|
973
|
+
const tttxSelect = this.fieldset.querySelector(`[name=overlay-${fieldName}]`);
|
|
974
|
+
tttxSelect.readOnly = readonly;
|
|
975
|
+
formField.disabled = readonly;
|
|
976
|
+
}
|
|
977
|
+
else {
|
|
978
|
+
formField.readOnly = readonly;
|
|
979
|
+
}
|
|
980
|
+
if (readonly) {
|
|
981
|
+
await this.clearValidationFor(fieldName);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
/**
|
|
985
|
+
* Renders the component's template as a form element with a fieldset container. The form's
|
|
986
|
+
* "onSubmit" event is bound to the "doSubmit" function, which handles the form submission
|
|
987
|
+
* and emits a "dataSubmitted" event with the form data. The fieldset element is assigned
|
|
988
|
+
* to the "fieldset" instance variable using a ref, so it can be populated with form elements
|
|
989
|
+
* later on.
|
|
990
|
+
*/
|
|
991
|
+
render() {
|
|
992
|
+
//react rendering so we can't JEST it
|
|
993
|
+
//ignore so it doesn't ruin coverage
|
|
994
|
+
/*istanbul ignore next*/
|
|
995
|
+
return (h(Host, null, h("form", { onSubmit: this.doSubmit.bind(this), ref: frm => this.form = frm }, h("fieldset", { ref: this.assignFieldsetReference.bind(this) }), h("input", { type: "submit", ref: this.assignButtonReference.bind(this), style: { display: 'none' } }))));
|
|
996
|
+
}
|
|
997
|
+
static get watchers() { return {
|
|
998
|
+
"formschema": ["onFormSchemaChange"],
|
|
999
|
+
"data": ["onDataChange"]
|
|
1000
|
+
}; }
|
|
1001
|
+
static get style() { return tttxFormCss; }
|
|
1002
|
+
}, [1, "tttx-form_1_9_103", {
|
|
1003
|
+
"formschema": [1025],
|
|
1004
|
+
"data": [1032],
|
|
1005
|
+
"submit": [64],
|
|
1006
|
+
"showLoadingSpinner": [64],
|
|
1007
|
+
"setSelectedItem": [64],
|
|
1008
|
+
"setSelectOptions": [64],
|
|
1009
|
+
"isValid": [64],
|
|
1010
|
+
"setValidationFor": [64],
|
|
1011
|
+
"clearValidationFor": [64],
|
|
1012
|
+
"disableFormField": [64],
|
|
1013
|
+
"enableFormField": [64],
|
|
1014
|
+
"setInputFieldValue": [64],
|
|
1015
|
+
"setFieldReadOnlyMode": [64]
|
|
1016
|
+
}]);
|
|
1017
|
+
function defineCustomElement$1() {
|
|
1018
|
+
if (typeof customElements === "undefined") {
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
const components = ["tttx-form_1_9_103", "tttx-icon_1_9_103", "tttx-loading-spinner_1_9_103", "tttx-select-box_1_9_103", "tttx-standalone-input_1_9_103", "tttx-tag_1_9_103"];
|
|
1022
|
+
components.forEach(tagName => { switch (tagName) {
|
|
1023
|
+
case "tttx-form_1_9_103":
|
|
1024
|
+
if (!customElements.get(tagName)) {
|
|
1025
|
+
customElements.define(tagName, TttxForm);
|
|
1026
|
+
}
|
|
1027
|
+
break;
|
|
1028
|
+
case "tttx-icon_1_9_103":
|
|
1029
|
+
if (!customElements.get(tagName)) {
|
|
1030
|
+
defineCustomElement$6();
|
|
1031
|
+
}
|
|
1032
|
+
break;
|
|
1033
|
+
case "tttx-loading-spinner_1_9_103":
|
|
1034
|
+
if (!customElements.get(tagName)) {
|
|
1035
|
+
defineCustomElement$5();
|
|
1036
|
+
}
|
|
1037
|
+
break;
|
|
1038
|
+
case "tttx-select-box_1_9_103":
|
|
1039
|
+
if (!customElements.get(tagName)) {
|
|
1040
|
+
defineCustomElement$4();
|
|
1041
|
+
}
|
|
1042
|
+
break;
|
|
1043
|
+
case "tttx-standalone-input_1_9_103":
|
|
1044
|
+
if (!customElements.get(tagName)) {
|
|
1045
|
+
defineCustomElement$3();
|
|
1046
|
+
}
|
|
1047
|
+
break;
|
|
1048
|
+
case "tttx-tag_1_9_103":
|
|
1049
|
+
if (!customElements.get(tagName)) {
|
|
1050
|
+
defineCustomElement$2();
|
|
1051
|
+
}
|
|
1052
|
+
break;
|
|
1053
|
+
} });
|
|
1054
1054
|
}
|
|
1055
1055
|
|
|
1056
|
-
const
|
|
1056
|
+
const TttxForm_1_9_103 = TttxForm;
|
|
1057
1057
|
const defineCustomElement = defineCustomElement$1;
|
|
1058
1058
|
|
|
1059
|
-
export {
|
|
1059
|
+
export { TttxForm_1_9_103, defineCustomElement };
|