Grido – DataGrid pro Nette

VK
Člen | 10
+
0
-

@Lexi Osobně si myslím, že je to kvůli tomu, že ten alias vezme a vlastně se pod jeho názvem zavolají metody:

$entity->getCustomer()->getFirstname()

tzn. že pokud bys zvolil jako alias customer – který má svojí property v entitě, tak by ti to fungovalo…nebo se pletu? :) @o5

Nemám teď zrovna totiž grid, kde bych měl možnost vyzkoušet a ten můj případ je jak jsem psal trochu odlišný :)

Editoval VK (13. 3. 2015 12:52)

o5
Člen | 416
+
0
-

@Lexi Na čem to zkoušíš? Zkus to prosím na verzi 2.0.8.

VK
Člen | 10
+
0
-

@o5 Já používám verzi 2.0.8 a rozhodně jsem tam tenhle problém vypozoroval…když jsem zadal alias ke kterému neexistovala property v entitě, tak to vyhazovala laděna, že např. getFirstname není definována

// EDIT
Proto jsem taky musel mapování zapsat takto:

		$model = new Doctrine(
    $this->events
        ->createQueryBuilder('e')
        ->addSelect('t')
        ->addSelect('et')
        ->addSelect('ett')
        ->leftJoin('e.translations', 't')
        ->leftJoin('e.eventType', 'et')
        ->leftJoin('et.translations', 'ett')
    ,
    [
        'name' => 't.name',
        'eventType.name' => 'ett.name'
    ]
);

místo abych to mohl zapsat takto:

		$model = new Doctrine(
   	...,
    [
        'name' => 't.name',
        'typename' => 'ett.name'
    ]
);
a tento alias pak používat při deklaraci sloupců a nemusel tedy využívat setter setColumn()

Editoval VK (13. 3. 2015 13:04)

Jan Mikeš
Člen | 771
+
0
-

@o5 jedu na masteru, ale otestoval jsem na 2.0.8 a i zde je to chovani, ktere popisuje @VK kazdopadne ten „workaround“ (nevim jak jinak to nazvat) funguje a tim padem nenarusuje funkcnost

sKopheK
Člen | 207
+
0
-

Mám grid v tabech a potřeboval bych přidávat za URL hash, aby se při refreshi zobrazil tab, na kterém grid je. Je to možné bez nějakých hacků?

Protože asi nejde udělat smazání a editaci položek v gridu aniž bych nemusel použít redirect, je možné nějak jednoduše získat z URL všechny parametry použité grid0m?

Editoval sKopheK (19. 3. 2015 22:44)

majkl324
Člen | 13
+
0
-

Musím potvrdit problém od @Lexi
Podle namapované entity User existuje podobná vazba, tedy Role.

<?php
        $model = new \Grido\DataSources\Doctrine(
            $this->userRepository
                ->createQueryBuilder('u')
                ->addSelect('r')
                ->join('u.role', 'r'),
                [
                    'role_name' => 'r.name',
                ]
        );

        $grid->model = $model;
?>

A takto vypadá samotný column

<?php
$grid->addColumnText('role_name', 'Role')
?>

Dočkám se ale pouze exceptionu

Kdyby\Doctrine\MemberAccessException
Cannot read an undeclared property App\User::$role_name.

o5/grido ver 2.0.8
nette ver 2.2.3

Zkoušel jsem to taky tak, že bych přímo do columnu dal jako první parametr r.name, ale dostanu exception, že property r. neexistuje, jak jinak se dá tady toto prosím vás obejít a co nejrychleji vyřešit?

Jan Mikeš
Člen | 771
+
0
-

@Majkl578 workaround je docela jednoduchy, najdes jej zde

<?php
        $model = new \Grido\DataSources\Doctrine(
            $this->userRepository
                ->createQueryBuilder('u')
                ->addSelect('r')
                ->join('u.role', 'r'),
                [
                    'role.name' => 'r.name',
                ]
        );

        $grid->model = $model;
?>

<?php
	$grid->addColumnText('role_name', 'Role')
		->setColumn("role.name");
?>

Editoval Lexi (23. 3. 2015 14:26)

Oli
Člen | 1215
+
0
-

