blob: 48f50730d02de3c0ec291493b9210cd846a172fc [file] [log] [blame]
export const selectedRows = [];
export const tableHeaderCheckboxModel = false;
export const tableHeaderCheckboxIndeterminate = false;
const BVTableSelectableMixin = {
data() {
return {
selectedRows: [],
tableHeaderCheckboxModel: false,
tableHeaderCheckboxIndeterminate: false,
};
},
watch: {
currentPage() {
// Bootstrap Vue 2 behavior: Clear selections when page changes
// This prevents confusion with checkboxes appearing checked on the new page
const table = this.$refs.table;
if (table) {
table.clearSelected();
this.selectedRows = [];
this.tableHeaderCheckboxModel = false;
this.tableHeaderCheckboxIndeterminate = false;
}
},
},
methods: {
clearSelectedRows(tableRef) {
if (tableRef) {
tableRef.clearSelected();
this.selectedRows = [];
this.tableHeaderCheckboxModel = false;
this.tableHeaderCheckboxIndeterminate = false;
}
},
toggleSelectRow(tableRef, rowIndex) {
if (tableRef && rowIndex !== undefined) {
const wasSelected = tableRef.isRowSelected(rowIndex);
if (wasSelected) {
tableRef.unselectRow(rowIndex);
} else {
tableRef.selectRow(rowIndex);
}
// Manually trigger onRowSelected after toggle since unselectRow might not fire event
this.$nextTick(() => {
this.onRowSelected();
});
}
},
onRowSelected() {
/*
* Bootstrap Vue Next fires @row-selected for each individual row change.
* Query the table's internal state to get ALL currently selected rows.
*/
const table = this.$refs.table;
if (!table) return;
const allItems = table.filteredItems || table.items || [];
const selectedItems = allItems.filter((item, index) => {
return table.isRowSelected(index);
});
this.selectedRows = selectedItems;
// Update header checkbox state
const currentPage = this.currentPage || 1;
const perPage = this.perPage || 10;
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) {
this.tableHeaderCheckboxIndeterminate = false;
this.tableHeaderCheckboxModel = false;
} else if (selectedOnPageCount === pageItemsCount) {
this.tableHeaderCheckboxIndeterminate = false;
this.tableHeaderCheckboxModel = true;
} else {
this.tableHeaderCheckboxIndeterminate = true;
this.tableHeaderCheckboxModel = true;
}
},
onChangeHeaderCheckbox(tableRef, event) {
/*
* Bootstrap Vue Next Migration:
* Handle header checkbox to select/deselect all rows on current page.
*/
if (!tableRef) return;
// Extract checked state from event (could be boolean or Event object)
const isChecked =
typeof event === 'boolean' ? event : event?.target?.checked;
if (isChecked) {
// Select all rows on the current page
const currentPage = this.currentPage || 1;
const perPage = this.perPage || 10;
const startIndex = (currentPage - 1) * perPage;
const allItems = tableRef.filteredItems || tableRef.items || [];
const endIndex = Math.min(startIndex + perPage, allItems.length);
for (let i = startIndex; i < endIndex; i++) {
tableRef.selectRow(i);
}
} else {
// Deselect all rows
tableRef.clearSelected();
// Manually trigger update since clearSelected might not fire @row-selected
this.selectedRows = [];
this.tableHeaderCheckboxModel = false;
this.tableHeaderCheckboxIndeterminate = false;
}
// onRowSelected will be triggered automatically for selections
},
},
};
export default BVTableSelectableMixin;