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';
currentPageAktuální stránka
totalRecordsCelkový počet záznamů
recordsPerPagePočet záznamů na stránku
rangePočet stránek zobrazených vlevo a vpravo od aktuální (výchozí: 5)
hrefURL 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:

paginationVýchozí — odpovídá pozadí stránky
pagination lighterMírně světlejší — pro card-footer apod.
pagination lightNejsvě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-urlURL ze které se obsah záložky načte AJAXem. Bez tohoto atributu se obsah renderuje staticky.
data-load-postJSON 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-alwaysPř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-pageNa <a> uvnitř stránkování — číslo stránky. TabCard přidá /page/X k data-load-url a odešle požadavek.
data-tabcard-postNa <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.