Jde v grido udělat upload souboru schovaný v jednom sloupci? Potřeboval bych do výpisu v gridu na každý řádek přidat upload souboru. Formular tam vykreslit není problém (standardní inline editace mě nefungovala). Ale po odeslání se nic neděje. Zkoušel jsem to takhle:

$grid->addColumnText('upload', 'Nahrát soubor')
	->setColumn(function($item) {
		$form = new \Nette\Application\UI\Form;
		$form->addUpload('upload');
		$form->addSubmit('send', 'Odeslat');
		$form->onSuccess[] = [$this, 'uploadProcess'];
		return $form;
	})
	->setEditableCallback(function ($id, $newValue) {
		\Nette\Diagnostics\Debugger::log($newValue); // nezavolá se
		\Nette\Diagnostics\Debugger::log($id);
		$uploaded = ['filename' => $newValue];
		return TRUE;
	});

// tahle celá metoda se taky nezavolá
public function uploadProcess(\Nette\Application\UI\Form $form)
{
	$values = $form->getValues();
	dump($values);
}
o5
Člen | 416
+
0
-

@Oli: není ti rozumět, co vlastně chceš udělat a navíc to motáš dohromady. Chceš ten upload ukazovat v inline editaci nebo na při renderu buňky?

Pokud při renderu buňky, místo setColumn() použij setCustomRender(). Pokud to chceš pro inline editaci, tak se koukni na setEditableControl().

Oli
Člen | 1215
+
0
-

@o5 říkal jsem si, jestli to není zmateně popsaný :-).
No ono je mě to vlastně jedno. Nefunguje mi ale ani jedno. Pokud to udělám přes inline editaci tak to právě nefunguje, protože Nette\InvalidStateException File upload requires method POST.Editable.php.

Pokud to udělám tak aby se to vykreslilo hned při renderu buňky, tak se vykreslí formulář, ale jeho zpracování odchytne grido inline editace a nic se nestane (to jsem právě popisoval, nedostane se to ani do setEditableCallback a ani do uploadProcess). Vykresluju to takhle:

$grid->addColumnText('upload', 'nahrát')
	->disableEditable()
	->setCustomRender(function () {
		$form = new Form;
		$form->addUpload('upload');
		$form->addSubmit('send');
		$form->onSuccess[] = [$this, 'uploadProcess'];
		return $form;
	});

Možná důležitá poznámka, ostatní buňky jsou editovatelné inline editací. (proto se mě do toho možná naváží ta inline editace při setCustomRender).

Jan Mikeš
Člen | 771
+
0
-

Ahoj, snažím se udělat select filtr (doctrine data source). attendedAt je DateTime, a já chci pomocí filtru rozeznávat, jestli je, nebo není hodnota NULL.

Filtry pro hodnoty "" a „Ano“ fungují super, ale jakmile dám „Ne“, tak grid nevypíše ani jeden řádek.

$grid->addFilterSelect('attendedAt', 'Přítomen', ["" => "", "attended" => "Ano", "unattended" => "Ne"])
		    ->setCondition(array(
		        'attended' => ['attendedAt',  '!= ?', ["NULL"]],
		        'unattended' => ['attendedAt',  '= ?', ["NULL"]]
		));

Prosím o radu, co dělám špatně. Díky.

Jan Mikeš
Člen | 771
+
0
-

Lze nějak udělat filtrování dle data, v případě, že mám sloupec DateTime, namísto Date? Řekněme, že chci vyfiltrovat řádek s hodnotou „2000–10–10 10:00:00“ ale při zadání data 2000–10–10 do filtru mi nenajde žádný výsledek. V případě, že změním typ sloupce na Date, je to ok.

Pavel Kravčík
Člen | 1195
+
0
-

Lexi napsal(a):

Lze nějak udělat filtrování dle data, v případě, že mám sloupec DateTime, namísto Date? Řekněme, že chci vyfiltrovat řádek s hodnotou „2000–10–10 10:00:00“ ale při zadání data 2000–10–10 do filtru mi nenajde žádný výsledek. V případě, že změním typ sloupce na Date, je to ok.

Já jsem to vyřešil rozdělením sloupce datetime na date a time. Pak se dá snadno filtrovat v Grido podle time a date.

Pavel Janda
Člen | 977
+
0
-

Lexi napsal(a):

