Filtr pro produkty v komponente

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
shanoy
Člen | 7
+
0
-

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)

shanoy
Člen | 7
+
0
-

Naozaj nikto? Skusal som hladat no nic podobne som nenasiel. Mozem poskytnut aj komplexnejsie zdrojaky

Martk
Člen | 656
+
+1
-

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

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

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

@Antik lepší by bylo použít metodu $control->getParameterId (‚gender‘) atd.

Editoval CZechBoY (26. 8. 2016 9:48)