@oat-sa/tao-core-ui 1.64.1 → 1.64.2
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/LICENSE +339 -339
- package/README.md +22 -22
- package/dist/actionbar.js +92 -92
- package/dist/adder.js +109 -109
- package/dist/animable/absorbable/absorbable.js +29 -29
- package/dist/animable/absorbable/css/absorb.css +7 -7
- package/dist/animable/absorbable/css/absorb.css.map +1 -1
- package/dist/animable/pulsable/css/pulse.css +7 -7
- package/dist/animable/pulsable/css/pulse.css.map +1 -1
- package/dist/animable/pulsable/pulsable.js +23 -23
- package/dist/areaBroker.js +51 -51
- package/dist/autocomplete/css/autocomplete.css +7 -7
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/autocomplete.js +384 -384
- package/dist/autoscroll.js +22 -22
- package/dist/badge/badge.js +35 -35
- package/dist/badge/css/badge.css +7 -7
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs/css/breadcrumbs.css +7 -7
- package/dist/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/dist/breadcrumbs.js +57 -57
- package/dist/btngrouper.js +64 -64
- package/dist/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/dist/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/dist/bulkActionPopup.js +91 -91
- package/dist/button.js +89 -89
- package/dist/calculator/css/calculator.css +10 -10
- package/dist/calculator/css/calculator.css.map +1 -1
- package/dist/calculator.js +51 -51
- package/dist/cascadingComboBox.js +34 -34
- package/dist/ckeditor/ckConfigurator.js +49 -49
- package/dist/ckeditor/dtdHandler.js +110 -110
- package/dist/class/css/selector.css +7 -7
- package/dist/class/css/selector.css.map +1 -1
- package/dist/class/selector.js +98 -98
- package/dist/component/alignable.js +81 -81
- package/dist/component/containable.js +37 -37
- package/dist/component/css/components.css +7 -7
- package/dist/component/css/components.css.map +1 -1
- package/dist/component/css/windowComponent.css +7 -7
- package/dist/component/css/windowComponent.css.map +1 -1
- package/dist/component/draggable.js +25 -25
- package/dist/component/placeable.js +70 -70
- package/dist/component/resizable.js +61 -61
- package/dist/component/stackable.js +20 -20
- package/dist/component/windowed.js +46 -46
- package/dist/component.js +140 -140
- package/dist/container.js +76 -76
- package/dist/contextualPopup/css/contextualPopup.css +7 -7
- package/dist/contextualPopup/css/contextualPopup.css.map +1 -1
- package/dist/contextualPopup.js +100 -100
- package/dist/dashboard/css/dashboard.css +7 -7
- package/dist/dashboard/css/dashboard.css.map +1 -1
- package/dist/dashboard.js +62 -62
- package/dist/datalist/css/datalist.css +7 -7
- package/dist/datalist/css/datalist.css.map +1 -1
- package/dist/datalist.js +147 -147
- package/dist/datatable/css/datatable.css +7 -7
- package/dist/datatable/css/datatable.css.map +1 -1
- package/dist/datatable/filterStrategy/filterStrategy.js +27 -27
- package/dist/datatable/filterStrategy/multiple.js +25 -25
- package/dist/datatable/filterStrategy/single.js +25 -25
- package/dist/datatable.js +377 -377
- package/dist/dateRange/css/dateRange.css +7 -7
- package/dist/dateRange/css/dateRange.css.map +1 -1
- package/dist/dateRange/dateRange.js +97 -97
- package/dist/datetime/css/picker.css +7 -7
- package/dist/datetime/css/picker.css.map +1 -1
- package/dist/datetime/picker.js +161 -161
- package/dist/deleter.js +79 -79
- package/dist/destination/css/selector.css +7 -7
- package/dist/destination/css/selector.css.map +1 -1
- package/dist/destination/selector.js +52 -52
- package/dist/dialog/alert.js +26 -26
- package/dist/dialog/confirm.js +27 -27
- package/dist/dialog/confirmDelete.js +31 -31
- package/dist/dialog.js +141 -141
- package/dist/disabler.js +90 -90
- package/dist/documentViewer/css/documentViewer.css +7 -7
- package/dist/documentViewer/css/documentViewer.css.map +1 -1
- package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +30 -30
- package/dist/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +25 -25
- package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +120 -120
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +89 -89
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +52 -52
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +112 -112
- package/dist/documentViewer/providers/pdfViewer/pdfjs/textManager.js +67 -67
- package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +81 -81
- package/dist/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +111 -111
- package/dist/documentViewer/providers/pdfViewer.js +29 -29
- package/dist/documentViewer/viewerFactory.js +71 -71
- package/dist/documentViewer.js +86 -86
- package/dist/dropdown/css/dropdown.css +7 -7
- package/dist/dropdown/css/dropdown.css.map +1 -1
- package/dist/dropdown.js +84 -84
- package/dist/durationer.js +58 -58
- package/dist/dynamicComponent/css/dynamicComponent.css +7 -7
- package/dist/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/dist/dynamicComponent.js +103 -103
- package/dist/feedback.js +84 -84
- package/dist/figure/FigureStateActive.js +111 -111
- package/dist/filesender.js +26 -26
- package/dist/filter.js +34 -34
- package/dist/form/css/dropdownForm.css +7 -7
- package/dist/form/css/dropdownForm.css.map +1 -1
- package/dist/form/css/form.css +7 -7
- package/dist/form/css/form.css.map +1 -1
- package/dist/form/dropdownForm.js +99 -99
- package/dist/form/form.js +248 -248
- package/dist/form/simpleForm.js +71 -71
- package/dist/form/validator/css/validator.css +7 -7
- package/dist/form/validator/css/validator.css.map +1 -1
- package/dist/form/validator/renderer.js +52 -52
- package/dist/form/validator/validator.js +103 -103
- package/dist/form/widget/css/widget.css +7 -7
- package/dist/form/widget/css/widget.css.map +1 -1
- package/dist/form/widget/definitions.js +24 -24
- package/dist/form/widget/loader.js +16 -16
- package/dist/form/widget/providers/checkBox.js +62 -62
- package/dist/form/widget/providers/comboBox.js +46 -46
- package/dist/form/widget/providers/default.js +35 -35
- package/dist/form/widget/providers/hidden.js +37 -37
- package/dist/form/widget/providers/hiddenBox.js +58 -58
- package/dist/form/widget/providers/radioBox.js +57 -57
- package/dist/form/widget/providers/textArea.js +35 -35
- package/dist/form/widget/providers/textBox.js +34 -34
- package/dist/form/widget/widget.js +141 -141
- package/dist/form.js +10 -10
- package/dist/formValidator/formValidator.js +61 -61
- package/dist/formValidator/highlighters/highlighter.js +41 -41
- package/dist/formValidator/highlighters/message.js +29 -29
- package/dist/formValidator/highlighters/tooltip.js +32 -32
- package/dist/generis/form/css/form.css +7 -7
- package/dist/generis/form/css/form.css.map +1 -1
- package/dist/generis/form/form.js +73 -73
- package/dist/generis/validator/css/validator.css +7 -7
- package/dist/generis/validator/css/validator.css.map +1 -1
- package/dist/generis/validator/validator.js +38 -38
- package/dist/generis/widget/checkBox/checkBox.js +39 -39
- package/dist/generis/widget/comboBox/comboBox.js +32 -32
- package/dist/generis/widget/css/widget.css +7 -7
- package/dist/generis/widget/css/widget.css.map +1 -1
- package/dist/generis/widget/hiddenBox/hiddenBox.js +40 -40
- package/dist/generis/widget/loader.js +20 -20
- package/dist/generis/widget/textBox/textBox.js +27 -27
- package/dist/generis/widget/widget.js +47 -47
- package/dist/groupedComboBox.js +36 -36
- package/dist/groupvalidator.js +19 -19
- package/dist/hider.js +41 -41
- package/dist/highlighter.js +278 -278
- package/dist/image/ImgStateActive/extractLabel.js +20 -20
- package/dist/image/ImgStateActive/helper.js +16 -16
- package/dist/image/ImgStateActive/initHelper.js +85 -85
- package/dist/image/ImgStateActive/initMediaEditor.js +48 -48
- package/dist/image/ImgStateActive/mediaSizer.js +32 -32
- package/dist/image/ImgStateActive.js +104 -104
- package/dist/incrementer.js +58 -58
- package/dist/inplacer.js +87 -87
- package/dist/interactUtils.js +42 -42
- package/dist/itemButtonList/css/item-button-list.css +23 -23
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +102 -102
- package/dist/keyNavigation/navigableDomElement.js +76 -76
- package/dist/keyNavigation/navigator.js +158 -158
- package/dist/listbox/css/listbox.css +7 -7
- package/dist/listbox/css/listbox.css.map +1 -1
- package/dist/listbox.js +84 -84
- package/dist/liststyler.js +57 -57
- package/dist/loadingButton/css/button.css +7 -7
- package/dist/loadingButton/css/button.css.map +1 -1
- package/dist/loadingButton/loadingButton.js +35 -35
- package/dist/lock.js +112 -112
- package/dist/login/login.js +87 -87
- package/dist/maths/calculator/basicCalculator.js +50 -50
- package/dist/maths/calculator/calculatorComponent.js +29 -29
- package/dist/maths/calculator/core/areaBroker.js +25 -25
- package/dist/maths/calculator/core/board.js +300 -300
- package/dist/maths/calculator/core/expression.js +98 -98
- package/dist/maths/calculator/core/labels.js +16 -16
- package/dist/maths/calculator/core/plugin.js +19 -19
- package/dist/maths/calculator/core/terms.js +26 -26
- package/dist/maths/calculator/core/tokenizer.js +98 -98
- package/dist/maths/calculator/core/tokens.js +75 -75
- package/dist/maths/calculator/css/calculator.css +7 -7
- package/dist/maths/calculator/css/calculator.css.map +1 -1
- package/dist/maths/calculator/defaultCalculator.js +23 -23
- package/dist/maths/calculator/plugins/core/degrad.js +22 -22
- package/dist/maths/calculator/plugins/core/history.js +45 -45
- package/dist/maths/calculator/plugins/core/remind.js +22 -22
- package/dist/maths/calculator/plugins/core/stepNavigation.js +31 -31
- package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +48 -48
- package/dist/maths/calculator/plugins/modifiers/pow10.js +35 -35
- package/dist/maths/calculator/plugins/modifiers/sign.js +90 -90
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +47 -47
- package/dist/maths/calculator/pluginsLoader.js +21 -21
- package/dist/maths/calculator/scientificCalculator.js +78 -78
- package/dist/mediaEditor/mediaEditorComponent.js +51 -51
- package/dist/mediaEditor/plugins/mediaAlignment/helper.js +16 -16
- package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +47 -47
- package/dist/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/dist/mediaEditor/plugins/mediaDimension/helper.js +70 -70
- package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +140 -140
- package/dist/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/dist/mediaplayer/css/player.css +7 -7
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +52 -52
- package/dist/mediaplayer/players/youtube.js +39 -39
- package/dist/mediaplayer/players.js +18 -18
- package/dist/mediaplayer/support.js +55 -55
- package/dist/mediaplayer/utils/reminder.js +100 -100
- package/dist/mediaplayer/utils/timeObserver.js +92 -92
- package/dist/mediaplayer/youtubeManager.js +51 -51
- package/dist/mediaplayer.js +447 -447
- package/dist/mediasizer.js +122 -122
- package/dist/modal.js +87 -87
- package/dist/movableComponent.js +35 -35
- package/dist/pageSizeSelector.js +31 -31
- package/dist/pageStatus.js +33 -33
- package/dist/pagination/css/pagination.css +7 -7
- package/dist/pagination/css/pagination.css.map +1 -1
- package/dist/pagination/paginationStrategy.js +23 -23
- package/dist/pagination/providers/pages.js +24 -24
- package/dist/pagination/providers/simple.js +22 -22
- package/dist/pagination.js +45 -45
- package/dist/previewer.js +67 -67
- package/dist/progressbar.js +58 -58
- package/dist/propertySelector/css/propertySelector.css +7 -7
- package/dist/propertySelector/css/propertySelector.css.map +1 -1
- package/dist/propertySelector/propertySelector.js +86 -86
- package/dist/report.js +73 -73
- package/dist/resource/css/selector.css +7 -7
- package/dist/resource/css/selector.css.map +1 -1
- package/dist/resource/filters.js +60 -60
- package/dist/resource/list.js +53 -53
- package/dist/resource/selectable.js +92 -92
- package/dist/resource/selector.js +182 -182
- package/dist/resource/tree.js +91 -91
- package/dist/resourcemgr/css/resourcemgr.css +7 -7
- package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
- package/dist/resourcemgr/fileBrowser.js +75 -75
- package/dist/resourcemgr/fileSelector.js +45 -45
- package/dist/resourcemgr/util/updatePermissions.js +4 -4
- package/dist/resourcemgr.js +49 -49
- package/dist/scroller.js +26 -26
- package/dist/searchModal/advancedSearch.js +155 -155
- package/dist/searchModal/css/advancedSearch.css +7 -7
- package/dist/searchModal/css/advancedSearch.css.map +1 -1
- package/dist/searchModal/css/searchModal.css +7 -7
- package/dist/searchModal/css/searchModal.css.map +1 -1
- package/dist/searchModal.js +134 -134
- package/dist/selecter.js +6 -6
- package/dist/stacker.js +43 -43
- package/dist/switch/css/switch.css +7 -7
- package/dist/switch/css/switch.css.map +1 -1
- package/dist/switch/switch.js +62 -62
- package/dist/tableModel.js +33 -33
- package/dist/tabs/css/tabs.css +12 -12
- package/dist/tabs/css/tabs.css.map +1 -1
- package/dist/tabs.js +220 -220
- package/dist/taskQueue/css/taskQueue.css +7 -7
- package/dist/taskQueue/css/taskQueue.css.map +1 -1
- package/dist/taskQueue/status.js +59 -59
- package/dist/taskQueue/table.js +54 -54
- package/dist/taskQueue/taskQueue.js +18 -18
- package/dist/taskQueue/taskQueueModel.js +102 -102
- package/dist/taskQueue.js +47 -47
- package/dist/taskQueueButton/css/taskable.css +7 -7
- package/dist/taskQueueButton/css/taskable.css.map +1 -1
- package/dist/taskQueueButton/css/treeButton.css +7 -7
- package/dist/taskQueueButton/css/treeButton.css.map +1 -1
- package/dist/taskQueueButton/standardButton.js +39 -39
- package/dist/taskQueueButton/taskable.js +41 -41
- package/dist/taskQueueButton/treeButton.js +43 -43
- package/dist/themeLoader.js +75 -75
- package/dist/themes.js +84 -84
- package/dist/toggler.js +57 -57
- package/dist/tooltip.js +41 -41
- package/dist/tooltipster.js +17 -17
- package/dist/transformer.js +117 -117
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/dist/tristateCheckboxGroup.js +62 -62
- package/dist/uploader.js +145 -145
- package/dist/validator/validators.js +48 -48
- package/dist/validator.js +23 -23
- package/dist/waitForMedia.js +33 -33
- package/dist/waitingDialog/css/waitingDialog.css +7 -7
- package/dist/waitingDialog/css/waitingDialog.css.map +1 -1
- package/dist/waitingDialog/waitingDialog.js +54 -54
- package/package.json +110 -110
- package/scss/basic.scss +16 -16
- package/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +60 -60
- package/scss/ckeditor/skins/tao/scss/inc/_tao.scss +59 -59
- package/scss/font/tao/tao.svg +235 -235
- package/scss/inc/_base.scss +495 -495
- package/scss/inc/_bootstrap.scss +6 -6
- package/scss/inc/_buttons.scss +114 -114
- package/scss/inc/_colors.scss +93 -93
- package/scss/inc/_feedback.scss +154 -154
- package/scss/inc/_flex-grid.scss +15 -15
- package/scss/inc/_fonts.scss +4 -4
- package/scss/inc/_forms.scss +832 -832
- package/scss/inc/_functions.scss +283 -283
- package/scss/inc/_jquery.nouislider.scss +254 -254
- package/scss/inc/_normalize.scss +528 -528
- package/scss/inc/_report.scss +67 -67
- package/scss/inc/_secondary-properties.scss +89 -89
- package/scss/inc/_select2.scss +634 -634
- package/scss/inc/_toolbars.scss +155 -155
- package/scss/inc/_tooltip.scss +312 -312
- package/scss/inc/_variables.scss +21 -21
- package/scss/inc/base/_highlight.scss +5 -5
- package/scss/inc/base/_list-style.scss +58 -58
- package/scss/inc/base/_svg.scss +3 -3
- package/scss/inc/base/_table.scss +62 -62
- package/scss/inc/fonts/_source-sans-pro.scss +29 -29
- package/scss/inc/fonts/_tao-icon-classes.scss +227 -227
- package/scss/inc/fonts/_tao-icon-def.scss +12 -12
- package/scss/inc/fonts/_tao-icon-vars.scss +241 -241
- package/src/actionbar/tpl/main.tpl +8 -8
- package/src/actionbar.js +251 -251
- package/src/adder.js +250 -250
- package/src/animable/absorbable/absorbable.js +134 -134
- package/src/animable/absorbable/css/absorb.css +7 -7
- package/src/animable/absorbable/css/absorb.css.map +1 -1
- package/src/animable/absorbable/scss/absorb.scss +37 -37
- package/src/animable/pulsable/css/pulse.css +7 -7
- package/src/animable/pulsable/css/pulse.css.map +1 -1
- package/src/animable/pulsable/pulsable.js +90 -90
- package/src/animable/pulsable/scss/pulse.scss +22 -22
- package/src/areaBroker.js +160 -160
- package/src/autocomplete/css/autocomplete.css +7 -7
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/autocomplete/scss/autocomplete.scss +37 -37
- package/src/autocomplete.js +1027 -1027
- package/src/autoscroll.js +57 -57
- package/src/badge/badge.js +119 -119
- package/src/badge/css/badge.css +7 -7
- package/src/badge/css/badge.css.map +1 -1
- package/src/badge/scss/badge.scss +92 -92
- package/src/badge/tpl/badge.tpl +4 -4
- package/src/breadcrumbs/css/breadcrumbs.css +7 -7
- package/src/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/src/breadcrumbs/scss/breadcrumbs.scss +52 -52
- package/src/breadcrumbs/tpl/breadcrumbs.tpl +20 -20
- package/src/breadcrumbs.js +99 -99
- package/src/btngrouper.js +213 -213
- package/src/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/src/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/src/bulkActionPopup/scss/bulkActionPopup.scss +63 -63
- package/src/bulkActionPopup/tpl/layout.tpl +76 -76
- package/src/bulkActionPopup/tpl/select.tpl +8 -8
- package/src/bulkActionPopup.js +274 -274
- package/src/button/tpl/button.tpl +4 -4
- package/src/button.js +135 -135
- package/src/calculator/css/calculator.css +10 -10
- package/src/calculator/css/calculator.css.map +1 -1
- package/src/calculator/scss/calculator.scss +139 -139
- package/src/calculator.js +188 -188
- package/src/cascadingComboBox.js +126 -126
- package/src/ckeditor/ckConfigurator.js +742 -742
- package/src/ckeditor/dtdHandler.js +1030 -1030
- package/src/class/css/selector.css +7 -7
- package/src/class/css/selector.css.map +1 -1
- package/src/class/scss/selector.scss +101 -101
- package/src/class/selector.js +329 -329
- package/src/class/tpl/listItem.tpl +9 -9
- package/src/class/tpl/selector.tpl +10 -10
- package/src/component/alignable.js +274 -274
- package/src/component/containable.js +122 -122
- package/src/component/css/components.css +7 -7
- package/src/component/css/components.css.map +1 -1
- package/src/component/css/windowComponent.css +7 -7
- package/src/component/css/windowComponent.css.map +1 -1
- package/src/component/draggable.js +104 -104
- package/src/component/placeable.js +233 -233
- package/src/component/resizable.js +195 -195
- package/src/component/scss/components.scss +507 -507
- package/src/component/scss/windowComponent.scss +62 -62
- package/src/component/stackable.js +67 -67
- package/src/component/tpl/window.tpl +7 -7
- package/src/component/windowed.js +206 -206
- package/src/component.js +401 -401
- package/src/container.js +200 -200
- package/src/contextualPopup/css/contextualPopup.css +7 -7
- package/src/contextualPopup/css/contextualPopup.css.map +1 -1
- package/src/contextualPopup/scss/contextualPopup.scss +78 -78
- package/src/contextualPopup/tpl/popup.tpl +10 -10
- package/src/contextualPopup.js +294 -294
- package/src/css/basic.css +104 -104
- package/src/css/basic.css.map +1 -1
- package/src/dashboard/css/dashboard.css +7 -7
- package/src/dashboard/css/dashboard.css.map +1 -1
- package/src/dashboard/scss/dashboard.scss +93 -93
- package/src/dashboard/tpl/dashboard.tpl +16 -16
- package/src/dashboard/tpl/dashboardMetricsList.tpl +15 -15
- package/src/dashboard.js +179 -179
- package/src/datalist/css/datalist.css +7 -7
- package/src/datalist/css/datalist.css.map +1 -1
- package/src/datalist/scss/datalist.scss +116 -116
- package/src/datalist/tpl/list.tpl +24 -24
- package/src/datalist/tpl/main.tpl +44 -44
- package/src/datalist.js +500 -500
- package/src/datatable/css/datatable.css +7 -7
- package/src/datatable/css/datatable.css.map +1 -1
- package/src/datatable/filterStrategy/filterStrategy.js +70 -70
- package/src/datatable/filterStrategy/multiple.js +126 -126
- package/src/datatable/filterStrategy/single.js +108 -108
- package/src/datatable/scss/datatable.scss +149 -149
- package/src/datatable/tpl/button.tpl +6 -6
- package/src/datatable/tpl/layout.tpl +158 -158
- package/src/datatable.js +1056 -1056
- package/src/dateRange/css/dateRange.css +7 -7
- package/src/dateRange/css/dateRange.css.map +1 -1
- package/src/dateRange/dateRange.js +341 -341
- package/src/dateRange/scss/dateRange.scss +7 -7
- package/src/dateRange/tpl/select.tpl +18 -18
- package/src/datetime/css/picker.css +7 -7
- package/src/datetime/css/picker.css.map +1 -1
- package/src/datetime/picker.js +576 -576
- package/src/datetime/scss/picker.scss +192 -192
- package/src/datetime/tpl/picker.tpl +18 -18
- package/src/deleter/undo.tpl +6 -6
- package/src/deleter.js +296 -296
- package/src/destination/css/selector.css +7 -7
- package/src/destination/css/selector.css.map +1 -1
- package/src/destination/scss/selector.scss +36 -36
- package/src/destination/selector.js +195 -195
- package/src/destination/tpl/selector.tpl +13 -13
- package/src/dialog/alert.js +70 -70
- package/src/dialog/confirm.js +85 -85
- package/src/dialog/confirmDelete.js +95 -95
- package/src/dialog/tpl/body.tpl +24 -24
- package/src/dialog/tpl/buttons.tpl +6 -6
- package/src/dialog/tpl/checkbox.tpl +5 -5
- package/src/dialog.js +517 -517
- package/src/disabler.js +230 -230
- package/src/documentViewer/css/documentViewer.css +7 -7
- package/src/documentViewer/css/documentViewer.css.map +1 -1
- package/src/documentViewer/providers/pdfViewer/fallback/viewer.js +69 -69
- package/src/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +41 -41
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.js +475 -475
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.tpl +20 -20
- package/src/documentViewer/providers/pdfViewer/pdfjs/match.tpl +1 -1
- package/src/documentViewer/providers/pdfViewer/pdfjs/page.tpl +4 -4
- package/src/documentViewer/providers/pdfViewer/pdfjs/pageView.js +318 -318
- package/src/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +167 -167
- package/src/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +451 -451
- package/src/documentViewer/providers/pdfViewer/pdfjs/textManager.js +252 -252
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.js +299 -299
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.tpl +16 -16
- package/src/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +351 -351
- package/src/documentViewer/providers/pdfViewer.js +93 -93
- package/src/documentViewer/scss/documentViewer.scss +184 -184
- package/src/documentViewer/viewerFactory.js +191 -191
- package/src/documentViewer.js +238 -238
- package/src/dropdown/css/dropdown.css +7 -7
- package/src/dropdown/css/dropdown.css.map +1 -1
- package/src/dropdown/scss/dropdown.scss +99 -99
- package/src/dropdown/tpl/dropdown.tpl +8 -8
- package/src/dropdown/tpl/list-item.tpl +4 -4
- package/src/dropdown.js +255 -255
- package/src/durationer.js +220 -220
- package/src/dynamicComponent/css/dynamicComponent.css +7 -7
- package/src/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/src/dynamicComponent/scss/dynamicComponent.scss +98 -98
- package/src/dynamicComponent/tpl/layout.tpl +17 -17
- package/src/dynamicComponent.js +553 -553
- package/src/feedback/feedback.tpl +7 -7
- package/src/feedback.js +295 -295
- package/src/figure/FigureStateActive.js +184 -184
- package/src/filesender.js +112 -112
- package/src/filter/template.tpl +5 -5
- package/src/filter.js +129 -129
- package/src/form/css/dropdownForm.css +7 -7
- package/src/form/css/dropdownForm.css.map +1 -1
- package/src/form/css/form.css +7 -7
- package/src/form/css/form.css.map +1 -1
- package/src/form/dropdownForm.js +281 -281
- package/src/form/form.js +688 -688
- package/src/form/scss/dropdownForm.scss +60 -60
- package/src/form/scss/form.scss +25 -25
- package/src/form/simpleForm.js +125 -125
- package/src/form/tpl/dropdownForm.tpl +4 -4
- package/src/form/tpl/form.tpl +7 -7
- package/src/form/validator/css/validator.css +7 -7
- package/src/form/validator/css/validator.css.map +1 -1
- package/src/form/validator/renderer.js +118 -118
- package/src/form/validator/scss/validator.scss +14 -14
- package/src/form/validator/tpl/message.tpl +1 -1
- package/src/form/validator/tpl/validator.tpl +1 -1
- package/src/form/validator/validator.js +220 -220
- package/src/form/widget/css/widget.css +7 -7
- package/src/form/widget/css/widget.css.map +1 -1
- package/src/form/widget/definitions.js +51 -51
- package/src/form/widget/loader.js +40 -40
- package/src/form/widget/providers/checkBox.js +138 -138
- package/src/form/widget/providers/comboBox.js +63 -63
- package/src/form/widget/providers/default.js +90 -90
- package/src/form/widget/providers/hidden.js +62 -62
- package/src/form/widget/providers/hiddenBox.js +152 -152
- package/src/form/widget/providers/radioBox.js +99 -99
- package/src/form/widget/providers/textArea.js +52 -52
- package/src/form/widget/providers/textBox.js +48 -48
- package/src/form/widget/scss/widget.scss +55 -55
- package/src/form/widget/tpl/checkBox.tpl +25 -25
- package/src/form/widget/tpl/comboBox.tpl +13 -13
- package/src/form/widget/tpl/hidden.tpl +1 -1
- package/src/form/widget/tpl/hiddenBox.tpl +17 -17
- package/src/form/widget/tpl/label.tpl +6 -6
- package/src/form/widget/tpl/radioBox.tpl +25 -25
- package/src/form/widget/tpl/textArea.tpl +8 -8
- package/src/form/widget/tpl/widget.tpl +8 -8
- package/src/form/widget/widget.js +372 -372
- package/src/form.js +47 -47
- package/src/formValidator/formValidator.js +253 -253
- package/src/formValidator/highlighters/highlighter.js +103 -103
- package/src/formValidator/highlighters/message.js +68 -68
- package/src/formValidator/highlighters/tooltip.js +78 -78
- package/src/generis/form/css/form.css +7 -7
- package/src/generis/form/css/form.css.map +1 -1
- package/src/generis/form/form.js +239 -239
- package/src/generis/form/readme.md +70 -70
- package/src/generis/form/scss/form.scss +23 -23
- package/src/generis/form/tpl/form.tpl +16 -16
- package/src/generis/validator/css/validator.css +7 -7
- package/src/generis/validator/css/validator.css.map +1 -1
- package/src/generis/validator/readme.md +46 -46
- package/src/generis/validator/scss/validator.scss +13 -13
- package/src/generis/validator/validator.js +128 -128
- package/src/generis/widget/checkBox/checkBox.js +112 -112
- package/src/generis/widget/checkBox/checkBox.tpl +18 -18
- package/src/generis/widget/comboBox/comboBox.js +66 -66
- package/src/generis/widget/comboBox/comboBox.tpl +12 -12
- package/src/generis/widget/css/widget.css +7 -7
- package/src/generis/widget/css/widget.css.map +1 -1
- package/src/generis/widget/hiddenBox/hiddenBox.js +131 -131
- package/src/generis/widget/hiddenBox/hiddenBox.tpl +16 -16
- package/src/generis/widget/loader.js +49 -49
- package/src/generis/widget/readme.md +59 -59
- package/src/generis/widget/scss/widget.scss +61 -61
- package/src/generis/widget/textBox/textBox.js +64 -64
- package/src/generis/widget/textBox/textBox.tpl +7 -7
- package/src/generis/widget/widget.js +164 -164
- package/src/generis/widget/widget.tpl +5 -5
- package/src/groupedComboBox.js +99 -99
- package/src/groupvalidator.js +84 -84
- package/src/hider.js +88 -88
- package/src/highlighter.js +1192 -1192
- package/src/image/ImgStateActive/extractLabel.js +29 -29
- package/src/image/ImgStateActive/helper.js +36 -36
- package/src/image/ImgStateActive/initHelper.js +137 -137
- package/src/image/ImgStateActive/initMediaEditor.js +92 -92
- package/src/image/ImgStateActive/mediaSizer.js +63 -63
- package/src/image/ImgStateActive.js +115 -115
- package/src/incrementer.js +309 -309
- package/src/inplacer.js +315 -315
- package/src/interactUtils.js +140 -140
- package/src/itemButtonList/css/item-button-list.css +23 -23
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/itemButtonList/scss/item-button-list.scss +236 -236
- package/src/itemButtonList/tpl/itemButtonList.tpl +21 -21
- package/src/itemButtonList.js +274 -274
- package/src/keyNavigation/navigableDomElement.js +285 -285
- package/src/keyNavigation/navigator.js +535 -535
- package/src/listbox/css/listbox.css +7 -7
- package/src/listbox/css/listbox.css.map +1 -1
- package/src/listbox/scss/listbox.scss +116 -116
- package/src/listbox/tpl/list.tpl +14 -14
- package/src/listbox/tpl/main.tpl +9 -9
- package/src/listbox.js +252 -252
- package/src/liststyler.js +155 -155
- package/src/loadingButton/css/button.css +7 -7
- package/src/loadingButton/css/button.css.map +1 -1
- package/src/loadingButton/loadingButton.js +110 -110
- package/src/loadingButton/scss/button.scss +41 -41
- package/src/loadingButton/tpl/button.tpl +5 -5
- package/src/lock/lock.tpl +16 -16
- package/src/lock.js +393 -393
- package/src/login/login.js +317 -317
- package/src/login/tpl/login.tpl +29 -29
- package/src/login/tpl/passwordReveal.tpl +7 -7
- package/src/maths/calculator/basicCalculator.js +55 -55
- package/src/maths/calculator/calculatorComponent.js +128 -128
- package/src/maths/calculator/core/areaBroker.js +38 -38
- package/src/maths/calculator/core/board.js +841 -841
- package/src/maths/calculator/core/expression.js +430 -430
- package/src/maths/calculator/core/labels.js +116 -116
- package/src/maths/calculator/core/plugin.js +40 -40
- package/src/maths/calculator/core/terms.js +459 -459
- package/src/maths/calculator/core/tokenizer.js +245 -245
- package/src/maths/calculator/core/tokens.js +178 -178
- package/src/maths/calculator/core/tpl/board.tpl +4 -4
- package/src/maths/calculator/css/calculator.css +7 -7
- package/src/maths/calculator/css/calculator.css.map +1 -1
- package/src/maths/calculator/defaultCalculator.js +66 -66
- package/src/maths/calculator/plugins/core/degrad.js +90 -90
- package/src/maths/calculator/plugins/core/history.js +166 -166
- package/src/maths/calculator/plugins/core/remind.js +96 -96
- package/src/maths/calculator/plugins/core/stepNavigation.js +175 -175
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/defaultTemplate.tpl +36 -36
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +91 -91
- package/src/maths/calculator/plugins/modifiers/pow10.js +143 -143
- package/src/maths/calculator/plugins/modifiers/sign.js +339 -339
- package/src/maths/calculator/plugins/screen/simpleScreen/defaultTemplate.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/history.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +190 -190
- package/src/maths/calculator/pluginsLoader.js +46 -46
- package/src/maths/calculator/scientificCalculator.js +74 -74
- package/src/maths/calculator/scss/calculator.scss +396 -396
- package/src/maths/calculator/tpl/basicKeyboard.tpl +37 -37
- package/src/maths/calculator/tpl/basicScreen.tpl +2 -2
- package/src/maths/calculator/tpl/scientificKeyboard.tpl +61 -61
- package/src/maths/calculator/tpl/scientificScreen.tpl +3 -3
- package/src/mediaEditor/mediaEditorComponent.js +141 -141
- package/src/mediaEditor/plugins/mediaAlignment/helper.js +110 -110
- package/src/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +99 -99
- package/src/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/src/mediaEditor/plugins/mediaAlignment/tpl/mediaAlignment.tpl +25 -25
- package/src/mediaEditor/plugins/mediaDimension/helper.js +190 -190
- package/src/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +561 -561
- package/src/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/src/mediaEditor/plugins/mediaDimension/tpl/mediaDimension.tpl +55 -55
- package/src/mediaEditor/tpl/editor.tpl +4 -4
- package/src/mediaplayer/css/player.css +7 -7
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/mediaplayer/players/html5.js +564 -564
- package/src/mediaplayer/players/youtube.js +323 -323
- package/src/mediaplayer/players.js +29 -29
- package/src/mediaplayer/readme.md +305 -305
- package/src/mediaplayer/scss/player.scss +569 -569
- package/src/mediaplayer/support.js +126 -126
- package/src/mediaplayer/tpl/audio.tpl +6 -6
- package/src/mediaplayer/tpl/player.tpl +37 -37
- package/src/mediaplayer/tpl/source.tpl +1 -1
- package/src/mediaplayer/tpl/video.tpl +6 -6
- package/src/mediaplayer/tpl/youtube.tpl +1 -1
- package/src/mediaplayer/utils/reminder.js +184 -184
- package/src/mediaplayer/utils/timeObserver.js +143 -143
- package/src/mediaplayer/youtubeManager.js +161 -161
- package/src/mediaplayer.js +1606 -1606
- package/src/mediasizer/mediasizer.tpl +55 -55
- package/src/mediasizer.js +635 -635
- package/src/modal.js +365 -365
- package/src/movableComponent.js +78 -78
- package/src/pageSizeSelector/tpl/pageSizeSelector.tpl +9 -9
- package/src/pageSizeSelector.js +106 -106
- package/src/pageStatus.js +147 -147
- package/src/pagination/css/pagination.css +7 -7
- package/src/pagination/css/pagination.css.map +1 -1
- package/src/pagination/paginationStrategy.js +53 -53
- package/src/pagination/providers/pages.js +161 -161
- package/src/pagination/providers/simple.js +74 -74
- package/src/pagination/providers/tpl/pages/page.tpl +1 -1
- package/src/pagination/providers/tpl/pages.tpl +8 -8
- package/src/pagination/providers/tpl/simple.tpl +7 -7
- package/src/pagination/scss/pagination.scss +111 -111
- package/src/pagination.js +237 -237
- package/src/previewer.js +300 -300
- package/src/progressbar.js +165 -165
- package/src/propertySelector/css/propertySelector.css +7 -7
- package/src/propertySelector/css/propertySelector.css.map +1 -1
- package/src/propertySelector/propertySelector.js +286 -286
- package/src/propertySelector/scss/propertySelector.scss +66 -66
- package/src/propertySelector/tpl/property-description.tpl +12 -12
- package/src/propertySelector/tpl/property-selector.tpl +6 -6
- package/src/report/feedback.tpl +11 -11
- package/src/report/layout.tpl +10 -10
- package/src/report.js +184 -184
- package/src/resource/css/selector.css +7 -7
- package/src/resource/css/selector.css.map +1 -1
- package/src/resource/filters.js +208 -208
- package/src/resource/list.js +200 -200
- package/src/resource/scss/_filters.scss +26 -26
- package/src/resource/scss/_resource-list.scss +107 -107
- package/src/resource/scss/_resource-tree.scss +205 -205
- package/src/resource/scss/selector.scss +187 -187
- package/src/resource/selectable.js +322 -322
- package/src/resource/selector.js +871 -871
- package/src/resource/tpl/filters.tpl +2 -2
- package/src/resource/tpl/list.tpl +7 -7
- package/src/resource/tpl/listNode.tpl +4 -4
- package/src/resource/tpl/selector.tpl +46 -46
- package/src/resource/tpl/tree.tpl +4 -4
- package/src/resource/tpl/treeNode.tpl +30 -30
- package/src/resource/tree.js +398 -398
- package/src/resourcemgr/css/resourcemgr.css +7 -7
- package/src/resourcemgr/css/resourcemgr.css.map +1 -1
- package/src/resourcemgr/fileBrowser.js +381 -381
- package/src/resourcemgr/filePreview.js +73 -73
- package/src/resourcemgr/fileSelector.js +322 -322
- package/src/resourcemgr/scss/resourcemgr.scss +254 -254
- package/src/resourcemgr/tpl/fileSelect.tpl +39 -39
- package/src/resourcemgr/tpl/folder.tpl +11 -11
- package/src/resourcemgr/tpl/layout.tpl +84 -84
- package/src/resourcemgr/tpl/rootFolder.tpl +13 -13
- package/src/resourcemgr/util/updatePermissions.js +53 -53
- package/src/resourcemgr.js +216 -216
- package/src/scroller.js +94 -94
- package/src/scss/basic.scss +16 -16
- package/src/searchModal/advancedSearch.js +638 -638
- package/src/searchModal/css/advancedSearch.css +7 -7
- package/src/searchModal/css/advancedSearch.css.map +1 -1
- package/src/searchModal/css/searchModal.css +7 -7
- package/src/searchModal/css/searchModal.css.map +1 -1
- package/src/searchModal/scss/advancedSearch.scss +171 -171
- package/src/searchModal/scss/searchModal.scss +393 -393
- package/src/searchModal/tpl/advanced-search.tpl +9 -9
- package/src/searchModal/tpl/info-message.tpl +3 -3
- package/src/searchModal/tpl/invalid-criteria-warning.tpl +10 -10
- package/src/searchModal/tpl/layout.tpl +27 -27
- package/src/searchModal/tpl/list-checkbox-criterion.tpl +17 -17
- package/src/searchModal/tpl/list-select-criterion.tpl +12 -12
- package/src/searchModal/tpl/text-criterion.tpl +11 -11
- package/src/searchModal.js +760 -760
- package/src/selecter.js +43 -43
- package/src/stacker.js +133 -133
- package/src/switch/css/switch.css +7 -7
- package/src/switch/css/switch.css.map +1 -1
- package/src/switch/scss/switch.scss +83 -83
- package/src/switch/switch.js +195 -195
- package/src/switch/tpl/switch.tpl +7 -7
- package/src/tableModel.js +112 -112
- package/src/tabs/css/tabs.css +12 -12
- package/src/tabs/css/tabs.css.map +1 -1
- package/src/tabs/scss/tabs.scss +50 -50
- package/src/tabs/tpl/panel.tpl +3 -3
- package/src/tabs/tpl/tabs.tpl +10 -10
- package/src/tabs.js +528 -528
- package/src/taskQueue/css/taskQueue.css +7 -7
- package/src/taskQueue/css/taskQueue.css.map +1 -1
- package/src/taskQueue/scss/taskQueue.scss +47 -47
- package/src/taskQueue/status.js +228 -228
- package/src/taskQueue/table.js +350 -350
- package/src/taskQueue/taskQueue.js +33 -33
- package/src/taskQueue/taskQueueModel.js +548 -548
- package/src/taskQueue/tpl/statusMessage.tpl +7 -7
- package/src/taskQueue.js +216 -216
- package/src/taskQueueButton/css/taskable.css +7 -7
- package/src/taskQueueButton/css/taskable.css.map +1 -1
- package/src/taskQueueButton/css/treeButton.css +7 -7
- package/src/taskQueueButton/css/treeButton.css.map +1 -1
- package/src/taskQueueButton/scss/taskable.scss +4 -4
- package/src/taskQueueButton/scss/treeButton.scss +34 -34
- package/src/taskQueueButton/standardButton.js +108 -108
- package/src/taskQueueButton/taskable.js +202 -202
- package/src/taskQueueButton/tpl/report.tpl +5 -5
- package/src/taskQueueButton/tpl/treeButton.tpl +6 -6
- package/src/taskQueueButton/treeButton.js +108 -108
- package/src/themeLoader.js +252 -252
- package/src/themes.js +162 -162
- package/src/toggler.js +200 -200
- package/src/tooltip/default.tpl +3 -3
- package/src/tooltip.js +160 -160
- package/src/tooltipster.js +25 -25
- package/src/transformer.js +327 -327
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/src/tristateCheckboxGroup/scss/tristateCheckboxGroup.scss +15 -15
- package/src/tristateCheckboxGroup/tpl/li.tpl +6 -6
- package/src/tristateCheckboxGroup.js +207 -207
- package/src/uploader/fileEntry.tpl +6 -6
- package/src/uploader/uploader.tpl +32 -32
- package/src/uploader.js +594 -594
- package/src/validator/Report.js +10 -10
- package/src/validator/Validator.js +108 -108
- package/src/validator/validators.js +217 -217
- package/src/validator.js +262 -262
- package/src/waitForMedia.js +82 -82
- package/src/waitingDialog/css/waitingDialog.css +7 -7
- package/src/waitingDialog/css/waitingDialog.css.map +1 -1
- package/src/waitingDialog/scss/waitingDialog.scss +34 -34
- package/src/waitingDialog/waitingDialog.js +240 -240
package/src/datatable.js
CHANGED
|
@@ -1,1056 +1,1056 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This program is free software; you can redistribute it and/or
|
|
3
|
-
* modify it under the terms of the GNU General Public License
|
|
4
|
-
* as published by the Free Software Foundation; under version 2
|
|
5
|
-
* of the License (non-upgradable).
|
|
6
|
-
*
|
|
7
|
-
* This program is distributed in the hope that it will be useful,
|
|
8
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
-
* GNU General Public License for more details.
|
|
11
|
-
*
|
|
12
|
-
* You should have received a copy of the GNU General Public License
|
|
13
|
-
* along with this program; if not, write to the Free Software
|
|
14
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
15
|
-
*
|
|
16
|
-
* Copyright (c) 2015-2020 (original work) Open Assessment Technologies SA;
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import $ from 'jquery';
|
|
20
|
-
import _ from 'lodash';
|
|
21
|
-
import __ from 'i18n';
|
|
22
|
-
import Pluginifier from 'core/pluginifier';
|
|
23
|
-
import layout from 'ui/datatable/tpl/layout';
|
|
24
|
-
import buttonTpl from 'ui/datatable/tpl/button';
|
|
25
|
-
import filterStrategyFactory from 'ui/datatable/filterStrategy/filterStrategy';
|
|
26
|
-
import paginationComponent from 'ui/pagination';
|
|
27
|
-
import loadingBar from 'layout/loading-bar';
|
|
28
|
-
import loggerFactory from 'core/logger';
|
|
29
|
-
import httpErrorParser from 'util/httpErrorParser';
|
|
30
|
-
import pageSizeSelector from 'ui/pageSizeSelector';
|
|
31
|
-
import 'ui/datatable/css/datatable.css';
|
|
32
|
-
import DOMPurify from 'lib/dompurify/purify';
|
|
33
|
-
|
|
34
|
-
const ns = 'datatable';
|
|
35
|
-
|
|
36
|
-
const dataNs = 'ui.' + ns;
|
|
37
|
-
|
|
38
|
-
const defaults = {
|
|
39
|
-
atomicUpdate: false,
|
|
40
|
-
start: 0,
|
|
41
|
-
rows: 25,
|
|
42
|
-
page: 1,
|
|
43
|
-
sortby: 'id',
|
|
44
|
-
sortorder: 'asc',
|
|
45
|
-
sorttype: 'string',
|
|
46
|
-
paginationStrategyTop: 'none',
|
|
47
|
-
paginationStrategyBottom: 'simple',
|
|
48
|
-
labels: {
|
|
49
|
-
filter: __('Filter'),
|
|
50
|
-
empty: __('Nothing to list!'),
|
|
51
|
-
available: __('Available'),
|
|
52
|
-
loading: __('Loading'),
|
|
53
|
-
actions: __('Actions')
|
|
54
|
-
},
|
|
55
|
-
pageSizeSelector: false
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const logger = loggerFactory('ui/datatable');
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* The CSS class used to hide an element
|
|
62
|
-
* @type {String}
|
|
63
|
-
*/
|
|
64
|
-
const hiddenCls = 'hidden';
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Deactivate pagination's
|
|
68
|
-
* @param {Array} pagination
|
|
69
|
-
*/
|
|
70
|
-
const disablePagination = pagination => {
|
|
71
|
-
if (pagination && pagination.length) {
|
|
72
|
-
pagination.forEach(step => {
|
|
73
|
-
step.disable();
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Activate pagination's
|
|
80
|
-
* @param {Array} pagination
|
|
81
|
-
*/
|
|
82
|
-
const enablePagination = pagination => {
|
|
83
|
-
if (pagination && pagination.length) {
|
|
84
|
-
pagination.forEach(step => {
|
|
85
|
-
step.enable();
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Helper for reading actions value in context
|
|
92
|
-
*
|
|
93
|
-
* @param {String} property
|
|
94
|
-
* @param {Object} action
|
|
95
|
-
* @param {Object} context
|
|
96
|
-
*/
|
|
97
|
-
const getPropertyValue = (property, action, context) => {
|
|
98
|
-
const value = action[property];
|
|
99
|
-
|
|
100
|
-
return _.isFunction(value) ? value.apply(context) : value;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Update the data table status in the header
|
|
105
|
-
*
|
|
106
|
-
* @param {Object} options
|
|
107
|
-
* @param {jQueryElement} $container
|
|
108
|
-
* @param {Object} dataset
|
|
109
|
-
*/
|
|
110
|
-
const updateHeaderStatus = (options, $container, dataset) => {
|
|
111
|
-
if (!options.status) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const $statusEmpty = $container.find('.empty-list');
|
|
116
|
-
const $statusAvailable = $container.find('.available-list');
|
|
117
|
-
const $statusCount = $statusAvailable.find('.count');
|
|
118
|
-
|
|
119
|
-
$container.find('.loading').addClass(hiddenCls);
|
|
120
|
-
|
|
121
|
-
// when the status is enabled, the response must contain the total amount of records
|
|
122
|
-
const amount = dataset.amount || dataset.length;
|
|
123
|
-
|
|
124
|
-
if (amount) {
|
|
125
|
-
$statusCount.text(amount);
|
|
126
|
-
$statusAvailable.removeClass(hiddenCls);
|
|
127
|
-
$statusEmpty.addClass(hiddenCls);
|
|
128
|
-
} else {
|
|
129
|
-
$statusEmpty.removeClass(hiddenCls);
|
|
130
|
-
$statusAvailable.addClass(hiddenCls);
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* The dataTable component makes you able to browse items and bind specific
|
|
136
|
-
* actions to undertake for edition and removal of them.
|
|
137
|
-
*
|
|
138
|
-
* Parameters that will be send to backend by component:
|
|
139
|
-
*
|
|
140
|
-
* Pagination
|
|
141
|
-
* @param {Number} rows - count of rows, that should be returned from backend, in other words limit.
|
|
142
|
-
* @param {Number} page - number of page, that should be requested.
|
|
143
|
-
*
|
|
144
|
-
* Sorting
|
|
145
|
-
* @param {String} sortby - name of column
|
|
146
|
-
* @param {String} sortorder - order of sorting, can be 'asc' or 'desc' for ascending sorting and descending sorting respectively.
|
|
147
|
-
* @param {String} sorttype - type of sorting, can be 'string' or 'numeric' for proper sorting numeric and string values.
|
|
148
|
-
*
|
|
149
|
-
* Filtering
|
|
150
|
-
* @param {String} filterstrategy - filtering strategy. Default is single (see ui/datatable/filterStrategy/single.js).
|
|
151
|
-
* @param {String} filterquery - query string for filtering of rows.
|
|
152
|
-
* @param {String[]} filtercolumns[] - array of columns, in which will be implemented search during filtering process.
|
|
153
|
-
* For column filter it will be only one item with column name, but component has ability define list of columns for default filter (in top toolbar).
|
|
154
|
-
* Backend should correctly receive this list of columns and do search in accordance with this parameters.
|
|
155
|
-
* By default, columns are not defined, so this parameter not will be sent. If filtercolumns[] not exists, backend should search by all columns.
|
|
156
|
-
*
|
|
157
|
-
* @example of query (GET): rows=25&page=1&sortby=login&sortorder=asc&filterquery=loginame&filtercolumns[]=login
|
|
158
|
-
*
|
|
159
|
-
* @exports ui/datatable
|
|
160
|
-
*/
|
|
161
|
-
const dataTable = {
|
|
162
|
-
/**
|
|
163
|
-
* Used for generating action button action button
|
|
164
|
-
* @typedef Action
|
|
165
|
-
* @type {Object}
|
|
166
|
-
* @property {String} id ID is added to the button class
|
|
167
|
-
* @property {String} [title] Button title
|
|
168
|
-
* @property {Boolean} [disabled] When present, button should be disabled
|
|
169
|
-
* @property {String} [icon] Generate button icon
|
|
170
|
-
* @property {Boolean} [hidden] When present, button is hidden
|
|
171
|
-
* @property {Function} [action] Handler on button click
|
|
172
|
-
*/
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Used for generating action button from Object
|
|
176
|
-
* @deprecated
|
|
177
|
-
* @typedef {{
|
|
178
|
-
* [key: Action.id & Action.icon & Action.title ]: Action.action,
|
|
179
|
-
* }} ActionsObject
|
|
180
|
-
*
|
|
181
|
-
* @example
|
|
182
|
-
* {
|
|
183
|
-
* actions: {
|
|
184
|
-
* edit: editUser,
|
|
185
|
-
* remove: removeUser,
|
|
186
|
-
* }
|
|
187
|
-
* }
|
|
188
|
-
*
|
|
189
|
-
* ! IMPORTANT USE INSTEAD:
|
|
190
|
-
* {
|
|
191
|
-
* actions: [
|
|
192
|
-
* {
|
|
193
|
-
* id: "edit",
|
|
194
|
-
* title: __("Edit"),
|
|
195
|
-
* icon: "edit",
|
|
196
|
-
* action: editUser
|
|
197
|
-
* },
|
|
198
|
-
* {
|
|
199
|
-
* id: "edit",
|
|
200
|
-
* title: __("Edit"),
|
|
201
|
-
* icon: "edit",
|
|
202
|
-
* action: editUser
|
|
203
|
-
* }
|
|
204
|
-
* ]
|
|
205
|
-
* }
|
|
206
|
-
*/
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Initialize the plugin.
|
|
210
|
-
*
|
|
211
|
-
* Called the jQuery way once registered by the Pluginifier.
|
|
212
|
-
* @example $('selector').datatable([], {});
|
|
213
|
-
*
|
|
214
|
-
* @constructor
|
|
215
|
-
* @param {Object} options - the plugin options.
|
|
216
|
-
* @param {String} options.url - the URL of the service used to retrieve the resources.
|
|
217
|
-
* @param {Object[]} options.model - the model definition.
|
|
218
|
-
* @param {ActionsObject | Action[]} options.actions - Generates action buttons
|
|
219
|
-
* @param {Function} options.listeners.xxx - the callback function for event xxx, parameters depends to event trigger call.
|
|
220
|
-
* @param {Boolean} options.selectable - enables the selection of rows using checkboxes.
|
|
221
|
-
* @param {Boolean} options.rowSelection - enables the selection of rows by clicking on them.
|
|
222
|
-
* @param {Object} options.tools - a list of tool buttons to display above the table.
|
|
223
|
-
* @param {Object|Boolean} options.status - allow to display a status bar.
|
|
224
|
-
* @param {Object|Boolean} options.filter - allow to display a filter bar.
|
|
225
|
-
* @param {String} options.filterStrategy - 'multiple' | 'single' -- filtered by all filters together or filtering allowed only by one field at the moment (default 'single'),
|
|
226
|
-
* @param {String} options.filterSelector - css selector for search of filter inputs, by defaul 'select, input'
|
|
227
|
-
* @param {String} options.filterTransform - transform filter value before send to server.
|
|
228
|
-
* @param {String[]} options.filter.columns - a list of columns that will be used for default filter. Can be overridden by column filter.
|
|
229
|
-
* @param {String} options.filterquery - a query string for filtering, using only in runtime.
|
|
230
|
-
* @param {String[]} options.filtercolumns - a list of columns, in that should be done search, using only in runtime.
|
|
231
|
-
* @param {String} options.paginationStrategyTop - 'none' | 'pages' | 'simple' -- 'none' by default (next/prev), 'pages' show pages and extended control for pagination
|
|
232
|
-
* @param {String} options.paginationStrategyBottom - 'none' | 'pages' | 'simple' -- 'simple' by default (next/prev), 'pages' show pages and extended control for pagination
|
|
233
|
-
* @param {Object} options.labels - list of labels in datatable interface, that can be overridden by incoming options
|
|
234
|
-
* @param {String} options.emptyText - text that will be shown when no data found for showing in the grid.
|
|
235
|
-
* @param {Boolean} options.pageSizeSelector - flag that indicates if control for changing page size should be displayed
|
|
236
|
-
* @param {Boolean} options.atomicUpdate - allowed to keep the datatable state to be able on "render" event, compare with new state and atomically update the table cells.
|
|
237
|
-
* @param {Function} options.requestInterceptor - Intercept sending AJAX request. The call of function must returns promise with provided data.
|
|
238
|
-
* @param {Object} [data] - inject predefined data to avoid the first query.
|
|
239
|
-
* @fires dataTable#create.datatable
|
|
240
|
-
* @returns {jQueryElement} for chaining
|
|
241
|
-
*/
|
|
242
|
-
init(options, data) {
|
|
243
|
-
options = _.defaults(options, defaults);
|
|
244
|
-
|
|
245
|
-
return this.each(function () {
|
|
246
|
-
const $elt = $(this);
|
|
247
|
-
const currentOptions = $elt.data(dataNs);
|
|
248
|
-
|
|
249
|
-
if (options.atomicUpdate && data) {
|
|
250
|
-
$elt.data(`${dataNs}state`, data.data);
|
|
251
|
-
}
|
|
252
|
-
// implement encapsulated pages for the datatable
|
|
253
|
-
$elt.paginations = [];
|
|
254
|
-
|
|
255
|
-
if (!currentOptions) {
|
|
256
|
-
//add data to the element
|
|
257
|
-
$elt.data(dataNs, options);
|
|
258
|
-
|
|
259
|
-
$elt.one('load.' + ns, function () {
|
|
260
|
-
/**
|
|
261
|
-
* @event dataTable#create.datatable
|
|
262
|
-
*/
|
|
263
|
-
$elt.trigger('create.' + ns);
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
if (data) {
|
|
267
|
-
dataTable._render($elt, data);
|
|
268
|
-
} else {
|
|
269
|
-
dataTable._query($elt);
|
|
270
|
-
}
|
|
271
|
-
} else {
|
|
272
|
-
// update existing options
|
|
273
|
-
$elt.data(dataNs, _.merge(currentOptions, options));
|
|
274
|
-
|
|
275
|
-
dataTable._refresh($elt, data);
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
},
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Refresh the data table using current options
|
|
282
|
-
*
|
|
283
|
-
* Called the jQuery way once registered by the Pluginifier.
|
|
284
|
-
* @example $('selector').datatable('refresh');
|
|
285
|
-
*
|
|
286
|
-
* @param {jQueryElement} $elt - plugin's element
|
|
287
|
-
* @param {Object} [data] - Data to render immediately, prevents the query to be made.
|
|
288
|
-
*/
|
|
289
|
-
_refresh($elt, data) {
|
|
290
|
-
if (data) {
|
|
291
|
-
this._render($elt, data);
|
|
292
|
-
} else {
|
|
293
|
-
this._query($elt);
|
|
294
|
-
}
|
|
295
|
-
},
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Query the server for data and load the table.
|
|
299
|
-
*
|
|
300
|
-
* @private
|
|
301
|
-
* @param {jQueryElement} $elt - plugin's element
|
|
302
|
-
* @param $filter
|
|
303
|
-
* @fires dataTable#query.datatable
|
|
304
|
-
*/
|
|
305
|
-
_query($elt, $filter) {
|
|
306
|
-
const self = this;
|
|
307
|
-
let options = $elt.data(dataNs);
|
|
308
|
-
|
|
309
|
-
loadingBar.start();
|
|
310
|
-
|
|
311
|
-
if (!$filter) {
|
|
312
|
-
$filter = $('.filter', $elt);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
options = _.assign({}, options, this._getFilterStrategy($elt).getQueryData($elt, $filter, options));
|
|
316
|
-
|
|
317
|
-
const parameters = _.merge(
|
|
318
|
-
{},
|
|
319
|
-
_.pick(options, ['rows', 'page', 'sortby', 'sortorder', 'sorttype', 'filterquery', 'filtercolumns']),
|
|
320
|
-
options.params || {}
|
|
321
|
-
);
|
|
322
|
-
|
|
323
|
-
const ajaxConfig = {
|
|
324
|
-
url: options.url,
|
|
325
|
-
data: parameters,
|
|
326
|
-
dataType: 'json',
|
|
327
|
-
type: options.querytype || 'GET'
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
// disable pagination to not press multiple on it
|
|
331
|
-
disablePagination($elt.paginations);
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* @event dataTable#query.datatable
|
|
335
|
-
* @param {Object} ajaxConfig - The config object used to setup the AJAX request
|
|
336
|
-
*/
|
|
337
|
-
$elt.trigger('query.' + ns, [ajaxConfig]);
|
|
338
|
-
|
|
339
|
-
// display the loading state
|
|
340
|
-
if (options.status) {
|
|
341
|
-
$elt.find('.loading').removeClass(hiddenCls);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
if (typeof options.requestInterceptor === 'function') {
|
|
345
|
-
Promise.resolve(options.requestInterceptor(parameters))
|
|
346
|
-
.then(data => {
|
|
347
|
-
self._render($elt, data);
|
|
348
|
-
})
|
|
349
|
-
.catch(error => {
|
|
350
|
-
$elt.trigger('error.' + ns, [error]);
|
|
351
|
-
self._render($elt, {});
|
|
352
|
-
});
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
$.ajax(ajaxConfig)
|
|
357
|
-
.done(function (response) {
|
|
358
|
-
if ($elt && typeof $elt.data(dataNs) !== 'object') {
|
|
359
|
-
return $elt.trigger(`error.${ns}`, [new Error(`Unable to load data attached to the element`)]);
|
|
360
|
-
}
|
|
361
|
-
self._render($elt, response);
|
|
362
|
-
})
|
|
363
|
-
.fail(function (response, option, err) {
|
|
364
|
-
const requestErr = httpErrorParser.parse(response, option, err);
|
|
365
|
-
logger.error(requestErr.message);
|
|
366
|
-
requestErr.code = response.status;
|
|
367
|
-
enablePagination(this.paginations);
|
|
368
|
-
$elt.trigger('error.' + ns, [requestErr]);
|
|
369
|
-
|
|
370
|
-
self._render($elt, {});
|
|
371
|
-
});
|
|
372
|
-
},
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Renders the table using the provided data set
|
|
376
|
-
*
|
|
377
|
-
* @param {jQueryElement} $elt - plugin's element
|
|
378
|
-
* @param {Object} dataset - the data set to render
|
|
379
|
-
* @private
|
|
380
|
-
* @fires dataTable#beforeload.datatable
|
|
381
|
-
* @fires dataTable#load.datatable
|
|
382
|
-
*/
|
|
383
|
-
_render($elt, dataset = {}) {
|
|
384
|
-
const self = this;
|
|
385
|
-
let options = _.cloneDeep($elt.data(dataNs));
|
|
386
|
-
if (typeof options === 'undefined') {
|
|
387
|
-
return $elt.trigger(`error.${ns}`, [new Error(`Unable to load data attached to the element`)]);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const model = [];
|
|
391
|
-
let $massActionBtns = $();
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* @event dataTable#beforeload.datatable
|
|
395
|
-
* @param {Object} dataset - The data set object used to render the table
|
|
396
|
-
*/
|
|
397
|
-
$elt.trigger('beforeload.' + ns, [_.cloneDeep(dataset)]);
|
|
398
|
-
|
|
399
|
-
// overrides column options
|
|
400
|
-
_.forEach(options.model, function (field, key) {
|
|
401
|
-
if (!options.filter) {
|
|
402
|
-
field.filterable = false;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
if (_.isUndefined(field.order)) {
|
|
406
|
-
field.order = key + 1;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
if (field.filterable && typeof field.filterable !== 'object') {
|
|
410
|
-
field.filterable = { placeholder: __('Filter') };
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
if (typeof field.visible === 'undefined') {
|
|
414
|
-
model.push(field);
|
|
415
|
-
} else if (typeof field.visible === 'function' && field.visible()) {
|
|
416
|
-
model.push(field);
|
|
417
|
-
} else if (field.visible === true) {
|
|
418
|
-
model.push(field);
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
model.sort(function (a, b) {
|
|
423
|
-
return a.order - b.order;
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
if (options.sortby) {
|
|
427
|
-
options = this._sortOptions($elt, options.sortby, options.sortorder, options.sorttype);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// process data by model rules
|
|
431
|
-
if (_.some(model, 'transform')) {
|
|
432
|
-
const transforms = _.where(model, 'transform');
|
|
433
|
-
|
|
434
|
-
_.forEach(dataset.data, (row, index) => {
|
|
435
|
-
_.forEach(transforms, field => {
|
|
436
|
-
if (_.isFunction(field.transform)) {
|
|
437
|
-
row[field.id] = field.transform(row[field.id], row, field, index, dataset.data);
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
options.model = model;
|
|
444
|
-
|
|
445
|
-
if (options.atomicUpdate) {
|
|
446
|
-
const skipForceUpdate = this._shallowUpdate($elt, dataset, options);
|
|
447
|
-
|
|
448
|
-
if (skipForceUpdate) {
|
|
449
|
-
updateHeaderStatus(options, $elt, dataset);
|
|
450
|
-
loadingBar.stop();
|
|
451
|
-
$elt.trigger(`load.${ns}`, [dataset]);
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// Call the rendering
|
|
457
|
-
const $rendering = $(layout({ options: options, dataset: dataset }));
|
|
458
|
-
|
|
459
|
-
// the readonly property contains an associative array where keys are the ids of the items (lines)
|
|
460
|
-
// the value can be a boolean (true for disable buttons, false to enable)
|
|
461
|
-
// it can also bo an array that let you disable/enable the action you want
|
|
462
|
-
// readonly = {
|
|
463
|
-
// id1 : {'view':true, 'delete':false},
|
|
464
|
-
// id2 : true
|
|
465
|
-
//}
|
|
466
|
-
_.forEach(dataset.readonly, function (values, id) {
|
|
467
|
-
if (values === true) {
|
|
468
|
-
$('[data-item-identifier="' + id + '"] button', $rendering).addClass('disabled');
|
|
469
|
-
} else if (values && typeof values === 'object') {
|
|
470
|
-
for (const action in values) {
|
|
471
|
-
if (Object.prototype.hasOwnProperty.call(values, action) && values[action] === true) {
|
|
472
|
-
$(`[data-item-identifier="${id}"] button.${action}`, $rendering).addClass('disabled');
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Attach handlers on the action buttons
|
|
480
|
-
* @param {ActionsObject | Action[]} actions
|
|
481
|
-
*/
|
|
482
|
-
const attachActionListeners = actions => {
|
|
483
|
-
// Attach a listener to every action button created
|
|
484
|
-
_.forEach(actions, (action, name) => {
|
|
485
|
-
if (!_.isFunction(action)) {
|
|
486
|
-
name = action.id || name;
|
|
487
|
-
action = action.action || function () {};
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
const css = `.${name}`;
|
|
491
|
-
|
|
492
|
-
$rendering.off('click', css).on('click', css, function (e) {
|
|
493
|
-
e.preventDefault();
|
|
494
|
-
|
|
495
|
-
const $btn = $(this);
|
|
496
|
-
|
|
497
|
-
if (!$btn.hasClass('disabled')) {
|
|
498
|
-
const identifier = $btn.closest('[data-item-identifier]').data('item-identifier');
|
|
499
|
-
|
|
500
|
-
action.apply($btn, [
|
|
501
|
-
identifier,
|
|
502
|
-
_.first(
|
|
503
|
-
_.where(dataset.data, {
|
|
504
|
-
id: identifier
|
|
505
|
-
})
|
|
506
|
-
)
|
|
507
|
-
]);
|
|
508
|
-
}
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
};
|
|
512
|
-
|
|
513
|
-
if (options.actions) {
|
|
514
|
-
attachActionListeners(options.actions);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// Attach listeners to model.type = action
|
|
518
|
-
if (_.some(options.model, 'type')) {
|
|
519
|
-
const types = _.where(options.model, 'type');
|
|
520
|
-
_.forEach(types, field => {
|
|
521
|
-
if (field.type === 'actions' && field.actions) {
|
|
522
|
-
attachActionListeners(field.actions);
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// Attach a listener to every tool button created
|
|
528
|
-
_.forEach(options.tools, (action, name) => {
|
|
529
|
-
let isMassAction = true;
|
|
530
|
-
|
|
531
|
-
if (!_.isFunction(action)) {
|
|
532
|
-
name = action.id || name;
|
|
533
|
-
isMassAction = action.massAction;
|
|
534
|
-
action = action.action || function () {};
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
const css = `.tool-${name}`;
|
|
538
|
-
|
|
539
|
-
if (isMassAction) {
|
|
540
|
-
$massActionBtns = $massActionBtns.add($rendering.find(css));
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
$rendering.off('click', css).on('click', css, function (e) {
|
|
544
|
-
e.preventDefault();
|
|
545
|
-
|
|
546
|
-
const $btn = $(this);
|
|
547
|
-
|
|
548
|
-
if (!$btn.hasClass('disabled')) {
|
|
549
|
-
action.apply($btn, [self._selection($elt)]);
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
// bind listeners to events
|
|
555
|
-
_.forEach(options.listeners, (callback, event) => {
|
|
556
|
-
const ev = [event, ns].join('.');
|
|
557
|
-
$elt.off(ev).on(ev, callback);
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
function renderPagination($container, mode) {
|
|
561
|
-
return paginationComponent({
|
|
562
|
-
mode: mode,
|
|
563
|
-
activePage: dataset.page,
|
|
564
|
-
totalPages: dataset.total
|
|
565
|
-
})
|
|
566
|
-
.on('change', function () {
|
|
567
|
-
self._setPage($elt, this.getActivePage());
|
|
568
|
-
})
|
|
569
|
-
.on('prev', function () {
|
|
570
|
-
/**
|
|
571
|
-
* @event dataTable#backward.dataTable
|
|
572
|
-
*/
|
|
573
|
-
$elt.trigger('backward.' + ns);
|
|
574
|
-
})
|
|
575
|
-
.on('next', function () {
|
|
576
|
-
/**
|
|
577
|
-
* @event dataTable#forward.dataTable
|
|
578
|
-
*/
|
|
579
|
-
$elt.trigger('forward.' + ns);
|
|
580
|
-
})
|
|
581
|
-
.render($container);
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
$elt.paginations = [];
|
|
585
|
-
|
|
586
|
-
if (options.paginationStrategyTop !== 'none') {
|
|
587
|
-
// bind pagination component to the datatable
|
|
588
|
-
$elt.paginations.push(
|
|
589
|
-
renderPagination($('.datatable-pagination-top', $rendering), options.paginationStrategyTop)
|
|
590
|
-
);
|
|
591
|
-
}
|
|
592
|
-
if (options.paginationStrategyBottom !== 'none') {
|
|
593
|
-
// bind pagination component to the datatable
|
|
594
|
-
$elt.paginations.push(
|
|
595
|
-
renderPagination($('.datatable-pagination-bottom', $rendering), options.paginationStrategyBottom)
|
|
596
|
-
);
|
|
597
|
-
}
|
|
598
|
-
disablePagination($elt.paginations);
|
|
599
|
-
|
|
600
|
-
// Now $rendering takes the place of $elt...
|
|
601
|
-
const $rows = $rendering.find('tbody tr');
|
|
602
|
-
const $sortBy = $rendering.find('th [data-sort-by]');
|
|
603
|
-
const $sortElement = $rendering.find('[data-sort-by="' + options.sortby + '"]');
|
|
604
|
-
const $checkAll = $rendering.find('th.checkboxes input');
|
|
605
|
-
const $checkboxes = $rendering.find('td.checkboxes input');
|
|
606
|
-
|
|
607
|
-
if (options.rowSelection) {
|
|
608
|
-
$('table.datatable', $rendering).addClass('hoverable');
|
|
609
|
-
$rendering.on('click', 'tbody td', function (e) {
|
|
610
|
-
// exclude from processing columns with actions
|
|
611
|
-
if ($(e.target).hasClass('checkboxes') || $(e.target).hasClass('actions')) {
|
|
612
|
-
return false;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
const currentRow = $(this).parent();
|
|
616
|
-
|
|
617
|
-
$rows.removeClass('selected');
|
|
618
|
-
currentRow.toggleClass('selected');
|
|
619
|
-
|
|
620
|
-
$elt.trigger('selected.' + ns, _.where(dataset.data, { id: currentRow.data('item-identifier') }));
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
$sortBy.on('click keyup', function (e) {
|
|
625
|
-
if (e.type === 'keyup' && e.keyCode !== 13) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
e.preventDefault();
|
|
629
|
-
const column = $(this).data('sort-by');
|
|
630
|
-
const type = $(this).data('sort-type');
|
|
631
|
-
|
|
632
|
-
self._sort($elt, column, void 0, type);
|
|
633
|
-
});
|
|
634
|
-
|
|
635
|
-
// Add the filter behavior
|
|
636
|
-
if (options.filter) {
|
|
637
|
-
self._getFilterStrategy($elt).render($rendering, options);
|
|
638
|
-
_.forEach($('.filter', $rendering), function (filter) {
|
|
639
|
-
const $filter = $(filter);
|
|
640
|
-
const $filterBtn = $('button', $filter);
|
|
641
|
-
const $filterInput = $('select, input', $filter);
|
|
642
|
-
|
|
643
|
-
if ($filterInput.is('select')) {
|
|
644
|
-
$filterInput.on('change', function () {
|
|
645
|
-
self._filter($elt, $filter);
|
|
646
|
-
});
|
|
647
|
-
} else {
|
|
648
|
-
// clicking the button trigger the request
|
|
649
|
-
$filterBtn.off('click').on('click', function (e) {
|
|
650
|
-
e.preventDefault();
|
|
651
|
-
self._filter($elt, $filter);
|
|
652
|
-
});
|
|
653
|
-
|
|
654
|
-
// or press ENTER
|
|
655
|
-
$filterInput.off('keypress').on('keypress', function (e) {
|
|
656
|
-
if (e.which === 13) {
|
|
657
|
-
e.preventDefault();
|
|
658
|
-
self._filter($elt, $filter);
|
|
659
|
-
}
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
// check/uncheck all checkboxes
|
|
666
|
-
$checkAll.click(function () {
|
|
667
|
-
if (this.checked) {
|
|
668
|
-
$checkAll.prop('checked', true);
|
|
669
|
-
$checkboxes.prop('checked', true);
|
|
670
|
-
} else {
|
|
671
|
-
$checkAll.prop('checked', false);
|
|
672
|
-
$checkboxes.prop('checked', false);
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
if ($massActionBtns.length) {
|
|
676
|
-
$massActionBtns.toggleClass('invisible', !$checkboxes.filter(':checked').length);
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
/**
|
|
680
|
-
* @event dataTable#select.dataTable
|
|
681
|
-
*/
|
|
682
|
-
$elt.trigger('select.' + ns);
|
|
683
|
-
});
|
|
684
|
-
|
|
685
|
-
// when check/uncheck a box, toggle the check/uncheck all
|
|
686
|
-
$checkboxes.click(function () {
|
|
687
|
-
const $checked = $checkboxes.filter(':checked');
|
|
688
|
-
|
|
689
|
-
if ($checked.length === $checkboxes.length) {
|
|
690
|
-
$checkAll.prop('checked', true);
|
|
691
|
-
} else {
|
|
692
|
-
$checkAll.prop('checked', false);
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
if ($massActionBtns.length) {
|
|
696
|
-
$massActionBtns.toggleClass('invisible', !$checkboxes.filter(':checked').length);
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
/**
|
|
700
|
-
* @event dataTable#select.dataTable
|
|
701
|
-
*/
|
|
702
|
-
$elt.trigger('select.' + ns);
|
|
703
|
-
});
|
|
704
|
-
|
|
705
|
-
// Remove sorted class from all th
|
|
706
|
-
$('th.sorted', $rendering).removeClass('sorted');
|
|
707
|
-
// Add the sorted class to the sorted element and the order class
|
|
708
|
-
$sortElement.addClass('sorted').addClass('sorted_' + options.sortorder);
|
|
709
|
-
|
|
710
|
-
// Update the status
|
|
711
|
-
|
|
712
|
-
updateHeaderStatus(options, $rendering, dataset);
|
|
713
|
-
|
|
714
|
-
$elt.html($rendering);
|
|
715
|
-
|
|
716
|
-
// if the filter is enabled and a value is present, set the focus on the input field
|
|
717
|
-
if (options.filter && options.filterquery) {
|
|
718
|
-
$rendering.find('[name=filter].focused').focus();
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
// restore pagination's after data loaded
|
|
722
|
-
enablePagination($elt.paginations);
|
|
723
|
-
|
|
724
|
-
if (options.pageSizeSelector) {
|
|
725
|
-
pageSizeSelector({
|
|
726
|
-
renderTo: $('.toolbox-container', $rendering),
|
|
727
|
-
defaultSize: options.rows
|
|
728
|
-
}).on('change', function (val) {
|
|
729
|
-
self._setRows($elt, val);
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
loadingBar.stop();
|
|
734
|
-
|
|
735
|
-
/**
|
|
736
|
-
* @event dataTable#load.dataTable
|
|
737
|
-
* @param {Object} dataset - The data set used to render the table
|
|
738
|
-
*/
|
|
739
|
-
$elt.trigger('load.' + ns, [dataset]);
|
|
740
|
-
},
|
|
741
|
-
|
|
742
|
-
/**
|
|
743
|
-
* Query set new page
|
|
744
|
-
*
|
|
745
|
-
* @param $elt
|
|
746
|
-
* @param page
|
|
747
|
-
* @fires dataTable#setpage.datatable
|
|
748
|
-
*/
|
|
749
|
-
_setPage($elt, page) {
|
|
750
|
-
const options = $elt.data(dataNs);
|
|
751
|
-
|
|
752
|
-
if (options.page !== page) {
|
|
753
|
-
// set new page value
|
|
754
|
-
options.page = page;
|
|
755
|
-
|
|
756
|
-
//rebind options to the elt
|
|
757
|
-
$elt.data(dataNs, options);
|
|
758
|
-
|
|
759
|
-
/**
|
|
760
|
-
* @event dataTable#setpage.dataTable
|
|
761
|
-
*/
|
|
762
|
-
$elt.trigger('setpage.' + ns);
|
|
763
|
-
|
|
764
|
-
// Call the query
|
|
765
|
-
this._query($elt);
|
|
766
|
-
}
|
|
767
|
-
},
|
|
768
|
-
|
|
769
|
-
/**
|
|
770
|
-
* Query filtered list of items
|
|
771
|
-
*
|
|
772
|
-
* @param {jQueryElement} $elt - plugin's element
|
|
773
|
-
* @param {jQueryElement} $filter - the filter input
|
|
774
|
-
* @fires dataTable#filter.datatable
|
|
775
|
-
* @fires dataTable#sort.datatable
|
|
776
|
-
* @private
|
|
777
|
-
*/
|
|
778
|
-
_filter($elt, $filter) {
|
|
779
|
-
const options = $elt.data(dataNs);
|
|
780
|
-
const filtersData = this._getFilterStrategy($elt).getFiltersData($elt, $filter, options);
|
|
781
|
-
options.page = 1;
|
|
782
|
-
$elt.data(dataNs, _.assign(options, filtersData));
|
|
783
|
-
|
|
784
|
-
/**
|
|
785
|
-
* @event dataTable#filter.datatable
|
|
786
|
-
* @param {Object} options - The options list
|
|
787
|
-
*/
|
|
788
|
-
$elt.trigger('filter.' + ns, [options]);
|
|
789
|
-
|
|
790
|
-
// Call the query
|
|
791
|
-
this._query($elt, $filter);
|
|
792
|
-
},
|
|
793
|
-
|
|
794
|
-
_getFilterStrategy($elt) {
|
|
795
|
-
const options = $elt.data(dataNs);
|
|
796
|
-
|
|
797
|
-
return filterStrategyFactory(options);
|
|
798
|
-
},
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
* Query the previous page
|
|
802
|
-
*
|
|
803
|
-
* Called the jQuery way once registered by the Pluginifier.
|
|
804
|
-
* @example $('selector').datatable('sort', 'firstname', false);
|
|
805
|
-
*
|
|
806
|
-
* @param {jQueryElement} $elt - plugin's element
|
|
807
|
-
* @param {String} sortBy - the model id of the col to sort
|
|
808
|
-
* @param {Boolean} [asc] - sort direction true for asc of deduced
|
|
809
|
-
* @param {String} sortType - type of sorting, numeric or string
|
|
810
|
-
* @fires dataTable#sort.datatable
|
|
811
|
-
*/
|
|
812
|
-
_sort($elt, sortBy, asc, sortType) {
|
|
813
|
-
const options = this._sortOptions($elt, sortBy, asc, sortType);
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* @event dataTable#sort.datatable
|
|
817
|
-
* @param {String} column - The name of the column to sort
|
|
818
|
-
* @param {String} direction - The sort direction
|
|
819
|
-
* @param {String} type - The type of sorting field, string or numeric
|
|
820
|
-
*/
|
|
821
|
-
$elt.trigger('sort.' + ns, [options.sortby, options.sortorder, options.sorttype]);
|
|
822
|
-
|
|
823
|
-
this._query($elt);
|
|
824
|
-
},
|
|
825
|
-
|
|
826
|
-
/**
|
|
827
|
-
* Compared current and next number of row and identifiers order of rows.
|
|
828
|
-
*
|
|
829
|
-
* @param {dataset} currentState
|
|
830
|
-
* @param {dataset} nextState
|
|
831
|
-
* @returns {Boolean}
|
|
832
|
-
*/
|
|
833
|
-
_canApplyShallowUpdate(currentState, nextState) {
|
|
834
|
-
const isStatesHasData = _.has(currentState, 'data') && _.has(nextState, 'data');
|
|
835
|
-
|
|
836
|
-
if (!isStatesHasData) {
|
|
837
|
-
return false;
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
const currentData = currentState.data;
|
|
841
|
-
const nextData = nextState.data;
|
|
842
|
-
|
|
843
|
-
if (currentData.length !== nextData.length) {
|
|
844
|
-
return false;
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
return _.isEqual(
|
|
848
|
-
currentData.map(data => data.id),
|
|
849
|
-
nextData.map(data => data.id)
|
|
850
|
-
);
|
|
851
|
-
},
|
|
852
|
-
|
|
853
|
-
/**
|
|
854
|
-
* Check possibility of atomic update data in datatable.
|
|
855
|
-
*
|
|
856
|
-
* @param {jQueryElement} $container Data table container element
|
|
857
|
-
* @param {Object} nextState Data to be set to the data table
|
|
858
|
-
* @param {Object} options Data table options
|
|
859
|
-
* @returns {Boolean} Return true when data in table can be atomically updated
|
|
860
|
-
*/
|
|
861
|
-
_shallowUpdate($container, nextState, options) {
|
|
862
|
-
const currentState = $container.data(`${dataNs}state`);
|
|
863
|
-
|
|
864
|
-
// Always update data state
|
|
865
|
-
$container.data(`${dataNs}state`, nextState);
|
|
866
|
-
|
|
867
|
-
if (!this._canApplyShallowUpdate(currentState, nextState)) {
|
|
868
|
-
return;
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
// NOTE: The code above generate the table cell. With updating handlebars to the version > 2.*, please move it to the dedicated template to reuse it in layout.tpl as well
|
|
872
|
-
nextState.data.forEach(nextData => {
|
|
873
|
-
const $row = $container.find(`tr[data-item-identifier="${nextData.id}"]`);
|
|
874
|
-
|
|
875
|
-
options.model.forEach(model => {
|
|
876
|
-
const cellId = model.id;
|
|
877
|
-
|
|
878
|
-
if (model.type) {
|
|
879
|
-
const $actionCell = $row.find(`td.actions.${cellId}`);
|
|
880
|
-
|
|
881
|
-
$actionCell.html('');
|
|
882
|
-
|
|
883
|
-
model.actions.forEach(action => {
|
|
884
|
-
const id = action.id;
|
|
885
|
-
const hidden = getPropertyValue('hidden', action, nextData);
|
|
886
|
-
const title = getPropertyValue('title', action, nextData);
|
|
887
|
-
const disabled = getPropertyValue('disabled', action, nextData);
|
|
888
|
-
const icon = getPropertyValue('icon', action, nextData);
|
|
889
|
-
const label = getPropertyValue('label', action, nextData);
|
|
890
|
-
const $actionButton = $(buttonTpl({ id, icon, label, title, disabled }));
|
|
891
|
-
|
|
892
|
-
if (!hidden) {
|
|
893
|
-
$actionCell.append('\n').append($actionButton);
|
|
894
|
-
}
|
|
895
|
-
});
|
|
896
|
-
} else {
|
|
897
|
-
const nextContent = nextData[cellId];
|
|
898
|
-
|
|
899
|
-
$row.find(`td.${cellId}`).html(DOMPurify.sanitize(nextContent));
|
|
900
|
-
}
|
|
901
|
-
});
|
|
902
|
-
});
|
|
903
|
-
|
|
904
|
-
return true;
|
|
905
|
-
},
|
|
906
|
-
|
|
907
|
-
/**
|
|
908
|
-
* Set the sort options.
|
|
909
|
-
*
|
|
910
|
-
* @param {jQueryElement} $elt - plugin's element
|
|
911
|
-
* @param {String} sortBy - the model id of the col to sort
|
|
912
|
-
* @param {Boolean|String} [asc] - sort direction true for asc of deduced
|
|
913
|
-
* @param {String} sortType - sorting type, numeric or string sorting
|
|
914
|
-
* @returns {Object} - returns the options
|
|
915
|
-
* @private
|
|
916
|
-
*/
|
|
917
|
-
_sortOptions($elt, sortBy, asc, sortType) {
|
|
918
|
-
const options = $elt.data(dataNs);
|
|
919
|
-
|
|
920
|
-
if (typeof asc !== 'undefined') {
|
|
921
|
-
if ('asc' !== asc && 'desc' !== asc) {
|
|
922
|
-
asc = asc ? 'asc' : 'desc';
|
|
923
|
-
}
|
|
924
|
-
options.sortorder = asc;
|
|
925
|
-
} else if (options.sortorder === 'asc' && options.sortby === sortBy) {
|
|
926
|
-
// If I already sort asc this element
|
|
927
|
-
options.sortorder = 'desc';
|
|
928
|
-
} else {
|
|
929
|
-
// If I never sort by this element or
|
|
930
|
-
// I sort by this element & the order was desc
|
|
931
|
-
options.sortorder = 'asc';
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
// Change the sorting element anyway.
|
|
935
|
-
options.sortby = sortBy;
|
|
936
|
-
|
|
937
|
-
// define sorting type
|
|
938
|
-
options.sorttype = sortType;
|
|
939
|
-
|
|
940
|
-
//rebind options to the elt
|
|
941
|
-
$elt.data(dataNs, options);
|
|
942
|
-
|
|
943
|
-
return _.cloneDeep(options);
|
|
944
|
-
},
|
|
945
|
-
|
|
946
|
-
/**
|
|
947
|
-
* Gets the selected items. Returns an array of identifiers.
|
|
948
|
-
*
|
|
949
|
-
* @param {jQueryElement} $elt - plugin's element
|
|
950
|
-
* @returns {Array} - Returns an array of identifiers.
|
|
951
|
-
*/
|
|
952
|
-
_selection($elt) {
|
|
953
|
-
const $selected = $elt.find('[data-item-identifier]').has('td.checkboxes input:checked');
|
|
954
|
-
const selection = [];
|
|
955
|
-
|
|
956
|
-
$selected.each(function () {
|
|
957
|
-
selection.push($(this).data('item-identifier'));
|
|
958
|
-
});
|
|
959
|
-
|
|
960
|
-
return selection;
|
|
961
|
-
},
|
|
962
|
-
|
|
963
|
-
_highlightRows($elt, rowIds) {
|
|
964
|
-
$elt.find('[data-item-identifier]').removeClass('highlight');
|
|
965
|
-
|
|
966
|
-
rowIds.forEach(rowId => {
|
|
967
|
-
this._highlightRow($elt, rowId);
|
|
968
|
-
});
|
|
969
|
-
},
|
|
970
|
-
/**
|
|
971
|
-
* Highlight the row with identifier
|
|
972
|
-
*
|
|
973
|
-
* @param $elt
|
|
974
|
-
* @param rowId
|
|
975
|
-
* @deprecated Use highlightRows instead
|
|
976
|
-
*/
|
|
977
|
-
_highlightRow($elt, rowId) {
|
|
978
|
-
this._addRowClass($elt, rowId, 'highlight');
|
|
979
|
-
},
|
|
980
|
-
|
|
981
|
-
/**
|
|
982
|
-
* Css class add to the row with id
|
|
983
|
-
*
|
|
984
|
-
* @param $elt
|
|
985
|
-
* @param rowId
|
|
986
|
-
* @param className
|
|
987
|
-
* @private
|
|
988
|
-
*/
|
|
989
|
-
_addRowClass($elt, rowId, className) {
|
|
990
|
-
const $row = $elt.find('[data-item-identifier="' + rowId + '"]');
|
|
991
|
-
|
|
992
|
-
if (!$row.hasClass(className)) {
|
|
993
|
-
$row.addClass(className);
|
|
994
|
-
}
|
|
995
|
-
},
|
|
996
|
-
|
|
997
|
-
/**
|
|
998
|
-
* Css class remove from the row with id
|
|
999
|
-
*
|
|
1000
|
-
* @param $elt
|
|
1001
|
-
* @param rowId
|
|
1002
|
-
* @param className
|
|
1003
|
-
* @private
|
|
1004
|
-
*/
|
|
1005
|
-
_removeRowClass($elt, rowId, className) {
|
|
1006
|
-
const $row = $elt.find('[data-item-identifier="' + rowId + '"]');
|
|
1007
|
-
|
|
1008
|
-
if ($row.hasClass(className)) {
|
|
1009
|
-
$row.removeClass(className);
|
|
1010
|
-
}
|
|
1011
|
-
},
|
|
1012
|
-
|
|
1013
|
-
/**
|
|
1014
|
-
* Update amount items per page
|
|
1015
|
-
*
|
|
1016
|
-
* @param $elt
|
|
1017
|
-
* @param rows
|
|
1018
|
-
* @fires dataTable#setpage.datatable
|
|
1019
|
-
*/
|
|
1020
|
-
_setRows($elt, rows) {
|
|
1021
|
-
const options = $elt.data(dataNs);
|
|
1022
|
-
|
|
1023
|
-
if (options.rows !== rows) {
|
|
1024
|
-
// set new amount of items per page
|
|
1025
|
-
options.rows = rows;
|
|
1026
|
-
|
|
1027
|
-
// set page to the first one
|
|
1028
|
-
options.page = 1;
|
|
1029
|
-
|
|
1030
|
-
//rebind options to the elt
|
|
1031
|
-
$elt.data(dataNs, options);
|
|
1032
|
-
|
|
1033
|
-
/**
|
|
1034
|
-
* @event dataTable#setpage.dataTable
|
|
1035
|
-
*/
|
|
1036
|
-
$elt.trigger('setpage.' + ns);
|
|
1037
|
-
|
|
1038
|
-
// Call the query
|
|
1039
|
-
this._query($elt);
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
};
|
|
1043
|
-
|
|
1044
|
-
Pluginifier.register(ns, dataTable, {
|
|
1045
|
-
expose: [
|
|
1046
|
-
'refresh',
|
|
1047
|
-
'sort',
|
|
1048
|
-
'filter',
|
|
1049
|
-
'selection',
|
|
1050
|
-
'render',
|
|
1051
|
-
'highlightRow',
|
|
1052
|
-
'highlightRows',
|
|
1053
|
-
'addRowClass',
|
|
1054
|
-
'removeRowClass'
|
|
1055
|
-
]
|
|
1056
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* This program is free software; you can redistribute it and/or
|
|
3
|
+
* modify it under the terms of the GNU General Public License
|
|
4
|
+
* as published by the Free Software Foundation; under version 2
|
|
5
|
+
* of the License (non-upgradable).
|
|
6
|
+
*
|
|
7
|
+
* This program is distributed in the hope that it will be useful,
|
|
8
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
* GNU General Public License for more details.
|
|
11
|
+
*
|
|
12
|
+
* You should have received a copy of the GNU General Public License
|
|
13
|
+
* along with this program; if not, write to the Free Software
|
|
14
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
15
|
+
*
|
|
16
|
+
* Copyright (c) 2015-2020 (original work) Open Assessment Technologies SA;
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import $ from 'jquery';
|
|
20
|
+
import _ from 'lodash';
|
|
21
|
+
import __ from 'i18n';
|
|
22
|
+
import Pluginifier from 'core/pluginifier';
|
|
23
|
+
import layout from 'ui/datatable/tpl/layout';
|
|
24
|
+
import buttonTpl from 'ui/datatable/tpl/button';
|
|
25
|
+
import filterStrategyFactory from 'ui/datatable/filterStrategy/filterStrategy';
|
|
26
|
+
import paginationComponent from 'ui/pagination';
|
|
27
|
+
import loadingBar from 'layout/loading-bar';
|
|
28
|
+
import loggerFactory from 'core/logger';
|
|
29
|
+
import httpErrorParser from 'util/httpErrorParser';
|
|
30
|
+
import pageSizeSelector from 'ui/pageSizeSelector';
|
|
31
|
+
import 'ui/datatable/css/datatable.css';
|
|
32
|
+
import DOMPurify from 'lib/dompurify/purify';
|
|
33
|
+
|
|
34
|
+
const ns = 'datatable';
|
|
35
|
+
|
|
36
|
+
const dataNs = 'ui.' + ns;
|
|
37
|
+
|
|
38
|
+
const defaults = {
|
|
39
|
+
atomicUpdate: false,
|
|
40
|
+
start: 0,
|
|
41
|
+
rows: 25,
|
|
42
|
+
page: 1,
|
|
43
|
+
sortby: 'id',
|
|
44
|
+
sortorder: 'asc',
|
|
45
|
+
sorttype: 'string',
|
|
46
|
+
paginationStrategyTop: 'none',
|
|
47
|
+
paginationStrategyBottom: 'simple',
|
|
48
|
+
labels: {
|
|
49
|
+
filter: __('Filter'),
|
|
50
|
+
empty: __('Nothing to list!'),
|
|
51
|
+
available: __('Available'),
|
|
52
|
+
loading: __('Loading'),
|
|
53
|
+
actions: __('Actions')
|
|
54
|
+
},
|
|
55
|
+
pageSizeSelector: false
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const logger = loggerFactory('ui/datatable');
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The CSS class used to hide an element
|
|
62
|
+
* @type {String}
|
|
63
|
+
*/
|
|
64
|
+
const hiddenCls = 'hidden';
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Deactivate pagination's
|
|
68
|
+
* @param {Array} pagination
|
|
69
|
+
*/
|
|
70
|
+
const disablePagination = pagination => {
|
|
71
|
+
if (pagination && pagination.length) {
|
|
72
|
+
pagination.forEach(step => {
|
|
73
|
+
step.disable();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Activate pagination's
|
|
80
|
+
* @param {Array} pagination
|
|
81
|
+
*/
|
|
82
|
+
const enablePagination = pagination => {
|
|
83
|
+
if (pagination && pagination.length) {
|
|
84
|
+
pagination.forEach(step => {
|
|
85
|
+
step.enable();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Helper for reading actions value in context
|
|
92
|
+
*
|
|
93
|
+
* @param {String} property
|
|
94
|
+
* @param {Object} action
|
|
95
|
+
* @param {Object} context
|
|
96
|
+
*/
|
|
97
|
+
const getPropertyValue = (property, action, context) => {
|
|
98
|
+
const value = action[property];
|
|
99
|
+
|
|
100
|
+
return _.isFunction(value) ? value.apply(context) : value;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Update the data table status in the header
|
|
105
|
+
*
|
|
106
|
+
* @param {Object} options
|
|
107
|
+
* @param {jQueryElement} $container
|
|
108
|
+
* @param {Object} dataset
|
|
109
|
+
*/
|
|
110
|
+
const updateHeaderStatus = (options, $container, dataset) => {
|
|
111
|
+
if (!options.status) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const $statusEmpty = $container.find('.empty-list');
|
|
116
|
+
const $statusAvailable = $container.find('.available-list');
|
|
117
|
+
const $statusCount = $statusAvailable.find('.count');
|
|
118
|
+
|
|
119
|
+
$container.find('.loading').addClass(hiddenCls);
|
|
120
|
+
|
|
121
|
+
// when the status is enabled, the response must contain the total amount of records
|
|
122
|
+
const amount = dataset.amount || dataset.length;
|
|
123
|
+
|
|
124
|
+
if (amount) {
|
|
125
|
+
$statusCount.text(amount);
|
|
126
|
+
$statusAvailable.removeClass(hiddenCls);
|
|
127
|
+
$statusEmpty.addClass(hiddenCls);
|
|
128
|
+
} else {
|
|
129
|
+
$statusEmpty.removeClass(hiddenCls);
|
|
130
|
+
$statusAvailable.addClass(hiddenCls);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The dataTable component makes you able to browse items and bind specific
|
|
136
|
+
* actions to undertake for edition and removal of them.
|
|
137
|
+
*
|
|
138
|
+
* Parameters that will be send to backend by component:
|
|
139
|
+
*
|
|
140
|
+
* Pagination
|
|
141
|
+
* @param {Number} rows - count of rows, that should be returned from backend, in other words limit.
|
|
142
|
+
* @param {Number} page - number of page, that should be requested.
|
|
143
|
+
*
|
|
144
|
+
* Sorting
|
|
145
|
+
* @param {String} sortby - name of column
|
|
146
|
+
* @param {String} sortorder - order of sorting, can be 'asc' or 'desc' for ascending sorting and descending sorting respectively.
|
|
147
|
+
* @param {String} sorttype - type of sorting, can be 'string' or 'numeric' for proper sorting numeric and string values.
|
|
148
|
+
*
|
|
149
|
+
* Filtering
|
|
150
|
+
* @param {String} filterstrategy - filtering strategy. Default is single (see ui/datatable/filterStrategy/single.js).
|
|
151
|
+
* @param {String} filterquery - query string for filtering of rows.
|
|
152
|
+
* @param {String[]} filtercolumns[] - array of columns, in which will be implemented search during filtering process.
|
|
153
|
+
* For column filter it will be only one item with column name, but component has ability define list of columns for default filter (in top toolbar).
|
|
154
|
+
* Backend should correctly receive this list of columns and do search in accordance with this parameters.
|
|
155
|
+
* By default, columns are not defined, so this parameter not will be sent. If filtercolumns[] not exists, backend should search by all columns.
|
|
156
|
+
*
|
|
157
|
+
* @example of query (GET): rows=25&page=1&sortby=login&sortorder=asc&filterquery=loginame&filtercolumns[]=login
|
|
158
|
+
*
|
|
159
|
+
* @exports ui/datatable
|
|
160
|
+
*/
|
|
161
|
+
const dataTable = {
|
|
162
|
+
/**
|
|
163
|
+
* Used for generating action button action button
|
|
164
|
+
* @typedef Action
|
|
165
|
+
* @type {Object}
|
|
166
|
+
* @property {String} id ID is added to the button class
|
|
167
|
+
* @property {String} [title] Button title
|
|
168
|
+
* @property {Boolean} [disabled] When present, button should be disabled
|
|
169
|
+
* @property {String} [icon] Generate button icon
|
|
170
|
+
* @property {Boolean} [hidden] When present, button is hidden
|
|
171
|
+
* @property {Function} [action] Handler on button click
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Used for generating action button from Object
|
|
176
|
+
* @deprecated
|
|
177
|
+
* @typedef {{
|
|
178
|
+
* [key: Action.id & Action.icon & Action.title ]: Action.action,
|
|
179
|
+
* }} ActionsObject
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* {
|
|
183
|
+
* actions: {
|
|
184
|
+
* edit: editUser,
|
|
185
|
+
* remove: removeUser,
|
|
186
|
+
* }
|
|
187
|
+
* }
|
|
188
|
+
*
|
|
189
|
+
* ! IMPORTANT USE INSTEAD:
|
|
190
|
+
* {
|
|
191
|
+
* actions: [
|
|
192
|
+
* {
|
|
193
|
+
* id: "edit",
|
|
194
|
+
* title: __("Edit"),
|
|
195
|
+
* icon: "edit",
|
|
196
|
+
* action: editUser
|
|
197
|
+
* },
|
|
198
|
+
* {
|
|
199
|
+
* id: "edit",
|
|
200
|
+
* title: __("Edit"),
|
|
201
|
+
* icon: "edit",
|
|
202
|
+
* action: editUser
|
|
203
|
+
* }
|
|
204
|
+
* ]
|
|
205
|
+
* }
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Initialize the plugin.
|
|
210
|
+
*
|
|
211
|
+
* Called the jQuery way once registered by the Pluginifier.
|
|
212
|
+
* @example $('selector').datatable([], {});
|
|
213
|
+
*
|
|
214
|
+
* @constructor
|
|
215
|
+
* @param {Object} options - the plugin options.
|
|
216
|
+
* @param {String} options.url - the URL of the service used to retrieve the resources.
|
|
217
|
+
* @param {Object[]} options.model - the model definition.
|
|
218
|
+
* @param {ActionsObject | Action[]} options.actions - Generates action buttons
|
|
219
|
+
* @param {Function} options.listeners.xxx - the callback function for event xxx, parameters depends to event trigger call.
|
|
220
|
+
* @param {Boolean} options.selectable - enables the selection of rows using checkboxes.
|
|
221
|
+
* @param {Boolean} options.rowSelection - enables the selection of rows by clicking on them.
|
|
222
|
+
* @param {Object} options.tools - a list of tool buttons to display above the table.
|
|
223
|
+
* @param {Object|Boolean} options.status - allow to display a status bar.
|
|
224
|
+
* @param {Object|Boolean} options.filter - allow to display a filter bar.
|
|
225
|
+
* @param {String} options.filterStrategy - 'multiple' | 'single' -- filtered by all filters together or filtering allowed only by one field at the moment (default 'single'),
|
|
226
|
+
* @param {String} options.filterSelector - css selector for search of filter inputs, by defaul 'select, input'
|
|
227
|
+
* @param {String} options.filterTransform - transform filter value before send to server.
|
|
228
|
+
* @param {String[]} options.filter.columns - a list of columns that will be used for default filter. Can be overridden by column filter.
|
|
229
|
+
* @param {String} options.filterquery - a query string for filtering, using only in runtime.
|
|
230
|
+
* @param {String[]} options.filtercolumns - a list of columns, in that should be done search, using only in runtime.
|
|
231
|
+
* @param {String} options.paginationStrategyTop - 'none' | 'pages' | 'simple' -- 'none' by default (next/prev), 'pages' show pages and extended control for pagination
|
|
232
|
+
* @param {String} options.paginationStrategyBottom - 'none' | 'pages' | 'simple' -- 'simple' by default (next/prev), 'pages' show pages and extended control for pagination
|
|
233
|
+
* @param {Object} options.labels - list of labels in datatable interface, that can be overridden by incoming options
|
|
234
|
+
* @param {String} options.emptyText - text that will be shown when no data found for showing in the grid.
|
|
235
|
+
* @param {Boolean} options.pageSizeSelector - flag that indicates if control for changing page size should be displayed
|
|
236
|
+
* @param {Boolean} options.atomicUpdate - allowed to keep the datatable state to be able on "render" event, compare with new state and atomically update the table cells.
|
|
237
|
+
* @param {Function} options.requestInterceptor - Intercept sending AJAX request. The call of function must returns promise with provided data.
|
|
238
|
+
* @param {Object} [data] - inject predefined data to avoid the first query.
|
|
239
|
+
* @fires dataTable#create.datatable
|
|
240
|
+
* @returns {jQueryElement} for chaining
|
|
241
|
+
*/
|
|
242
|
+
init(options, data) {
|
|
243
|
+
options = _.defaults(options, defaults);
|
|
244
|
+
|
|
245
|
+
return this.each(function () {
|
|
246
|
+
const $elt = $(this);
|
|
247
|
+
const currentOptions = $elt.data(dataNs);
|
|
248
|
+
|
|
249
|
+
if (options.atomicUpdate && data) {
|
|
250
|
+
$elt.data(`${dataNs}state`, data.data);
|
|
251
|
+
}
|
|
252
|
+
// implement encapsulated pages for the datatable
|
|
253
|
+
$elt.paginations = [];
|
|
254
|
+
|
|
255
|
+
if (!currentOptions) {
|
|
256
|
+
//add data to the element
|
|
257
|
+
$elt.data(dataNs, options);
|
|
258
|
+
|
|
259
|
+
$elt.one('load.' + ns, function () {
|
|
260
|
+
/**
|
|
261
|
+
* @event dataTable#create.datatable
|
|
262
|
+
*/
|
|
263
|
+
$elt.trigger('create.' + ns);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
if (data) {
|
|
267
|
+
dataTable._render($elt, data);
|
|
268
|
+
} else {
|
|
269
|
+
dataTable._query($elt);
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
// update existing options
|
|
273
|
+
$elt.data(dataNs, _.merge(currentOptions, options));
|
|
274
|
+
|
|
275
|
+
dataTable._refresh($elt, data);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Refresh the data table using current options
|
|
282
|
+
*
|
|
283
|
+
* Called the jQuery way once registered by the Pluginifier.
|
|
284
|
+
* @example $('selector').datatable('refresh');
|
|
285
|
+
*
|
|
286
|
+
* @param {jQueryElement} $elt - plugin's element
|
|
287
|
+
* @param {Object} [data] - Data to render immediately, prevents the query to be made.
|
|
288
|
+
*/
|
|
289
|
+
_refresh($elt, data) {
|
|
290
|
+
if (data) {
|
|
291
|
+
this._render($elt, data);
|
|
292
|
+
} else {
|
|
293
|
+
this._query($elt);
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Query the server for data and load the table.
|
|
299
|
+
*
|
|
300
|
+
* @private
|
|
301
|
+
* @param {jQueryElement} $elt - plugin's element
|
|
302
|
+
* @param $filter
|
|
303
|
+
* @fires dataTable#query.datatable
|
|
304
|
+
*/
|
|
305
|
+
_query($elt, $filter) {
|
|
306
|
+
const self = this;
|
|
307
|
+
let options = $elt.data(dataNs);
|
|
308
|
+
|
|
309
|
+
loadingBar.start();
|
|
310
|
+
|
|
311
|
+
if (!$filter) {
|
|
312
|
+
$filter = $('.filter', $elt);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
options = _.assign({}, options, this._getFilterStrategy($elt).getQueryData($elt, $filter, options));
|
|
316
|
+
|
|
317
|
+
const parameters = _.merge(
|
|
318
|
+
{},
|
|
319
|
+
_.pick(options, ['rows', 'page', 'sortby', 'sortorder', 'sorttype', 'filterquery', 'filtercolumns']),
|
|
320
|
+
options.params || {}
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
const ajaxConfig = {
|
|
324
|
+
url: options.url,
|
|
325
|
+
data: parameters,
|
|
326
|
+
dataType: 'json',
|
|
327
|
+
type: options.querytype || 'GET'
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// disable pagination to not press multiple on it
|
|
331
|
+
disablePagination($elt.paginations);
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* @event dataTable#query.datatable
|
|
335
|
+
* @param {Object} ajaxConfig - The config object used to setup the AJAX request
|
|
336
|
+
*/
|
|
337
|
+
$elt.trigger('query.' + ns, [ajaxConfig]);
|
|
338
|
+
|
|
339
|
+
// display the loading state
|
|
340
|
+
if (options.status) {
|
|
341
|
+
$elt.find('.loading').removeClass(hiddenCls);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (typeof options.requestInterceptor === 'function') {
|
|
345
|
+
Promise.resolve(options.requestInterceptor(parameters))
|
|
346
|
+
.then(data => {
|
|
347
|
+
self._render($elt, data);
|
|
348
|
+
})
|
|
349
|
+
.catch(error => {
|
|
350
|
+
$elt.trigger('error.' + ns, [error]);
|
|
351
|
+
self._render($elt, {});
|
|
352
|
+
});
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
$.ajax(ajaxConfig)
|
|
357
|
+
.done(function (response) {
|
|
358
|
+
if ($elt && typeof $elt.data(dataNs) !== 'object') {
|
|
359
|
+
return $elt.trigger(`error.${ns}`, [new Error(`Unable to load data attached to the element`)]);
|
|
360
|
+
}
|
|
361
|
+
self._render($elt, response);
|
|
362
|
+
})
|
|
363
|
+
.fail(function (response, option, err) {
|
|
364
|
+
const requestErr = httpErrorParser.parse(response, option, err);
|
|
365
|
+
logger.error(requestErr.message);
|
|
366
|
+
requestErr.code = response.status;
|
|
367
|
+
enablePagination(this.paginations);
|
|
368
|
+
$elt.trigger('error.' + ns, [requestErr]);
|
|
369
|
+
|
|
370
|
+
self._render($elt, {});
|
|
371
|
+
});
|
|
372
|
+
},
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Renders the table using the provided data set
|
|
376
|
+
*
|
|
377
|
+
* @param {jQueryElement} $elt - plugin's element
|
|
378
|
+
* @param {Object} dataset - the data set to render
|
|
379
|
+
* @private
|
|
380
|
+
* @fires dataTable#beforeload.datatable
|
|
381
|
+
* @fires dataTable#load.datatable
|
|
382
|
+
*/
|
|
383
|
+
_render($elt, dataset = {}) {
|
|
384
|
+
const self = this;
|
|
385
|
+
let options = _.cloneDeep($elt.data(dataNs));
|
|
386
|
+
if (typeof options === 'undefined') {
|
|
387
|
+
return $elt.trigger(`error.${ns}`, [new Error(`Unable to load data attached to the element`)]);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const model = [];
|
|
391
|
+
let $massActionBtns = $();
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* @event dataTable#beforeload.datatable
|
|
395
|
+
* @param {Object} dataset - The data set object used to render the table
|
|
396
|
+
*/
|
|
397
|
+
$elt.trigger('beforeload.' + ns, [_.cloneDeep(dataset)]);
|
|
398
|
+
|
|
399
|
+
// overrides column options
|
|
400
|
+
_.forEach(options.model, function (field, key) {
|
|
401
|
+
if (!options.filter) {
|
|
402
|
+
field.filterable = false;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (_.isUndefined(field.order)) {
|
|
406
|
+
field.order = key + 1;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (field.filterable && typeof field.filterable !== 'object') {
|
|
410
|
+
field.filterable = { placeholder: __('Filter') };
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (typeof field.visible === 'undefined') {
|
|
414
|
+
model.push(field);
|
|
415
|
+
} else if (typeof field.visible === 'function' && field.visible()) {
|
|
416
|
+
model.push(field);
|
|
417
|
+
} else if (field.visible === true) {
|
|
418
|
+
model.push(field);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
model.sort(function (a, b) {
|
|
423
|
+
return a.order - b.order;
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
if (options.sortby) {
|
|
427
|
+
options = this._sortOptions($elt, options.sortby, options.sortorder, options.sorttype);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// process data by model rules
|
|
431
|
+
if (_.some(model, 'transform')) {
|
|
432
|
+
const transforms = _.where(model, 'transform');
|
|
433
|
+
|
|
434
|
+
_.forEach(dataset.data, (row, index) => {
|
|
435
|
+
_.forEach(transforms, field => {
|
|
436
|
+
if (_.isFunction(field.transform)) {
|
|
437
|
+
row[field.id] = field.transform(row[field.id], row, field, index, dataset.data);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
options.model = model;
|
|
444
|
+
|
|
445
|
+
if (options.atomicUpdate) {
|
|
446
|
+
const skipForceUpdate = this._shallowUpdate($elt, dataset, options);
|
|
447
|
+
|
|
448
|
+
if (skipForceUpdate) {
|
|
449
|
+
updateHeaderStatus(options, $elt, dataset);
|
|
450
|
+
loadingBar.stop();
|
|
451
|
+
$elt.trigger(`load.${ns}`, [dataset]);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Call the rendering
|
|
457
|
+
const $rendering = $(layout({ options: options, dataset: dataset }));
|
|
458
|
+
|
|
459
|
+
// the readonly property contains an associative array where keys are the ids of the items (lines)
|
|
460
|
+
// the value can be a boolean (true for disable buttons, false to enable)
|
|
461
|
+
// it can also bo an array that let you disable/enable the action you want
|
|
462
|
+
// readonly = {
|
|
463
|
+
// id1 : {'view':true, 'delete':false},
|
|
464
|
+
// id2 : true
|
|
465
|
+
//}
|
|
466
|
+
_.forEach(dataset.readonly, function (values, id) {
|
|
467
|
+
if (values === true) {
|
|
468
|
+
$('[data-item-identifier="' + id + '"] button', $rendering).addClass('disabled');
|
|
469
|
+
} else if (values && typeof values === 'object') {
|
|
470
|
+
for (const action in values) {
|
|
471
|
+
if (Object.prototype.hasOwnProperty.call(values, action) && values[action] === true) {
|
|
472
|
+
$(`[data-item-identifier="${id}"] button.${action}`, $rendering).addClass('disabled');
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Attach handlers on the action buttons
|
|
480
|
+
* @param {ActionsObject | Action[]} actions
|
|
481
|
+
*/
|
|
482
|
+
const attachActionListeners = actions => {
|
|
483
|
+
// Attach a listener to every action button created
|
|
484
|
+
_.forEach(actions, (action, name) => {
|
|
485
|
+
if (!_.isFunction(action)) {
|
|
486
|
+
name = action.id || name;
|
|
487
|
+
action = action.action || function () {};
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const css = `.${name}`;
|
|
491
|
+
|
|
492
|
+
$rendering.off('click', css).on('click', css, function (e) {
|
|
493
|
+
e.preventDefault();
|
|
494
|
+
|
|
495
|
+
const $btn = $(this);
|
|
496
|
+
|
|
497
|
+
if (!$btn.hasClass('disabled')) {
|
|
498
|
+
const identifier = $btn.closest('[data-item-identifier]').data('item-identifier');
|
|
499
|
+
|
|
500
|
+
action.apply($btn, [
|
|
501
|
+
identifier,
|
|
502
|
+
_.first(
|
|
503
|
+
_.where(dataset.data, {
|
|
504
|
+
id: identifier
|
|
505
|
+
})
|
|
506
|
+
)
|
|
507
|
+
]);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
});
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
if (options.actions) {
|
|
514
|
+
attachActionListeners(options.actions);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Attach listeners to model.type = action
|
|
518
|
+
if (_.some(options.model, 'type')) {
|
|
519
|
+
const types = _.where(options.model, 'type');
|
|
520
|
+
_.forEach(types, field => {
|
|
521
|
+
if (field.type === 'actions' && field.actions) {
|
|
522
|
+
attachActionListeners(field.actions);
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Attach a listener to every tool button created
|
|
528
|
+
_.forEach(options.tools, (action, name) => {
|
|
529
|
+
let isMassAction = true;
|
|
530
|
+
|
|
531
|
+
if (!_.isFunction(action)) {
|
|
532
|
+
name = action.id || name;
|
|
533
|
+
isMassAction = action.massAction;
|
|
534
|
+
action = action.action || function () {};
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
const css = `.tool-${name}`;
|
|
538
|
+
|
|
539
|
+
if (isMassAction) {
|
|
540
|
+
$massActionBtns = $massActionBtns.add($rendering.find(css));
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
$rendering.off('click', css).on('click', css, function (e) {
|
|
544
|
+
e.preventDefault();
|
|
545
|
+
|
|
546
|
+
const $btn = $(this);
|
|
547
|
+
|
|
548
|
+
if (!$btn.hasClass('disabled')) {
|
|
549
|
+
action.apply($btn, [self._selection($elt)]);
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
// bind listeners to events
|
|
555
|
+
_.forEach(options.listeners, (callback, event) => {
|
|
556
|
+
const ev = [event, ns].join('.');
|
|
557
|
+
$elt.off(ev).on(ev, callback);
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
function renderPagination($container, mode) {
|
|
561
|
+
return paginationComponent({
|
|
562
|
+
mode: mode,
|
|
563
|
+
activePage: dataset.page,
|
|
564
|
+
totalPages: dataset.total
|
|
565
|
+
})
|
|
566
|
+
.on('change', function () {
|
|
567
|
+
self._setPage($elt, this.getActivePage());
|
|
568
|
+
})
|
|
569
|
+
.on('prev', function () {
|
|
570
|
+
/**
|
|
571
|
+
* @event dataTable#backward.dataTable
|
|
572
|
+
*/
|
|
573
|
+
$elt.trigger('backward.' + ns);
|
|
574
|
+
})
|
|
575
|
+
.on('next', function () {
|
|
576
|
+
/**
|
|
577
|
+
* @event dataTable#forward.dataTable
|
|
578
|
+
*/
|
|
579
|
+
$elt.trigger('forward.' + ns);
|
|
580
|
+
})
|
|
581
|
+
.render($container);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
$elt.paginations = [];
|
|
585
|
+
|
|
586
|
+
if (options.paginationStrategyTop !== 'none') {
|
|
587
|
+
// bind pagination component to the datatable
|
|
588
|
+
$elt.paginations.push(
|
|
589
|
+
renderPagination($('.datatable-pagination-top', $rendering), options.paginationStrategyTop)
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
if (options.paginationStrategyBottom !== 'none') {
|
|
593
|
+
// bind pagination component to the datatable
|
|
594
|
+
$elt.paginations.push(
|
|
595
|
+
renderPagination($('.datatable-pagination-bottom', $rendering), options.paginationStrategyBottom)
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
disablePagination($elt.paginations);
|
|
599
|
+
|
|
600
|
+
// Now $rendering takes the place of $elt...
|
|
601
|
+
const $rows = $rendering.find('tbody tr');
|
|
602
|
+
const $sortBy = $rendering.find('th [data-sort-by]');
|
|
603
|
+
const $sortElement = $rendering.find('[data-sort-by="' + options.sortby + '"]');
|
|
604
|
+
const $checkAll = $rendering.find('th.checkboxes input');
|
|
605
|
+
const $checkboxes = $rendering.find('td.checkboxes input');
|
|
606
|
+
|
|
607
|
+
if (options.rowSelection) {
|
|
608
|
+
$('table.datatable', $rendering).addClass('hoverable');
|
|
609
|
+
$rendering.on('click', 'tbody td', function (e) {
|
|
610
|
+
// exclude from processing columns with actions
|
|
611
|
+
if ($(e.target).hasClass('checkboxes') || $(e.target).hasClass('actions')) {
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const currentRow = $(this).parent();
|
|
616
|
+
|
|
617
|
+
$rows.removeClass('selected');
|
|
618
|
+
currentRow.toggleClass('selected');
|
|
619
|
+
|
|
620
|
+
$elt.trigger('selected.' + ns, _.where(dataset.data, { id: currentRow.data('item-identifier') }));
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
$sortBy.on('click keyup', function (e) {
|
|
625
|
+
if (e.type === 'keyup' && e.keyCode !== 13) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
e.preventDefault();
|
|
629
|
+
const column = $(this).data('sort-by');
|
|
630
|
+
const type = $(this).data('sort-type');
|
|
631
|
+
|
|
632
|
+
self._sort($elt, column, void 0, type);
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
// Add the filter behavior
|
|
636
|
+
if (options.filter) {
|
|
637
|
+
self._getFilterStrategy($elt).render($rendering, options);
|
|
638
|
+
_.forEach($('.filter', $rendering), function (filter) {
|
|
639
|
+
const $filter = $(filter);
|
|
640
|
+
const $filterBtn = $('button', $filter);
|
|
641
|
+
const $filterInput = $('select, input', $filter);
|
|
642
|
+
|
|
643
|
+
if ($filterInput.is('select')) {
|
|
644
|
+
$filterInput.on('change', function () {
|
|
645
|
+
self._filter($elt, $filter);
|
|
646
|
+
});
|
|
647
|
+
} else {
|
|
648
|
+
// clicking the button trigger the request
|
|
649
|
+
$filterBtn.off('click').on('click', function (e) {
|
|
650
|
+
e.preventDefault();
|
|
651
|
+
self._filter($elt, $filter);
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
// or press ENTER
|
|
655
|
+
$filterInput.off('keypress').on('keypress', function (e) {
|
|
656
|
+
if (e.which === 13) {
|
|
657
|
+
e.preventDefault();
|
|
658
|
+
self._filter($elt, $filter);
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// check/uncheck all checkboxes
|
|
666
|
+
$checkAll.click(function () {
|
|
667
|
+
if (this.checked) {
|
|
668
|
+
$checkAll.prop('checked', true);
|
|
669
|
+
$checkboxes.prop('checked', true);
|
|
670
|
+
} else {
|
|
671
|
+
$checkAll.prop('checked', false);
|
|
672
|
+
$checkboxes.prop('checked', false);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
if ($massActionBtns.length) {
|
|
676
|
+
$massActionBtns.toggleClass('invisible', !$checkboxes.filter(':checked').length);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* @event dataTable#select.dataTable
|
|
681
|
+
*/
|
|
682
|
+
$elt.trigger('select.' + ns);
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
// when check/uncheck a box, toggle the check/uncheck all
|
|
686
|
+
$checkboxes.click(function () {
|
|
687
|
+
const $checked = $checkboxes.filter(':checked');
|
|
688
|
+
|
|
689
|
+
if ($checked.length === $checkboxes.length) {
|
|
690
|
+
$checkAll.prop('checked', true);
|
|
691
|
+
} else {
|
|
692
|
+
$checkAll.prop('checked', false);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
if ($massActionBtns.length) {
|
|
696
|
+
$massActionBtns.toggleClass('invisible', !$checkboxes.filter(':checked').length);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* @event dataTable#select.dataTable
|
|
701
|
+
*/
|
|
702
|
+
$elt.trigger('select.' + ns);
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
// Remove sorted class from all th
|
|
706
|
+
$('th.sorted', $rendering).removeClass('sorted');
|
|
707
|
+
// Add the sorted class to the sorted element and the order class
|
|
708
|
+
$sortElement.addClass('sorted').addClass('sorted_' + options.sortorder);
|
|
709
|
+
|
|
710
|
+
// Update the status
|
|
711
|
+
|
|
712
|
+
updateHeaderStatus(options, $rendering, dataset);
|
|
713
|
+
|
|
714
|
+
$elt.html($rendering);
|
|
715
|
+
|
|
716
|
+
// if the filter is enabled and a value is present, set the focus on the input field
|
|
717
|
+
if (options.filter && options.filterquery) {
|
|
718
|
+
$rendering.find('[name=filter].focused').focus();
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// restore pagination's after data loaded
|
|
722
|
+
enablePagination($elt.paginations);
|
|
723
|
+
|
|
724
|
+
if (options.pageSizeSelector) {
|
|
725
|
+
pageSizeSelector({
|
|
726
|
+
renderTo: $('.toolbox-container', $rendering),
|
|
727
|
+
defaultSize: options.rows
|
|
728
|
+
}).on('change', function (val) {
|
|
729
|
+
self._setRows($elt, val);
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
loadingBar.stop();
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* @event dataTable#load.dataTable
|
|
737
|
+
* @param {Object} dataset - The data set used to render the table
|
|
738
|
+
*/
|
|
739
|
+
$elt.trigger('load.' + ns, [dataset]);
|
|
740
|
+
},
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Query set new page
|
|
744
|
+
*
|
|
745
|
+
* @param $elt
|
|
746
|
+
* @param page
|
|
747
|
+
* @fires dataTable#setpage.datatable
|
|
748
|
+
*/
|
|
749
|
+
_setPage($elt, page) {
|
|
750
|
+
const options = $elt.data(dataNs);
|
|
751
|
+
|
|
752
|
+
if (options.page !== page) {
|
|
753
|
+
// set new page value
|
|
754
|
+
options.page = page;
|
|
755
|
+
|
|
756
|
+
//rebind options to the elt
|
|
757
|
+
$elt.data(dataNs, options);
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* @event dataTable#setpage.dataTable
|
|
761
|
+
*/
|
|
762
|
+
$elt.trigger('setpage.' + ns);
|
|
763
|
+
|
|
764
|
+
// Call the query
|
|
765
|
+
this._query($elt);
|
|
766
|
+
}
|
|
767
|
+
},
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* Query filtered list of items
|
|
771
|
+
*
|
|
772
|
+
* @param {jQueryElement} $elt - plugin's element
|
|
773
|
+
* @param {jQueryElement} $filter - the filter input
|
|
774
|
+
* @fires dataTable#filter.datatable
|
|
775
|
+
* @fires dataTable#sort.datatable
|
|
776
|
+
* @private
|
|
777
|
+
*/
|
|
778
|
+
_filter($elt, $filter) {
|
|
779
|
+
const options = $elt.data(dataNs);
|
|
780
|
+
const filtersData = this._getFilterStrategy($elt).getFiltersData($elt, $filter, options);
|
|
781
|
+
options.page = 1;
|
|
782
|
+
$elt.data(dataNs, _.assign(options, filtersData));
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* @event dataTable#filter.datatable
|
|
786
|
+
* @param {Object} options - The options list
|
|
787
|
+
*/
|
|
788
|
+
$elt.trigger('filter.' + ns, [options]);
|
|
789
|
+
|
|
790
|
+
// Call the query
|
|
791
|
+
this._query($elt, $filter);
|
|
792
|
+
},
|
|
793
|
+
|
|
794
|
+
_getFilterStrategy($elt) {
|
|
795
|
+
const options = $elt.data(dataNs);
|
|
796
|
+
|
|
797
|
+
return filterStrategyFactory(options);
|
|
798
|
+
},
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* Query the previous page
|
|
802
|
+
*
|
|
803
|
+
* Called the jQuery way once registered by the Pluginifier.
|
|
804
|
+
* @example $('selector').datatable('sort', 'firstname', false);
|
|
805
|
+
*
|
|
806
|
+
* @param {jQueryElement} $elt - plugin's element
|
|
807
|
+
* @param {String} sortBy - the model id of the col to sort
|
|
808
|
+
* @param {Boolean} [asc] - sort direction true for asc of deduced
|
|
809
|
+
* @param {String} sortType - type of sorting, numeric or string
|
|
810
|
+
* @fires dataTable#sort.datatable
|
|
811
|
+
*/
|
|
812
|
+
_sort($elt, sortBy, asc, sortType) {
|
|
813
|
+
const options = this._sortOptions($elt, sortBy, asc, sortType);
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* @event dataTable#sort.datatable
|
|
817
|
+
* @param {String} column - The name of the column to sort
|
|
818
|
+
* @param {String} direction - The sort direction
|
|
819
|
+
* @param {String} type - The type of sorting field, string or numeric
|
|
820
|
+
*/
|
|
821
|
+
$elt.trigger('sort.' + ns, [options.sortby, options.sortorder, options.sorttype]);
|
|
822
|
+
|
|
823
|
+
this._query($elt);
|
|
824
|
+
},
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Compared current and next number of row and identifiers order of rows.
|
|
828
|
+
*
|
|
829
|
+
* @param {dataset} currentState
|
|
830
|
+
* @param {dataset} nextState
|
|
831
|
+
* @returns {Boolean}
|
|
832
|
+
*/
|
|
833
|
+
_canApplyShallowUpdate(currentState, nextState) {
|
|
834
|
+
const isStatesHasData = _.has(currentState, 'data') && _.has(nextState, 'data');
|
|
835
|
+
|
|
836
|
+
if (!isStatesHasData) {
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
const currentData = currentState.data;
|
|
841
|
+
const nextData = nextState.data;
|
|
842
|
+
|
|
843
|
+
if (currentData.length !== nextData.length) {
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
return _.isEqual(
|
|
848
|
+
currentData.map(data => data.id),
|
|
849
|
+
nextData.map(data => data.id)
|
|
850
|
+
);
|
|
851
|
+
},
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Check possibility of atomic update data in datatable.
|
|
855
|
+
*
|
|
856
|
+
* @param {jQueryElement} $container Data table container element
|
|
857
|
+
* @param {Object} nextState Data to be set to the data table
|
|
858
|
+
* @param {Object} options Data table options
|
|
859
|
+
* @returns {Boolean} Return true when data in table can be atomically updated
|
|
860
|
+
*/
|
|
861
|
+
_shallowUpdate($container, nextState, options) {
|
|
862
|
+
const currentState = $container.data(`${dataNs}state`);
|
|
863
|
+
|
|
864
|
+
// Always update data state
|
|
865
|
+
$container.data(`${dataNs}state`, nextState);
|
|
866
|
+
|
|
867
|
+
if (!this._canApplyShallowUpdate(currentState, nextState)) {
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// NOTE: The code above generate the table cell. With updating handlebars to the version > 2.*, please move it to the dedicated template to reuse it in layout.tpl as well
|
|
872
|
+
nextState.data.forEach(nextData => {
|
|
873
|
+
const $row = $container.find(`tr[data-item-identifier="${nextData.id}"]`);
|
|
874
|
+
|
|
875
|
+
options.model.forEach(model => {
|
|
876
|
+
const cellId = model.id;
|
|
877
|
+
|
|
878
|
+
if (model.type) {
|
|
879
|
+
const $actionCell = $row.find(`td.actions.${cellId}`);
|
|
880
|
+
|
|
881
|
+
$actionCell.html('');
|
|
882
|
+
|
|
883
|
+
model.actions.forEach(action => {
|
|
884
|
+
const id = action.id;
|
|
885
|
+
const hidden = getPropertyValue('hidden', action, nextData);
|
|
886
|
+
const title = getPropertyValue('title', action, nextData);
|
|
887
|
+
const disabled = getPropertyValue('disabled', action, nextData);
|
|
888
|
+
const icon = getPropertyValue('icon', action, nextData);
|
|
889
|
+
const label = getPropertyValue('label', action, nextData);
|
|
890
|
+
const $actionButton = $(buttonTpl({ id, icon, label, title, disabled }));
|
|
891
|
+
|
|
892
|
+
if (!hidden) {
|
|
893
|
+
$actionCell.append('\n').append($actionButton);
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
} else {
|
|
897
|
+
const nextContent = nextData[cellId];
|
|
898
|
+
|
|
899
|
+
$row.find(`td.${cellId}`).html(DOMPurify.sanitize(nextContent));
|
|
900
|
+
}
|
|
901
|
+
});
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
return true;
|
|
905
|
+
},
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Set the sort options.
|
|
909
|
+
*
|
|
910
|
+
* @param {jQueryElement} $elt - plugin's element
|
|
911
|
+
* @param {String} sortBy - the model id of the col to sort
|
|
912
|
+
* @param {Boolean|String} [asc] - sort direction true for asc of deduced
|
|
913
|
+
* @param {String} sortType - sorting type, numeric or string sorting
|
|
914
|
+
* @returns {Object} - returns the options
|
|
915
|
+
* @private
|
|
916
|
+
*/
|
|
917
|
+
_sortOptions($elt, sortBy, asc, sortType) {
|
|
918
|
+
const options = $elt.data(dataNs);
|
|
919
|
+
|
|
920
|
+
if (typeof asc !== 'undefined') {
|
|
921
|
+
if ('asc' !== asc && 'desc' !== asc) {
|
|
922
|
+
asc = asc ? 'asc' : 'desc';
|
|
923
|
+
}
|
|
924
|
+
options.sortorder = asc;
|
|
925
|
+
} else if (options.sortorder === 'asc' && options.sortby === sortBy) {
|
|
926
|
+
// If I already sort asc this element
|
|
927
|
+
options.sortorder = 'desc';
|
|
928
|
+
} else {
|
|
929
|
+
// If I never sort by this element or
|
|
930
|
+
// I sort by this element & the order was desc
|
|
931
|
+
options.sortorder = 'asc';
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// Change the sorting element anyway.
|
|
935
|
+
options.sortby = sortBy;
|
|
936
|
+
|
|
937
|
+
// define sorting type
|
|
938
|
+
options.sorttype = sortType;
|
|
939
|
+
|
|
940
|
+
//rebind options to the elt
|
|
941
|
+
$elt.data(dataNs, options);
|
|
942
|
+
|
|
943
|
+
return _.cloneDeep(options);
|
|
944
|
+
},
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* Gets the selected items. Returns an array of identifiers.
|
|
948
|
+
*
|
|
949
|
+
* @param {jQueryElement} $elt - plugin's element
|
|
950
|
+
* @returns {Array} - Returns an array of identifiers.
|
|
951
|
+
*/
|
|
952
|
+
_selection($elt) {
|
|
953
|
+
const $selected = $elt.find('[data-item-identifier]').has('td.checkboxes input:checked');
|
|
954
|
+
const selection = [];
|
|
955
|
+
|
|
956
|
+
$selected.each(function () {
|
|
957
|
+
selection.push($(this).data('item-identifier'));
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
return selection;
|
|
961
|
+
},
|
|
962
|
+
|
|
963
|
+
_highlightRows($elt, rowIds) {
|
|
964
|
+
$elt.find('[data-item-identifier]').removeClass('highlight');
|
|
965
|
+
|
|
966
|
+
rowIds.forEach(rowId => {
|
|
967
|
+
this._highlightRow($elt, rowId);
|
|
968
|
+
});
|
|
969
|
+
},
|
|
970
|
+
/**
|
|
971
|
+
* Highlight the row with identifier
|
|
972
|
+
*
|
|
973
|
+
* @param $elt
|
|
974
|
+
* @param rowId
|
|
975
|
+
* @deprecated Use highlightRows instead
|
|
976
|
+
*/
|
|
977
|
+
_highlightRow($elt, rowId) {
|
|
978
|
+
this._addRowClass($elt, rowId, 'highlight');
|
|
979
|
+
},
|
|
980
|
+
|
|
981
|
+
/**
|
|
982
|
+
* Css class add to the row with id
|
|
983
|
+
*
|
|
984
|
+
* @param $elt
|
|
985
|
+
* @param rowId
|
|
986
|
+
* @param className
|
|
987
|
+
* @private
|
|
988
|
+
*/
|
|
989
|
+
_addRowClass($elt, rowId, className) {
|
|
990
|
+
const $row = $elt.find('[data-item-identifier="' + rowId + '"]');
|
|
991
|
+
|
|
992
|
+
if (!$row.hasClass(className)) {
|
|
993
|
+
$row.addClass(className);
|
|
994
|
+
}
|
|
995
|
+
},
|
|
996
|
+
|
|
997
|
+
/**
|
|
998
|
+
* Css class remove from the row with id
|
|
999
|
+
*
|
|
1000
|
+
* @param $elt
|
|
1001
|
+
* @param rowId
|
|
1002
|
+
* @param className
|
|
1003
|
+
* @private
|
|
1004
|
+
*/
|
|
1005
|
+
_removeRowClass($elt, rowId, className) {
|
|
1006
|
+
const $row = $elt.find('[data-item-identifier="' + rowId + '"]');
|
|
1007
|
+
|
|
1008
|
+
if ($row.hasClass(className)) {
|
|
1009
|
+
$row.removeClass(className);
|
|
1010
|
+
}
|
|
1011
|
+
},
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* Update amount items per page
|
|
1015
|
+
*
|
|
1016
|
+
* @param $elt
|
|
1017
|
+
* @param rows
|
|
1018
|
+
* @fires dataTable#setpage.datatable
|
|
1019
|
+
*/
|
|
1020
|
+
_setRows($elt, rows) {
|
|
1021
|
+
const options = $elt.data(dataNs);
|
|
1022
|
+
|
|
1023
|
+
if (options.rows !== rows) {
|
|
1024
|
+
// set new amount of items per page
|
|
1025
|
+
options.rows = rows;
|
|
1026
|
+
|
|
1027
|
+
// set page to the first one
|
|
1028
|
+
options.page = 1;
|
|
1029
|
+
|
|
1030
|
+
//rebind options to the elt
|
|
1031
|
+
$elt.data(dataNs, options);
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* @event dataTable#setpage.dataTable
|
|
1035
|
+
*/
|
|
1036
|
+
$elt.trigger('setpage.' + ns);
|
|
1037
|
+
|
|
1038
|
+
// Call the query
|
|
1039
|
+
this._query($elt);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
Pluginifier.register(ns, dataTable, {
|
|
1045
|
+
expose: [
|
|
1046
|
+
'refresh',
|
|
1047
|
+
'sort',
|
|
1048
|
+
'filter',
|
|
1049
|
+
'selection',
|
|
1050
|
+
'render',
|
|
1051
|
+
'highlightRow',
|
|
1052
|
+
'highlightRows',
|
|
1053
|
+
'addRowClass',
|
|
1054
|
+
'removeRowClass'
|
|
1055
|
+
]
|
|
1056
|
+
});
|