Lze nějak udělat filtrování dle data, v případě, že mám sloupec DateTime, namísto Date? Řekněme, že chci vyfiltrovat řádek s hodnotou „2000–10–10 10:00:00“ ale při zadání data 2000–10–10 do filtru mi nenajde žádný výsledek. V případě, že změním typ sloupce na Date, je to ok.

Můžeš si v gridu zadat úplně vlastní podmínku:

	// Předpokládám zadání hodnoty '2000-10-10' do filtru

	$grid->addFilterSelect('attendedAt', '')
		->setWhere(function($value, $source) {
			$date_start = $value . ' 00:00:00';
			$date_end   = $value . ' 23:59:59';

			return $source->where('date > ? AND date < ?', $date_start, $date_end);
		});

Toto je řešení pro dibi (Potažmo NDB\Table). Nevím, jak to bude vypadat pro Doctrine, ale princip předpokládám stejný.

Editoval Beton (26. 3. 2015 14:11)

Jan Mikeš
Člen | 771
+
0
-

@Beton toto asi neni uplne to spravne reseni, to byly 2 na sobe nezavisle dotazy :) filtr pro datum (potazmo datetime) je typu datefilter, ne selecfilter.

o5
Člen | 416
+
0
-

@Oli: Do tý inline editace by to nějak dostat jít mělo, ale fakt nemám čas to teď zkoušet sorry. Jinak koukal si jak vypadá zdroják vygenerovaného gridu? Mně totiž před tím nenapadlo, ale zřejmě ti to nefunguje kvůli tomu, že ta tvoje jedna buňka s uploadem je formulář ve formuláři a to v HTML nelze. Jinak mít upload button na každém řádku mi příjde jako totální pitomost, já bych to dal do editačního formu, tedy do zvlášť obrazovky. Pokud na tom ale jó trváš, poděď si šablonu Grido a uprav si to tak, aby celý grid nebyl obalený tagem <form>.

Lexi:
Filtry pro hodnoty "" a „Ano“ fungují super, ale jakmile dám „Ne“, tak grid nevypíše ani jeden řádek.

Koukal si se co grid vygeneroval za query?

Lexi:
@Beton toto asi neni uplne to spravne reseni, to byly 2 na sobe nezavisle dotazy :) filtr pro datum (potazmo datetime) je typu datefilter, ne selecfilter.

Zkoušel si co ti radil @Beton? setWehere() funguje na všech filtrech, tudíž ti radil správně.

Editoval o5 (26. 3. 2015 17:20)

Jan Mikeš
Člen | 771
+
0
-

@o5 tak po chvilce experimentovani s tim co poradil @Beton jsem dosel k tomuto:

$grid->addColumnDate("createdAt", "Čas provedení")
			->setDateFormat("d.m.Y H:i")
			->setSortable()
			->setFilterDate()
				->setWhere(function($value, $qb){
					$datetime = \Nette\DateTime::from($value);
					return $qb
						->add("where", $qb->expr()->between("o.createdAt", ":datetimeFrom", ":datetimeTo"))
						->setParameter("datetimeFrom", $datetime->format("Y-m-d") . " 00:00:00")
						->setParameter("datetimeTo", $datetime->format("Y-m-d") . " 23:59:59");
				});

Generuje to spravne DQL, jenze dostavam tuto exception a dal se nehnu:

Doctrine\ORM\Query\QueryException
Invalid parameter number: number of bound variables does not match number of tokens

edit: omlouvam se, moje chyba, prepsal jsem si where, ktery byl pouzit v puvodim querybuilderu, stacilo ->add(„where“) prepsat na ->andWhere(…)

Editoval Lexi (26. 3. 2015 19:58)

Oli
Člen | 1215
+
0
-

@o5 nakonec jsem to vyřešil tou editací ve vlastním formuláři. Jsem si chtěl ušetřit práci :-)


Jde nějak nastavit sloupec aby se nevypsal při výpisu, ale zobrazil se při exportu? Aby se vůbec nezobrazil, ne jen jeho obsah.

Jan Mikeš
Člen | 771
+
0
-

Ahoj, našel jsem další chybku :) DaterangePicker v datefilteru má vždy nastavenou hodnotu na 26.2., namísto toho, aby zobrazoval aktuální měsíc s highlightem na dnešek.

