Jak rychle rozchodit paginator (IPub/VisualPaginator)
- ludek
- Člen | 83
Návod – rychlovka v češtině, jak promptně rozchodit skvělý doplněk VisualPaginator (github).
1. stáhnout do projektu:
composer require ipub/visual-paginator:@dev
2. zaregistrovat v config.local.neon:
extensions:
visualPaginator: IPub\VisualPaginator\DI\VisualPaginatorExtension
3. do Presenteru, kde chcete něco stránkovat:
// nahoru:
use IPub\VisualPaginator\Components as VisualPaginator;
// a někam mezi metody:
// továrna, která vrátí stránkovač
protected function createComponentVisualPaginator() {
// Init visual paginator
$control = new VisualPaginator\Control;
// vypnout Ajax, s tím si budeme hrát až bude čas
$control->disableAjax();
// nastavit vlastní šablonu
$control->setTemplateFile(__DIR__ . '/../../templates/paginator.latte'); // šablona je v app/templates
return $control; // <-- v šabloně dáme jen {control visualPaginator}
}
// a přidat k dotazu do databáze:
public function renderDefault() {
$items = $this->database->table('polozky')
->where('nějaké podmínky')
->order('datum DESC');
// přístup ke komponentě VisualPaginatoru:
$visualPaginator = $this['visualPaginator'];
// přístup k samotnému paginatoru:
$paginator = $visualPaginator->getPaginator();
// počet položek na stránku
$paginator->itemsPerPage = 15;
// spočítat celkový počet položek
$paginator->itemCount = $items->count();
// přidat stránkovač k dotazu
$items->limit($paginator->itemsPerPage, $paginator->offset);
// poslat do šablony:
$this->template->polozky = $items;
}
4. vlastní česká bootstrap šablona pro stránkovač app/templates/paginator.latte:
{if $paginator->pageCount > 1}
<nav aria-label="Stránkování">
<ul class="pagination">
{* PŘEDCHOZÍ *}
{if $paginator->isFirst()}
<li class="page-item disabled"><a class="page-link" href="#">« Předchozí</a></li>
{else}
<li class="page-item">
<a class="page-link{if $useAjax} ajax{/if}" href="{link $handle, 'page' => $paginator->page - 1}" rel="prev" >« Předchozí</a>
</li>
{/if}
{foreach $steps as $step}
{if $step == $paginator->page} {* AKTIVNÍ STRÁNKA *}
<li class="page-item active">
<a class="page-link" href="#">
<span>{$step}</span>
</a>
</li>
{else}
<li class="page-item">
<a class="page-link{if $useAjax} ajax{/if}" href="{link $handle, 'page' => $step}">{$step}</a>
</li>
{/if}
{if $iterator->nextValue > $step + 1}
<li class="disabled">…</li>
{/if}
{/foreach}
{* NÁSLEDUJÍCÍ *}
{if $paginator->isLast()}
<li class="page-item disabled"><a class="page-link" href="#">Následující »</a></li>
{else}
<li>
<a class="page-link{if $useAjax} ajax{/if}" href="{link $handle, 'page' => $paginator->page + 1}" rel="next" >Následující »</a>
</li>
{/if}
</ul>
</nav>
{/if}
5. stránkovač do šablony s výpisem dat:
{control visualPaginator} {* stránkovač nahoře *}
<table class="table table-hover table-striped table-bordered">
{foreach $polozky as $p}
<tr>
<td>{$p->datum}</td><td>{$p->cislo}</td><td>{$p->nazev}</td>
</tr>
{/foreach}
</table>
{control visualPaginator} {* stránkovač dole *}
Adamu Kadlecovi za doplněk moc díky.
AKTUALIZACE: doplněk byl opuštěn
(Package ipub/visual-paginator is abandoned, you should avoid using it. No replacement was suggested.
).
Nicméně prozatím
se dá používat dál – poslední verze 2.0.1 z 24.5.2019, vyzkoušeno
na NETTE 3.1.4.
Editoval ludek (20. 1. 2022 15:11)
- akadlec
- Člen | 1326
díky že se ti to chtělo takto popsat. jen k tomu bodu 5, nepřepisoval bych šablonu ve vendoru ale jak si uvedl použít setter a změnit šablonu. Do budoucna se plánuje s implementací translatoru, jen zatím je podpora neimplementována, bylo použito kdyby/translation a jeho provider nicméně to přináší nutnou závislost na kdyby což né všem musí vyhovovat.
- ludek
- Člen | 83
Translator: na ty 2 slova…
Nevidím do toho, ale kdyby to šlo tak, jak to má TwiGrid (4 slova k překladu), dalo by se to v projektech kde ve skutečnosti žádnou velkou lokalizaci nepotřebujete překládat takto primitivně.
- David Kregl
- Člen | 52
Díky za tutoriál.
Paginator mi chodí parádně včetně vlastní šablony, ale nemohu rozchodit
ten Ajax.
Mohl by mi někdo prosím ukázat příklad? Pravděpodobně stačí metoda renderDefault()
Díky,
David
- CZechBoY
- Člen | 3608
No bacha s tim ->count()! Lepší je imo
->count(‚*‘), protože nepočítá počet řádků
v php, ale rovnou na straně databáze.
https://api.nette.org/…ion.php.html#433
- TomasHuttner
- Člen | 66
Ahoj, při použití paginatoru jsem postupoval přesně podle tohoto návodu ale nedaří se mi to. Stránkování se mi zobrazuje i dopočítává správně jen když chci přejít na druhou stránku tak se mi stránka změní ale data ne. Používám Doctrine místo Nette Database a myslím si že bude chyba někde ve vytahování dat z databáze jen nemůžu přijít na to kde.
Takto vytahuji data:
$data = $this->facade->findBy(['category' => 'menu','subMenu' => ''],['position' => 'ASC'],$paginator->itemsPerPage,$paginator->offset);
Nejsem si jist jestli správně používám $paginator->itemsPerPage a $paginator->offset. Děkuji za radu
- Fyasko
- Člen | 106
@DavidKregl
Ajax v komponentě jsem zapl už v Presenteru kde vytvářím tu továrnu.
<?php
public function createComponentAdminChat()
{
$test = $this->adminchat->create();
$test->redrawControl('adminchat');
return $test;
}
?>
myslím že pro Presenter se má dát do renderu
<?php
public function renderDefault()
{
$that = $this;
// Define event for example to redraw snippets
$this['visualPaginator']->onShowPage[] = (function ($component, $page) use ($that) {
if ($that->isAjax()){
$that->invalidateControl();
}
});
}
?>
- mario85
- Člen | 22
čau, zkusil jsem to podle tohoto jednoduchého návodu (díky moc!), ale paginator se mi nezobrazí. Žádnou chybu ale tracy nehlásí. V čem může být problém?
Presenter:
class DocumentsPresenter extends BasePresenter
{
/** @var DocumentsModel @inject */
public $documentsModel;
/**
* Create items paginator
*
* @return VisualPaginator\Control
*/
protected function createComponentVisualPaginator()
{
// Init visual paginator
$control = new VisualPaginator\Control;
$control->setTemplateFile('bootstrap.latte');
// vypnout Ajax, s tím si budeme hrát až bude čas
$control->disableAjax();
return $control;
}
public function renderShowAll()
{
// Get visual paginator components
$visualPaginator = $this['visualPaginator'];
// Get paginator form visual paginator
$paginator = $visualPaginator->getPaginator();
// Define items count per one page
$paginator->itemsPerPage = 5;
// Define total items in list
$paginator->itemCount = $this->documentsModel->count();
// Apply limits to list
$this->template->documents = $this->documentsModel->selectAll($paginator->itemsPerPage, $paginator->offset);
}
}
a ještě šablona:
{control visualPaginator}
{block content}
{foreach $documents as $doc}
<p>{$doc->name}</p>
{/foreach}
{control visualPaginator}
- Lukeluha
- Člen | 130
Je to už trochu pozdější reakce, ale pokud by se sem někdo znovu dostal… AJAX paginator jsem rozjel takto:
public function createComponentVisualPaginator()
{
$paginator = new \IPub\VisualPaginator\Components\Control();
$paginator->setTemplateFile(__DIR__ . '/../pagination.latte');
$paginator->enableAjax();
$paginator->onShowPage[] = function() {
$this->redrawControl('my-snippet'); // my-snippet mi obaluje celou mou tabulku záznamů včetně paginatoru
};
return $paginator;
}
- Dismember
- Člen | 50
Mám jeden problém a nepřišel jsem na řešení.
Mám stránku s výpisem položek podle nějakého názvu předaného v URL.
SourcePresenter, function renderDefault a v URL je parametr source
<?php
/source/?source=aaa
?>
Když připojím VisualPaginator, tak mi to vytvoří odkazy takto:
<?php
/source/?page-page=2&do=page-showPage
?>
Můj parametr je pryč…potřebuji, aby ten odkaz vypadal takto:
<?php
/source/?source=aaa&page-page=2&do=page-showPage
?>
Na dřívější verzi VisualPaginatoru to fungovalo. Můžete mi prosím poradit.
Díky
- Mardzis
- Člen | 33
Lukeluha napsal(a):
Je to už trochu pozdější reakce, ale pokud by se sem někdo znovu dostal… AJAX paginator jsem rozjel takto:
public function createComponentVisualPaginator() { $paginator = new \IPub\VisualPaginator\Components\Control(); $paginator->setTemplateFile(__DIR__ . '/../pagination.latte'); $paginator->enableAjax(); $paginator->onShowPage[] = function() { $this->redrawControl('my-snippet'); // my-snippet mi obaluje celou mou tabulku záznamů včetně paginatoru }; return $paginator; }
díky za toto, vše funguje skvěle, jen mám maličkej bug, po kliknutí na stránku se mi vykreslí nový paginátor na webu. Neresil si tento problem?
- jAkErCZ
- Člen | 322
Chtěl sem dle tohoto návodu rozběhnout paginator ale přišel jsem na chybu…
Call to a member function count() on array
$paginator->itemCount = $reviews->count();
ReviewManager
/**
* @return Vrátí jméno uživatele + překreslí user_id na jméno a příjmení
*/
public function getNameIdentification()
{
$reviews = $this->database->table(self::TABLE_NAME)->order('(sent) DESC');
$names = [];
foreach ($reviews as $review) {
$names[] = $review->user_id;
}
$use_name = $this->database->table(self::TABLE_USER)->where('user_id', $names)->select("user_id, CONCAT(first_name, ' ',last_name) AS use_names")->fetchPairs('user_id', 'use_names');
$reviewsAsArray = [];
foreach ($reviews as $review) {
$reviewAsArray = $review->toArray();
$reviewAsArray['user_id'] = isset($use_name[$reviewAsArray['user_id']]) ? $use_name[$reviewAsArray['user_id']] : null;
$reviewsAsArray[] = $reviewAsArray;
}
return $reviewsAsArray;
}
Kde dělám chybu?
- David Matějka
- Moderator | 6445
@jAkErCZ vracis pole, ktere nema metody. na pole se pouziva klasicka
funkce count()
. a cela ta tva implementace je spatne, jelikoz tam
zpracovavas vse z te tabulky self::TABLE_NAME
, takze to bude
pomale.
- jAkErCZ
- Člen | 322
David Matějka napsal(a):
@jAkErCZ vracis pole, ktere nema metody. na pole se pouziva klasicka funkce
count()
. a cela ta tva implementace je spatne, jelikoz tam zpracovavas vse z te tabulkyself::TABLE_NAME
, takze to bude pomale.
No tu funkci co mám mi vrací jméno místo id uživatele… proto to mám nebo jak to udělat jinak?
- David Matějka
- Moderator | 6445
standardni postup s nette database je, ze vratis $reviews
a
v sablone mas pak neco jako
{foreach $reviews as $review}
{$review->user->first_name} {$review->user->last_name}
{/foreach}
- jAkErCZ
- Člen | 322
David Matějka napsal(a):
standardni postup s nette database je, ze vratis
$reviews
a v sablone mas pak neco jako{foreach $reviews as $review} {$review->user->first_name} {$review->user->last_name} {/foreach}
Však ale to mám
<div n:foreach="$reviews as $review" class="entry clearfix">
<div class="entry-image">
<div class="fslider" data-arrows="false" data-lightbox="gallery">
<div class="flexslider">
<div class="slider-wrap">
<div n:for="$img = 0; $img < $review['images_count']; $img++" class="slide"><a href="{$basePath}/images/reviews/{$review['review_id']}/{$review['review_id']}_{$img}.jpg" data-lightbox="gallery-item"><img class="image_fade" src="{$basePath}/images/reviews/{$review['review_id']}/{$review['review_id']}_{$img}.jpg" alt="Standard Post with Gallery"></a></div>
<div n:if="!$review['images_count']">
<p><strong>Litujeme k této recenzi nebyli přidané žádné fotografie</strong></p>
</div>
</div>
</div>
</div>
</div>
<div class="entry-title">
<h2><a href="#">{$review['title']}</a></h2>
</div>
<ul class="entry-meta clearfix">
<li><i class="icon-calendar3"></i> {$review['sent']|date:'j. n. Y H.i'}</li>
<li><a href="#"><i class="icon-user"></i> {$review['user_id']}</a></li>
</ul>
<div class="entry-content">
<p>{$review['content']|noescape}</p>
</div>
</div>
Phalanx napsal(a):
@jAkErCZ Tohle není chyba v paginatoru. Máš chybně návrh – z metody vracíš assoc pole a pak voláš na pole ->count() (viz chybová hláška). Můžeš to sice opravit count($reviews), ale stejně tam musíš přidat offset a limit.
Osobně používám vždycky 2 metody u paginatorů
- jedna vrací počet položek, parametr $params, kde si předám potřebné parametry do where
- vrací data a má parametry většinou $params, $offset = null, $limit = 20
No teď jde o to že v té celé metodě co mám public function getNameIdentification() si spojuji user_id s jménem a příjemním člověka… A teď jak vyřešit to aby mi to takto fungovalo stále ale zároveň fachal ten peginator
- David Matějka
- Moderator | 6445
Však ale to mám
ne, mas tam uplne neco jinyho. precti si to znova.
edit: v te metode modelu nedelej to spojovani, jen
vrat $reviews
- David Matějka
- Moderator | 6445
Upravis, aby v sablone bylo:
{foreach $reviews as $review}
{$review->user->first_name} {$review->user->last_name}
{/foreach}