Filtr pro produkty v komponente
- shanoy
- Člen | 7
Dobry den, momentalne riesim filter pre produkty a narazil som na jeden problem. Filtrovaci formular mam obaleny v persisentnej komponente. Ta je pouzita v ShopPresenter pri 2 actions: Default (vypis vyfiltrovanych produktov) a detail produktu (Product).
Presenter vyzera nasledovne:
<?php
namespace App\FrontModule\Presenters;
use App\Forms\ProductsFilterFormFactory;
use Nette;
use App\Model;
use Tracy;
use Nette\Application\UI\Form;
/**
* @persistent(filter)
*/
class ShopPresenter extends BasePresenter
{
private $bryleService;
private $filterComponentFactory;
public function __construct(\App\Service\Bryle $bryleService, \App\FrontModule\Components\IProductsFilterComponent $productsFilterComponentFactory)
{
$this->bryleService = $bryleService;
$this->filterComponentFactory = $productsFilterComponentFactory;
}
public function renderProduct($id)
{
$this->template->product = $this->context->getService('glassesRepository')->find($id);
}
public function renderDefault()
{
$res = $this->bryleService->getFiltered($this['filter']->getFilter());
$paginator = $this['paginator']->getPaginator();
$paginator->setItemsPerPage(10);
$this->template->products = $res->applyPaginator($paginator);
$this->template->totalCount = $res->getTotalCount();
}
protected function createComponentFilter()
{
return $this->filterComponentFactory->create();
}
protected function createComponentPaginator()
{
$paginator = new \VisualPaginator;
return $paginator;
}
}
Komponenta vyzera nasledovne:
<?php
namespace App\FrontModule\Components;
use Nette;
use App;
class ProductsFilterComponent extends Nette\Application\UI\Control
{
/** @persistent */
public $gender;
/** @persistent */
public $category;
/** @var App\FrontModule\Filters\ProductsFilter */
private $filter;
private $formFactory;
public function __construct(App\Forms\FormFactory $formFactory)
{
$this->formFactory = $formFactory;
}
protected function attached($parent)
{
parent::attached($parent);
if ($parent instanceof Nette\Application\IPresenter) {
$this->filter = new App\FrontModule\Filters\ProductsFilter();
// set default values
if ($this->gender !== NULL) {
$this['filterForm-gender']->setDefaultValue($this->gender);
$this->filter->setGender($this->gender);
}
if ($this->category !== NULL) {
$this['filterForm-category']->setDefaultValue($this->category);
$this->filter->setCategory($this->category);
}
}
}
public function getFilter()
{
return $this->filter;
}
protected function createComponentFilterForm()
{
$form = $this->formFactory->create();
$genders = [
null => 'Vsechny',
'men' => 'Pani',
'women' => 'Dami',
'kid' => 'Deti',
'girl' => 'Holky',
'boy' => 'Kluci',
];
$form->addSelect('gender', 'Gender:' , $genders)
->setAttribute('class', 'ajax')
->getControlPrototype()->onchange('submit();');
$categories = [
null => 'Vsechny',
'sport' => 'Sportovni',
'retro' => 'Retro',
'fashion' => 'Znacka',
'classic' => 'Klasika',
];
$form->addSelect('category', 'Category:' , $categories)
->setAttribute('class', 'ajax')
->getControlPrototype()->onchange('submit();');
// $form->addSubmit('submit', 'Filtrovat');
$form->onSuccess[] = function ($_, $values) {
$params = [
'gender' => $values->gender,
'category' => $values->category
];
if ($this->presenter->action == 'default') {
$this->redirect('this', $params);
} else {
// zistis preco toto nejde
//$this->redirect('default', $params);
//$this->presenter->redirect('default', $params);
}
};
return $form;
}
public function render()
{
$template = $this->template;
$template->setFile(__DIR__ . '/../templates/components/productsFilterComponent.latte');
$template->render();
}
}
interface IProductsFilterComponent
{
/** @return \App\FrontModule\Components\ProductsFilterComponent */
function create();
}
Pri kazdej zmene selectu sa formular odosle. Pokial som na default stranke (vypise produktov), tak sa pekne zmeni urlka a aj sa vyfiltruju produkty. Ale, pokial zmenim filter (napr. vyberem inu kategoriu) a som na detaile produktu tak som chcel docielit to aby ma presmerovalo zase na default (vypis produktov) aj so selektnutou novou hodnotou. Presmerovat ma to presmeruje ale zostava stary stav formulara – select sa nezmeni. Viete mi prosim poradit co s tym?
Dakujem
Editoval shanoy (24. 8. 2016 18:15)
- Martk
- Člen | 661
Zkus nahradit toto:
if ($this->presenter->action == 'default') {
$this->redirect('this', $params);
} else {
// zistis preco toto nejde
//$this->redirect('default', $params);
//$this->presenter->redirect('default', $params);
}
za:
$this->category = $params['category'];
$this->gender = $params['gender'];
$this->presenter->redirect('default');
Editoval Antik (25. 8. 2016 22:01)
- shanoy
- Člen | 7
Antik napsal(a):
Zkus nahradit toto:
if ($this->presenter->action == 'default') { $this->redirect('this', $params); } else { // zistis preco toto nejde //$this->redirect('default', $params); //$this->presenter->redirect('default', $params); }
za:
$this->category = $params['category']; $this->gender = $params['gender']; $this->presenter->redirect('default');
Diky moc, zabralo! Cize pred redirectom staci setnut persistentne parametre s novymi hodnotami, ktore prisli z formularu a nasledne redirect na pozadovanu metodu? Resp je na danu situaciu nejaky vhodnejsi design?
Editoval shanoy (25. 8. 2016 22:18)
- Martk
- Člen | 661
Ano, problém v tvém předchozím řešení bylo to, že jsi posílal přes:
$this->presenter->redirect('default', $params);
parametery na presenter, ne na komponentu. Řešením by bylo také toto (už to není pěkné):
$prefix = $this->getUniqueId() . self::NAME_SEPARATOR;
$this->presenter->redirect('default', [
$prefix . 'gender' => $params['gender'],
$prefix . 'category' => $params['category']
]);
- CZechBoY
- Člen | 3608
@Antik lepší by bylo použít metodu $control->getParameterId (‚gender‘) atd.
Editoval CZechBoY (26. 8. 2016 9:48)