Toto chování lze pozorovat i na http://grido.bugyik.cz/example/
Zkoušel jsem aktualizovat moment.js, daterangepicker.js, testováno v chromu, safari, firefoxu.

Prosím o potvrzení, že není chyba pouze lokálně u mě, reportnul bych pak na githubu.

Oli
Člen | 1215
+
0
-

@Lexi chová se mě to taky tak. Ale nejedná se o dateRangePicker, ale o datePicker ;-)

Jan Mikeš
Člen | 771
+
0
-

@Oli nope, jedná se o tento doplněk ;)

Oli
Člen | 1215
+
0
-

@Lexi ten mě ale funguje správně. Zobrazuje defaultně 26.2 - 27.3.. Což je dneska rozsah posledního měsíce. Pokud ale nastavím setFilterDate místo setFilterDateRange, tak mě to zobrazuje 26.2. jak jsi psal.

Teď mě ale napadlo, že to může být tím, že ten doplněk jak jsi odkazoval používám a on se použije i na ten filterDate…

Jan Mikeš
Člen | 771
+
0
-

@o5 prosím o návod jak rozchodit testy k o5/grido, mám s tím nějaké problémy :)

Nejdříve jsem se setkávál s

Nette\DI\ServiceCreationException: Reference to missing service 'database.sqlite'.

To jsem fixl pomocí

ndb_sqlite: @database.sqlite  # původně ndb_sqlite: @nette.database.sqlite

Teď

Nette\DI\ServiceCreationException: Service 'application.1': Service of type Kdyby\Console\Application needed by KdybyModule\CliPresenter::injectConsole() not found. Did you register it in configuration file?
VK
Člen | 10
+
0
-

@o5 Prosím tě jaký důvod nebo smysl mělo v metodě setRememberState nahradit kombinaci monitor/attached za getPresenter? Jde totiž o to, že pokud mám konkrétní grid jako komponentu a využívám generovaných továrniček, tak mi začne vyhazovat exception, že komponenta není připojená k presenteru…což správně, opravdu v tu chvíli není.

To proč využívám factory má svůj důvod a tím je především předání závislostí do komponenty aniž bych je musel zbytečně předávat přes presenter…potom se totiž z presenterů stává „smetiště a moloch“ služeb, které vůbec nepotřebuje, ale jen je zbytečně předává.

Dokážu s tím žít, není nic snadnějšího než si přetížit setRememberState a napsat si ji „po staru“, ale spíš by mě zajímal důvod proč to tak je? Možná mi i uniká způsob jak i s použitím generovaných továrniček připojit presenter a vyhnout se tak tomuto problému. Díky ;)

Editoval VK (28. 3. 2015 21:28)

Jan Mikeš
Člen | 771
+
0
-

@VK zkousel jsi grid jako komponentu v komonente? Pouzivam to takto spolecne s automaticky generovanymi tovarnickami, sluzby se mi automaticky predavaji pres konstruktor a s tim co popisujes problem nemivam.

Mimochodem pokud potrebujes presenter, da se vytahnout pres $application->getPresenter()

VK
Člen | 10
+
0
-

@Lexi Jasný, stejně jako bych si mohl udělat setter pro presenter, nebo bych mohl použít interní metodu setParent, ale rozhodně to není směr kterým bych se chtěl ubírat…injectnout si Application mi vůbec připadá jako šílenost! Komponenta v komponentě je způsob jak to obejít a jak psát zbytečný kód.

Trošku jsem se bál toho, že můj dotaz bude brán jako dotaz, jak si mám připojit presenter, ale to není to podstatné a na to existuje mnoho způsobů. Každopádně díky za snahu ;)

Můj dotaz zní především takto…proč a jakou přidanou hodnotu má použití getPresenter před monitor/attached, že to bylo tak důležité to nahradit. Jak jsem psal už v předchozím postu, není to nic, co by mi nějak extra vadilo, protože si to prostě upravím bez nutnosti zásahu do grida, ale imho je to zbytečnost.

Oli
Člen | 1215
+
0
-

@o5 Jde nějak nastavit sloupec tak, aby nebyl vůbec vidět při normálním renderu gridu, ale zobrazil se při exportu? Potřeboval bych totiž axportovat všechny data z databáze, ideálně podle filtru z gridu, ale v gridu zároveň všechny ty sloupce nepotřebuju (respektive nesmí být).

