diff --git a/public/app.js b/public/app.js index a7fe8a4..24a4e98 100644 --- a/public/app.js +++ b/public/app.js @@ -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 || []