Исправлена работа чекбоксов и пагинации в таблице

- Чекбоксы теперь работают только при клике на сам чекбокс (не на строку)
- Повторный клик на чекбокс снимает выделение
- Множественное выделение строк работает корректно
- Исправлен выбор количества записей на странице (сервер читает параметр 'size')

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-01-23 15:17:46 +03:00
parent 0700fcd584
commit c001aed149
2 changed files with 61 additions and 9 deletions

View File

@@ -440,8 +440,33 @@ async function selectTable(schema, tableName) {
// ✅ Формируем колонки с правильными редакторами
const columns = [
{
formatter: "rowSelection",
titleFormatter: "rowSelection",
// ✅ Кастомный чекбокс - работает только при клике на сам чекбокс
formatter: function(cell, formatterParams, onRendered) {
const row = cell.getRow();
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.checked = row.isSelected();
checkbox.style.cursor = "pointer";
checkbox.style.width = "16px";
checkbox.style.height = "16px";
return checkbox;
},
titleFormatter: function(cell, formatterParams, onRendered) {
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.style.cursor = "pointer";
checkbox.style.width = "16px";
checkbox.style.height = "16px";
checkbox.addEventListener("click", function(e) {
e.stopPropagation();
if (checkbox.checked) {
table.getRows().forEach(row => row.select());
} else {
table.deselectRow();
}
});
return checkbox;
},
hozAlign: "center",
headerHozAlign: "center",
headerSort: false,
@@ -449,8 +474,19 @@ async function selectTable(schema, tableName) {
minWidth: 40,
maxWidth: 40,
resizable: false,
frozen: true
// ✅ Убран cellClick - Tabulator сам обрабатывает клики на rowSelection
frozen: true,
cellClick: function(e, cell) {
e.stopPropagation();
const row = cell.getRow();
const checkbox = cell.getElement().querySelector('input[type="checkbox"]');
if (row.isSelected()) {
row.deselect();
if (checkbox) checkbox.checked = false;
} else {
row.select();
if (checkbox) checkbox.checked = true;
}
}
},
...currentMeta.columns.map(col => {
// Определяем тип сортировщика на основе типа данных
@@ -621,8 +657,7 @@ async function selectTable(schema, tableName) {
console.log('🏗️ Создание Tabulator...');
table = new Tabulator("#table", {
selectableRows: true, // ✅ Включаем множественное выделение
selectableRowsRangeMode: "click", // ✅ Каждый клик добавляет/убирает строку
selectableRows: false, // ✅ Отключаем выделение по клику на строку - только через чекбокс
selectableRowsPersistence: true, // ✅ Сохраняем выделение при сортировке/фильтрации
columns: columns,
@@ -819,14 +854,24 @@ async function selectTable(schema, tableName) {
}
}
// События (не меняются)
// События выделения
table.on("rowSelectionChanged", function(data, rows) {
// ✅ Синхронизируем чекбоксы с состоянием выделения
table.getRows().forEach(row => {
const cells = row.getCells();
if (cells.length > 0) {
const checkbox = cells[0].getElement().querySelector('input[type="checkbox"]');
if (checkbox) {
checkbox.checked = row.isSelected();
}
}
});
updateSelectionCounter();
});
table.on("dataLoaded", function(data) {
console.log('📊 Данные загружены:', data.length, 'строк');
if (selectedRowsDataGlobal.size > 0) {
const rows = table.getRows();
rows.forEach(row => {
@@ -834,6 +879,12 @@ async function selectTable(schema, tableName) {
const key = getRowKey(rowData);
if (selectedRowsDataGlobal.has(key)) {
row.select();
// ✅ Обновляем чекбокс
const cell = row.getCells()[0];
if (cell) {
const checkbox = cell.getElement().querySelector('input[type="checkbox"]');
if (checkbox) checkbox.checked = true;
}
}
});
}

View File

@@ -97,7 +97,8 @@ $app->post('/api/table/data', function (Request $request, Response $response) us
$schema = $payload['schema'] ?? '';
$table = $payload['table'] ?? '';
$page = (int)($payload['page'] ?? 1);
$pageSize = (int)($payload['pageSize'] ?? 50);
// Tabulator отправляет 'size', для обратной совместимости также проверяем 'pageSize'
$pageSize = (int)($payload['size'] ?? $payload['pageSize'] ?? 50);
$filters = $payload['filters'] ?? [];
$sort = $payload['sort'] ?? null;
$columns = $payload['columns'] ?? [];