Pagination
Třída Moony\bootstrap\core\services\Pagination generuje HTML stránkování.
Základní použití
use Moony\bootstrap\core\services\Pagination;
$pagination = new Pagination();
$pagination->currentPage = $_GET['page'] ?? 1;
$pagination->totalRecords = 120;
$pagination->recordsPerPage = 10;
$pagination->range = 3;
$pagination->href = '/users?page=%s';
| currentPage | Aktuální stránka |
| totalRecords | Celkový počet záznamů |
| recordsPerPage | Počet záznamů na stránku |
| range | Počet stránek zobrazených vlevo a vpravo od aktuální (výchozí: 5) |
| href | URL pattern — %s se nahradí číslem stránky |
Metody
| draw() | Vrátí HTML string se stránkováním |
| hasPages() | Vrátí true pokud je potřeba stránkování (více záznamů než recordsPerPage) |
| setNumberStyle(string $html) | Vlastní HTML šablona pro neaktivní stránku. Dva %s: 1. = href, 2. = text. |
| setNumberStyleActive(string $html) | Vlastní HTML šablona pro aktivní stránku. Jeden %s = číslo stránky. |
V Twig šabloně
// Controller
$pagination = new Pagination();
$pagination->currentPage = $_GET['page'] ?? 1;
$pagination->totalRecords = 60;
$pagination->recordsPerPage = 5;
$pagination->range = 3;
$pagination->href = '/users?page=%s';
return new View('account/users', ['pagination' => $pagination]);
<!-- Twig šablona — hasPages() zajistí, že se <ul> nevyrenderuje pokud není potřeba -->
{% if pagination.hasPages() %}
<hr>
<ul class="pagination">
{{ pagination.draw()|raw }}
</ul>
{% endif %}
Vždy obalujte stránkování podmínkou {% if pagination.hasPages() %}, aby se prázdný <ul> neobjevil v HTML když je jen jedna stránka. Před stránkováním lze použít <hr> pro vizuální oddělení od obsahu.
Demo
CSS varianty
Stránkování podporuje tři vizuální varianty odpovídající pozadí, na kterém je použito:
| pagination | Výchozí — odpovídá pozadí stránky |
| pagination lighter | Mírně světlejší — pro card-footer apod. |
| pagination light | Nejsvětlejší varianta |
<ul class="pagination">...</ul>
<ul class="pagination lighter">...</ul>
<ul class="pagination light">...</ul>
Stránkování v TabCard (AJAX)
Pro AJAX stránkování uvnitř TabCard se používá data-tabcard-page atribut místo běžného odkazu. Stránka se přenáší vždy v URL jako /page/X, nikdy v POST datech.
Data atributy na tc-pane
| data-load-url | URL ze které se obsah záložky načte AJAXem. Bez tohoto atributu se obsah renderuje staticky. |
| data-load-post | JSON objekt s POST daty, která se odešlou při načtení (filtrace apod.). Pokud je přítomen, požadavek jde jako POST místo GET. |
| data-load-always | Při každém přepnutí na záložku se obsah načte znovu ze serveru. Bez tohoto atributu se obsah cachuje a načte pouze jednou. |
Data atributy na pagination
| data-tabcard-page | Na <a> uvnitř stránkování — číslo stránky. TabCard přidá /page/X k data-load-url a odešle požadavek. |
| data-tabcard-post | Na <ul class="pagination"> — JSON objekt s POST daty pro stránkování (filtrace). Sloučí se s data-load-post z panu. |
// Controller — AJAX endpoint
#[Route('/api/users', RequestTypeEnum::POST)]
#[Route('/api/users/page/<page common>', RequestTypeEnum::POST)]
public function usersApi(int $page = 1): View
{
$filter = $_POST['filter'] ?? null;
$pagination = new Pagination();
$pagination->currentPage = $page;
$pagination->totalRecords = UserRepository::count($filter);
$pagination->recordsPerPage = 10;
$pagination->range = 3;
$pagination->href = '%s';
$pagination->setNumberStyle(
"<li><a href='javascript:void(0)' data-tabcard-page='%s'>%s</a></li>"
);
return new View('account/partials/users-list', [
'users' => UserRepository::paginated($page, 10, $filter),
'pagination' => $pagination,
'filter' => $filter,
]);
}
<!-- account/partials/users-list.twig -->
<div>
{% for user in users %}
<div>{{ user.name }}</div>
{% endfor %}
<ul class="pagination"{% if filter %} data-tabcard-post='{{ {filter: filter}|json_encode }}'{% endif %}>
{{ pagination.draw()|raw }}
</ul>
</div>
<!-- Twig šablona — TabCard s AJAX stránkováním -->
<div class="tab-card">
<div class="tc-tabs">
<div class="tc-tab">
<div class="tc-tab-bar"></div>
<div><div class="tc-tab-label">Users</div></div>
</div>
</div>
<div class="tc-content">
<div class="tc-pane"
data-load-url="/api/users"
data-load-always
data-load-post='{"filter":"active"}'>
</div>
</div>
</div>
Při kliknutí na stránku se automaticky: 1. provede scroll nahoru k TabCard (pokud není viditelný), 2. zobrazí loader, 3. odešle POST na URL s /page/X a data z data-tabcard-post.
V data-tabcard-post nikdy neposílejte číslo stránky — to se přenáší vždy přes URL.
