Výpis z databáze + aplikace filtrů + ajax
- Alsatian
- Člen | 175
Ahoj. Pročítám diskuze a čas letí. A jelikož jsem se nedopátral konce, zkusím to zde :)
Vypisuji data z databáze, v mém případě seznam faktur. Pod výpisem mám IPub\VisualPaginator, vše funguje.
Nad tento seznam jsem umístil vyhledávací formulář a jeden checkbox „neuhrazené faktury“.
InvoicePresenter.php
/** @persistent */
public $filter = [];
public function renderDefault()
{
$this["searchForm"]->setDefaults($this->filter);
$filters = $this->getParameter('filter'); // zde načítám filtry z URL
$invoices = $this->invoiceManager->getAll(); // nactu záznamy z DB
$invoices = $this->applyFilters($invoices, $filters); // aplikace filtru
Paginator...
...
}
public function applyFilters($zaznamy, $filters)
{
$neuhrazeno = isset($filters['neuhrazeno']) ? $filters['neuhrazeno'] : 0;
$search = isset($filters['search']) ? $filters['search'] : '';
if($neuhrazeno) {
$zaznamy->where('!uhrazeno'); // v DB nauhrazená FA má uhrazeno 0 (výchozí stav)
}
if($search) {
$zaznamy->where('odberatel_jmeno LIKE CONCAT("%", ? ,"%")', $search);
}
return $zaznamy;
}
protected function createComponentSearchForm()
{
$form = new Form;
$form->addCheckbox('neuhrazeno', 'Neuhrazené')
->setAttribute('onclick', 'document.getElementById("searchFormBtn").click();');
$form->addText('search', 'Hledat');
$form->addSubmit('send', 'Hledat')
->setAttribute('id', 'searchFormBtn');
$form->onSuccess[] = [$this, 'searchFormSucceeded'];
return $form;
}
public function searchFormSucceeded($form, $values)
{
if ($form->isSubmitted()->name === "send") {
$this->filter = array_filter((array) $values, function ($s) {return ($s === "" || $s === NULL || $s === [] ? FALSE : TRUE);});
if($this->isAjax()) {
$this->payload->url = $this->link('this');
$this->redrawControl('itemsWrapper');
}
else {
$this->redirect("this");
}
}
}
Latte
{* Search Box *}
<form n:name="searchForm" class="ajax">
<div class="form-inline justify-content-end">
<div class="form-group">
<div class="pretty p-icon p-curve p-bigger">
<input n:name="neuhrazeno">
<div class="state p-primary">
<i class="icon mdi mdi-check"></i>
<label n:name="neuhrazeno" class="ml-sm-1 font-weight-bold" for="neuhrazene">neuhrazené</label>
</div>
</div>
</div>
<div class="form-group">
<input n:name="search" class="form-control" value="" placeholder="Hledaný text">
</div>
<div class="form-group">
<button n:name="send" class="btn btn-secondary">
<i class="fa fa-fw fa-search"></i>
</button>
</div>
</div>
</form>
<br>
{snippet itemsWrapper}
... vypis faktur + strankovac
{/snippet}
Bez ajaxového uplatnění filtrů funguje. V URL se mění adresa a filtry jsou aplikovány. Jenom se znovu načítá celá stránka, čemuž chci zabránit.
S ajaxovým nesmyslem se mi buď nemění URL a nebo výpis chybně reaguje na změnu checkboxu.
if($this->isAjax()) {
$this->payload->url = $this->link('this');
$this->redrawControl('itemsWrapper');
}
Jak tohle, prosím, správně řešit? Změnu v URL chci, aby bylo možné poslat někomu odkaz třeba na určitý výpis.
Editoval Alsatian (3. 10. 2018 20:08)
- Ondřej Kubíček
- Člen | 494
tak url bys musel měnit v javascriptu přes pushState
pokud používáš nette.ajax.js, můžeš využít tohle extension – https://componette.org/…tte.ajax.js/
- Alsatian
- Člen | 175
Rozšíření history.nette.ajax.j používám a funguje výborně.
Upravil jsem načítání filtrů, při prvním zavolání se vyčtou z URL, další už z proměnné.
renderDefault.php
$filters = isset($this->filter) ? $this->filter : $this->getParameter('filter');
Zajímalo by mě, jak filtry řešíte vy. V url mám nyní nehezké
/?filter%5Bneuhrazeno%5D=0
Dá se třeba router přesvědčit, aby generoval něco pěknějšího? :)
Editoval Alsatian (4. 10. 2018 13:27)