Pokud to grido nyní neumí, můžu zkusit poslat PR na něco jako setRenderDesibled a setExportDesibled.

VK
Člen | 10
+
0
-

Přikláním se k @Oli, jen místo setterů nad každým sloupcem bych volil callback…bude nabízet daleko více možností (třeba přidat i sloupec který bude kombinací 2 sloupců). Už jsem si toto u jednoho projektu dodělával, tak můžu implementovat do grida a poslat pull request.

o5
Člen | 416
+
0
-

Oli napsal(a):

Potřeboval bych totiž axportovat všechny data z databáze, ideálně podle filtru z gridu, ale v gridu zároveň všechny ty sloupce nepotřebuju (respektive nesmí být).

Tohle jde proti filozofii současného exportu a zavádět tam něco jako $column->setRenderDisabled() mi připadá jako WTF faktor, nehledě na to, že by se pro render (většina requestů) vytvářely některé Components\Column objekty zbytečně. Prostě export je aktuální view v CSV namísto HTML, nic víc :)

EDIT: Ale teoreticky by se to dalo asi řešit přes nějaký callback typu $grid->onFetchDataExport a v tomto místě ty data do exportu přidat.

Editoval o5 (31. 3. 2015 19:31)

Šaman
Člen | 2659
+
0
-

Ahoj, už to tu bylo, ale zatím se mi to nepodařílo rozchodit. Potřebuji umístit tlačítko pro export mimo grid. To mi v základu funguje, ale pokud ajaxově vyhledávám, tak se mi v tom exportu pomocí externího tlačítka ignorují nastavené filtry. Resp. už samotný odkaz je nezná. Je to asi kvůli tomu, že původní request byl bez filtrů a ty do něho byly dodány jen pomocí JS.

<div class="col-sm-3 col-md-2 column h1row">
	<a n:href="personGrid-export-export!" class="btn btn-success btn-block">CSV export</a>
	<!-- vygeneruje odkaz: https://localhost/project/www/?do=personGrid-export-export -->
</div>

{control personGrid}
<!-- vygeneruje odkaz: https://localhost/project/www/?personGrid-filter[pid]=77&do=personGrid-export-export -->

P.S. Doporučený způsob mi ten filtr ignoruje také.

<a href="{$presenter['personGrid']['export']->link('export!')}" class="btn btn-success btn-block">

@o5: Netušíš, jak to rozchodit? Když vypnu ajax, takže je filtr natvrdo součástí adresy, tak to funguje jak má. Případně můžeš někam nasdílet funkční projekt s aktuálním Gridem? Díky.

o5
Člen | 416
+
0
-

Šaman napsal(a):

Resp. už samotný odkaz je nezná. Je to asi kvůli tomu, že původní request byl bez filtrů a ty do > něho byly dodány jen pomocí JS.

No tak pokud si ten odkaz dal někam mimo snippet grid, tak se není čemu divit.

Editoval o5 (1. 4. 2015 11:03)

Šaman
Člen | 2659
+
0
-

Já se nedivím, já se ptám, jestli to lze řešit.

o5
Člen | 416
+
+1
-

@Šaman Obal ten odkaz do snippetu a invaliduj ho v reload metodě.

Oli
Člen | 1215
+
0
-

a v tomto místě ty data do exportu přidat.

@o5 proč až v tom foreache? Tím bych ztratil možnost vytáhnout si z Grido názvy sloupců. Implementoval jsem si to pro svůj externí export, ale hodil jsem to před ty foreache. Má tohle řešení nějakou zjevnou chybu? Použití je pak strašně jednoduchý:

$export = $this->grid->setExport();

$export->onFetchDataExport[] = function (\Nette\ComponentModel\RecursiveComponentIterator $columns, \Grido\Grid $grid) {
	$columns['street'] = $grid->addColumnText('street', 'Ulice');
	$columns['streetNumber'] = $grid->addColumnText('streetNumber', 'Číslo popisné');
	$columns['city'] = $grid->addColumnText('city', 'Město');
};

