@brightspot/ui 3.0.1-cms-ui-migration.2 → 3.0.1-cms-ui-migration.3
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/README.md +54 -35
- package/dist/custom-elements.json +1924 -1924
- package/dist/storybook/assets/{ActionBar.stories-hJ_5cm-P.js → ActionBar.stories-CSxtZl7v.js} +1 -1
- package/dist/storybook/assets/{ActionItem.stories-Bjx2803w.js → ActionItem.stories-BWcMRMP3.js} +1 -1
- package/dist/storybook/assets/{Avatar.stories-Cj0YgZ6f.js → Avatar.stories-CYTUGXzH.js} +1 -1
- package/dist/storybook/assets/{AvatarGroup.stories-Lh_sQFCU.js → AvatarGroup.stories-CSYBYo_5.js} +1 -1
- package/dist/storybook/assets/{Badge.stories-BL7RUibx.js → Badge.stories-LuF4BuVr.js} +1 -1
- package/dist/storybook/assets/{Button-BPHNcxqK.js → Button-CrXCMxHb.js} +1 -1
- package/dist/storybook/assets/{Button.stories-CAYO4gdU.js → Button.stories-JVwxdrdM.js} +1 -1
- package/dist/storybook/assets/{ButtonGroup.stories-Cd13Us5K.js → ButtonGroup.stories-qtq64a1H.js} +1 -1
- package/dist/storybook/assets/{Celebrate.stories-D_KE3Qze.js → Celebrate.stories-DjTtaSd6.js} +1 -1
- package/dist/storybook/assets/{Checkbox.stories-Aj1xgZVn.js → Checkbox.stories-v1Pr5mL6.js} +1 -1
- package/dist/storybook/assets/{CircularProgress.stories-BecV_v6d.js → CircularProgress.stories-DkV7PJ4D.js} +1 -1
- package/dist/storybook/assets/{ClipboardMixin.stories-DU-WiZ2f.js → ClipboardMixin.stories-Dh5c7uSM.js} +1 -1
- package/dist/storybook/assets/{Color-6BZIO3FS-BYl4KZZn.js → Color-6BZIO3FS-B1gcREt6.js} +1 -1
- package/dist/storybook/assets/{Colors.stories-BMUVUy2q.js → Colors.stories-DnubtRqn.js} +1 -1
- package/dist/storybook/assets/{CombinedEffects.stories-FHcPKFm6.js → CombinedEffects.stories-By6akSve.js} +1 -1
- package/dist/storybook/assets/{ComponentStatesMixin-EMUnfT5y.js → ComponentStatesMixin-CPLGv3h-.js} +1 -1
- package/dist/storybook/assets/{ComponentStatesMixin.stories-SXq0kzS9.js → ComponentStatesMixin.stories-CiQ_lyhm.js} +1 -1
- package/dist/storybook/assets/{CopyToClipboard.stories-u43lhvcI.js → CopyToClipboard.stories-cJ7rl3mj.js} +1 -1
- package/dist/storybook/assets/{Debounce.stories-BdCn5qgO.js → Debounce.stories-Bw-goobU.js} +1 -1
- package/dist/storybook/assets/{DocsRenderer-LL677BLK-DxiEJ_jx.js → DocsRenderer-LL677BLK-CNW57dGQ.js} +3 -3
- package/dist/storybook/assets/{Dropdown.stories-BWSRwjIF.js → Dropdown.stories-CwC3HXXd.js} +1 -1
- package/dist/storybook/assets/{EmptyState.stories-BpobeZL5.js → EmptyState.stories-BUEJwuhP.js} +1 -1
- package/dist/storybook/assets/{Events.stories-CP5kMzpr.js → Events.stories-D1mf9buv.js} +1 -1
- package/dist/storybook/assets/{Heading.stories-CbJD-oTB.js → Heading.stories-DO906G4P.js} +1 -1
- package/dist/storybook/assets/{HueRipple.stories-BOABJ7zw.js → HueRipple.stories-BOySRSZB.js} +1 -1
- package/dist/storybook/assets/{Icon.stories-CWlUHL4j.js → Icon.stories-BsqgTbdG.js} +1 -1
- package/dist/storybook/assets/{IconButton.stories-BWBs-OLT.js → IconButton.stories-aza1AAKk.js} +1 -1
- package/dist/storybook/assets/{LinearProgress.stories-LZ0GZoxF.js → LinearProgress.stories-CDYmiiex.js} +1 -1
- package/dist/storybook/assets/{Pagination.stories-CbLaR3P9.js → Pagination.stories-LXB-x7YB.js} +1 -1
- package/dist/storybook/assets/{Popover.stories-JHrWqYZw.js → Popover.stories-DY1HesPJ.js} +1 -1
- package/dist/storybook/assets/{ReadyMixin-B1H2a9x8.js → ReadyMixin-DmOC67IJ.js} +1 -1
- package/dist/storybook/assets/{RovingTabindexMixin.stories-UMHpYG73.js → RovingTabindexMixin.stories-BWy0Rq8d.js} +1 -1
- package/dist/storybook/assets/{Rtc.stories-VQtNSlls.js → Rtc.stories-DrmdqqbI.js} +1 -1
- package/dist/storybook/assets/{ScrollShadow.stories-CYdi8Tgp.js → ScrollShadow.stories-DiKFPazh.js} +1 -1
- package/dist/storybook/assets/{Switch.stories-D8F2hZCf.js → Switch.stories-BgFnw8_z.js} +1 -1
- package/dist/storybook/assets/{Tab.stories-wgBP0lTj.js → Tab.stories-c2wLMooF.js} +1 -1
- package/dist/storybook/assets/{Tabs.stories-C00rr5sf.js → Tabs.stories-CjH8seNP.js} +1 -1
- package/dist/storybook/assets/{Throttle.stories-BhQEfJbS.js → Throttle.stories-CXysc_QE.js} +1 -1
- package/dist/storybook/assets/{Tooltip.stories-CGoZ5qTn.js → Tooltip.stories-6qzyByPm.js} +1 -1
- package/dist/storybook/assets/{Upload.stories-B3K-HAXw.js → Upload.stories-BLxykydQ.js} +1 -1
- package/dist/storybook/assets/{UploadItem.stories-71ArSoUh.js → UploadItem.stories-CcfcqdJW.js} +1 -1
- package/dist/storybook/assets/{Welcome.stories-CihlfFXS.js → Welcome.stories-CzYS_3fH.js} +1 -1
- package/dist/storybook/assets/{Widget.stories-1u4KbiJM.js → Widget.stories-Du7T4LAI.js} +1 -1
- package/dist/storybook/assets/{WithTooltip-65CFNBJE-B3Jitxw9.js → WithTooltip-65CFNBJE-D4LfXdYt.js} +1 -1
- package/dist/storybook/assets/{blocks-C1HaXuQB.js → blocks-DR3fGePu.js} +5 -5
- package/dist/storybook/assets/{formatter-EIJCOSYU-Dy9Lt9fs.js → formatter-EIJCOSYU-Cf01216O.js} +1 -1
- package/dist/storybook/assets/if-defined-DaMmbcIU.js +1 -0
- package/dist/storybook/assets/{iframe-Dx6IxWXF.js → iframe-CQArUhO8.js} +4 -4
- package/dist/storybook/assets/{index-OrjedSVh.js → index-B1uI_67G.js} +1 -1
- package/dist/storybook/assets/{onFind-YTqjw6W0.js → onFind-BpFkN2Rh.js} +1 -1
- package/dist/storybook/assets/{onFind.stories-DEvwTrmx.js → onFind.stories-Cxdeg69X.js} +1 -1
- package/dist/storybook/assets/{onRemove.stories-D5mO-Lin.js → onRemove.stories-BHEWpNrE.js} +1 -1
- package/dist/storybook/assets/{onVisible.stories-C3Rcz0Eb.js → onVisible.stories-DFJ3S_ZS.js} +1 -1
- package/dist/storybook/assets/{style-map-CiMHry7H.js → style-map-DJ83UC3V.js} +1 -1
- package/dist/storybook/assets/{syntaxhighlighter-ED5Y7EFY-DIZnuhb2.js → syntaxhighlighter-ED5Y7EFY-zYN83mxK.js} +1 -1
- package/dist/storybook/iframe.html +1 -1
- package/dist/storybook/project.json +1 -1
- package/package.json +16 -2
- package/dist/storybook/assets/if-defined-CA2KmTqA.js +0 -1
- package/src/legacy/tool-ui/src/main/resources/settings.properties +0 -1
- package/src/legacy/tool-ui/src/main/webapp/WEB-INF/web.xml +0 -81
- package/src/legacy/tool-ui/src/main/webapp/script/bsp-uploader.js +0 -170
- package/src/legacy/tool-ui/src/main/webapp/script/bsp-utils.js +0 -393
- package/src/legacy/tool-ui/src/main/webapp/script/content/layout-element.js +0 -141
- package/src/legacy/tool-ui/src/main/webapp/script/input/query.js +0 -78
- package/src/legacy/tool-ui/src/main/webapp/script/input/workflow.js +0 -718
- package/src/legacy/tool-ui/src/main/webapp/script/jquery.extra.js +0 -633
- package/src/legacy/tool-ui/src/main/webapp/script/v3/Dropbox.js +0 -18
- package/src/legacy/tool-ui/src/main/webapp/script/v3/EditFieldUpdate.js +0 -406
- package/src/legacy/tool-ui/src/main/webapp/script/v3/EditFieldUpdateCache.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/script/v3/Notification.js +0 -151
- package/src/legacy/tool-ui/src/main/webapp/script/v3/content/edit.js +0 -194
- package/src/legacy/tool-ui/src/main/webapp/script/v3/content/state.js +0 -785
- package/src/legacy/tool-ui/src/main/webapp/script/v3/csrf.js +0 -35
- package/src/legacy/tool-ui/src/main/webapp/script/v3/dashboard.js +0 -65
- package/src/legacy/tool-ui/src/main/webapp/script/v3/input/dataTransfer.js +0 -129
- package/src/legacy/tool-ui/src/main/webapp/script/v3/input/file.js +0 -433
- package/src/legacy/tool-ui/src/main/webapp/script/v3/input/object.js +0 -743
- package/src/legacy/tool-ui/src/main/webapp/script/v3/input/read-only.js +0 -17
- package/src/legacy/tool-ui/src/main/webapp/script/v3/jquery.frame.js +0 -478
- package/src/legacy/tool-ui/src/main/webapp/script/v3/jquery.repeatable.js +0 -2406
- package/src/legacy/tool-ui/src/main/webapp/script/v3/plugin/popup.d.ts +0 -2
- package/src/legacy/tool-ui/src/main/webapp/script/v3/plugin/popup.js +0 -446
- package/src/legacy/tool-ui/src/main/webapp/script/v3/search-filters.js +0 -62
- package/src/legacy/tool-ui/src/main/webapp/script/v3/search.js +0 -53
- package/src/legacy/tool-ui/src/main/webapp/script/v3.js +0 -1049
- package/src/legacy/tool-ui/src/main/webapp/v4/Admin.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/AutoExpand.js +0 -84
- package/src/legacy/tool-ui/src/main/webapp/v4/AutoSubmit.js +0 -68
- package/src/legacy/tool-ui/src/main/webapp/v4/Bridge.js +0 -536
- package/src/legacy/tool-ui/src/main/webapp/v4/CheckboxInput.js +0 -22
- package/src/legacy/tool-ui/src/main/webapp/v4/ColorInput.js +0 -5
- package/src/legacy/tool-ui/src/main/webapp/v4/ColorInputSpectrum.js +0 -107
- package/src/legacy/tool-ui/src/main/webapp/v4/ComboInput.js +0 -1491
- package/src/legacy/tool-ui/src/main/webapp/v4/CommunityWidget.js +0 -29
- package/src/legacy/tool-ui/src/main/webapp/v4/ContentEdit.js +0 -2427
- package/src/legacy/tool-ui/src/main/webapp/v4/ContentLock.js +0 -470
- package/src/legacy/tool-ui/src/main/webapp/v4/ContentReporting.js +0 -32
- package/src/legacy/tool-ui/src/main/webapp/v4/DataTable.js +0 -31
- package/src/legacy/tool-ui/src/main/webapp/v4/DateStringField.js +0 -485
- package/src/legacy/tool-ui/src/main/webapp/v4/Entry.js +0 -264
- package/src/legacy/tool-ui/src/main/webapp/v4/ExternalItemAuth.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/Form.js +0 -31
- package/src/legacy/tool-ui/src/main/webapp/v4/Hierarchy.js +0 -100
- package/src/legacy/tool-ui/src/main/webapp/v4/Icon.ts +0 -49
- package/src/legacy/tool-ui/src/main/webapp/v4/ImageEditor.js +0 -2403
- package/src/legacy/tool-ui/src/main/webapp/v4/ImageEditorBundle.js +0 -5
- package/src/legacy/tool-ui/src/main/webapp/v4/LinkCarousel.js +0 -40
- package/src/legacy/tool-ui/src/main/webapp/v4/LinkList.js +0 -14
- package/src/legacy/tool-ui/src/main/webapp/v4/LinkTable.js +0 -123
- package/src/legacy/tool-ui/src/main/webapp/v4/Location.js +0 -19
- package/src/legacy/tool-ui/src/main/webapp/v4/LocationMap.js +0 -148
- package/src/legacy/tool-ui/src/main/webapp/v4/LookingGlass.js +0 -24
- package/src/legacy/tool-ui/src/main/webapp/v4/Message.js +0 -14
- package/src/legacy/tool-ui/src/main/webapp/v4/NumberBar.js +0 -32
- package/src/legacy/tool-ui/src/main/webapp/v4/Page.js +0 -890
- package/src/legacy/tool-ui/src/main/webapp/v4/Preview.js +0 -758
- package/src/legacy/tool-ui/src/main/webapp/v4/PreviewEditor.js +0 -86
- package/src/legacy/tool-ui/src/main/webapp/v4/PreviewOverlay.js +0 -1005
- package/src/legacy/tool-ui/src/main/webapp/v4/PubSub.js +0 -47
- package/src/legacy/tool-ui/src/main/webapp/v4/QueryField.js +0 -211
- package/src/legacy/tool-ui/src/main/webapp/v4/RegionMap.js +0 -215
- package/src/legacy/tool-ui/src/main/webapp/v4/RepeatableContentInputGroup.js +0 -160
- package/src/legacy/tool-ui/src/main/webapp/v4/RichTextEditor.js +0 -154
- package/src/legacy/tool-ui/src/main/webapp/v4/SearchFields.js +0 -281
- package/src/legacy/tool-ui/src/main/webapp/v4/SearchResult.js +0 -255
- package/src/legacy/tool-ui/src/main/webapp/v4/SharePreview.js +0 -56
- package/src/legacy/tool-ui/src/main/webapp/v4/Sortable.js +0 -874
- package/src/legacy/tool-ui/src/main/webapp/v4/StyleEmbeddedContent.js +0 -100
- package/src/legacy/tool-ui/src/main/webapp/v4/StyleguidePresets.js +0 -357
- package/src/legacy/tool-ui/src/main/webapp/v4/TabContainer.js +0 -360
- package/src/legacy/tool-ui/src/main/webapp/v4/Taxonomy.js +0 -27
- package/src/legacy/tool-ui/src/main/webapp/v4/ThemeBundleEditor.js +0 -224
- package/src/legacy/tool-ui/src/main/webapp/v4/TimedContent.js +0 -147
- package/src/legacy/tool-ui/src/main/webapp/v4/TimedContentBundle.js +0 -8
- package/src/legacy/tool-ui/src/main/webapp/v4/VideoEditor.js +0 -2417
- package/src/legacy/tool-ui/src/main/webapp/v4/VideoEditorBundle.js +0 -8
- package/src/legacy/tool-ui/src/main/webapp/v4/ViewMirror.js +0 -52
- package/src/legacy/tool-ui/src/main/webapp/v4/ViewPreview.d.ts +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/ViewPreview.js +0 -177
- package/src/legacy/tool-ui/src/main/webapp/v4/Widget.js +0 -90
- package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/fileMock.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/styleMock.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/textArea.mock.js +0 -20
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/globals.js +0 -770
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/ProseMirror.test.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/index.html +0 -54
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/comment_manager/CommentManager.test.js +0 -29
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/comment_manager/index.html +0 -35
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/custom_keyboard/CustomKeyboard.js +0 -42
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/custom_keyboard/index.html +0 -37
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/EnhancementManager.test.js +0 -288
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/block.html +0 -38
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/inline.html +0 -38
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/no-popups.html +0 -38
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/list_manager/ListManager.js +0 -257
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/list_manager/index.html +0 -38
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/hierarchal.html +0 -33
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/index.html +0 -33
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/menubar.test.js +0 -195
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/small.html +0 -34
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/tags.html +0 -34
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/PlaceholderManager.test.js +0 -134
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/has-editable-placeholder.html +0 -32
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/has-text.html +0 -34
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/index.html +0 -31
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/table_manager/TableManager.test.js +0 -63
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/table_manager/existing.html +0 -48
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/TrackManager.test.js +0 -291
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/existing.html +0 -39
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/insert.html +0 -37
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/Sortable.test.js +0 -105
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/ProseMirror.test.js +0 -41
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/codemirror-shim.test.js +0 -72
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/collab_manager/CollabManager.test.js +0 -46
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/enhancement_manager/EnhancementManager.test.js +0 -84
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/list_manager/ListManager.test.js +0 -54
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/menubar/menubar.test.js +0 -183
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/spellcheck/SpellCheck.test.js +0 -45
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/settings/BSSerializer.test.js +0 -346
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/settings/menuItemsBuilder.test.js +0 -226
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/utilities.test.js +0 -118
- package/src/legacy/tool-ui/src/main/webapp/v4/appetizeio/Appetizeio.js +0 -5
- package/src/legacy/tool-ui/src/main/webapp/v4/appetizeio/AppetizeioEmbedded.js +0 -113
- package/src/legacy/tool-ui/src/main/webapp/v4/compat/Fetch.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/compat/jquery.js +0 -32
- package/src/legacy/tool-ui/src/main/webapp/v4/compat/requirejs.js +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/Tether.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/TetherLayout.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/closest.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/create.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/find.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/findAll.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifClick.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifMatches.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifUnmodified.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/index.js +0 -5
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertBefore.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertFirst.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertLast.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onFind.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onFindOnce.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onRTEReady.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onRemove.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onVisible.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/previousUntil.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/resolveIconCompat.js +0 -40
- package/src/legacy/tool-ui/src/main/webapp/v4/rtc/Socket.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/rtc/index.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/ProseMirror.js +0 -909
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/README.md +0 -68
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/codemirror-shim.d.ts +0 -8
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/codemirror-shim.js +0 -274
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/collab-workflow.jpeg +0 -0
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/interchangeable.ts +0 -250
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/mention.js +0 -90
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/PluginProvider.js +0 -124
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/README.md +0 -46
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_inline_manager/AIInlineManager.ts +0 -124
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_inline_manager/views/AIInlineView.ts +0 -1019
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_manager/AiManager.ts +0 -199
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/collab_manager/CollabManager.js +0 -339
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/collab_manager/views/AvatarView.js +0 -96
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/comment_manager/CommentManager.js +0 -348
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/custom_keyboard/CustomKeyboard.js +0 -110
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/custom_keyboard/README.md +0 -29
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/EnhancementManager.js +0 -428
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/README.md +0 -63
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/commands.js +0 -690
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/constants.js +0 -12
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/enhancement-creation.jpeg +0 -0
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/index.js +0 -15
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/rte-flow.jpeg +0 -0
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/ActionButtonView.js +0 -86
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/BlockSubmenuView.js +0 -60
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/EnhancementView.js +0 -208
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/PreviewView.js +0 -102
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/SubmenuView.js +0 -365
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/find_replace_manager/FindReplaceManager.js +0 -239
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/find_replace_manager/views/FindView.js +0 -604
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/FullscreenManager.js +0 -57
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/README.md +0 -26
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/commands.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/index.js +0 -4
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/views/FullscreenView.js +0 -474
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/html_editor_manager/htmlEditorManager.js +0 -66
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/html_editor_manager/views/HtmlEditorView.js +0 -97
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/ListManager.js +0 -342
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/README.md +0 -50
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/commands.js +0 -207
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/constants.js +0 -26
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/index.js +0 -4
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/Menubar.js +0 -485
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/README.md +0 -40
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/views/MenuView.js +0 -842
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/paste_manager/PasteManager.js +0 -368
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/placeholder_manager/PlaceHolderManager.js +0 -128
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/raw_text_manager/README.md +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/raw_text_manager/RawTextManager.js +0 -96
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/index.js +0 -3
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/spellcheck-plugin.js +0 -280
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/spellcheck-service.js +0 -94
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/TableManager.js +0 -57
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/commands.js +0 -97
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/views/TableSizerView.js +0 -88
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/views/TableView.js +0 -613
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/track_manager/README.md +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/track_manager/TrackManager.js +0 -905
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/BSSerializer.js +0 -819
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/README.md +0 -80
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/commands.js +0 -98
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/constants.d.ts +0 -84
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/constants.js +0 -87
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/index.js +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/keymapBuilder.js +0 -223
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/menuItemsBuilder.js +0 -559
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/schemaBuilder.js +0 -1281
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/utilities.d.ts +0 -4
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/utilities.js +0 -359
- package/src/legacy/tool-ui/src/main/webapp/v4/theme/ColorRotator.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/debounce.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/getComponentKey.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/noise.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/repaint.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/storage.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/throttle.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssignmentContent.js +0 -33
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssignmentDeskDashboard.js +0 -217
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssociatedContentWidget.js +0 -7
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/BulkUpload.js +0 -19
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/Calendar.js +0 -7
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/ClosableWindow.js +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/PitchAssignments.js +0 -25
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/PitchContent.js +0 -33
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/Revisions.js +0 -61
|
@@ -1,2406 +0,0 @@
|
|
|
1
|
-
/***
|
|
2
|
-
|
|
3
|
-
Repeatable Inputs
|
|
4
|
-
-----------------
|
|
5
|
-
|
|
6
|
-
For the purposes of this code, there are three types of repeatables:
|
|
7
|
-
|
|
8
|
-
* object = an input that can be repeated (but not collapsed/uncollapsed)
|
|
9
|
-
|
|
10
|
-
* form = multiple inputs can be repeated (and collapsed/uncollapsed)
|
|
11
|
-
|
|
12
|
-
* preview = a slideshow, which will have grid view and gallery view
|
|
13
|
-
|
|
14
|
-
* single = A single input is used instead of an add more button.
|
|
15
|
-
This is used only when the addButtonText option is set to an empty string
|
|
16
|
-
and there is a single template and a single input
|
|
17
|
-
If user presses enter on the input, then a new input is created so the user can add more keywords.
|
|
18
|
-
|
|
19
|
-
The types have the following things in common:
|
|
20
|
-
|
|
21
|
-
* They can have a template (or multiple templates) to add new items.
|
|
22
|
-
An "add item" button is included for each template.
|
|
23
|
-
|
|
24
|
-
* A remove button is added next to each item item (or in the case of single input,
|
|
25
|
-
the remove button might be styled to overlay the input).
|
|
26
|
-
|
|
27
|
-
How removing / restoring works
|
|
28
|
-
------------------------------
|
|
29
|
-
|
|
30
|
-
When user clicks the "remove" button, the item is not actually removed from the page,
|
|
31
|
-
instead a "toBeRemoved" class is added so the item can be styled to indicate it will be removed,
|
|
32
|
-
the inputs are all set to be disabled so they will not be sent to the backend, and the remove
|
|
33
|
-
button is changed to a restore button.
|
|
34
|
-
|
|
35
|
-
When user clicks the "restore" button, the "toBeRemoved" class is removed, the inputs
|
|
36
|
-
are no longer disabled, and the restore button is changed to a remove button.
|
|
37
|
-
|
|
38
|
-
HTML for repeatables
|
|
39
|
-
--------------------
|
|
40
|
-
|
|
41
|
-
The HTML within the repeatable element must conform to these standards:
|
|
42
|
-
|
|
43
|
-
* It must contain a list (UL or OL) where each item within the list is
|
|
44
|
-
a repeatable input
|
|
45
|
-
|
|
46
|
-
* Within the list there should be a template. The template can be one of the list items
|
|
47
|
-
with classname li.template or a script element with type="text/template".
|
|
48
|
-
|
|
49
|
-
Acceptable variation for previewable items
|
|
50
|
-
-------------------------------------------
|
|
51
|
-
* The first visible `editable-view` <div> under view switcher will decide the default editing view for previewable items;
|
|
52
|
-
* By default, new items are inserted to the end of list;
|
|
53
|
-
set global variable 'repeatableInsertFront' to be true to let new *previewable* items inserted to the beginning of the list.
|
|
54
|
-
|
|
55
|
-
==================================================
|
|
56
|
-
***/
|
|
57
|
-
|
|
58
|
-
import create from '../../v4/dom/create'
|
|
59
|
-
import ColorRotator from '../../v4/theme/ColorRotator'
|
|
60
|
-
import scrollIntoView from 'scroll-into-view'
|
|
61
|
-
import { tabbable } from 'tabbable'
|
|
62
|
-
;(function ($, win, undef) {
|
|
63
|
-
var $win = $(win)
|
|
64
|
-
const tooltips = window.BRIGHTSPOT?.ui.tooltips
|
|
65
|
-
|
|
66
|
-
// Counter to use to make sure the browser doesn't cache ajax requests
|
|
67
|
-
var cacheNonce = 0
|
|
68
|
-
|
|
69
|
-
// Defaults to use for repeatables
|
|
70
|
-
var repeatableDefaults = {
|
|
71
|
-
addButtonText: 'Add',
|
|
72
|
-
removeButtonText: 'Remove',
|
|
73
|
-
restoreButtonText: 'Restore',
|
|
74
|
-
sortableOptions: {
|
|
75
|
-
delay: 300,
|
|
76
|
-
},
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Create the jquery plugin .repeatable() (using plugin2)
|
|
80
|
-
$.plugin2('repeatable', {
|
|
81
|
-
/**
|
|
82
|
-
* Default options used by plugin2
|
|
83
|
-
*/
|
|
84
|
-
_defaultOptions: repeatableDefaults,
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Function called by plugin2 when a new element is added to the page.
|
|
88
|
-
*
|
|
89
|
-
* ??? - it appears that a second parameter "options" is supported here,
|
|
90
|
-
* but we don't seem to be using that
|
|
91
|
-
*
|
|
92
|
-
* @param {Element} container
|
|
93
|
-
* The repeatable element that was added to the page.
|
|
94
|
-
*/
|
|
95
|
-
_create: function (container) {
|
|
96
|
-
var plugin = this
|
|
97
|
-
var $container = $(container)
|
|
98
|
-
var options = plugin.option()
|
|
99
|
-
var repeatable
|
|
100
|
-
|
|
101
|
-
// Create a copy of the repeatableUtility object
|
|
102
|
-
// This uses prototypal inheritance so we're not actually copying the entire object
|
|
103
|
-
// It allows each repeatable instance to have its own object that saves state
|
|
104
|
-
repeatable = Object.create(repeatableUtility)
|
|
105
|
-
|
|
106
|
-
// Initialize the repeatable utility to get things started
|
|
107
|
-
repeatable.init($container, options)
|
|
108
|
-
$container.data('repeatable', repeatable)
|
|
109
|
-
|
|
110
|
-
// ARIA support
|
|
111
|
-
// The content selector element comes from object.js so wait for its insertion and
|
|
112
|
-
// movement of items in the list.
|
|
113
|
-
const list = container.querySelector(':scope > ol, ul')
|
|
114
|
-
const label =
|
|
115
|
-
container.closest('.CIG-row')?.querySelector('.CIG-label label')
|
|
116
|
-
?.textContent || ''
|
|
117
|
-
|
|
118
|
-
if (list) {
|
|
119
|
-
const observer = new MutationObserver((records) => {
|
|
120
|
-
records.forEach((record) => {
|
|
121
|
-
if (
|
|
122
|
-
Array.from(record.addedNodes).some((n) => n.nodeName === 'A') ||
|
|
123
|
-
record.target.nodeName === 'OL'
|
|
124
|
-
) {
|
|
125
|
-
list.querySelectorAll(':scope > li').forEach((item, i) => {
|
|
126
|
-
const index = ++i
|
|
127
|
-
item.querySelectorAll(':scope > a, select').forEach((child) => {
|
|
128
|
-
const rowFieldName =
|
|
129
|
-
child.closest('.CIG-row')?.dataset.fieldName
|
|
130
|
-
const rowDisplayName =
|
|
131
|
-
child.closest('.CIG-row')?.dataset.fieldDisplayName
|
|
132
|
-
const childTitle = child.title
|
|
133
|
-
|
|
134
|
-
const ariaLabel = childTitle
|
|
135
|
-
? `${childTitle} `
|
|
136
|
-
: `${
|
|
137
|
-
rowDisplayName
|
|
138
|
-
? rowDisplayName
|
|
139
|
-
: rowFieldName
|
|
140
|
-
? rowFieldName
|
|
141
|
-
: label
|
|
142
|
-
} ${index}`
|
|
143
|
-
|
|
144
|
-
child.setAttribute('aria-label', ariaLabel)
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
})
|
|
149
|
-
})
|
|
150
|
-
observer.observe(container, {
|
|
151
|
-
childList: true,
|
|
152
|
-
subtree: true,
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
if (list.classList?.contains('RTI-list')) {
|
|
156
|
-
list.querySelectorAll(':scope > li').forEach((item, i) => {
|
|
157
|
-
const index = ++i
|
|
158
|
-
item.querySelectorAll(':scope > a, input').forEach((child) => {
|
|
159
|
-
const rowFieldName = child.closest('.CIG-row')?.dataset.fieldName
|
|
160
|
-
const rowDisplayName =
|
|
161
|
-
child.closest('.CIG-row')?.dataset.fieldDisplayName
|
|
162
|
-
const childTitle = child.title
|
|
163
|
-
|
|
164
|
-
const ariaLabel = childTitle
|
|
165
|
-
? `${childTitle} `
|
|
166
|
-
: `${
|
|
167
|
-
rowDisplayName
|
|
168
|
-
? rowDisplayName
|
|
169
|
-
: rowFieldName
|
|
170
|
-
? rowFieldName
|
|
171
|
-
: label
|
|
172
|
-
} ${index}`
|
|
173
|
-
|
|
174
|
-
child.setAttribute('aria-label', ariaLabel)
|
|
175
|
-
})
|
|
176
|
-
})
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Set starting point for additions.
|
|
181
|
-
if (
|
|
182
|
-
container.previousElementSibling?.nodeName === 'OL' ||
|
|
183
|
-
container.previousElementSibling?.nodeName === 'UL'
|
|
184
|
-
) {
|
|
185
|
-
repeatable.ariaIndex = container.previousElementSibling.children.length
|
|
186
|
-
}
|
|
187
|
-
},
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Function to add a new item after bulk file upload.
|
|
191
|
-
* This is called by by some code delivered by the back-end.
|
|
192
|
-
*
|
|
193
|
-
* @param {Function} callback
|
|
194
|
-
* Function to call after the item has been added.
|
|
195
|
-
* Refer to repeatableUtility.addItem
|
|
196
|
-
*/
|
|
197
|
-
add: function (callback, noFocus) {
|
|
198
|
-
var plugin = this
|
|
199
|
-
|
|
200
|
-
// In this case, the plugin is called on the add button
|
|
201
|
-
var $caller = plugin.$caller
|
|
202
|
-
|
|
203
|
-
// Not a great way to do this, but leaving this for now.
|
|
204
|
-
// The callback function modifies the template to insert actual values,
|
|
205
|
-
// then triggers a change event
|
|
206
|
-
$caller.closest('.addButton').trigger('click', [callback, noFocus])
|
|
207
|
-
|
|
208
|
-
return $caller
|
|
209
|
-
},
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Object to initialize and control repeatable inputs.
|
|
214
|
-
*
|
|
215
|
-
* This object should not be used directly, instead create a new object for each
|
|
216
|
-
* repeatable using Object.create and prototypal inheritance.
|
|
217
|
-
* After creating the new object, call the .init() function.
|
|
218
|
-
*
|
|
219
|
-
* @example
|
|
220
|
-
* myRepeatable = Object.create(repeatableUtility);
|
|
221
|
-
* myRepeatable.init(element, options);
|
|
222
|
-
*/
|
|
223
|
-
var repeatableUtility = {
|
|
224
|
-
/**
|
|
225
|
-
* Default options
|
|
226
|
-
*/
|
|
227
|
-
defaults: repeatableDefaults,
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Regex to check if data-preview-field is a method.
|
|
231
|
-
*/
|
|
232
|
-
methodRegex: '^get[A-Z]+|^is[A-Z]+|^has[A-Z]+',
|
|
233
|
-
|
|
234
|
-
ariaIndex: 0,
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Initialize the object and set up the user interface.
|
|
238
|
-
*
|
|
239
|
-
* @param {Element|jQuery object|jQuery selector} element
|
|
240
|
-
* The element that contains the repeatable HTML.
|
|
241
|
-
*
|
|
242
|
-
* @param {Object} [options]
|
|
243
|
-
*/
|
|
244
|
-
init: function (element, options) {
|
|
245
|
-
var self = this
|
|
246
|
-
self.cr = new ColorRotator()
|
|
247
|
-
|
|
248
|
-
// Save the element for later use
|
|
249
|
-
self.$element = $(element).first()
|
|
250
|
-
|
|
251
|
-
// Set up a place to save other dom elements for later use
|
|
252
|
-
self.dom = {}
|
|
253
|
-
|
|
254
|
-
// Override the default options
|
|
255
|
-
self.options = $.extend(true, {}, self.defaults, options)
|
|
256
|
-
|
|
257
|
-
self.initializingCount = 0
|
|
258
|
-
|
|
259
|
-
// Get the various things we will need from the DOM
|
|
260
|
-
self.initDOM()
|
|
261
|
-
|
|
262
|
-
// Set up the event-input-disable functionality
|
|
263
|
-
self.initInputDisable()
|
|
264
|
-
|
|
265
|
-
// Determine which type of repeatable we are dealing with
|
|
266
|
-
self.initMode()
|
|
267
|
-
|
|
268
|
-
// Initialize collection item weights if needed
|
|
269
|
-
self.modeWeightedInit()
|
|
270
|
-
|
|
271
|
-
// For each item initialize it
|
|
272
|
-
var $items = self.dom.$list.find('> li')
|
|
273
|
-
|
|
274
|
-
$items.each(function () {
|
|
275
|
-
self.initItem(this)
|
|
276
|
-
|
|
277
|
-
if (self.modeIsPreview()) {
|
|
278
|
-
self.itemLoad(this).then(() => {
|
|
279
|
-
self.initPreview(this)
|
|
280
|
-
})
|
|
281
|
-
}
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
if ($items.length === 0 && self.dom.$viewSwitcher) {
|
|
285
|
-
self.dom.$viewSwitcher.hide()
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Create the "Add Item" button(s)
|
|
289
|
-
self.initAddButton()
|
|
290
|
-
self.initViewSwitcher()
|
|
291
|
-
|
|
292
|
-
self.isInitialized = true
|
|
293
|
-
},
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Get various things we will need from the DOM and save for later.
|
|
297
|
-
*/
|
|
298
|
-
initDOM: function () {
|
|
299
|
-
var self = this
|
|
300
|
-
var $list
|
|
301
|
-
var $templates = $()
|
|
302
|
-
|
|
303
|
-
// Find the list of inputs (must be in a UL or OL)
|
|
304
|
-
$list = self.$element.find('> ul, > ol').first()
|
|
305
|
-
self.dom.$list = $list // save for later use
|
|
306
|
-
|
|
307
|
-
// Templates can be in an LI or a SCRIPT element
|
|
308
|
-
$list
|
|
309
|
-
.find('> li.template, > template, > script[type="text/template"]')
|
|
310
|
-
.each(function () {
|
|
311
|
-
var $template = $(this)
|
|
312
|
-
|
|
313
|
-
if ($template.is('li.template')) {
|
|
314
|
-
$templates = $templates.add($template)
|
|
315
|
-
} else if ($template.is('template')) {
|
|
316
|
-
$templates = $templates.add($template[0].content.cloneNode(true))
|
|
317
|
-
} else {
|
|
318
|
-
$templates = $templates.add($($template.text()))
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// Remove the template from the page
|
|
322
|
-
$template.remove()
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
// Save form for later use
|
|
326
|
-
self.dom.$form = self.dom.$list.closest('form')
|
|
327
|
-
|
|
328
|
-
// Save templates for later use
|
|
329
|
-
self.dom.$templates = $templates
|
|
330
|
-
},
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Set up the event-input-disable functionality.
|
|
334
|
-
* ??? need more info on how this works
|
|
335
|
-
*/
|
|
336
|
-
initInputDisable: function () {
|
|
337
|
-
var self = this
|
|
338
|
-
|
|
339
|
-
// Mark the input as something that can be locked or disabled
|
|
340
|
-
self.$element.addClass('event-input-disable')
|
|
341
|
-
|
|
342
|
-
// If the "input-disable" event is triggered, then add or remove a class
|
|
343
|
-
self.$element.bind('input-disable', function (event, disable) {
|
|
344
|
-
$(event.target)
|
|
345
|
-
.closest('.inputContainer')
|
|
346
|
-
.toggleClass('state-disabled', disable)
|
|
347
|
-
})
|
|
348
|
-
},
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Determine which type of repeatable we are dealing with:
|
|
352
|
-
* Sets the "mode" property to one of the following:
|
|
353
|
-
* form, single, preview
|
|
354
|
-
*
|
|
355
|
-
* Note that initDOM() must be called before this is called.
|
|
356
|
-
*
|
|
357
|
-
* Also see the following functions:
|
|
358
|
-
* modeIsPreview(), modeIsSingle(), ...
|
|
359
|
-
*/
|
|
360
|
-
initMode: function () {
|
|
361
|
-
var self = this
|
|
362
|
-
var $templateInputs
|
|
363
|
-
|
|
364
|
-
self.mode = 'form'
|
|
365
|
-
|
|
366
|
-
// Set to object mode if we are in a repeatableObjectId
|
|
367
|
-
if (
|
|
368
|
-
self.$element.hasClass('repeatableObjectId') ||
|
|
369
|
-
self.$element.hasClass('repeatableDropdown')
|
|
370
|
-
) {
|
|
371
|
-
self.mode = 'object'
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// Set to single input mode if there is no add button text,
|
|
375
|
-
// and if there is a single template with a single input
|
|
376
|
-
$templateInputs = self.dom.$templates
|
|
377
|
-
.find(':input')
|
|
378
|
-
.not(':input[name$=".toggle"]')
|
|
379
|
-
if (
|
|
380
|
-
!self.options.addButtonText &&
|
|
381
|
-
self.dom.$templates.length === 1 &&
|
|
382
|
-
$templateInputs.length === 1
|
|
383
|
-
) {
|
|
384
|
-
self.mode = 'single'
|
|
385
|
-
return
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// Set to preview mode
|
|
389
|
-
if (self.$element.hasClass('repeatableForm-previewable')) {
|
|
390
|
-
self.mode = 'preview'
|
|
391
|
-
self.isError = self.$element[0].querySelector('.message-error')
|
|
392
|
-
if (!window.GALLERY_LIST_VIEW_UI && !self.isError) {
|
|
393
|
-
self.$element.addClass('is-gridView')
|
|
394
|
-
}
|
|
395
|
-
return
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
if (self.$element.hasClass('repeatableForm-weighted')) {
|
|
399
|
-
self.mode = 'weighted'
|
|
400
|
-
}
|
|
401
|
-
},
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* Initialize the "Add Item" controls.
|
|
405
|
-
*
|
|
406
|
-
* There is a single container for the add item controls,
|
|
407
|
-
* and within it can be mutiple add buttons (one for each template).
|
|
408
|
-
*
|
|
409
|
-
* The text of the add button is defined by a data attribute on the template
|
|
410
|
-
* and the addButtonText options.
|
|
411
|
-
*/
|
|
412
|
-
initAddButton: function () {
|
|
413
|
-
var self = this
|
|
414
|
-
var $addButtonContainer
|
|
415
|
-
var $addButtonSelect
|
|
416
|
-
var tooManyButtons
|
|
417
|
-
|
|
418
|
-
// Create the Add Item container
|
|
419
|
-
// -- Initialize single input mode if necessary
|
|
420
|
-
// -- Create an add button for each template
|
|
421
|
-
// -- Set up click event on the add button
|
|
422
|
-
|
|
423
|
-
// Create a container where all the "Add Item" buttons will be displayed
|
|
424
|
-
// First check to see if there is already a div to place them,
|
|
425
|
-
// if not create a new div at the bottom.
|
|
426
|
-
$addButtonContainer = self.$element.find('.addButtonContainer')
|
|
427
|
-
if (!$addButtonContainer.length) {
|
|
428
|
-
$addButtonContainer = $('<div/>', {
|
|
429
|
-
class: 'addButtonContainer',
|
|
430
|
-
}).appendTo(self.$element)
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// Save the add button container for later use
|
|
434
|
-
// (in single mode we will add more to it)
|
|
435
|
-
self.dom.$addButtonContainer = $addButtonContainer
|
|
436
|
-
|
|
437
|
-
// If we are in single input mode then we'll do some extra stuff
|
|
438
|
-
self.modeSingleInitAddButton()
|
|
439
|
-
|
|
440
|
-
// Create an "Add Item" link for each template we found,
|
|
441
|
-
// or if there are too many links create a dropdown
|
|
442
|
-
|
|
443
|
-
tooManyButtons = Boolean(self.dom.$templates.length >= 2)
|
|
444
|
-
|
|
445
|
-
if (tooManyButtons) {
|
|
446
|
-
// Create a dropdown to list the available add buttons
|
|
447
|
-
var $addButtonSelectContainer = $('<span/>', {
|
|
448
|
-
class: 'addButtonSelectContainer',
|
|
449
|
-
}).appendTo($addButtonContainer)
|
|
450
|
-
|
|
451
|
-
$addButtonSelect = $('<select/>', {
|
|
452
|
-
class: 'addButtonSelect',
|
|
453
|
-
'aria-label': 'Type',
|
|
454
|
-
'data-searchable': true,
|
|
455
|
-
placeholder:
|
|
456
|
-
self.dom.$templates.first().attr('data-add') || tooltips.add,
|
|
457
|
-
on: {
|
|
458
|
-
change: function () {
|
|
459
|
-
// Get the selected option
|
|
460
|
-
var $selected = $addButtonSelect.find(':selected')
|
|
461
|
-
|
|
462
|
-
// Get a link to the add button for that option, and click it.
|
|
463
|
-
// The "addButton" data is saved on the OPTION element.
|
|
464
|
-
var $button = $selected.data('addButton')
|
|
465
|
-
if ($button) {
|
|
466
|
-
// Note: normally I wouldn't simulate a click on the button;
|
|
467
|
-
// however, there is other pre-existing code that requires that
|
|
468
|
-
// add button to be there, so we will continue creating the button
|
|
469
|
-
// and hide it if we have too many buttons to show.
|
|
470
|
-
$button.click()
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
$addButtonSelect.val('')
|
|
474
|
-
$addButtonSelectContainer
|
|
475
|
-
.find('.dropDown-label')
|
|
476
|
-
.trigger('dropDown-update')
|
|
477
|
-
$addButtonSelect.blur()
|
|
478
|
-
},
|
|
479
|
-
},
|
|
480
|
-
}).appendTo($addButtonSelectContainer)
|
|
481
|
-
|
|
482
|
-
$addButtonSelect.append(
|
|
483
|
-
$('<option/>', {
|
|
484
|
-
value: '',
|
|
485
|
-
}),
|
|
486
|
-
)
|
|
487
|
-
|
|
488
|
-
self.dom.$list[0]
|
|
489
|
-
.getAttributeNames()
|
|
490
|
-
.filter((name) => name.startsWith('aria-'))
|
|
491
|
-
.forEach((name) => {
|
|
492
|
-
$addButtonSelect.attr(name, self.dom.$list[0].getAttribute(name))
|
|
493
|
-
})
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
self.dom.$templates.each(function () {
|
|
497
|
-
var $template = $(this)
|
|
498
|
-
var itemType =
|
|
499
|
-
$template.attr('data-type') ||
|
|
500
|
-
$template.attr('data-type-label') ||
|
|
501
|
-
$template.attr('data-item-fallback') ||
|
|
502
|
-
''
|
|
503
|
-
var ariaLabel =
|
|
504
|
-
window.BRIGHTSPOT?.ui.tooltips.add +
|
|
505
|
-
' ' +
|
|
506
|
-
self.dom.$addButtonContainer
|
|
507
|
-
.closest('.CIG-row')
|
|
508
|
-
.find('label')
|
|
509
|
-
.text() || ''
|
|
510
|
-
var $addButton
|
|
511
|
-
var addButtonText
|
|
512
|
-
|
|
513
|
-
// Check if itemType should be URL
|
|
514
|
-
if ($template[0]?.firstChild?.classList?.contains('widget-urlsItem')) {
|
|
515
|
-
itemType = $template[0]?.firstChild?.getAttribute('data-type')
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// Determine which text to use for the add button
|
|
519
|
-
addButtonText = itemType
|
|
520
|
-
if (self.options.addButtonText) {
|
|
521
|
-
addButtonText =
|
|
522
|
-
($template.attr('data-add') || tooltips.add) + ' ' + addButtonText
|
|
523
|
-
if ($template.attr('data-type')) {
|
|
524
|
-
ariaLabel = addButtonText
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// Add an element for the "Add Button" control
|
|
529
|
-
$addButton = $('<a/>', {
|
|
530
|
-
class: 'addButton',
|
|
531
|
-
'aria-label': ariaLabel,
|
|
532
|
-
role: 'button',
|
|
533
|
-
href: '#',
|
|
534
|
-
text: addButtonText,
|
|
535
|
-
'data-sortable-item-type': $template.attr('data-sortable-item-type'),
|
|
536
|
-
|
|
537
|
-
// Save the template on the add button control so when user
|
|
538
|
-
// clicks it we will know which template to add
|
|
539
|
-
// 'data-addButtonTemplate': $template
|
|
540
|
-
})
|
|
541
|
-
.on('click keypress', function (event, customCallback, noFocus) {
|
|
542
|
-
if (event.type === 'keypress' && event.key !== 'Enter') {
|
|
543
|
-
return
|
|
544
|
-
}
|
|
545
|
-
++self.initializingCount
|
|
546
|
-
|
|
547
|
-
// The click event for the add button supports an
|
|
548
|
-
// optional callback function that will be called after
|
|
549
|
-
// the new item is added.
|
|
550
|
-
// Add the new item based on this template
|
|
551
|
-
self.addItem($template, customCallback, noFocus)
|
|
552
|
-
|
|
553
|
-
return false
|
|
554
|
-
})
|
|
555
|
-
.toggle(!tooManyButtons) // Hide button if there are too many buttons
|
|
556
|
-
.appendTo($addButtonContainer)
|
|
557
|
-
|
|
558
|
-
self.dom.$list[0]
|
|
559
|
-
.getAttributeNames()
|
|
560
|
-
.filter((name) => name.startsWith('aria-') && name !== 'aria-label')
|
|
561
|
-
.forEach((name) => {
|
|
562
|
-
$addButton.attr(name, self.dom.$list[0].getAttribute(name))
|
|
563
|
-
})
|
|
564
|
-
|
|
565
|
-
if (tooManyButtons) {
|
|
566
|
-
$('<option/>', {
|
|
567
|
-
value: itemType,
|
|
568
|
-
text: itemType,
|
|
569
|
-
data: {
|
|
570
|
-
// Save the add button in a data attribute,
|
|
571
|
-
// so later when user selects this item we know which
|
|
572
|
-
// add button should be clicked
|
|
573
|
-
addButton: $addButton,
|
|
574
|
-
},
|
|
575
|
-
}).appendTo($addButtonSelect)
|
|
576
|
-
}
|
|
577
|
-
})
|
|
578
|
-
},
|
|
579
|
-
|
|
580
|
-
/**
|
|
581
|
-
* Initialize an item. This should be called for each list item on the page,
|
|
582
|
-
* plus it should be called for any new item added to the page.
|
|
583
|
-
*
|
|
584
|
-
* @param {Element|jQuery object|jQuery selector} element
|
|
585
|
-
* The LI element that contains the item HTML.
|
|
586
|
-
*/
|
|
587
|
-
initItem: function (element) {
|
|
588
|
-
var self = this
|
|
589
|
-
var $item = $(element)
|
|
590
|
-
|
|
591
|
-
// Set form for dynamic previews if we need it by checking the first item init.
|
|
592
|
-
// This will delegate the preview to use the data-dynamic-preview
|
|
593
|
-
// attribute that is updated during a contentState ajax call.
|
|
594
|
-
if (
|
|
595
|
-
self.modeIsPreview() &&
|
|
596
|
-
$item.index() === 0 &&
|
|
597
|
-
!self.isDynamicPreview
|
|
598
|
-
) {
|
|
599
|
-
var previewField = $item.attr('data-preview-field')
|
|
600
|
-
if (previewField) {
|
|
601
|
-
var checkFields = previewField.split('/')
|
|
602
|
-
for (var i = 0; i < checkFields.length; i++) {
|
|
603
|
-
if (checkFields[i].match(self.methodRegex)) {
|
|
604
|
-
self.isDynamicPreview = true
|
|
605
|
-
break
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// Create item weight for the item if necessary,
|
|
612
|
-
// and set up other stuff for mode=weighted
|
|
613
|
-
self.modeWeightedInitItem($item)
|
|
614
|
-
|
|
615
|
-
// Create a the label for the item if necessary.
|
|
616
|
-
// The label acts as a toggle to show and hide the item,
|
|
617
|
-
// plus it can load the content of the item from a URL
|
|
618
|
-
self.initItemLabel($item)
|
|
619
|
-
|
|
620
|
-
// Collapse the item unless it has an error message within it
|
|
621
|
-
// Do not collapse "preview" or "object" mode
|
|
622
|
-
if (
|
|
623
|
-
$item.find('.message-error').length === 0 &&
|
|
624
|
-
$item.find('> .layouts').length === 0 &&
|
|
625
|
-
!$item.hasClass('expanded') &&
|
|
626
|
-
!self.modeIsObject()
|
|
627
|
-
) {
|
|
628
|
-
if (
|
|
629
|
-
!window.GALLERY_LIST_VIEW_UI &&
|
|
630
|
-
self.modeIsPreview() &&
|
|
631
|
-
!self.isError
|
|
632
|
-
) {
|
|
633
|
-
$item.addClass('is-gridItem')
|
|
634
|
-
}
|
|
635
|
-
self.itemCollapse($item)
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
// An input with ".toggle" in the name will be checked
|
|
639
|
-
// to tell the backend that it should be saved, but the checkbox will not actually
|
|
640
|
-
// be shown to the user, so we hid it here
|
|
641
|
-
$item.find(':input[name$=".toggle"]').hide()
|
|
642
|
-
|
|
643
|
-
// Create progress UI if necessary
|
|
644
|
-
self.initCollectionItemProgress($item)
|
|
645
|
-
|
|
646
|
-
// Create toggle UI if necessary
|
|
647
|
-
self.initCollectionItemToggle($item)
|
|
648
|
-
|
|
649
|
-
const $itemLiveRegion = $('<span/>', {
|
|
650
|
-
class: 'screen-reader-only',
|
|
651
|
-
'aria-live': 'polite',
|
|
652
|
-
})
|
|
653
|
-
$item.append($itemLiveRegion)
|
|
654
|
-
|
|
655
|
-
// Add the remove control to the item
|
|
656
|
-
self.initItemRemove($item)
|
|
657
|
-
},
|
|
658
|
-
|
|
659
|
-
initPreview: function (item) {
|
|
660
|
-
const previewField = item.dataset.previewField?.split('/')
|
|
661
|
-
|
|
662
|
-
if (previewField && previewField.length < 3) {
|
|
663
|
-
const field = item.querySelector(
|
|
664
|
-
`:scope > .objectInputs > .inputContainer[data-field="${previewField[0]}"]`,
|
|
665
|
-
)
|
|
666
|
-
|
|
667
|
-
if (field) {
|
|
668
|
-
field.classList.add('RCIG-previewField')
|
|
669
|
-
return
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
// If the preview is via methods on backend there won't be an associated HTML
|
|
674
|
-
// input so insert an Image for display whose click brings user to List view.
|
|
675
|
-
const $item = $(item)
|
|
676
|
-
const $objectInputs = $item.find('.objectInputs')
|
|
677
|
-
|
|
678
|
-
if ($objectInputs.length === 0) {
|
|
679
|
-
return
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
const self = this
|
|
683
|
-
const preview = create('img')
|
|
684
|
-
|
|
685
|
-
item.appendChild(
|
|
686
|
-
create(
|
|
687
|
-
'a',
|
|
688
|
-
{
|
|
689
|
-
className: 'RCIG-preview',
|
|
690
|
-
onclick: self.handleExpandClick.bind(self, $item),
|
|
691
|
-
},
|
|
692
|
-
preview,
|
|
693
|
-
),
|
|
694
|
-
)
|
|
695
|
-
|
|
696
|
-
const updatePreview = () => {
|
|
697
|
-
preview.src = item.dataset.preview || ''
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
updatePreview()
|
|
701
|
-
$item.on('change', updatePreview)
|
|
702
|
-
},
|
|
703
|
-
|
|
704
|
-
handleExpandClick: function ($item) {
|
|
705
|
-
let select = this.$element[0].querySelector(
|
|
706
|
-
'.repeatablePreviewControls select',
|
|
707
|
-
)
|
|
708
|
-
select.selectedIndex = 1
|
|
709
|
-
if (select.dispatchEvent(new Event('change'))) {
|
|
710
|
-
this.itemToggle($item)
|
|
711
|
-
$item[0].scrollIntoView()
|
|
712
|
-
}
|
|
713
|
-
},
|
|
714
|
-
|
|
715
|
-
/**
|
|
716
|
-
* Initialize the label for an item.
|
|
717
|
-
*
|
|
718
|
-
* @param {Element|jQuery object} element
|
|
719
|
-
* The item (LI element).
|
|
720
|
-
*/
|
|
721
|
-
initItemLabel: function (element) {
|
|
722
|
-
var self = this
|
|
723
|
-
var $item = $(element)
|
|
724
|
-
var type = $item.attr('data-type')
|
|
725
|
-
var label = $item.attr('data-label-html') || $item.attr('data-label')
|
|
726
|
-
var $label
|
|
727
|
-
var $existingLabel
|
|
728
|
-
var labelHtml
|
|
729
|
-
|
|
730
|
-
// Do not add a label if there is no data-type attribute
|
|
731
|
-
if (!type) {
|
|
732
|
-
return
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
// The text for the label will be the data type such as "Slideshow Slide"
|
|
736
|
-
// And if a data-label attribute was provided append it after a colon such as "Slideshow Slide: My Slide"
|
|
737
|
-
labelHtml = type
|
|
738
|
-
if (label) {
|
|
739
|
-
labelHtml += ': ' + label
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
$label = $('<div/>', {
|
|
743
|
-
class: 'repeatableLabel',
|
|
744
|
-
tabindex: '0',
|
|
745
|
-
html: labelHtml,
|
|
746
|
-
|
|
747
|
-
// Set up some parameters so the label text will dynamically update based on the input field
|
|
748
|
-
'data-object-id': $item
|
|
749
|
-
.find('> input[type="hidden"][name$=".id"]')
|
|
750
|
-
.val(),
|
|
751
|
-
})
|
|
752
|
-
.on('click', function (e) {
|
|
753
|
-
if (
|
|
754
|
-
$item[0].matches('.is-removing') ||
|
|
755
|
-
$item[0].hasAttribute('data-empty')
|
|
756
|
-
)
|
|
757
|
-
return
|
|
758
|
-
if (!self.itemIsGridView($item)) {
|
|
759
|
-
self.itemToggle($item)
|
|
760
|
-
} else {
|
|
761
|
-
self.handleExpandClick($item)
|
|
762
|
-
}
|
|
763
|
-
})
|
|
764
|
-
.keydown(function (event) {
|
|
765
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
766
|
-
if ($item[0].matches('.is-removing')) return
|
|
767
|
-
event.preventDefault()
|
|
768
|
-
$label.trigger('click')
|
|
769
|
-
}
|
|
770
|
-
})
|
|
771
|
-
|
|
772
|
-
if (!$item.attr('data-disable-dynamic-html')) {
|
|
773
|
-
$label.attr(
|
|
774
|
-
'data-dynamic-html',
|
|
775
|
-
'${toolPageContext.getObjectLabel(content.state.getType())}: ${toolPageContext.createObjectLabelHtml(content)}', // eslint-disable-line no-template-curly-in-string
|
|
776
|
-
)
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
// If there was already a label on the page remove the repeatableLabel class
|
|
780
|
-
// so it doesn't conflict with the new label we are creating,
|
|
781
|
-
// then add this existing label to the new label we are creating.
|
|
782
|
-
$existingLabel = $item.find(' > .repeatableLabel')
|
|
783
|
-
if ($existingLabel.length) {
|
|
784
|
-
$existingLabel.removeClass('repeatableLabel').appendTo($label)
|
|
785
|
-
|
|
786
|
-
// Just in case the label has any inputs, make sure clicks on the input do not bubble up
|
|
787
|
-
// to the label and make it toggle the item
|
|
788
|
-
$label.find(':input').click(function (e) {
|
|
789
|
-
e.stopPropagation()
|
|
790
|
-
})
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// Add our label to item at the top
|
|
794
|
-
$item.prepend($label)
|
|
795
|
-
},
|
|
796
|
-
|
|
797
|
-
/**
|
|
798
|
-
* Initialize the remove button for an individiual item.
|
|
799
|
-
*
|
|
800
|
-
* @param {Element|jQuery object} item
|
|
801
|
-
* The item (LI element).
|
|
802
|
-
*/
|
|
803
|
-
initItemRemove: function (item) {
|
|
804
|
-
var self = this
|
|
805
|
-
var $item = $(item)
|
|
806
|
-
var $label
|
|
807
|
-
var $itemLiveRegion = $item.find('.screen-reader-only')
|
|
808
|
-
|
|
809
|
-
let inputAriaLabel = ''
|
|
810
|
-
const cigRow = $item.closest('.CIG-row')
|
|
811
|
-
if (cigRow.length) {
|
|
812
|
-
inputAriaLabel = cigRow.find('.CIG-label label').first().text()
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
// Add the remove button to the item
|
|
816
|
-
var $remove = $('<button/>', {
|
|
817
|
-
class: 'removeButton',
|
|
818
|
-
type: 'button',
|
|
819
|
-
'aria-label': `${tooltips.remove} ${inputAriaLabel}`,
|
|
820
|
-
title: `${tooltips.remove} ${inputAriaLabel}`,
|
|
821
|
-
text: self.options.removeButtonText,
|
|
822
|
-
}).on('click', function (event) {
|
|
823
|
-
self.removeItemToggle($item)
|
|
824
|
-
|
|
825
|
-
if ($item.hasClass('is-removing')) {
|
|
826
|
-
this.title = `${tooltips.restore} ${inputAriaLabel}`
|
|
827
|
-
this.setAttribute(
|
|
828
|
-
'aria-label',
|
|
829
|
-
`${tooltips.restore} ${inputAriaLabel}`,
|
|
830
|
-
)
|
|
831
|
-
$itemLiveRegion.text(tooltips?.removedItem)
|
|
832
|
-
} else {
|
|
833
|
-
this.title = `${tooltips.remove} ${inputAriaLabel}`
|
|
834
|
-
this.setAttribute(
|
|
835
|
-
'aria-label',
|
|
836
|
-
`${tooltips.remove} ${inputAriaLabel}`,
|
|
837
|
-
)
|
|
838
|
-
$itemLiveRegion.text(tooltips?.restoredItem)
|
|
839
|
-
}
|
|
840
|
-
})
|
|
841
|
-
|
|
842
|
-
$label = $item.find('.repeatableLabel')
|
|
843
|
-
|
|
844
|
-
if ($label && $label[0]) {
|
|
845
|
-
$remove.insertAfter($label)
|
|
846
|
-
} else {
|
|
847
|
-
$remove.appendTo($item)
|
|
848
|
-
}
|
|
849
|
-
},
|
|
850
|
-
|
|
851
|
-
// Note: Repeatable with progress is not supported in V5 UI.
|
|
852
|
-
/**
|
|
853
|
-
* Conditionally initializes the progress information for an individual item.
|
|
854
|
-
*
|
|
855
|
-
* @param {Element|jquery object} item
|
|
856
|
-
* the item (LI element).
|
|
857
|
-
*/
|
|
858
|
-
initCollectionItemProgress: function (item) {
|
|
859
|
-
var $item = $(item)
|
|
860
|
-
var progressFieldValue = $item.attr('data-progress-field-value')
|
|
861
|
-
|
|
862
|
-
if (!progressFieldValue) {
|
|
863
|
-
return
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
$('<div>', {
|
|
867
|
-
class: 'repeatableLabel-progress',
|
|
868
|
-
})
|
|
869
|
-
.append(
|
|
870
|
-
$('<div>', {
|
|
871
|
-
class: 'repeatableLabel-progressBar',
|
|
872
|
-
}).append(
|
|
873
|
-
$('<div>', {
|
|
874
|
-
class: 'repeatableLabel-progressFill',
|
|
875
|
-
style: 'width: ' + progressFieldValue + '%',
|
|
876
|
-
}),
|
|
877
|
-
),
|
|
878
|
-
)
|
|
879
|
-
.prepend(
|
|
880
|
-
$('<div>', {
|
|
881
|
-
class: 'repeatableLabel-progressLabel',
|
|
882
|
-
text: progressFieldValue + '% of Target',
|
|
883
|
-
}),
|
|
884
|
-
)
|
|
885
|
-
.appendTo($item)
|
|
886
|
-
},
|
|
887
|
-
|
|
888
|
-
// Note: Repeatable with toggle is not supported in V5 UI.
|
|
889
|
-
/**
|
|
890
|
-
* Conditionally initializes the toggle button for an individual item.
|
|
891
|
-
*
|
|
892
|
-
* @param {Element|jquery object} item
|
|
893
|
-
* the item (LI element).
|
|
894
|
-
*/
|
|
895
|
-
initCollectionItemToggle: function (item) {
|
|
896
|
-
var self = this
|
|
897
|
-
var $item = $(item)
|
|
898
|
-
var toggleField = $item.attr('data-toggle-field')
|
|
899
|
-
var toggleFieldValue = $item.attr('data-toggle-field-value')
|
|
900
|
-
|
|
901
|
-
if (!toggleField) {
|
|
902
|
-
return
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
// Add the remove button to the item
|
|
906
|
-
var id = $item.find('> input[type="hidden"][name$=".id"]').val()
|
|
907
|
-
|
|
908
|
-
var input = $('<input/>', {
|
|
909
|
-
id: id + '-toggle',
|
|
910
|
-
class: 'repeatableLabel-toggle',
|
|
911
|
-
type: 'checkbox',
|
|
912
|
-
name: id + '/' + toggleField,
|
|
913
|
-
value: true,
|
|
914
|
-
}).on('change', function (event) {
|
|
915
|
-
// Add/remove weight and recalculate
|
|
916
|
-
var checked = $(this).is(':checked')
|
|
917
|
-
var previouslyChecked = $item.attr('data-toggle-field-value') === 'true'
|
|
918
|
-
|
|
919
|
-
if (checked !== previouslyChecked) {
|
|
920
|
-
$item.attr('data-toggle-field-value', checked)
|
|
921
|
-
|
|
922
|
-
if (
|
|
923
|
-
$item.closest('.repeatableForm').hasClass('repeatableForm-weighted')
|
|
924
|
-
) {
|
|
925
|
-
if (checked === true) {
|
|
926
|
-
self.addCollectionItemWeight($item)
|
|
927
|
-
} else {
|
|
928
|
-
self.removeCollectionItemWeight($item)
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
})
|
|
933
|
-
|
|
934
|
-
if (toggleFieldValue === 'true') {
|
|
935
|
-
input.attr('checked', 'checked')
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
input.after(
|
|
939
|
-
$('<label>', {
|
|
940
|
-
for: id + '-toggle',
|
|
941
|
-
class: 'repeatableLabel-toggleLabel',
|
|
942
|
-
}),
|
|
943
|
-
)
|
|
944
|
-
|
|
945
|
-
input.appendTo($item)
|
|
946
|
-
},
|
|
947
|
-
|
|
948
|
-
//= =================================================
|
|
949
|
-
// MODE WEIGHTED
|
|
950
|
-
//= =================================================
|
|
951
|
-
|
|
952
|
-
/**
|
|
953
|
-
* Initialize weighted mode
|
|
954
|
-
*/
|
|
955
|
-
modeWeightedInit: function () {
|
|
956
|
-
var self = this
|
|
957
|
-
|
|
958
|
-
if (!self.modeIsWeighted()) {
|
|
959
|
-
return
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
// Set up a listener for when the user drags and drops an item to change the order,
|
|
963
|
-
// so we can adjust the order of weights
|
|
964
|
-
self.dom.$list.on('sortable.end', function (event, element) {
|
|
965
|
-
var $item = $(element)
|
|
966
|
-
|
|
967
|
-
// Find the index for the new position of the element
|
|
968
|
-
var newIndex = $item.index()
|
|
969
|
-
var oldIndex = $item.data('repeatableIndex')
|
|
970
|
-
self.repositionCollectionItemWeight(oldIndex, newIndex)
|
|
971
|
-
})
|
|
972
|
-
|
|
973
|
-
var $itemWeightsContainer = self.dom.$list
|
|
974
|
-
.parent()
|
|
975
|
-
.find('.repeatableForm-itemWeights')
|
|
976
|
-
self.collectionItemWeightsCalculated =
|
|
977
|
-
$itemWeightsContainer.data('calculated')
|
|
978
|
-
|
|
979
|
-
// If values are calculated, handle updates from cms-updateContentState event
|
|
980
|
-
if (self.collectionItemWeightsCalculated) {
|
|
981
|
-
// TODO: Make this functionality generic, using meta tags or hidden fields
|
|
982
|
-
self.dom.$form.on(
|
|
983
|
-
'cms-updateContentState',
|
|
984
|
-
(function (self) {
|
|
985
|
-
return function (event, data) {
|
|
986
|
-
var allDiffs = $.extend(
|
|
987
|
-
{},
|
|
988
|
-
data._differences,
|
|
989
|
-
data._hiddenDifferences,
|
|
990
|
-
)
|
|
991
|
-
if (!allDiffs) {
|
|
992
|
-
return
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
$.each(allDiffs, function (id, fields) {
|
|
996
|
-
if (fields.length === 0) {
|
|
997
|
-
return
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
var $inputs = self.dom.$list.find(
|
|
1001
|
-
'.objectInputs[data-object-id="' + id + '"]',
|
|
1002
|
-
)
|
|
1003
|
-
|
|
1004
|
-
if (!$inputs) {
|
|
1005
|
-
return
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
var $item = $inputs.closest('li')
|
|
1009
|
-
|
|
1010
|
-
if (!$item) {
|
|
1011
|
-
return
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
var weightFieldName = $item.attr('data-weight-field')
|
|
1015
|
-
if (!weightFieldName) {
|
|
1016
|
-
return
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
var newWeightFieldValue = fields[weightFieldName]
|
|
1020
|
-
if (
|
|
1021
|
-
newWeightFieldValue &&
|
|
1022
|
-
$item.data('weight-field-value') !== newWeightFieldValue
|
|
1023
|
-
) {
|
|
1024
|
-
$item.data('weight-field-value', newWeightFieldValue)
|
|
1025
|
-
self.updateCollectionItemWeightData(
|
|
1026
|
-
$(
|
|
1027
|
-
self.dom.$list
|
|
1028
|
-
.siblings('.repeatableForm-itemWeights')
|
|
1029
|
-
.find('.repeatableForm-itemWeight')
|
|
1030
|
-
.get($item.index()),
|
|
1031
|
-
),
|
|
1032
|
-
Math.round(newWeightFieldValue * 100),
|
|
1033
|
-
)
|
|
1034
|
-
self.fixCollectionItemWeights()
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
var weightMarkersFieldName = $item.attr(
|
|
1038
|
-
'data-weight-markers-field',
|
|
1039
|
-
)
|
|
1040
|
-
if (!weightMarkersFieldName) {
|
|
1041
|
-
return
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
var newWeightMarkersFieldValue = fields[weightMarkersFieldName]
|
|
1045
|
-
if (
|
|
1046
|
-
newWeightMarkersFieldValue &&
|
|
1047
|
-
$item.data('weight-markers-field-value') !==
|
|
1048
|
-
newWeightMarkersFieldValue
|
|
1049
|
-
) {
|
|
1050
|
-
$item.data(
|
|
1051
|
-
'weight-markers-field-value',
|
|
1052
|
-
newWeightMarkersFieldValue,
|
|
1053
|
-
)
|
|
1054
|
-
self.setCollectionItemWeightMarkers($item)
|
|
1055
|
-
}
|
|
1056
|
-
})
|
|
1057
|
-
}
|
|
1058
|
-
})(self),
|
|
1059
|
-
)
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
self.initCollectionItemWeightResetButton()
|
|
1063
|
-
},
|
|
1064
|
-
|
|
1065
|
-
/**
|
|
1066
|
-
* Conditionally initializes the weighting display for an individual item.
|
|
1067
|
-
*
|
|
1068
|
-
* @param {Element|jquery object} item
|
|
1069
|
-
* the item (LI element).
|
|
1070
|
-
*/
|
|
1071
|
-
modeWeightedInitItem: function (item) {
|
|
1072
|
-
var self = this
|
|
1073
|
-
var $item = $(item)
|
|
1074
|
-
|
|
1075
|
-
var weightFieldName = $item.data('weight-field')
|
|
1076
|
-
|
|
1077
|
-
// Only display field weights if all valid types support collection weights
|
|
1078
|
-
if (!self.modeIsWeighted() || !weightFieldName) {
|
|
1079
|
-
return false
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
$item.on('click', '> .removeButton', function () {
|
|
1083
|
-
var $this = $(this)
|
|
1084
|
-
if (
|
|
1085
|
-
$this.closest('li').hasClass('is-removing') ||
|
|
1086
|
-
$this.closest('li').hasClass('toBeRemoved')
|
|
1087
|
-
) {
|
|
1088
|
-
self.removeCollectionItemWeight($item)
|
|
1089
|
-
} else {
|
|
1090
|
-
self.addCollectionItemWeight($item)
|
|
1091
|
-
}
|
|
1092
|
-
})
|
|
1093
|
-
|
|
1094
|
-
// Save original index so that we can use this in sortable.end handler
|
|
1095
|
-
$item.data('repeatableIndex', $item.index())
|
|
1096
|
-
|
|
1097
|
-
self.addCollectionItemWeight($item)
|
|
1098
|
-
},
|
|
1099
|
-
|
|
1100
|
-
/**
|
|
1101
|
-
* Adds a weight to the collection for a given item.
|
|
1102
|
-
*/
|
|
1103
|
-
addCollectionItemWeight: function (item) {
|
|
1104
|
-
var self = this
|
|
1105
|
-
var $item = $(item)
|
|
1106
|
-
var color = self.getCollectionItemWeightColor($item)
|
|
1107
|
-
var inputName =
|
|
1108
|
-
$item.find('> input[type="hidden"][name$=".id"]').val() +
|
|
1109
|
-
'/' +
|
|
1110
|
-
$item.data('weight-field')
|
|
1111
|
-
var $repeatableWeightLabel = $item.find('> .repeatableLabel-weightLabel')
|
|
1112
|
-
|
|
1113
|
-
var weightFieldValue
|
|
1114
|
-
if ($repeatableWeightLabel.size() === 0) {
|
|
1115
|
-
weightFieldValue = $item.attr('data-weight-field-value')
|
|
1116
|
-
|
|
1117
|
-
$('<div>', {
|
|
1118
|
-
class: 'repeatableLabel-weightLabel',
|
|
1119
|
-
})
|
|
1120
|
-
.append(
|
|
1121
|
-
$('<span>', {
|
|
1122
|
-
class: 'repeatableLabel-color',
|
|
1123
|
-
style: 'background-color: ' + color,
|
|
1124
|
-
}),
|
|
1125
|
-
)
|
|
1126
|
-
.append(
|
|
1127
|
-
$('<input>', {
|
|
1128
|
-
type: 'hidden',
|
|
1129
|
-
name: inputName,
|
|
1130
|
-
value: weightFieldValue,
|
|
1131
|
-
}),
|
|
1132
|
-
)
|
|
1133
|
-
.prependTo($item)
|
|
1134
|
-
} else {
|
|
1135
|
-
weightFieldValue = $item
|
|
1136
|
-
.find('> .repeatableLabel-weightLabel')
|
|
1137
|
-
.find('input')
|
|
1138
|
-
.val()
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
// Only add weight and handle if toggle is true or not available
|
|
1142
|
-
if ($item.attr('data-toggle-field-value') === 'false') {
|
|
1143
|
-
return
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
var $itemWeight = $('<div>', {
|
|
1147
|
-
class: 'repeatableForm-itemWeight',
|
|
1148
|
-
style: 'background-color: ' + color + ';',
|
|
1149
|
-
'data-target': inputName,
|
|
1150
|
-
'data-weight': weightFieldValue,
|
|
1151
|
-
})
|
|
1152
|
-
|
|
1153
|
-
// Filter items that have been toggled off
|
|
1154
|
-
var itemIndex = $item
|
|
1155
|
-
.parent()
|
|
1156
|
-
.children(':not([data-toggle-field-value="false"], .is-removing)')
|
|
1157
|
-
.index($item)
|
|
1158
|
-
|
|
1159
|
-
var $itemWeightContainer = $item
|
|
1160
|
-
.closest('.repeatableForm')
|
|
1161
|
-
.find('> .repeatableForm-itemWeights')
|
|
1162
|
-
if (itemIndex === 0) {
|
|
1163
|
-
$itemWeightContainer.prepend($itemWeight)
|
|
1164
|
-
} else {
|
|
1165
|
-
$itemWeightContainer
|
|
1166
|
-
.children()
|
|
1167
|
-
.eq(itemIndex - 1)
|
|
1168
|
-
.after($itemWeight)
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
self.setCollectionItemWeightMarkers($item)
|
|
1172
|
-
|
|
1173
|
-
// Avoid creating handles if draggable is false
|
|
1174
|
-
if (!self.collectionItemWeightsCalculated) {
|
|
1175
|
-
$itemWeight.prepend(self.createCollectionItemWeightHandle($item))
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
var itemWeightDoubleValue = $itemWeight.attr('data-weight')
|
|
1179
|
-
|
|
1180
|
-
// If item has no data-weight attr, it is a new item,
|
|
1181
|
-
// and should scale other weights against `baseWeight`
|
|
1182
|
-
|
|
1183
|
-
if (self.isInitialized === true || !itemWeightDoubleValue) {
|
|
1184
|
-
var newWeightDouble
|
|
1185
|
-
|
|
1186
|
-
if (!itemWeightDoubleValue) {
|
|
1187
|
-
// new items are added with a weight proportional to the number of items
|
|
1188
|
-
newWeightDouble =
|
|
1189
|
-
Math.round((1 / $itemWeightContainer.children().size()) * 100) / 100
|
|
1190
|
-
} else {
|
|
1191
|
-
// if item exists, use existing weight
|
|
1192
|
-
newWeightDouble = parseFloat(itemWeightDoubleValue)
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
var modifier = 1 - newWeightDouble
|
|
1196
|
-
|
|
1197
|
-
$($itemWeightContainer.children().not($itemWeight)).each(function () {
|
|
1198
|
-
self.updateCollectionItemWeightData(
|
|
1199
|
-
$(this),
|
|
1200
|
-
Math.floor(modifier * $(this).attr('data-weight') * 100),
|
|
1201
|
-
)
|
|
1202
|
-
})
|
|
1203
|
-
|
|
1204
|
-
self.updateCollectionItemWeightData(
|
|
1205
|
-
$itemWeight,
|
|
1206
|
-
(newWeightDouble * 100).toFixed(),
|
|
1207
|
-
)
|
|
1208
|
-
self.fixCollectionItemWeights()
|
|
1209
|
-
} else {
|
|
1210
|
-
self.updateCollectionItemWeightData(
|
|
1211
|
-
$itemWeight,
|
|
1212
|
-
(itemWeightDoubleValue * 100).toFixed(),
|
|
1213
|
-
)
|
|
1214
|
-
}
|
|
1215
|
-
},
|
|
1216
|
-
|
|
1217
|
-
/**
|
|
1218
|
-
* Sets markers to repeatableForm-itemWeight.
|
|
1219
|
-
*/
|
|
1220
|
-
setCollectionItemWeightMarkers: function (item) {
|
|
1221
|
-
var self = this
|
|
1222
|
-
var $item = $(item)
|
|
1223
|
-
var $itemWeight = $(
|
|
1224
|
-
self.dom.$list
|
|
1225
|
-
.siblings('.repeatableForm-itemWeights')
|
|
1226
|
-
.find('.repeatableForm-itemWeight')
|
|
1227
|
-
.get($item.index()),
|
|
1228
|
-
)
|
|
1229
|
-
|
|
1230
|
-
$itemWeight.find('.repeatableForm-itemWeight-marker').remove()
|
|
1231
|
-
|
|
1232
|
-
var markerValues = $item.data('weight-markers-field-value')
|
|
1233
|
-
if (markerValues) {
|
|
1234
|
-
Array.prototype.forEach.call(markerValues, function (markerValue, i) {
|
|
1235
|
-
$itemWeight.append(
|
|
1236
|
-
$('<div/>', {
|
|
1237
|
-
class: 'repeatableForm-itemWeight-marker',
|
|
1238
|
-
style: 'left:' + markerValue * 100 + '%;',
|
|
1239
|
-
}),
|
|
1240
|
-
)
|
|
1241
|
-
})
|
|
1242
|
-
}
|
|
1243
|
-
},
|
|
1244
|
-
|
|
1245
|
-
/**
|
|
1246
|
-
* Removes a weight to the collection for a given item.
|
|
1247
|
-
*/
|
|
1248
|
-
removeCollectionItemWeight: function (item) {
|
|
1249
|
-
var self = this
|
|
1250
|
-
var $item = $(item)
|
|
1251
|
-
|
|
1252
|
-
var $repeatableForm = self.dom.$list.parent()
|
|
1253
|
-
var $itemWeightsContainer = $repeatableForm.find(
|
|
1254
|
-
'.repeatableForm-itemWeights',
|
|
1255
|
-
)
|
|
1256
|
-
|
|
1257
|
-
$itemWeightsContainer
|
|
1258
|
-
.find(
|
|
1259
|
-
'.repeatableForm-itemWeight[data-target="' +
|
|
1260
|
-
$item.find('.repeatableLabel-weightLabel input').attr('name') +
|
|
1261
|
-
'"]',
|
|
1262
|
-
)
|
|
1263
|
-
.remove()
|
|
1264
|
-
|
|
1265
|
-
var $itemWeights = $repeatableForm.find('.repeatableForm-itemWeight')
|
|
1266
|
-
|
|
1267
|
-
var totalRemainingPercent = 0
|
|
1268
|
-
$itemWeights.each(function (i) {
|
|
1269
|
-
var $itemWeight = $(this)
|
|
1270
|
-
totalRemainingPercent += parseFloat($itemWeight.attr('data-weight'))
|
|
1271
|
-
})
|
|
1272
|
-
|
|
1273
|
-
$itemWeights.each(function (i) {
|
|
1274
|
-
var $itemWeight = $(this)
|
|
1275
|
-
var newDouble =
|
|
1276
|
-
parseFloat($itemWeight.attr('data-weight')) / totalRemainingPercent
|
|
1277
|
-
self.updateCollectionItemWeightData(
|
|
1278
|
-
$itemWeight,
|
|
1279
|
-
Math.round(newDouble * 100),
|
|
1280
|
-
)
|
|
1281
|
-
})
|
|
1282
|
-
|
|
1283
|
-
self.fixCollectionItemWeights()
|
|
1284
|
-
},
|
|
1285
|
-
|
|
1286
|
-
repositionCollectionItemWeight: function (oldIndex, newIndex) {
|
|
1287
|
-
var self = this
|
|
1288
|
-
|
|
1289
|
-
var $weightsContainer = self.dom.$list
|
|
1290
|
-
.parent()
|
|
1291
|
-
.find('.repeatableForm-itemWeights')
|
|
1292
|
-
var $weights = $weightsContainer.children()
|
|
1293
|
-
var $weight = $weights.eq(oldIndex)
|
|
1294
|
-
|
|
1295
|
-
if (newIndex === 0) {
|
|
1296
|
-
$weightsContainer.prepend($weight)
|
|
1297
|
-
} else {
|
|
1298
|
-
$weights.eq(newIndex).after($weight)
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
self.dom.$list.children().each(function () {
|
|
1302
|
-
var $item = $(this)
|
|
1303
|
-
$item.data('repeatableIndex', $item.index())
|
|
1304
|
-
})
|
|
1305
|
-
},
|
|
1306
|
-
|
|
1307
|
-
initCollectionItemWeightResetButton: function () {
|
|
1308
|
-
var self = this
|
|
1309
|
-
|
|
1310
|
-
if (self.collectionItemWeightsCalculated) {
|
|
1311
|
-
return
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
|
-
self.dom.$list.parent().prepend(
|
|
1315
|
-
$('<a>', {
|
|
1316
|
-
class: 'repeatableForm-weightResetButton',
|
|
1317
|
-
text: 'Reset Weights',
|
|
1318
|
-
title: tooltips.resetWeights,
|
|
1319
|
-
}).on('click', function () {
|
|
1320
|
-
self.resetCollectionItemWeights()
|
|
1321
|
-
return false
|
|
1322
|
-
}),
|
|
1323
|
-
)
|
|
1324
|
-
},
|
|
1325
|
-
|
|
1326
|
-
/**
|
|
1327
|
-
* Resets the collection item weights with an even distribution.
|
|
1328
|
-
*/
|
|
1329
|
-
resetCollectionItemWeights: function () {
|
|
1330
|
-
var self = this
|
|
1331
|
-
var $itemWeights = self.dom.$list
|
|
1332
|
-
.parent()
|
|
1333
|
-
.find('.repeatableForm-itemWeight')
|
|
1334
|
-
var itemWeightsCount = $itemWeights.size()
|
|
1335
|
-
|
|
1336
|
-
if (itemWeightsCount <= 0) {
|
|
1337
|
-
return false
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
var weight = Math.floor(100 / itemWeightsCount)
|
|
1341
|
-
|
|
1342
|
-
$itemWeights.each(function () {
|
|
1343
|
-
self.updateCollectionItemWeightData(this, weight)
|
|
1344
|
-
})
|
|
1345
|
-
|
|
1346
|
-
self.fixCollectionItemWeights()
|
|
1347
|
-
},
|
|
1348
|
-
|
|
1349
|
-
/**
|
|
1350
|
-
* Prevents rounding errors and sum of weights from exceeding 100%.
|
|
1351
|
-
*/
|
|
1352
|
-
fixCollectionItemWeights: function () {
|
|
1353
|
-
var self = this
|
|
1354
|
-
var $itemWeights = self.dom.$list
|
|
1355
|
-
.parent()
|
|
1356
|
-
.find('.repeatableForm-itemWeights > .repeatableForm-itemWeight')
|
|
1357
|
-
var totalPercent = 0
|
|
1358
|
-
|
|
1359
|
-
$itemWeights.each(function (i) {
|
|
1360
|
-
var $itemWeight = $(this)
|
|
1361
|
-
var $itemWeightValue = parseFloat($itemWeight.attr('data-weight'))
|
|
1362
|
-
var $itemWeightPercent = $itemWeightValue * 100
|
|
1363
|
-
totalPercent += $itemWeightPercent
|
|
1364
|
-
|
|
1365
|
-
if (i + 1 === $itemWeights.size() && totalPercent !== 100) {
|
|
1366
|
-
self.updateCollectionItemWeightData(
|
|
1367
|
-
$itemWeight,
|
|
1368
|
-
$itemWeightPercent + 100 - totalPercent,
|
|
1369
|
-
)
|
|
1370
|
-
}
|
|
1371
|
-
})
|
|
1372
|
-
},
|
|
1373
|
-
|
|
1374
|
-
updateCollectionItemWeightData: function (itemWeight, percent) {
|
|
1375
|
-
var self = this
|
|
1376
|
-
var $itemWeight = $(itemWeight)
|
|
1377
|
-
var $repeatableForm = $itemWeight.closest('.repeatableForm')
|
|
1378
|
-
var double = percent / 100
|
|
1379
|
-
|
|
1380
|
-
$itemWeight.css({ flex: double + ' 1 0%' })
|
|
1381
|
-
$itemWeight.attr('data-weight', double)
|
|
1382
|
-
|
|
1383
|
-
var liIndex = $repeatableForm
|
|
1384
|
-
.find('input[name="' + $itemWeight.attr('data-target') + '"]')
|
|
1385
|
-
.closest('li')
|
|
1386
|
-
.index()
|
|
1387
|
-
|
|
1388
|
-
var $repeatableWeightDisplay = $(
|
|
1389
|
-
self.dom.$list.children('li').get(liIndex),
|
|
1390
|
-
).find('.repeatableLabel-weightLabel')
|
|
1391
|
-
$repeatableWeightDisplay.attr('data-weight-label', percent + '%')
|
|
1392
|
-
$repeatableWeightDisplay.find('input').val(double)
|
|
1393
|
-
},
|
|
1394
|
-
|
|
1395
|
-
/**
|
|
1396
|
-
* Gets a color for an item to represent the item's weight.
|
|
1397
|
-
*/
|
|
1398
|
-
getCollectionItemWeightColor: function (item) {
|
|
1399
|
-
var $item = $(item)
|
|
1400
|
-
var weightColor = $item.data('weight-color-field-value')
|
|
1401
|
-
|
|
1402
|
-
if (weightColor) {
|
|
1403
|
-
return weightColor
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
weightColor = this.cr.getNext()
|
|
1407
|
-
|
|
1408
|
-
$item.data('weight-color-field-value', weightColor)
|
|
1409
|
-
|
|
1410
|
-
return weightColor
|
|
1411
|
-
},
|
|
1412
|
-
|
|
1413
|
-
/**
|
|
1414
|
-
* Creates an element that handles dragging to
|
|
1415
|
-
* change the collection item weight field.
|
|
1416
|
-
*/
|
|
1417
|
-
createCollectionItemWeightHandle: function (item) {
|
|
1418
|
-
var self = this
|
|
1419
|
-
|
|
1420
|
-
return $('<div>', {
|
|
1421
|
-
class: 'repeatableForm-itemWeightHandle',
|
|
1422
|
-
mousedown: function (event) {
|
|
1423
|
-
event.stopPropagation()
|
|
1424
|
-
$.drag(
|
|
1425
|
-
this,
|
|
1426
|
-
event,
|
|
1427
|
-
function (event, data) {
|
|
1428
|
-
data.originX = event.clientX
|
|
1429
|
-
data.rightElement = $(this).parent()
|
|
1430
|
-
data.leftElement = data.rightElement.prev()
|
|
1431
|
-
|
|
1432
|
-
data.originalRightWeight = parseFloat(
|
|
1433
|
-
data.rightElement.attr('data-weight'),
|
|
1434
|
-
)
|
|
1435
|
-
data.originalLeftWeight = parseFloat(
|
|
1436
|
-
data.leftElement.attr('data-weight'),
|
|
1437
|
-
)
|
|
1438
|
-
|
|
1439
|
-
data.rightIndex = data.rightElement.index()
|
|
1440
|
-
data.leftIndex = data.leftElement.index()
|
|
1441
|
-
|
|
1442
|
-
var $listElements = self.dom.$list.children(
|
|
1443
|
-
':not([data-toggle-field-value="false"], .is-removing, .toBeRemoved)',
|
|
1444
|
-
)
|
|
1445
|
-
|
|
1446
|
-
data.rightLabel = $($listElements.get(data.rightIndex)).find(
|
|
1447
|
-
'.repeatableLabel-weightLabel',
|
|
1448
|
-
)
|
|
1449
|
-
data.leftLabel = $($listElements.get(data.leftIndex)).find(
|
|
1450
|
-
'.repeatableLabel-weightLabel',
|
|
1451
|
-
)
|
|
1452
|
-
|
|
1453
|
-
data.rightInput = data.rightLabel.find('input')
|
|
1454
|
-
data.leftInput = data.leftLabel.find('input')
|
|
1455
|
-
|
|
1456
|
-
data.totalWidth =
|
|
1457
|
-
data.rightElement.outerWidth() + data.leftElement.outerWidth()
|
|
1458
|
-
data.totalWeightDouble =
|
|
1459
|
-
data.originalRightWeight + data.originalLeftWeight
|
|
1460
|
-
},
|
|
1461
|
-
function (event, data) {
|
|
1462
|
-
var delta = data.originX - event.clientX
|
|
1463
|
-
var deltaPercent = Math.round((delta / data.totalWidth) * 100)
|
|
1464
|
-
var deltaDouble = deltaPercent / 100
|
|
1465
|
-
|
|
1466
|
-
var newLeftWeightDouble =
|
|
1467
|
-
Math.round((data.originalLeftWeight - deltaDouble) * 100) / 100
|
|
1468
|
-
var newRightWeightDouble =
|
|
1469
|
-
Math.round(
|
|
1470
|
-
(data.totalWeightDouble - newLeftWeightDouble) * 100,
|
|
1471
|
-
) / 100
|
|
1472
|
-
|
|
1473
|
-
if (newLeftWeightDouble < 0) {
|
|
1474
|
-
newLeftWeightDouble = 0
|
|
1475
|
-
newRightWeightDouble = data.totalWeightDouble
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
if (newRightWeightDouble < 0) {
|
|
1479
|
-
newRightWeightDouble = 0
|
|
1480
|
-
newLeftWeightDouble = data.totalWeightDouble
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
var newLeftWeightPct = Math.max(
|
|
1484
|
-
Math.round(newLeftWeightDouble * 100),
|
|
1485
|
-
0,
|
|
1486
|
-
)
|
|
1487
|
-
var newRightWeightPct = Math.max(
|
|
1488
|
-
Math.round(newRightWeightDouble * 100),
|
|
1489
|
-
0,
|
|
1490
|
-
)
|
|
1491
|
-
|
|
1492
|
-
data.leftElement
|
|
1493
|
-
.css({
|
|
1494
|
-
flex: newLeftWeightDouble + ' 1 0%',
|
|
1495
|
-
})
|
|
1496
|
-
.attr('data-weight', newLeftWeightDouble)
|
|
1497
|
-
|
|
1498
|
-
data.rightElement
|
|
1499
|
-
.css({
|
|
1500
|
-
flex: newRightWeightDouble + ' 1 0% ',
|
|
1501
|
-
})
|
|
1502
|
-
.attr('data-weight', newRightWeightDouble)
|
|
1503
|
-
|
|
1504
|
-
// Update input and numerical display
|
|
1505
|
-
data.rightLabel.attr('data-weight-label', newRightWeightPct + '%')
|
|
1506
|
-
data.leftLabel.attr('data-weight-label', newLeftWeightPct + '%')
|
|
1507
|
-
|
|
1508
|
-
data.rightInput.val(newRightWeightDouble)
|
|
1509
|
-
data.leftInput.val(newLeftWeightDouble)
|
|
1510
|
-
},
|
|
1511
|
-
function (event) {
|
|
1512
|
-
// do nothing.
|
|
1513
|
-
},
|
|
1514
|
-
)
|
|
1515
|
-
},
|
|
1516
|
-
})
|
|
1517
|
-
},
|
|
1518
|
-
|
|
1519
|
-
/**
|
|
1520
|
-
* Add a new item to the list, based from a template.
|
|
1521
|
-
*
|
|
1522
|
-
* checks on global variable `repeatableInsertFront` and for class `addToTop`
|
|
1523
|
-
* to decide if to insert new item to the beginning of the list
|
|
1524
|
-
*
|
|
1525
|
-
* @param {Element|jQuery object} template
|
|
1526
|
-
* The template for the new item.
|
|
1527
|
-
*
|
|
1528
|
-
* @param {Function} customCallback
|
|
1529
|
-
* A function to call after the new item has been added.
|
|
1530
|
-
*/
|
|
1531
|
-
addItem: function (template, customCallback, noFocus) {
|
|
1532
|
-
var self = this
|
|
1533
|
-
var $template = $(template)
|
|
1534
|
-
var $addedItem
|
|
1535
|
-
var promise
|
|
1536
|
-
var templateUrl
|
|
1537
|
-
var $templateInputs
|
|
1538
|
-
|
|
1539
|
-
// For single input mode, don't add another item if the input is empty
|
|
1540
|
-
if (self.modeIsSingle() && !self.dom.$singleInput.val()) {
|
|
1541
|
-
return false
|
|
1542
|
-
}
|
|
1543
|
-
|
|
1544
|
-
self.$element[0].dispatchEvent(new Event('repeatable.add'))
|
|
1545
|
-
|
|
1546
|
-
if (self.dom.$viewSwitcher) {
|
|
1547
|
-
self.dom.$viewSwitcher.show()
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
// Create a copy of the template to use as the new item
|
|
1551
|
-
$addedItem = $template.clone()
|
|
1552
|
-
$addedItem.removeClass('template')
|
|
1553
|
-
|
|
1554
|
-
// If the template contains inputs that end with ".toggle" then
|
|
1555
|
-
// start by making them checked to tell the backend it should save this item
|
|
1556
|
-
$addedItem.find(':input[name$=".toggle"]').attr('checked', 'checked')
|
|
1557
|
-
|
|
1558
|
-
// Determine if we need to AJAX the template onto the page
|
|
1559
|
-
// (if the template has no input but has a link)
|
|
1560
|
-
templateUrl = $addedItem.find('a').attr('href')
|
|
1561
|
-
$templateInputs = $addedItem.find(':input')
|
|
1562
|
-
if (templateUrl && $templateInputs.length === 0) {
|
|
1563
|
-
// Not sure why, but sending some kind of cache breaker in the data?
|
|
1564
|
-
++cacheNonce
|
|
1565
|
-
|
|
1566
|
-
promise = $.ajax({
|
|
1567
|
-
cache: false,
|
|
1568
|
-
url: templateUrl,
|
|
1569
|
-
data: { _nonce: cacheNonce },
|
|
1570
|
-
}).always(function (response) {
|
|
1571
|
-
// The response will either be the data (on success), or a jqXHR object (on error)
|
|
1572
|
-
var content =
|
|
1573
|
-
typeof response === 'string' ? response : response.responseText
|
|
1574
|
-
|
|
1575
|
-
// Add the loaded content into the new item
|
|
1576
|
-
$addedItem.html(content)
|
|
1577
|
-
})
|
|
1578
|
-
} else {
|
|
1579
|
-
// We're not loading any data, so we'll create an already
|
|
1580
|
-
// resolved promise to the next step will complete immediately
|
|
1581
|
-
promise = $.Deferred().resolve().promise()
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
++this.ariaIndex
|
|
1585
|
-
$templateInputs.each((i, element) => {
|
|
1586
|
-
if (element.hasAttribute('aria-label')) {
|
|
1587
|
-
element.setAttribute(
|
|
1588
|
-
'aria-label',
|
|
1589
|
-
`${element.getAttribute('aria-label')} ${this.ariaIndex}`,
|
|
1590
|
-
)
|
|
1591
|
-
}
|
|
1592
|
-
})
|
|
1593
|
-
|
|
1594
|
-
// Run more code after the item has been loaded
|
|
1595
|
-
promise.always(function () {
|
|
1596
|
-
if (self.dom.$list.find('.RCIG-replace').length) {
|
|
1597
|
-
self.dom.$list.find('.RCIG-replace').after($addedItem)
|
|
1598
|
-
} else {
|
|
1599
|
-
// Add the item to the page, prepending if `.addToTop` is present
|
|
1600
|
-
if (self.dom.$list.parent('.addToTop').length) {
|
|
1601
|
-
self.dom.$list.prepend($addedItem)
|
|
1602
|
-
} else {
|
|
1603
|
-
self.dom.$list.append($addedItem)
|
|
1604
|
-
// Scroll to the newly added item.
|
|
1605
|
-
if (self.initializingCount > 1) {
|
|
1606
|
-
var children = self.dom.$list[0].children
|
|
1607
|
-
const targetEl = children[children.length - 1]
|
|
1608
|
-
scrollIntoView(targetEl)
|
|
1609
|
-
}
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
|
-
// If item has no fields add to list item data attribute to indicate
|
|
1614
|
-
if ($addedItem[0].querySelector(':scope > [data-empty]')) {
|
|
1615
|
-
$addedItem[0].dataset.empty = ''
|
|
1616
|
-
}
|
|
1617
|
-
|
|
1618
|
-
// Initialize stuff on the new item
|
|
1619
|
-
// If there was a custom callback provided, call it now.
|
|
1620
|
-
// This is used for example, in Image Upload.
|
|
1621
|
-
// After the image is uploaded a new repeatable item is added,
|
|
1622
|
-
// then the callback inserts values into the template.
|
|
1623
|
-
if (customCallback) {
|
|
1624
|
-
// Call the customcallback funtion, setting "this" to be the element for the new item
|
|
1625
|
-
customCallback.call($addedItem[0])
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
// Note this will collapse the item as well so we will uncollapse it below
|
|
1629
|
-
self.initItem($addedItem)
|
|
1630
|
-
|
|
1631
|
-
if (self.modeIsPreview()) {
|
|
1632
|
-
self.initPreview($addedItem[0])
|
|
1633
|
-
}
|
|
1634
|
-
|
|
1635
|
-
// Make sure it's not collapsed since it's a new item
|
|
1636
|
-
self.itemUncollapse($addedItem)
|
|
1637
|
-
|
|
1638
|
-
// For single input mode, when user enters a value into the input,
|
|
1639
|
-
// we copy that value into the added item, then clear the value
|
|
1640
|
-
// from the original input so the user can enter another value
|
|
1641
|
-
if (self.modeIsSingle()) {
|
|
1642
|
-
$addedItem
|
|
1643
|
-
.find(':input:not([name$=".toggle"])')
|
|
1644
|
-
.val(self.dom.$singleInput.val())
|
|
1645
|
-
self.dom.$singleInput.val('')
|
|
1646
|
-
self.dom.$singleInput.focus()
|
|
1647
|
-
}
|
|
1648
|
-
|
|
1649
|
-
// Adjust the element ids so they don't conflict
|
|
1650
|
-
$addedItem.find('*[id]').attr('id', function (index, attr) {
|
|
1651
|
-
var newAttr
|
|
1652
|
-
|
|
1653
|
-
self.ariaIndex += 1
|
|
1654
|
-
|
|
1655
|
-
newAttr = attr + 'r' + self.ariaIndex
|
|
1656
|
-
|
|
1657
|
-
// Also adjust the LABEL elements that are linked to other inputs
|
|
1658
|
-
$addedItem.find('*[for="' + attr + '"]').attr('for', newAttr)
|
|
1659
|
-
|
|
1660
|
-
// Also adjust the auto-show elements so they show the correct elements
|
|
1661
|
-
$addedItem
|
|
1662
|
-
.find('*[data-show="#' + attr + '"]')
|
|
1663
|
-
.attr('data-show', '#' + newAttr)
|
|
1664
|
-
|
|
1665
|
-
return newAttr
|
|
1666
|
-
})
|
|
1667
|
-
|
|
1668
|
-
// Trigger a custom "create" event for the item
|
|
1669
|
-
// So other code can act on this if necessary
|
|
1670
|
-
$addedItem.trigger('create')
|
|
1671
|
-
|
|
1672
|
-
if ($addedItem[0].parentNode?.matches('.RCIG-list, .RCS-list')) {
|
|
1673
|
-
$addedItem[0].classList.add('is-new-item')
|
|
1674
|
-
}
|
|
1675
|
-
|
|
1676
|
-
// If we are in mode preview, adjust the added item.
|
|
1677
|
-
self.modePreviewAddItem($addedItem)
|
|
1678
|
-
|
|
1679
|
-
$addedItem.trigger('change')
|
|
1680
|
-
|
|
1681
|
-
var currentIndex = $addedItem.index()
|
|
1682
|
-
|
|
1683
|
-
if (win.repeatableInsertFront && self.modeIsPreview()) {
|
|
1684
|
-
// move added item to the beginning
|
|
1685
|
-
self.repositionItem(currentIndex, 0, $addedItem)
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
// Trigger a resize event for the window
|
|
1689
|
-
// Since we have added new content
|
|
1690
|
-
$win.resize()
|
|
1691
|
-
|
|
1692
|
-
// Insert another option to indexer
|
|
1693
|
-
if (self.dom.$indexer) {
|
|
1694
|
-
self.dom.$indexer.find('select').append(
|
|
1695
|
-
$('<option></option>')
|
|
1696
|
-
.val(currentIndex + 1)
|
|
1697
|
-
.html(currentIndex + 1),
|
|
1698
|
-
)
|
|
1699
|
-
}
|
|
1700
|
-
|
|
1701
|
-
// Delay the forced click until content state is finished adding data-additional-query attribute to the DOM, when applicable.
|
|
1702
|
-
function delayClick(input) {
|
|
1703
|
-
const combo = $addedItem[0].querySelector(':scope > .ComboInput')
|
|
1704
|
-
|
|
1705
|
-
if (
|
|
1706
|
-
combo &&
|
|
1707
|
-
(!input.dataset.dynamicPredicate || input.dataset.additionalQuery)
|
|
1708
|
-
) {
|
|
1709
|
-
combo.click()
|
|
1710
|
-
} else {
|
|
1711
|
-
setTimeout(() => delayClick(input), 10)
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
// A little hacky but should work fine given how onFind is currently implemented.
|
|
1716
|
-
if (!self.modeIsSingle() && !noFocus) {
|
|
1717
|
-
window.requestAnimationFrame(() => {
|
|
1718
|
-
window.requestAnimationFrame(() => {
|
|
1719
|
-
const first = tabbable($addedItem[0])[0]
|
|
1720
|
-
|
|
1721
|
-
if (first && !first.classList.contains('RCIG-title')) {
|
|
1722
|
-
const input = $addedItem[0].querySelector(
|
|
1723
|
-
':scope > input.objectId',
|
|
1724
|
-
)
|
|
1725
|
-
|
|
1726
|
-
if (input) {
|
|
1727
|
-
delayClick(input)
|
|
1728
|
-
} else {
|
|
1729
|
-
first.focus()
|
|
1730
|
-
first.click()
|
|
1731
|
-
}
|
|
1732
|
-
} else if (first) {
|
|
1733
|
-
first.focus()
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
// Handle UrlsWidget input focus
|
|
1737
|
-
const urlsWidgetItem = self.dom.$list[0]?.lastChild
|
|
1738
|
-
|
|
1739
|
-
if (
|
|
1740
|
-
urlsWidgetItem &&
|
|
1741
|
-
urlsWidgetItem.classList.contains('widget-urlsItem')
|
|
1742
|
-
) {
|
|
1743
|
-
urlsWidgetItem.querySelector('.widget-urlsItemLabel')?.focus()
|
|
1744
|
-
}
|
|
1745
|
-
})
|
|
1746
|
-
})
|
|
1747
|
-
}
|
|
1748
|
-
}) // END promise.always()
|
|
1749
|
-
|
|
1750
|
-
// Return the promise just in case someone wants to do something after the item is added
|
|
1751
|
-
// (but doesn't want to use the callback function)
|
|
1752
|
-
return promise
|
|
1753
|
-
},
|
|
1754
|
-
|
|
1755
|
-
/**
|
|
1756
|
-
* Shortcut function to tell if the mode is 'form'
|
|
1757
|
-
* @returns {Boolean}
|
|
1758
|
-
*/
|
|
1759
|
-
modeIsObject: function () {
|
|
1760
|
-
var self = this
|
|
1761
|
-
return self.mode === 'object'
|
|
1762
|
-
},
|
|
1763
|
-
|
|
1764
|
-
/**
|
|
1765
|
-
* Shortcut function to tell if the mode is 'form'
|
|
1766
|
-
* @returns {Boolean}
|
|
1767
|
-
*/
|
|
1768
|
-
modeIsForm: function () {
|
|
1769
|
-
var self = this
|
|
1770
|
-
return self.mode === 'form'
|
|
1771
|
-
},
|
|
1772
|
-
|
|
1773
|
-
/**
|
|
1774
|
-
* Shortcut function to tell if the mode is 'single'
|
|
1775
|
-
* @returns {Boolean}
|
|
1776
|
-
*/
|
|
1777
|
-
modeIsSingle: function () {
|
|
1778
|
-
var self = this
|
|
1779
|
-
return self.mode === 'single'
|
|
1780
|
-
},
|
|
1781
|
-
|
|
1782
|
-
/**
|
|
1783
|
-
* Shortcut function to tell if the mode is 'preview'
|
|
1784
|
-
* @returns {Boolean}
|
|
1785
|
-
*/
|
|
1786
|
-
modeIsPreview: function () {
|
|
1787
|
-
var self = this
|
|
1788
|
-
return self.mode === 'preview'
|
|
1789
|
-
},
|
|
1790
|
-
|
|
1791
|
-
/**
|
|
1792
|
-
* Shortcut function to tell if the mode is 'weighted'
|
|
1793
|
-
* @returns {Boolean}
|
|
1794
|
-
*/
|
|
1795
|
-
modeIsWeighted: function () {
|
|
1796
|
-
var self = this
|
|
1797
|
-
return self.mode === 'weighted'
|
|
1798
|
-
},
|
|
1799
|
-
|
|
1800
|
-
/**
|
|
1801
|
-
* Toggle the display of an item (and load the item if necessary).
|
|
1802
|
-
* If the item contains a hidden input with data-form-fields-url attribute,
|
|
1803
|
-
* then that means it has not been loaded yet.
|
|
1804
|
-
* In that case dynamically load the item the first time the item is toggled.
|
|
1805
|
-
*
|
|
1806
|
-
* @param {Element|jQuery object} item
|
|
1807
|
-
* The list item that should be toggled.
|
|
1808
|
-
*
|
|
1809
|
-
* @param {Boolean} [collapseFlag]
|
|
1810
|
-
* Set to true to force the item to collapse.
|
|
1811
|
-
* Set to false to force the item to uncollapse.
|
|
1812
|
-
* If undefined then the item will toggle between collapsed and uncollapsed.
|
|
1813
|
-
*/
|
|
1814
|
-
itemToggle: function (item, collapseFlag) {
|
|
1815
|
-
var self = this
|
|
1816
|
-
var $item = $(item)
|
|
1817
|
-
// var deferred
|
|
1818
|
-
|
|
1819
|
-
// Call for textareas to redraw.
|
|
1820
|
-
if ($item.hasClass('is-collapsed')) {
|
|
1821
|
-
$item.find('textarea').each((i, textarea) => {
|
|
1822
|
-
textarea.dispatchEvent(new CustomEvent('change', { bubbles: true }))
|
|
1823
|
-
})
|
|
1824
|
-
}
|
|
1825
|
-
|
|
1826
|
-
// Collapse or uncollapse the item
|
|
1827
|
-
$item.toggleClass('is-collapsed collapsed', collapseFlag)
|
|
1828
|
-
if (!self.itemIsCollapsed($item)) {
|
|
1829
|
-
$item.find('> .objectInputs').css('display', '')
|
|
1830
|
-
} else if (
|
|
1831
|
-
!self.itemIsGridView($item) &&
|
|
1832
|
-
!self.itemIsVerticalView($item)
|
|
1833
|
-
) {
|
|
1834
|
-
$item.find('> .objectInputs').hide()
|
|
1835
|
-
}
|
|
1836
|
-
|
|
1837
|
-
if (collapseFlag && $item.hasClass('expanded')) {
|
|
1838
|
-
$item.removeClass('expanded')
|
|
1839
|
-
}
|
|
1840
|
-
|
|
1841
|
-
self.$element[0].dispatchEvent(new Event('repeatable.toggle'))
|
|
1842
|
-
|
|
1843
|
-
// Don't do anything if mode=preview
|
|
1844
|
-
if (self.modeIsPreview()) {
|
|
1845
|
-
return
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
// Load the item if necessary,
|
|
1849
|
-
// or if it's already loaded do some stuff immediately
|
|
1850
|
-
if (!self.itemIsCollapsed($item)) {
|
|
1851
|
-
self.itemLoad($item).always(function () {
|
|
1852
|
-
// Trigger the resize event since we changed the item size
|
|
1853
|
-
$item.resize()
|
|
1854
|
-
|
|
1855
|
-
// Trigger a change event on the first input within the item
|
|
1856
|
-
// so other code can do something if necessary
|
|
1857
|
-
const firstInput = $item.find(':input:first')
|
|
1858
|
-
if (firstInput.length) {
|
|
1859
|
-
firstInput.change()
|
|
1860
|
-
|
|
1861
|
-
// The triggered change above adds data-interacted to the inputContainer
|
|
1862
|
-
// (via state.js) once it is expanded, but we don't want that in this case
|
|
1863
|
-
const inputContainer = firstInput.closest('.inputContainer')
|
|
1864
|
-
if (inputContainer.length) {
|
|
1865
|
-
inputContainer.removeAttr('data-interacted')
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
})
|
|
1869
|
-
}
|
|
1870
|
-
},
|
|
1871
|
-
|
|
1872
|
-
/**
|
|
1873
|
-
* Collapse an item.
|
|
1874
|
-
*
|
|
1875
|
-
* @param {Element|jQuery object} item
|
|
1876
|
-
* The list item that should be collapsed.
|
|
1877
|
-
*/
|
|
1878
|
-
itemCollapse: function (item) {
|
|
1879
|
-
var self = this
|
|
1880
|
-
self.itemToggle(item, true)
|
|
1881
|
-
},
|
|
1882
|
-
|
|
1883
|
-
/**
|
|
1884
|
-
* Uncollapse an item (and load the item if necessary).
|
|
1885
|
-
*
|
|
1886
|
-
* @param {Element|jQuery object} item
|
|
1887
|
-
* The list item that should be uncollapsed.
|
|
1888
|
-
*/
|
|
1889
|
-
itemUncollapse: function (item) {
|
|
1890
|
-
var self = this
|
|
1891
|
-
self.itemToggle(item, false)
|
|
1892
|
-
},
|
|
1893
|
-
|
|
1894
|
-
/**
|
|
1895
|
-
* Determine if an item is currently collapsed.
|
|
1896
|
-
*
|
|
1897
|
-
* @param {Element|jQuery object} item
|
|
1898
|
-
* The list item to test.
|
|
1899
|
-
*/
|
|
1900
|
-
itemIsCollapsed: function (item) {
|
|
1901
|
-
// var self = this
|
|
1902
|
-
var $item = $(item)
|
|
1903
|
-
return $item.hasClass('is-collapsed') || $item.hasClass('collapsed')
|
|
1904
|
-
},
|
|
1905
|
-
|
|
1906
|
-
/**
|
|
1907
|
-
* Checks an item to determine if it needs to load some dynamic content,
|
|
1908
|
-
* and loads it if necessary.
|
|
1909
|
-
*
|
|
1910
|
-
* @param {Element|jQuery object} item
|
|
1911
|
-
* The item to load.
|
|
1912
|
-
*
|
|
1913
|
-
* @param {Element|jQuery object} [location]
|
|
1914
|
-
* Optional location where to append the loaded content.
|
|
1915
|
-
* If not specified will append the loaded content to the item.
|
|
1916
|
-
*
|
|
1917
|
-
* @returns {Promise}
|
|
1918
|
-
* Returns a promise that tells you when the item is done loading.
|
|
1919
|
-
* You can use this promise even if the item is already on the page
|
|
1920
|
-
* and doesn't need to load anything.
|
|
1921
|
-
*
|
|
1922
|
-
* @example
|
|
1923
|
-
* myRepeatable.itemLoad(element).always(function(){ alert('Item is done loading'); });
|
|
1924
|
-
*/
|
|
1925
|
-
itemLoad: function (item, location) {
|
|
1926
|
-
var self = this
|
|
1927
|
-
var $item = $(item)
|
|
1928
|
-
var $location = location ? $(location) : $item
|
|
1929
|
-
var $input
|
|
1930
|
-
var url
|
|
1931
|
-
var data
|
|
1932
|
-
|
|
1933
|
-
// In case we do not need to load anything, we'll create a deferred
|
|
1934
|
-
// promise that is already resolved
|
|
1935
|
-
var promise = $.Deferred().resolve().promise()
|
|
1936
|
-
|
|
1937
|
-
if ($item.data('loaded')) {
|
|
1938
|
-
return promise
|
|
1939
|
-
}
|
|
1940
|
-
// Look for a hidden input that has a data-form-fields-url attribute
|
|
1941
|
-
// which indicates we need to load the form fields fields for this item.
|
|
1942
|
-
// Note after we load the content we will remove data-form-fields-url
|
|
1943
|
-
// so it will only be found and loaded once.
|
|
1944
|
-
$input = $item.find('> input[data-form-fields-url]')
|
|
1945
|
-
|
|
1946
|
-
if ($input.length > 0) {
|
|
1947
|
-
$item.addClass('is-loading')
|
|
1948
|
-
|
|
1949
|
-
// Get the URL to fetch
|
|
1950
|
-
url = $input.attr('data-form-fields-url')
|
|
1951
|
-
|
|
1952
|
-
// Get the data to pass to the URL
|
|
1953
|
-
data = $input.val()
|
|
1954
|
-
|
|
1955
|
-
// remove attr so it won't be loaded again
|
|
1956
|
-
$input.removeAttr('data-form-fields-url')
|
|
1957
|
-
|
|
1958
|
-
// Fetch the content
|
|
1959
|
-
// Override the promise we created by that returned by the ajax call,
|
|
1960
|
-
// so we can pass that back and you can take action when the ajax completes
|
|
1961
|
-
promise = $.ajax({
|
|
1962
|
-
type: 'POST',
|
|
1963
|
-
cache: false,
|
|
1964
|
-
url: url,
|
|
1965
|
-
data: { data: data },
|
|
1966
|
-
}).always(function (response) {
|
|
1967
|
-
$item.removeClass('is-loading')
|
|
1968
|
-
|
|
1969
|
-
// The response will either be the data (on success), or a jqXHR object (on error)
|
|
1970
|
-
var content =
|
|
1971
|
-
typeof response === 'string' ? response : response.responseText
|
|
1972
|
-
var $content = $(content)
|
|
1973
|
-
|
|
1974
|
-
// When ajax completes add the content to the page
|
|
1975
|
-
$input.next('input[name$=".expanded"]').val('true')
|
|
1976
|
-
$content.appendTo($location)
|
|
1977
|
-
$item.data('loaded', true)
|
|
1978
|
-
|
|
1979
|
-
// If the item has already been removed, mark the new content to be removed as well
|
|
1980
|
-
if (self.itemIsRemoved($item)) {
|
|
1981
|
-
// Call the removeItem function again and this time
|
|
1982
|
-
// it will also mark the newly loaded content to be disabled
|
|
1983
|
-
self.removeItem($item)
|
|
1984
|
-
}
|
|
1985
|
-
|
|
1986
|
-
// Trigger some events so other code can know we have added content
|
|
1987
|
-
// and can add more controls to the form we just loaded
|
|
1988
|
-
$location.trigger('create')
|
|
1989
|
-
$location.trigger('load')
|
|
1990
|
-
})
|
|
1991
|
-
}
|
|
1992
|
-
|
|
1993
|
-
// Return a promise so other events can be triggered after the item is loaded
|
|
1994
|
-
return promise
|
|
1995
|
-
},
|
|
1996
|
-
|
|
1997
|
-
/**
|
|
1998
|
-
* Toggle the remove state for an item.
|
|
1999
|
-
* When an item is marked for removal we perform the following steps:
|
|
2000
|
-
* - Add toBeRemoved class on the item.
|
|
2001
|
-
* - Disable all inputs.
|
|
2002
|
-
* - Change remove link text.
|
|
2003
|
-
*
|
|
2004
|
-
* @param {Element|jQuery object} item
|
|
2005
|
-
* The item (LI element).
|
|
2006
|
-
*
|
|
2007
|
-
* @param {Boolean} [removeFlag]
|
|
2008
|
-
* Set to true to force the item to be removed.
|
|
2009
|
-
* Set to false to force the item to be restored.
|
|
2010
|
-
* If undefined then the item will toggle between remove/restore.
|
|
2011
|
-
*/
|
|
2012
|
-
removeItemToggle: function (item, removeFlag) {
|
|
2013
|
-
var self = this
|
|
2014
|
-
var $item = $(item)
|
|
2015
|
-
var $removeButton = $item.find('.removeButton')
|
|
2016
|
-
var $searchButton = $item.find('.ContentSelector-search')
|
|
2017
|
-
var $editButton = $item.find('.ContentSelector-edit')
|
|
2018
|
-
var $inputs
|
|
2019
|
-
var $content = $()
|
|
2020
|
-
|
|
2021
|
-
// Define the content where we need to disable inputs and mark toBeRemoved
|
|
2022
|
-
$content = $content.add($item)
|
|
2023
|
-
|
|
2024
|
-
// Find all the input elements except the content summary quick view button
|
|
2025
|
-
// within the content so we can disable them
|
|
2026
|
-
$inputs = $content.find(':input:not(".ContentSummary-info")')
|
|
2027
|
-
|
|
2028
|
-
// If the removeFlag was not specified, determine if it should be true
|
|
2029
|
-
// or false, based on the current class of the item
|
|
2030
|
-
if (removeFlag === undefined) {
|
|
2031
|
-
removeFlag = !$item.is('.is-removing') && !$item.is('.toBeRemoved')
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
|
-
if (removeFlag) {
|
|
2035
|
-
// Add the "toBeRemoved" class to the item.
|
|
2036
|
-
$content.addClass('is-removing toBeRemoved')
|
|
2037
|
-
|
|
2038
|
-
// Disable all the inputs within the item so they will not be sent to the backend
|
|
2039
|
-
// when the form is submitted
|
|
2040
|
-
$inputs.each(function () {
|
|
2041
|
-
const $input = $(this)
|
|
2042
|
-
|
|
2043
|
-
// Keep remove button enabled so item can always be restored or removed
|
|
2044
|
-
if ($input.is($removeButton) && $input.parent().is($item)) return
|
|
2045
|
-
|
|
2046
|
-
if ($input.prop('disabled')) {
|
|
2047
|
-
$input.data('already-disabled', true)
|
|
2048
|
-
} else {
|
|
2049
|
-
$input.prop('disabled', true)
|
|
2050
|
-
}
|
|
2051
|
-
})
|
|
2052
|
-
|
|
2053
|
-
$searchButton.addClass('is-disabled')
|
|
2054
|
-
$editButton.addClass('is-disabled')
|
|
2055
|
-
|
|
2056
|
-
$item.find('> .objectInputs').hide()
|
|
2057
|
-
|
|
2058
|
-
// Change the text in the remove button
|
|
2059
|
-
if (self.options.restoreButtonText) {
|
|
2060
|
-
$removeButton.text(self.options.restoreButtonText)
|
|
2061
|
-
}
|
|
2062
|
-
|
|
2063
|
-
self.$element[0].dispatchEvent(new Event('repeatable.remove'))
|
|
2064
|
-
} else {
|
|
2065
|
-
// Remove the "toBeRemoved" class to the item.
|
|
2066
|
-
$content.removeClass('is-removing toBeRemoved')
|
|
2067
|
-
|
|
2068
|
-
// Disable all the inputs within the item so they will not be sent to the backend
|
|
2069
|
-
// when the form is submitted
|
|
2070
|
-
$inputs.each(function () {
|
|
2071
|
-
const $input = $(this)
|
|
2072
|
-
|
|
2073
|
-
if ($input.data('already-disabled')) {
|
|
2074
|
-
$input.removeData('already-disabled')
|
|
2075
|
-
} else {
|
|
2076
|
-
$input.prop('disabled', false)
|
|
2077
|
-
}
|
|
2078
|
-
})
|
|
2079
|
-
|
|
2080
|
-
$searchButton.removeClass('is-disabled')
|
|
2081
|
-
$editButton.removeClass('is-disabled')
|
|
2082
|
-
|
|
2083
|
-
$item.find('> .objectInputs').show()
|
|
2084
|
-
|
|
2085
|
-
// Change the text in the remove button
|
|
2086
|
-
if (self.options.removeButtonText) {
|
|
2087
|
-
$removeButton.text(self.options.removeButtonText)
|
|
2088
|
-
}
|
|
2089
|
-
|
|
2090
|
-
self.$element[0].dispatchEvent(new Event('repeatable.add'))
|
|
2091
|
-
}
|
|
2092
|
-
|
|
2093
|
-
// Trigger a change event to notify other code
|
|
2094
|
-
$item.change()
|
|
2095
|
-
},
|
|
2096
|
-
|
|
2097
|
-
/**
|
|
2098
|
-
* Mark an item to be removed.
|
|
2099
|
-
*
|
|
2100
|
-
* @param {Element|jQuery object} item
|
|
2101
|
-
* The item (LI element).
|
|
2102
|
-
*/
|
|
2103
|
-
removeItem: function (item) {
|
|
2104
|
-
var self = this
|
|
2105
|
-
self.removeItemToggle(item, true)
|
|
2106
|
-
},
|
|
2107
|
-
|
|
2108
|
-
/**
|
|
2109
|
-
* Immediately removes an item from
|
|
2110
|
-
* the DOM. Invoked by objectIdResult.jsp.
|
|
2111
|
-
*/
|
|
2112
|
-
removeItemImmediately: function (item) {
|
|
2113
|
-
var self = this
|
|
2114
|
-
var $item = $(item)
|
|
2115
|
-
|
|
2116
|
-
if (self.modeIsWeighted) {
|
|
2117
|
-
self.removeCollectionItemWeight($item)
|
|
2118
|
-
}
|
|
2119
|
-
|
|
2120
|
-
$item.remove()
|
|
2121
|
-
},
|
|
2122
|
-
|
|
2123
|
-
/**
|
|
2124
|
-
* Unmark an item to be removed (that is, restore the item).
|
|
2125
|
-
*
|
|
2126
|
-
* @param {Element|jQuery object} item
|
|
2127
|
-
* The item (LI element).
|
|
2128
|
-
*/
|
|
2129
|
-
restoreItem: function (item) {
|
|
2130
|
-
var self = this
|
|
2131
|
-
self.removeItemToggle(item, false)
|
|
2132
|
-
},
|
|
2133
|
-
|
|
2134
|
-
/**
|
|
2135
|
-
* Determine if an item is currently removed.
|
|
2136
|
-
*
|
|
2137
|
-
* @param {Element|jQuery object} item
|
|
2138
|
-
* The item (LI element).
|
|
2139
|
-
*/
|
|
2140
|
-
itemIsRemoved: function (item) {
|
|
2141
|
-
// var self = this
|
|
2142
|
-
return $(item).hasClass('is-removing') || $(item).hasClass('toBeRemoved')
|
|
2143
|
-
},
|
|
2144
|
-
|
|
2145
|
-
//= =================================================
|
|
2146
|
-
// MODE SINGLE
|
|
2147
|
-
//= =================================================
|
|
2148
|
-
|
|
2149
|
-
/**
|
|
2150
|
-
* Additional initializing for the "Add Item" controls when mode is "single".
|
|
2151
|
-
*/
|
|
2152
|
-
modeSingleInitAddButton: function () {
|
|
2153
|
-
var self = this
|
|
2154
|
-
var $input
|
|
2155
|
-
var $toggle
|
|
2156
|
-
var $singleInput
|
|
2157
|
-
var $addButtonContainer = self.dom.$addButtonContainer
|
|
2158
|
-
|
|
2159
|
-
// Only do this for single input mode
|
|
2160
|
-
if (!self.modeIsSingle()) {
|
|
2161
|
-
return
|
|
2162
|
-
}
|
|
2163
|
-
|
|
2164
|
-
// Get the single input from the template, but not the ".toggle" input.
|
|
2165
|
-
// We will also clone the $toggle input later
|
|
2166
|
-
$toggle = self.dom.$templates.find(':input[name$=".toggle"]')
|
|
2167
|
-
$input = self.dom.$templates.find(':input').not($toggle)
|
|
2168
|
-
|
|
2169
|
-
// Make a copy of the input
|
|
2170
|
-
$singleInput = $input.clone()
|
|
2171
|
-
|
|
2172
|
-
// Remove ID if it has it since duplicates not allowed
|
|
2173
|
-
$singleInput.removeAttr('id')
|
|
2174
|
-
|
|
2175
|
-
// When user presses Enter on the input then simulate a click on Add Item button
|
|
2176
|
-
// so another item can be added
|
|
2177
|
-
$singleInput.keydown(function (event) {
|
|
2178
|
-
// Check for Enter key
|
|
2179
|
-
if (event.which === 13) {
|
|
2180
|
-
// TODO: instead of triggering a click on the add button
|
|
2181
|
-
// we should just call the method that the click button calls
|
|
2182
|
-
$addButtonContainer.find('.addButton').trigger('click')
|
|
2183
|
-
return false
|
|
2184
|
-
}
|
|
2185
|
-
})
|
|
2186
|
-
|
|
2187
|
-
// Put a toggle input into the add button container
|
|
2188
|
-
// So it will tell the back-end that this input should be added
|
|
2189
|
-
// ???: this is not checked initially (but is is checked when the new input is added?)
|
|
2190
|
-
$('<input/>', {
|
|
2191
|
-
name: $toggle.attr('name'),
|
|
2192
|
-
type: 'hidden',
|
|
2193
|
-
value: $toggle.attr('value'),
|
|
2194
|
-
}).appendTo($addButtonContainer)
|
|
2195
|
-
|
|
2196
|
-
// Put the copy of the single input into the add button container
|
|
2197
|
-
// so user can type into it and create new items
|
|
2198
|
-
$singleInput.appendTo($addButtonContainer)
|
|
2199
|
-
|
|
2200
|
-
// Save for later use (so we can check if it contains a value)
|
|
2201
|
-
self.dom.$singleInput = $singleInput
|
|
2202
|
-
|
|
2203
|
-
// TODO: determine how these inputs are duplicated when the add button container is clicked...
|
|
2204
|
-
},
|
|
2205
|
-
|
|
2206
|
-
/**
|
|
2207
|
-
* Reposition an item by index
|
|
2208
|
-
*/
|
|
2209
|
-
repositionItem: function (oldIndex, newIndex, item) {
|
|
2210
|
-
var self = this
|
|
2211
|
-
var $item = $(item)
|
|
2212
|
-
var $items = self.dom.$list.find('li')
|
|
2213
|
-
|
|
2214
|
-
if (!$item || newIndex === oldIndex || newIndex > $items.length) {
|
|
2215
|
-
return
|
|
2216
|
-
}
|
|
2217
|
-
|
|
2218
|
-
// Remove active item temporarily
|
|
2219
|
-
$item = $item.detach()
|
|
2220
|
-
|
|
2221
|
-
// Add active item in the new position
|
|
2222
|
-
if (newIndex === 0) {
|
|
2223
|
-
// Special case add to the front of the list
|
|
2224
|
-
self.dom.$list.prepend($item)
|
|
2225
|
-
} else {
|
|
2226
|
-
self.dom.$list
|
|
2227
|
-
.find('li')
|
|
2228
|
-
.eq(newIndex - 1)
|
|
2229
|
-
.after($item)
|
|
2230
|
-
}
|
|
2231
|
-
},
|
|
2232
|
-
|
|
2233
|
-
//= =================================================
|
|
2234
|
-
// MODE PREVIEW
|
|
2235
|
-
//= =================================================
|
|
2236
|
-
|
|
2237
|
-
/**
|
|
2238
|
-
* After adding a new item, this function cleans it up for mode=preview.
|
|
2239
|
-
* Create the thumbnail image for the empty item.
|
|
2240
|
-
* The added item will have a complete form, so move the form to the gallery view.
|
|
2241
|
-
*/
|
|
2242
|
-
modePreviewAddItem: function (item) {
|
|
2243
|
-
var self = this
|
|
2244
|
-
var $item = $(item)
|
|
2245
|
-
|
|
2246
|
-
if (!self.modeIsPreview()) {
|
|
2247
|
-
return
|
|
2248
|
-
}
|
|
2249
|
-
|
|
2250
|
-
let $galleryViewState
|
|
2251
|
-
const $galleryViewLabel = $(
|
|
2252
|
-
'.view-switcher:enabled + .ComboInput .ComboInput-selected',
|
|
2253
|
-
).text()
|
|
2254
|
-
|
|
2255
|
-
if ($galleryViewLabel === 'List View') {
|
|
2256
|
-
$galleryViewState = 'list'
|
|
2257
|
-
if (!window.GALLERY_LIST_VIEW_UI) {
|
|
2258
|
-
$item.removeClass('is-gridItem')
|
|
2259
|
-
}
|
|
2260
|
-
} else if ($galleryViewLabel === 'Grid View') {
|
|
2261
|
-
$galleryViewState = 'grid'
|
|
2262
|
-
}
|
|
2263
|
-
|
|
2264
|
-
self.$galleryViewState = $galleryViewState
|
|
2265
|
-
|
|
2266
|
-
$item.addClass('state-new')
|
|
2267
|
-
$item.addClass(`is-${$galleryViewState}Item`)
|
|
2268
|
-
|
|
2269
|
-
// Applies RCIG-previewField class for styling on initial upload
|
|
2270
|
-
let previewField = $item.attr('data-preview-field')
|
|
2271
|
-
if (previewField) {
|
|
2272
|
-
const index = previewField.indexOf('/')
|
|
2273
|
-
if (index > -1) previewField = previewField.substring(0, index)
|
|
2274
|
-
$item
|
|
2275
|
-
.find(
|
|
2276
|
-
`> .objectInputs > .inputContainer[data-field="${previewField}"]`,
|
|
2277
|
-
)
|
|
2278
|
-
.addClass('RCIG-previewField')
|
|
2279
|
-
}
|
|
2280
|
-
},
|
|
2281
|
-
|
|
2282
|
-
initViewSwitcher: function () {
|
|
2283
|
-
var self = this
|
|
2284
|
-
var $container = self.$element
|
|
2285
|
-
var $viewGrid
|
|
2286
|
-
var $viewVertical
|
|
2287
|
-
var $viewSwitcher
|
|
2288
|
-
var $topButtonContainer
|
|
2289
|
-
|
|
2290
|
-
if (!self.modeIsPreview()) {
|
|
2291
|
-
return
|
|
2292
|
-
}
|
|
2293
|
-
|
|
2294
|
-
// Create controls at the top
|
|
2295
|
-
$topButtonContainer = $('<div/>', {
|
|
2296
|
-
class: 'repeatablePreviewControls',
|
|
2297
|
-
}).prependTo($container)
|
|
2298
|
-
|
|
2299
|
-
// Create dropdown to switch between grid view and vertical view
|
|
2300
|
-
var $gridSelected =
|
|
2301
|
-
!window.GALLERY_LIST_VIEW_UI && !self.isError
|
|
2302
|
-
? "selected='selected'"
|
|
2303
|
-
: ''
|
|
2304
|
-
var $listSelected =
|
|
2305
|
-
window.GALLERY_LIST_VIEW_UI || self.isError ? "selected='selected'" : ''
|
|
2306
|
-
$viewSwitcher = $(
|
|
2307
|
-
'<select class="view-switcher">' +
|
|
2308
|
-
`<option class="view-switcher-grid" ${$gridSelected} value="grid">Grid View</option>` +
|
|
2309
|
-
`<option class="view-switcher-vertical" ${$listSelected} value="vertical">List View</option>` +
|
|
2310
|
-
'</select>',
|
|
2311
|
-
).appendTo($topButtonContainer)
|
|
2312
|
-
|
|
2313
|
-
self.dom.$viewSwitcher = $viewSwitcher // Save for later
|
|
2314
|
-
|
|
2315
|
-
// The grid view will use the existing UL or OL
|
|
2316
|
-
$viewGrid = self.dom.$list
|
|
2317
|
-
self.dom.$viewGrid = $viewGrid // save for later
|
|
2318
|
-
|
|
2319
|
-
// The vertical view will also use the existing UL or OL as skeleton
|
|
2320
|
-
$viewVertical = self.dom.$list
|
|
2321
|
-
self.dom.$viewVertical = $viewVertical // save for later
|
|
2322
|
-
|
|
2323
|
-
// Switches between vertical and grid views
|
|
2324
|
-
$viewSwitcher.change(function () {
|
|
2325
|
-
if ($viewSwitcher.find('option[value="grid"]').attr('selected')) {
|
|
2326
|
-
$viewSwitcher.find('option[value="grid"]').removeAttr('selected')
|
|
2327
|
-
$viewSwitcher
|
|
2328
|
-
.find('option[value="vertical"]')
|
|
2329
|
-
.attr('selected', 'selected')
|
|
2330
|
-
self.modePreviewShowVertical()
|
|
2331
|
-
} else {
|
|
2332
|
-
$viewSwitcher.find('option[value="vertical"]').removeAttr('selected')
|
|
2333
|
-
$viewSwitcher
|
|
2334
|
-
.find('option[value="grid"]')
|
|
2335
|
-
.attr('selected', 'selected')
|
|
2336
|
-
self.modePreviewShowGrid()
|
|
2337
|
-
}
|
|
2338
|
-
})
|
|
2339
|
-
},
|
|
2340
|
-
|
|
2341
|
-
/**
|
|
2342
|
-
* When in preview mode, show the grid view.
|
|
2343
|
-
*/
|
|
2344
|
-
modePreviewShowGrid: function () {
|
|
2345
|
-
var self = this
|
|
2346
|
-
|
|
2347
|
-
if (!self.modeIsPreview()) {
|
|
2348
|
-
return
|
|
2349
|
-
}
|
|
2350
|
-
|
|
2351
|
-
self.dom.$viewGrid.show()
|
|
2352
|
-
self.dom.$viewVertical.find('> li').removeClass('is-listItem')
|
|
2353
|
-
self.dom.$viewGrid.find('> li').addClass('is-gridItem')
|
|
2354
|
-
self.$element.addClass('is-gridView')
|
|
2355
|
-
|
|
2356
|
-
self.dom.$viewGrid.find('> li').each(function () {
|
|
2357
|
-
var $item = $(this)
|
|
2358
|
-
self.itemUncollapse($item)
|
|
2359
|
-
})
|
|
2360
|
-
},
|
|
2361
|
-
|
|
2362
|
-
/**
|
|
2363
|
-
* When in preview mode, show the vertical view.
|
|
2364
|
-
*/
|
|
2365
|
-
modePreviewShowVertical: function (activeItem) {
|
|
2366
|
-
var self = this
|
|
2367
|
-
|
|
2368
|
-
if (!self.modeIsPreview()) {
|
|
2369
|
-
return
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
self.dom.$viewVertical.show()
|
|
2373
|
-
self.dom.$viewVertical.find('> li').addClass('is-listItem')
|
|
2374
|
-
self.dom.$viewGrid.find('> li').removeClass('is-gridItem')
|
|
2375
|
-
self.$element.removeClass('is-gridView')
|
|
2376
|
-
|
|
2377
|
-
self.dom.$viewVertical.find('> li').each(function () {
|
|
2378
|
-
var $item = $(this)
|
|
2379
|
-
self.itemCollapse($item)
|
|
2380
|
-
})
|
|
2381
|
-
},
|
|
2382
|
-
|
|
2383
|
-
/**
|
|
2384
|
-
* Determine if an item is an vertical view item
|
|
2385
|
-
*
|
|
2386
|
-
* @param {Element|jQuery object} item
|
|
2387
|
-
* The list item to test.
|
|
2388
|
-
*/
|
|
2389
|
-
itemIsVerticalView: function (item) {
|
|
2390
|
-
return item && $(item).hasClass('is-listItem')
|
|
2391
|
-
},
|
|
2392
|
-
|
|
2393
|
-
/**
|
|
2394
|
-
* Determine if an item is a grid view item
|
|
2395
|
-
*
|
|
2396
|
-
* @param {Element|jQuery object} item
|
|
2397
|
-
* The list item to test.
|
|
2398
|
-
*/
|
|
2399
|
-
itemIsGridView: function (item) {
|
|
2400
|
-
return item && $(item).hasClass('is-gridItem')
|
|
2401
|
-
},
|
|
2402
|
-
} // END repeatableUtility
|
|
2403
|
-
})(jQuery, window)
|
|
2404
|
-
|
|
2405
|
-
// Set filename for debugging tools to allow breakpoints even when using a cachebuster
|
|
2406
|
-
// # sourceURL=jquery.repeatable.js
|