From 229ba9415399ee3fc2a76a83f4a0f80dc2281c65 Mon Sep 17 00:00:00 2001 From: mertsincan Date: Mon, 6 Dec 2021 11:45:21 +0300 Subject: [PATCH] Fixed #1841 - DataTable component does not work correctly "Checkbox selection" together with "lazy" --- src/components/datatable/DataTable.vue | 41 +++-- src/components/datatable/HeaderCheckbox.vue | 5 +- src/service/CustomerService.js | 2 +- src/views/datatable/DataTableLazyDemo.vue | 155 ++++++++++++++---- .../datatable/DataTableSelectionDemo.vue | 18 +- 5 files changed, 169 insertions(+), 52 deletions(-) diff --git a/src/components/datatable/DataTable.vue b/src/components/datatable/DataTable.vue index b33bbb1bf..be9ee76c6 100755 --- a/src/components/datatable/DataTable.vue +++ b/src/components/datatable/DataTable.vue @@ -82,7 +82,7 @@ import TableFooter from './TableFooter.vue'; export default { name: 'DataTable', emits: ['value-change', 'update:first', 'update:rows', 'page', 'update:sortField', 'update:sortOrder', 'update:multiSortMeta', 'sort', 'filter', 'row-click', 'row-dblclick', - 'update:selection', 'row-select', 'row-unselect', 'update:contextMenuSelection', 'row-contextmenu', 'row-unselect-all', 'row-select-all', + 'update:selection', 'row-select', 'row-unselect', 'update:contextMenuSelection', 'row-contextmenu', 'row-unselect-all', 'row-select-all', 'select-all-change', 'column-resize-end', 'column-reorder', 'row-reorder', 'update:expandedRows', 'row-collapse', 'row-expand', 'update:expandedRowGroups', 'rowgroup-collapse', 'rowgroup-expand', 'update:filters', 'state-restore', 'state-save', 'cell-edit-init', 'cell-edit-complete', 'cell-edit-cancel', 'update:editingRows', 'row-edit-init', 'row-edit-save', 'row-edit-cancel'], @@ -211,6 +211,10 @@ export default { type: Object, default: null }, + selectAll: { + type: Boolean, + default: null + }, rowHover: { type: Boolean, default: false @@ -883,15 +887,24 @@ export default { } }, toggleRowsWithCheckbox(event) { - const processedData = this.processedData; - const checked = this.allRowsSelected; - const _selection = checked ? [] : (this.frozenValue ? [...this.frozenValue, ...processedData]: processedData); - this.$emit('update:selection', _selection); + if (this.selectAll !== null) { + this.$emit('select-all-change', event); + } + else { + const { originalEvent, checked } = event; + let _selection = []; - if (checked) - this.$emit('row-unselect-all', {originalEvent: event}); - else - this.$emit('row-select-all', {originalEvent: event, data: _selection}); + if (checked) { + _selection = this.frozenValue ? [...this.frozenValue, ...this.processedData] : this.processedData; + this.$emit('row-select-all', {originalEvent, data: _selection}); + } + else { + this.$emit('row-unselect-all', {originalEvent}); + } + + this.$emit('update:selection', _selection); + + } }, isSingleSelectionMode() { return this.selectionMode === 'single'; @@ -1887,9 +1900,13 @@ export default { return ['p-datatable-loading-icon pi-spin', this.loadingIcon]; }, allRowsSelected() { - const val = this.frozenValue ? [...this.frozenValue, ...this.processedData]: this.processedData; - const length = this.lazy ? this.totalRecords : (val ? val.length : 0); - return (val && length > 0 && this.selection && this.selection.length > 0 && this.selection.length === length); + if (this.selectAll !== null) { + return this.selectAll; + } + else { + const val = this.frozenValue ? [...this.frozenValue, ...this.processedData] : this.processedData; + return val && this.selection && Array.isArray(this.selection) && val.every(v => this.selection.some(s => this.equals(s, v))); + } }, attributeSelector() { return UniqueComponentId(); diff --git a/src/components/datatable/HeaderCheckbox.vue b/src/components/datatable/HeaderCheckbox.vue index aa7f7493f..2d9edea31 100755 --- a/src/components/datatable/HeaderCheckbox.vue +++ b/src/components/datatable/HeaderCheckbox.vue @@ -24,7 +24,10 @@ export default { onClick(event) { if (!this.$attrs.disabled) { this.focused = true; - this.$emit('change', event); + this.$emit('change', { + originalEvent: event, + checked: !this.checked + }); } }, onFocus() { diff --git a/src/service/CustomerService.js b/src/service/CustomerService.js index 0ed3c5955..24ede27b9 100755 --- a/src/service/CustomerService.js +++ b/src/service/CustomerService.js @@ -21,7 +21,7 @@ export default class CustomerService { } getCustomers(params) { - const queryParams = Object.keys(params).map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k])).join('&'); + const queryParams = params ? Object.keys(params).map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k])).join('&') : ''; return fetch('https://www.primefaces.org/data/customers?' + queryParams).then(res => res.json()) } } diff --git a/src/views/datatable/DataTableLazyDemo.vue b/src/views/datatable/DataTableLazyDemo.vue index c01f9d8e8..ebc64bad7 100755 --- a/src/views/datatable/DataTableLazyDemo.vue +++ b/src/views/datatable/DataTableLazyDemo.vue @@ -13,13 +13,15 @@
- - + :globalFilterFields="['name','country.name', 'company', 'representative.name']" responsiveLayout="scroll" + v-model:selection="selectedCustomers" :selectAll="selectAll" @select-all-change="onSelectAllChange" @row-select="onRowSelect" @row-unselect="onRowUnselect"> + + + @@ -53,6 +55,8 @@ export default { loading: false, totalRecords: 0, customers: null, + selectedCustomers: null, + selectAll: false, filters: { 'name': {value: '', matchMode: 'contains'}, 'country.name': {value: '', matchMode: 'contains'}, @@ -72,13 +76,15 @@ export default { content: ` @@ -208,7 +208,7 @@ export default { } } } -<\\/script> +<\\/script> ` }, 'composition-api': { @@ -283,7 +283,7 @@ export default { -
+
@@ -319,7 +319,7 @@ export default { return { products, selectedProduct1, selectedProduct2, selectedProduct3, selectedProducts1, selectedProducts2, selectedProducts3, onRowSelect, onRowUnselect} } } -<\\/script> +<\\/script> ` }, 'browser-source': { @@ -397,7 +397,7 @@ export default { - + \ No newline at end of file +