Co přidat možnost vlastního exportu? Potřebuju export do xsl. Udělal jsem si proto na to třídu velmi podobnou, té která je v Grido, akorát používá PHPExcel knihovnu. Volám to potom takhle

public function handleExport()
{
	if(is_null($this->grid))
	{
		$this['grid'];
	}

	$export = new MujExport($this->grid);
	$export->onFetchDataExport[] = function ($columns, \Grido\Grid $grid) {
		$columns['street'] = $grid->addColumnText('street', 'Ulice');
		$columns['streetNumber'] = $grid->addColumnText('streetNumber', 'Číslo popisné');
		$columns['city'] = $grid->addColumnText('city', 'Město');
	};

	$this->grid->onRegistered && $this->grid->onRegistered($this->grid);
	$this->grid->presenter->sendResponse($export);
}

Uplně by stačilo něco jako:

public function setExport($label = NULL)
{
	if($customExport instanceof IExport)
	{
		return $customExport;
	}
	return new Export($this, $label);
}

Pak by se to pohodlněji volalo a fungovalo by i to defaultní tlačítko…

Editoval Oli (1. 4. 2015 13:11)

Ja
Člen | 260
+
0
-

V novem Nette 2.3.1

„Call to undefined function Grido\callback()“

<?php
File: ...\vendor\others\Grido\Grid.php:733

