Výpis z databáze + aplikace filtrů + ajax

Alsatian
Člen | 175
+
0
-

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
+
0
-

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
+
0
-

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)