1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/**
* Composable for table selection utilities
* Extracted from BVTableSelectableMixin for use in Composition API
*/
import { ref, nextTick, watch } from 'vue';
export function useTableSelection(currentPage = ref(1)) {
const selectedRows = ref([]);
const tableHeaderCheckboxModel = ref(false);
const tableHeaderCheckboxIndeterminate = ref(false);
// Watch for page changes and clear selections
// This prevents confusion with checkboxes appearing checked on the new page
watch(currentPage, (newPage, oldPage) => {
if (newPage !== oldPage) {
selectedRows.value = [];
tableHeaderCheckboxModel.value = false;
tableHeaderCheckboxIndeterminate.value = false;
}
});
const clearSelectedRows = (tableRef) => {
if (tableRef) {
tableRef.clearSelected();
selectedRows.value = [];
tableHeaderCheckboxModel.value = false;
tableHeaderCheckboxIndeterminate.value = false;
}
};
const toggleSelectRow = (tableRef, rowIndex) => {
if (tableRef && rowIndex !== undefined) {
const wasSelected = tableRef.isRowSelected(rowIndex);
if (wasSelected) {
tableRef.unselectRow(rowIndex);
} else {
tableRef.selectRow(rowIndex);
}
nextTick(() => {
onRowSelected(tableRef);
});
}
};
const onRowSelected = (tableRef) => {
if (!tableRef) return;
const allItems = tableRef.filteredItems || tableRef.items || [];
const selectedItems = allItems.filter((item, index) => {
return tableRef.isRowSelected(index);
});
selectedRows.value = selectedItems;
const currentPage = 1;
const perPage = allItems.length;
const startIndex = (currentPage - 1) * perPage;
const endIndex = Math.min(startIndex + perPage, allItems.length);
const pageItemsCount = endIndex - startIndex;
const selectedOnPageCount = selectedItems.filter((item) =>
allItems
.slice(startIndex, endIndex)
.some((pageItem) => pageItem === item),
).length;
if (selectedOnPageCount === 0) {
tableHeaderCheckboxIndeterminate.value = false;
tableHeaderCheckboxModel.value = false;
} else if (selectedOnPageCount === pageItemsCount) {
tableHeaderCheckboxIndeterminate.value = false;
tableHeaderCheckboxModel.value = true;
} else {
tableHeaderCheckboxIndeterminate.value = true;
tableHeaderCheckboxModel.value = true;
}
};
const onChangeHeaderCheckbox = (tableRef, event) => {
/*
* Bootstrap Vue Next Migration:
* Handle header checkbox to select/deselect all rows on current page.
*/
if (!tableRef) return;
const isChecked =
typeof event === 'boolean' ? event : event?.target?.checked;
if (isChecked) {
const allItems = tableRef.filteredItems || tableRef.items || [];
const endIndex = allItems.length;
for (let i = 0; i < endIndex; i++) {
tableRef.selectRow(i);
}
} else {
tableRef.clearSelected();
selectedRows.value = [];
tableHeaderCheckboxModel.value = false;
tableHeaderCheckboxIndeterminate.value = false;
}
nextTick(() => {
onRowSelected(tableRef);
});
};
return {
selectedRows,
tableHeaderCheckboxModel,
tableHeaderCheckboxIndeterminate,
clearSelectedRows,
toggleSelectRow,
onRowSelected,
onChangeHeaderCheckbox,
};
}
|