723:
724:        /**
725:         * @param string $class
726:         * @return \Nette\Templating\FileTemplate
727:         * @internal
728:         */
729:        public function createTemplate($class = NULL)
730:        {
731:            $template = parent::createTemplate($class);
732:            $template->setFile(__DIR__ . '/Grid.latte');
733:            $template->registerHelper('translate', callback($this->getTranslator(), 'translate'));
734:
735:            $namespaceFilter = function($source)
736:            {
737:                $namespaces = array(
?>

Nestalo se nekomu, netusite jak fixnout?

Moc diky

bezsebesam
Člen | 8
+
0
-

Ahoj, mám trochu problém s filtry a s metodou setRememberState(). Pokud zapnu ukládání stavu gridu, v určitých situacích pak dostanu výjimku:

Nette\InvalidArgumentException
Value ‚2‘ is out of allowed range ['', 1, 4] in field…

Nastane to v případě, kdy jeden grid používám pro výpis různých dat a mám v něm filtr typu Select. Když nastavím filtr třeba na hodnotu ‚2‘ a vrátím se sem později, kdy jsou zde jiná data, grido se snaží do filtru předvyplnit hodnotu ‚2‘, která ale již není v nabídce.

Konkrétně se jedná o tuto situaci. Mám databázi společností, jejich poboček a uživatelů. V detailu společnosti vypisuju grid s uživateli vybrané společnosti. V gridu mám sloupec Pobočka, kde je uvedeno, na jakou pobočku uživatel patří. Pokud v detailu společnosti A nastavím filtr na pobočku Praha, pak v detailu společnosti B dojde k výjimce, protože společnost B pobočku Praha nemá.

Ideální by bylo, aby

  • grido nenastavovalo hodnoty filtru, které neexistují nebo
  • aby se stav grida ukládal do session nějak konkrétněji, tedy ne jen podle názvu presenteru a komponenty, ale s nějakou opravdu unikátní identifikací.

Je toto nějak řešitelné nebo mi jen něco uniká? Díky za odpověď.

Unlink
Člen | 298
+
0
-

@bezsebesam a skúsil si každému z nich dať iný názov?

Ja by som sa chcel spýtať, momentálne pri dibi fluente sa nedá používať select ktorý obsahuje aliasy, teda dá sa podľa nich maximálne sortovať ale pokiaľ chceme niečo vyhľadávať tak proste WHERE s aliasom nieje možné použiť. A pokiaľ joinujete tabuľky, kde máte stĺpce s rovnakým názvom, tak nič iné ako aliasy sa použiť nedá.

Rozmýšľal som čo s tým, momentálne to riešime pohľadom, ale to sa mi nepáči. Ďalším riešením by bolo, keby dibi parsovalo aj nejako select klauzulu, a bolo by možné z fluentu získať nejaký „maping“ vo formáte "alias" => "tabulka.realnyStlpec" pre všetky položky v selecte. Neviem, nieje možné nejako toto z dibi fluent získať?
Viem že by sa dalo vytiahnuť tu select klauzulu, ale parsovať to na úrovni grida je asi blbosť.

Poslednou možnosťou čo ma napadá je podobné riešenie ako sa používa pri doctrime datasource, tá ma ako druhý nepovinný parameter mapping.

Nejaké nápady ako toto riešiť?

Editoval Unlink (10. 4. 2015 20:39)

o5
Člen | 416
+
+1
-

Unlink napsal(a):

Ja by som sa chcel spýtať, momentálne pri dibi fluente sa nedá používať select ktorý obsahuje aliasy, teda dá sa podľa nich maximálne sortovať ale pokiaľ chceme niečo vyhľadávať tak proste WHERE s aliasom nieje možné použiť.

Filtru lze nastavit název sloupce, který se pak použije při sestavování SQL.

$grid->addFilterText(...)
	->setColumn('aliased_column')
Pavel Kravčík
Člen | 1195
+
0
-

VK napsal(a):

@o5 Prosím tě jaký důvod nebo smysl mělo v metodě setRememberState nahradit kombinaci monitor/attached za getPresenter? Jde totiž o to, že pokud mám konkrétní grid jako komponentu a využívám generovaných továrniček, tak mi začne vyhazovat exception, že komponenta není připojená k presenteru…což správně, opravdu v tu chvíli není.

To proč využívám factory má svůj důvod a tím je především předání závislostí do komponenty aniž bych je musel zbytečně předávat přes presenter…potom se totiž z presenterů stává „smetiště a moloch“ služeb, které vůbec nepotřebuje, ale jen je zbytečně předává.

Dokážu s tím žít, není nic snadnějšího než si přetížit setRememberState a napsat si ji „po staru“, ale spíš by mě zajímal důvod proč to tak je? Možná mi i uniká způsob jak i s použitím generovaných továrniček připojit presenter a vyhnout se tak tomuto problému. Díky ;)

@VK @o5: Snažil jsem se z toho něco vydolovat, ale moc smysl mi to nedává.

	Component '' is not attached to 'Nette\Application\UI\Presenter'

A to mám Grido v presenteru. Pokud ho používám bez setRememberState() tak je vše v pořádku. Ale, když chci ukládat stav Grida, tak to hází výše zmíněnou chybu. Zkoušel jsem nějak ten presenter připojit, ale opravdu nemám nápad jak. Díky.

EDIT: Stačí používat komponentu s $name a voláním Grid($this, $name), což mi ale myslím někdo radil ať nepoužívám při volání komponent.

Editoval kzk_cz (14. 4. 2015 8:46)

Pavel Kravčík
Člen | 1195
+
0
-

@o5: Dá se nějak nastavit ta podmínka v setCondition pro více values? Zkoušel jsem několik různých přístupů, ale nepovedlo se.

Mám nějaký soubor hodnot, řekněme třeba 5. A rád bych je filtroval podle klíče filtru ano/ne. První tři se filtrují pro ne a zbylé pro ano.

Ty čárky samozřejmě nefungují, ale zkoušel jsem array, array s OR a podobně. Ale asi se to musí připravit před gridem?

->setFilterSelect(['' => '~ Vše ~', 'no' => 'Nevyplácená', 'yes' => 'Vyplácená'])
	->setCondition([
		'no' => array(['typ'],  '= ?', 'VN, TR, BR'),
        'yes' => array(['typ'],  '= ?', 'SVN, VPN')
    ]);
Pavel Kravčík
Člen | 1195
+
0
-

Ano, to jsem prošel a je to v příspěvku výše, koukal jsem i do kódu od Grido. Ale nepřišel jsem na žádný způsob jak napsat tohle:

	'no' => array(['typ'],  'IS IN ?', ['VN', 'TR', 'BR']

Zkoušel jsem i stejný přístup jako u sloupců, ale vezme jen první parametr a ostatní zahodí:

	'no' => array(['typ'],  '= ?', ['VN', 'OR', 'TR', 'OR', 'BR']),
	'no' => array(['typ'],  '= ?', ['VN', 'TR', 'BR']),
	'no' => array(['typ', 'OR', 'typ'],  '= ?', ['VN', 'SVN']),

Proto se ptám, jestli to jde zapsat. Nebo to mám vyřešit ještě předtím, než data pošlu do Grido. :)

o5
Člen | 416
+
+1
-

@kzk_cz: tak to se na to podívej znovu, protože tam je na konci ukázka na setWhere(), kde předáš callback a podmínku si sestavíš stejně jako v dibi/ndb/doctrine/arraysource

Pavel Kravčík
Člen | 1195
+
0
-

@o5: Dobrý. Jsem debil. :( Evidentně si počínají nemoc selektivního čtení vybírá svoji daň. Viděl jsem selection + where a tak jsem to považoval za rozšíření nad selection a ne callback. Pomocí callbacku to půjde snadno. Díky a omlouvám se za zbytečný spam. :|

kolsi
Člen | 131
+
0
-

Může mě prosim někdo nakoupnout? Mám v gridu filtr bootstrap-multiselect. V grido.ext.js mám:

	Grido.Grid.prototype.initMultiSelect = function() {
    var _this = this;

    if ($.fn.multiselect === undefined) {
        if (window.console) {
            console.error('Plugin "bootstrap-multiselect.js" is missing!');
        }
    } else {
        $('select[data-multiple=multiple]').off('change.grido');
        $('select[data-multiple=multiple]').multiselect({
				includeSelectAllOption: true,
				includeSelectAllDivider: true,
				includeSelectAllIfMoreThan: 3,
            onDropdownHide: function() {
                $('input.search ', _this.$table).click();
            },
        });
    }
};

Všechno funguje v pohodě, filtruje jak má. Jediná drobnost je ta, že při načtení stránky a otevření toho multiselect seznamu se filtr refreshne už při prvním kliknutí na checkbox. Při dalším kliknutí už to funguje jak má a refreshne se až po zavření (onDropdownHide).

Našel jsem v kódu, že Grido naváže událost na všechny checkboxy, aby se filtr aktivoval okamžitě. Zkusil jsem tedy tuto událost vypnout pro checkboxy v tom multiselect filtru:

$("input[type=checkbox][name=multiselect]").off('change.grido');

Výsledek je ten, že se filtrování úplně rozhodí. Buď se to při zavření neodešle vůbec, nebo se odešlou náhodný hodnoty (a ne ty co zakšrtnu).

flexroad
Člen | 117
+
0
-

Ahoj,

predpokladam, ze to bude neco jednoducheho, ale nemuzu to nikde najit.

V grido bych rad vypsal v jednom sloupci seznam skupin oddelenych carkou, do kterych patri uzivatel

Pro komunikaci s db pouzivam doctrine.

zkousim nasledujici:

$grid->addColumnText('email', 'Email')->setFilterText()->setSuggestion(); // FUNGUJE
$grid->addColumnText('roles', 'Role'); // VRATI CHYBU - Doctrine\ORM\PersistentCollection could not be converted to string

Diky moc za cokoliv,

@flexroad

Oli
Člen | 1215
+
0
-

@flexroad něco jako

$grid->addColumnText('roles', 'Role')
	->setColumn(function ($item) {
		$string = '';
		foreach ($item->roles as $role)
		{
			$string .= $role->name . ', ';
		}
		return $string;
	});

Vloží i za poslední element čárku, nejlíp to ošetříš asi pomocí http://image.slidesharecdn.com/…68-3-638.jpg?…

chap
Člen | 81
+
+1
-

Oli napsal(a):
Vloží i za poslední element čárku, nejlíp to ošetříš asi pomocí …

a co takhle

return substr($string, 0, -2);
Oli
Člen | 1215
+
0
-

Tak jasně. Tenhle můj post měl za cíl i ukázat i tuhle možnost. Jsem o ní před tou přednáškou ani nevěděl. Tam by se pak hodila třeba tahle metoda. Z hlediska rychlosti kodu, je substr lepší. :-) Asi jsem tam neměl psát to

nejlíp to ošetříš asi pomocí

Hafran
Člen | 121
+
0
-

Zdravím,
potřeboval bych v šabloně zjistit jestli je aktivní jakýkoliv filtr (případně řazení) – když není tak si chci schovat lištu s filtrem. Našel jsem getActualFilter() ale vypadá to, že ten to nezvládá v Ajaxu, neví někdo, jestli si to tam někde Grido nepředává samo, ať to tam nebastlím ručně? :)