This commit is contained in:
2026-03-10 21:37:24 +01:00
parent 5bce68c56b
commit 9d70ea0547
37 changed files with 1534 additions and 282 deletions

View File

@@ -9,7 +9,7 @@ $buildUrl = function(array $params = []) use ($list): string {
}
}
$qs = http_build_query($query);
return $list->basePath . ($qs ? ('?' . $qs) : '');
return $list->basePath . $qs;
};
$currentSort = $list->sort['column'] ?? '';
@@ -19,6 +19,14 @@ $totalPages = max(1, (int)($list->pagination['total_pages'] ?? 1));
$total = (int)($list->pagination['total'] ?? 0);
$perPage = (int)($list->pagination['per_page'] ?? 15);
$hasActiveFilters = false;
foreach ($list->filters as $filter) {
if (isset($filter['value']) && (string)$filter['value'] !== '') {
$hasActiveFilters = true;
break;
}
}
$isCompactColumn = function(array $column): bool {
$key = strtolower(trim((string)($column['key'] ?? '')));
$label = strtolower(trim((string)($column['label'] ?? '')));
@@ -48,6 +56,14 @@ $isCompactColumn = function(array $column): bool {
<div class="col-sm-4 text-right">
<div class="table-list-header-actions">
<span class="text-muted">Wyników: <?= $total; ?></span>
<?php if (!empty($list->filters)): ?>
<button type="button" class="btn btn-default btn-sm js-filter-toggle-btn<?= $hasActiveFilters ? ' active' : ''; ?>" title="Filtry">
<i class="fa fa-filter"></i>
<?php if ($hasActiveFilters): ?>
<span class="badge badge-primary table-filter-badge"><?= count(array_filter($list->filters, function($f) { return isset($f['value']) && (string)$f['value'] !== ''; })); ?></span>
<?php endif; ?>
</button>
<?php endif; ?>
<div class="table-col-toggle-wrapper">
<button type="button" class="btn btn-default btn-sm js-col-toggle-btn" title="Widoczność kolumn">
<i class="fa fa-columns"></i>
@@ -75,7 +91,8 @@ $isCompactColumn = function(array $column): bool {
</div>
<div class="panel-body">
<form method="get" action="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="row mb15 js-table-filters-form">
<div class="js-table-filters-wrapper table-filters-wrapper<?= $hasActiveFilters ? ' open' : ''; ?>">
<form method="get" action="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" data-path-submit="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="row mb15 js-table-filters-form">
<?php foreach ($list->filters as $filter): ?>
<?php
$filterKey = (string)($filter['key'] ?? '');
@@ -145,9 +162,10 @@ $isCompactColumn = function(array $column): bool {
<div class="col-sm-12">
<button type="submit" class="btn btn-primary btn-sm">Szukaj</button>
<a href="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-default btn-sm">Wyczyść</a>
<a href="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-default btn-sm js-table-filters-clear">Wyczyść</a>
</div>
</form>
</div>
<div class="table-responsive">
<table class="table table-hover table-striped table-bordered mbn table-list-table">
@@ -274,7 +292,7 @@ $isCompactColumn = function(array $column): bool {
</ul>
</div>
<div class="col-sm-6 text-right">
<form method="get" action="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="form-inline table-list-per-page-form">
<form method="get" action="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" data-path-submit="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="form-inline table-list-per-page-form">
<?php foreach ($list->query as $key => $value): ?>
<?php if ($key !== 'per_page' && $key !== 'page'): ?>
<input type="hidden" name="<?= htmlspecialchars((string)$key, ENT_QUOTES, 'UTF-8'); ?>" value="<?= htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); ?>" />
@@ -282,7 +300,7 @@ $isCompactColumn = function(array $column): bool {
<?php endforeach; ?>
<input type="hidden" name="page" value="1" />
Wyświetlaj
<select name="per_page" class="form-control input-sm" onchange="this.form.submit()">
<select name="per_page" class="form-control input-sm js-per-page-select">
<?php foreach ($list->perPageOptions as $opt): ?>
<option value="<?= (int)$opt; ?>"<?= ((int)$opt === $perPage) ? ' selected="selected"' : ''; ?>><?= (int)$opt; ?></option>
<?php endforeach; ?>
@@ -294,6 +312,40 @@ $isCompactColumn = function(array $column): bool {
</div>
</div>
<script type="text/javascript">
// Table state persistence — redirect ASAP to saved view
(function() {
var basePath = <?= json_encode($list->basePath); ?>;
var stateKey = 'tableListQuery_' + basePath;
var clearKey = 'tableListCleared_' + basePath;
var pathname = window.location.pathname.replace(/\/+$/, '/');
var bp = basePath.replace(/\/+$/, '/');
var queryPart = '';
if (pathname.length > bp.length && pathname.indexOf(bp) === 0) {
queryPart = pathname.substring(bp.length);
}
if (!queryPart && window.location.search) {
queryPart = window.location.search.substring(1);
}
try {
var justCleared = sessionStorage.getItem(clearKey) === '1';
sessionStorage.removeItem(clearKey);
if (queryPart) {
localStorage.setItem(stateKey, queryPart);
} else if (!justCleared) {
var saved = localStorage.getItem(stateKey);
if (saved) {
window.location.replace(basePath + saved);
}
}
} catch (e) {}
})();
</script>
<script type="text/javascript">
(function($) {
if (!$) {
@@ -469,5 +521,80 @@ $isCompactColumn = function(array $column): bool {
saveHiddenCols([]);
applyColumnVisibility([]);
});
// --- Filter toggle ---
var filterStorageKey = 'tableListFilters_' + <?= json_encode($list->basePath); ?>;
function isFilterVisible() {
try {
return localStorage.getItem(filterStorageKey) === '1';
} catch (e) {}
return false;
}
function saveFilterState(visible) {
try {
localStorage.setItem(filterStorageKey, visible ? '1' : '0');
} catch (e) {}
}
var $filterWrapper = $('.js-table-filters-wrapper');
var $filterBtn = $('.js-filter-toggle-btn');
var hasActiveFilters = $filterWrapper.hasClass('open');
if (!hasActiveFilters && isFilterVisible()) {
$filterWrapper.addClass('open');
$filterBtn.addClass('active');
}
$(document).off('click.filterToggle', '.js-filter-toggle-btn');
$(document).on('click.filterToggle', '.js-filter-toggle-btn', function() {
var $wrapper = $('.js-table-filters-wrapper');
var $btn = $(this);
var isOpen = $wrapper.hasClass('open');
if (isOpen) {
$wrapper.removeClass('open');
$btn.removeClass('active');
saveFilterState(false);
} else {
$wrapper.addClass('open');
$btn.addClass('active');
saveFilterState(true);
}
});
// --- Path-based form submission (admin URL routing) ---
$(document).off('submit.tablePathSubmit', 'form[data-path-submit]');
$(document).on('submit.tablePathSubmit', 'form[data-path-submit]', function(e) {
e.preventDefault();
var basePath = $(this).attr('data-path-submit');
var data = $(this).serializeArray();
var parts = [];
for (var i = 0; i < data.length; i++) {
if (String(data[i].value) !== '') {
parts.push(encodeURIComponent(data[i].name) + '=' + encodeURIComponent(data[i].value));
}
}
window.location.href = basePath + (parts.length ? parts.join('&') : '');
});
// Per-page select auto-submit
$(document).off('change.tablePerPage', '.js-per-page-select');
$(document).on('change.tablePerPage', '.js-per-page-select', function() {
$(this).closest('form').trigger('submit');
});
// --- Table state clear on "Wyczyść" ---
var stateStorageKey = 'tableListQuery_' + <?= json_encode($list->basePath); ?>;
var stateClearKey = 'tableListCleared_' + <?= json_encode($list->basePath); ?>;
$(document).off('click.tableClearState', '.js-table-filters-clear');
$(document).on('click.tableClearState', '.js-table-filters-clear', function() {
try {
localStorage.removeItem(stateStorageKey);
sessionStorage.setItem(stateClearKey, '1');
} catch (e) {}
});
})(window.jQuery);
</script>