Исправлена фильтрация и сортировка таблицы

- Исправлен ajaxParams: использование this вместо глобальной переменной
- Добавлен headerFilterFunc для всех колонок для серверной фильтрации
- Исправлены параметры headerFilter для FK колонок

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-01-22 11:02:17 +03:00
parent d23a5dd829
commit 10cd6e36df

View File

@@ -472,20 +472,21 @@ async function selectTable(schema, tableName) {
// ✅ ФИЛЬТР В ЗАГОЛОВКЕ - выпадающий список для FK колонок
if (allLoaded || total <= 1000) {
// Формируем список значений для фильтра с пустым значением
const filterValues = { "": "Все" };
const filterValues = { "": "-- Все --" };
values.forEach(v => { filterValues[v] = v; });
colDef.headerFilter = "list";
colDef.headerFilterParams = {
values: filterValues,
clearable: true,
placeholderEmpty: "Все значения",
placeholderLoaded: "Выберите..."
clearable: false // Не показываем кнопку очистки, есть "Все"
};
// Серверная фильтрация - пропускаем все на клиенте
colDef.headerFilterFunc = function() { return true; };
} else {
// Много значений - оставляем текстовый поиск
colDef.headerFilter = "input";
colDef.headerFilterPlaceholder = `Поиск (${total})...`;
colDef.headerFilterFunc = function() { return true; };
}
if (allLoaded || total <= 1000) {
@@ -553,6 +554,7 @@ async function selectTable(schema, tableName) {
} else {
// Нет значений - обычный input с предупреждением
colDef.headerFilter = "input";
colDef.headerFilterFunc = function() { return true; }; // Серверная фильтрация
colDef.editor = "input";
colDef.editorParams = {
elementAttributes: {
@@ -563,6 +565,7 @@ async function selectTable(schema, tableName) {
} else {
// Обычный фильтр и редактор
colDef.headerFilter = "input";
colDef.headerFilterFunc = function() { return true; }; // Серверная фильтрация
colDef.editor = "input";
}
@@ -603,53 +606,47 @@ async function selectTable(schema, tableName) {
sortMode: "remote",
ajaxURL: "/api/table/data",
ajaxConfig: "POST",
ajaxContentType: "json",
ajaxRequestFunc: function(url, config, params) {
// Получаем параметры напрямую из экземпляра таблицы
const tbl = this;
ajaxParams: function() {
// this указывает на экземпляр Tabulator
let filters = [];
let sort = null;
const headerFilters = tbl.getHeaderFilters ? tbl.getHeaderFilters() : [];
const filters = (headerFilters || []).map(f => ({
field: f.field,
value: f.value
})).filter(f => f.value !== null && f.value !== '');
// Получаем фильтры из заголовков
if (typeof this.getHeaderFilters === 'function') {
const headerFilters = this.getHeaderFilters();
filters = (headerFilters || []).map(f => ({
field: f.field,
value: f.value
})).filter(f => f.value !== null && f.value !== '');
}
const sorters = tbl.getSorters ? tbl.getSorters() : [];
const sort = (sorters && sorters.length > 0) ? {
field: sorters[0].field,
dir: sorters[0].dir
} : null;
// Получаем параметры сортировки
if (typeof this.getSorters === 'function') {
const sorters = this.getSorters();
if (sorters && sorters.length > 0) {
sort = {
field: sorters[0].field,
dir: sorters[0].dir
};
}
}
console.log('📊 AJAX запрос:', {
filters: filters,
sort: sort,
page: params.page,
size: params.size
});
console.log('📊 AJAX запрос:', { filters, sort, page: this.getPage ? this.getPage() : 1 });
const requestBody = {
return {
schema: currentSchema,
table: currentTable,
filters: filters,
sort: sort,
columns: currentMeta.columns,
page: params.page || 1,
pageSize: params.size || 50
columns: currentMeta.columns
};
return fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestBody)
})
.then(response => response.json())
.then(data => {
console.log('📊 Ответ сервера:', { total: data.total, lastPage: data.last_page });
return data;
});
},
ajaxResponse: function (url, params, response) {
ajaxResponse: function(url, params, response) {
console.log('📊 Ответ сервера:', { total: response.total, lastPage: response.last_page });
return {
last_page: response.last_page || 1,
data: response.data || []