Grido – DataGrid pro Nette
- o5
- Člen | 416
looky napsal(a):
pepakriz napsal(a):
Přesně tímto řešením jsem chtěl přispět, bohužel jsem zjistil, že to sice vyřeší vykreslování sloupce, ale například napovídání zůstane rozbité.
Bohužel nemám teď moc času, abych se tím zabýval. Kdyby byl někdo jiný ochotný, bylo by to super!
Ono je to lepší řešit přes ten setColumn s callbackem (viz můj předchozí příspěvek), ale právě díky tomu pak nejde řadit a filtrovat (a napovídání jsem radši vůbec nezkoušel :D )
Řešením je nepoužívat NDB!! :D
Né, ale teď vážně. Přístup k najoinovanému sloupci se v NDB řeší takto:
$item->country->title;
Ale třeba řazení se řeší takto:
->order('country.title')
Callback do setColumn() vyřeší první, ale druhé samozřejmě nikoli. Zkus to takto:
$grid->addColumn('country', 'Country')
->setSortable()
->setColumn('country.title')
->setCustomRender(function($item) { return $item->country->title; })
->setFilterText()
->setColumn('country.title')
->setSuggestion(function($item) { return $item->country->title; });
Je to trochu kostrbaté ale jinak to prostě nejde. To „druhé“ volání setColumn() pro filtr by mělo jít udělat „automaticky“ – podívám se na to.
- Jiří Nápravník
- Člen | 710
Předně díky za skvělý datagrid.
Měl bych jendu otázku: je možné nějak nastavit defaultně jazyk pro všechny instance Grida?
- George
- Člen | 8
LOL, co to ma byt za popichovani? :) Ten tvuj problem vyresi refactoring klientske casti grida, dostanu se k tomu snad pristi tyden.
Nikdo nereagoval, tak jsem doufal, ze to zabere a taky ze jo :)
Na refaktoring si rad pockam. Porad jsem si rikal, proc mi nefunguje naseptavac,
ale zatim jsem to moc nezkoumal a koukam, ze pises, ze je to kvuli
nette.ajax.js.
Takze refaktoring snad vyresi hned dva moje problemy :)
Skvela prace, jen tak dal.
- miler
- Člen | 75
@o5: Díky za odpověď. Stránkování si myslím že by to nemuselo vypínat automaticky, ale nevím jestli by to pak nějak funkčně nevadilo.
Moje představa, kterou jsem zatím nedokázal realizovat byla, že by to fungovalo jako u filtrů, zavolalo by se na daný sloupec třeba ->addSum() a v přídadě že by alespoň jeden sloupec tuto vlastnost měl, přidal by se do spodní části gridu jeden součtový sloupec. Sčítalo by to číselné sloupce, kdo by chtěl jiné, dopsal by si callback.
Toliko moje naivní představa :-)
Editoval miler (25. 7. 2013 14:29)
- o5
- Člen | 416
News:
K přepsání klientské části Grida jsem se dokopával dlouho, ale pořád jsem to tak nějak odkládal, protože jsem tušil, že to nebude hotové za pár hodin. Po několika nočních studií onoho „javascriptování“, jsem to dnes konečně realizoval a to přesně na 500 řádků :))
- Byla opravena chyba co mi tu @George hlásil a pár dalších.
- Využívá nette.ajax.js
- Hlavní novinkou ale je, že nyní můžete konečně použít prototype a tedy si třeba změnit výchozí datepicker apod. bez modifikace originálního skriptu. Lze takto měnit všechny metody skriptu.
<script>
$.fn.grido.Grid.prototype.initDatepicker = function() {
this.$element.on('focus', 'input.date').mySuperTruperDatePicker();
};
</script>
- Nakonec jsem přidal možnost nastavovat options pro skript ($.fn.grido.defaults) z php.
$grid->setClientSideOptions(array('datepicker' => array('mask' => '99-99-9999')));
Je potřeba aktualizovat jak Grido tak jquery.grido.js. Dá se to vyčíst z tohoto a tohodle diffu.
Enjoy :)
Editoval o5 (27. 7. 2013 18:40)
- o5
- Člen | 416
@djdaca: A na co by jsi to chtěl změnit prosím tě?
Lze to udělat takto:
- Nastavíš vlastní translátor..
$grid->translator = $customTranslator;
- Nebo použiješ ten co je součástí Grida
$grid->translator = new Grido\Translations\FileTranslator(NULL, array('Reset' => 'RESEET'));
Jinak překlady najdeš tady.
Editoval o5 (25. 7. 2013 20:43)
- Jiří Nápravník
- Člen | 710
Díky za přepsání client side a podporu nette.ajax.js. Nicméně nejsem úplně znalý, ale pochopil jsem, že application.ajax.js má btýt jako extension pro nette.ajax.js – potom by to asi chtělo vyhodit ten řádek s $.nette.init(); jelikož nette.init() může být zavoláno jen jednou, a to si pravděpodobně volá každý sám ve svém skriptu a nemělo by asi v extension být. A možná bych ještě bylo lepší ten soubor přejmenovat na grido.ajax.js než application.ajax.js. Samozřejmě jsem si obojí udělal sám, ale bylo by lepší mít to asi rovnou.
Ale berte mě s rezervou, jeslti to tak není. Jsem pořád začátečník v univerzu nette.
- o5
- Člen | 416
@Jiří Nápravník: Přejmenovat na grido.ajax.js to by asi šlo :)) Každopádně jsem to nechal oddělený schválně. Ono „grido-sandbox“ je potřeba brát s rezervou, ikdyž to má v názvu sandbox, tak to sandboxem není (v projektu nepotřebuješ konfigurace pro všechny typy db/orm, atd..). Takže by se to asi spíše mělo jmenovat „grido-demo“, jsou to historické důvody.
Jinak nebyl záměr myslet „application.ajax.js“ jako extension pro nette.ajax, prostě jsem potřeboval oddělit soubor, který se načítá pro ajaxové/neajaxové demo (suffix „*.ajax.js“ byl zvolen čistě náhodně, naopak se mi jmenná konvence k těm nette extensions nelíbí).
Takže spíš možná
„application.ajax.js“ -> „main.ajax.js“
„application.js“ -> „main.js“.
Editoval o5 (25. 7. 2013 23:43)
- o5
- Člen | 416
pepakriz napsal(a):
Co takhle začít s větvením/tagováním verzí?
Done, 0.9.0
libik napsal(a):
K filtru RENDER_INNER: zobrazuje sloupec Actions i kdyz v grido neni definovana zadna akce a pozadi prostoru mezi headerem a prvnim radkem neni stejne pres vsechny sloupce – viz. http://i44.tinypic.com/f36pox.png
Opraveno, díky.. přidal jsem do sandboxu multirender view, kde jsou vidět možné varianty (snad jsem na nic nezapomněl). Zjistil jsem tím dvě malé nedokonalosti s jquery.grido.js, už jsem je hodil mezi issues…
Jednou už jsem tady psal o tom, že button „Reset“ je pro mě klíčový, ale zároveň třeba tady to vypadá divně. Takže kam ho dát, vpravo vedle tlačítka pro export? Ale zase pokud je definovaný filtr, je podle mě správné ho mít vedle tlačítka pro filtrování… :D
o5 napsal(a):
Takže spíš možná
„application.ajax.js“ -> „main.ajax.js“
„application.js“ -> „main.js“.
Přejmenováno.
Editoval o5 (26. 7. 2013 16:36)
- lunak83
- Člen | 47
Ahoj,
mám problém s ajaxovým voláním filtrů. Po každém přefiltrování, resp. i po každém jiném ajaxovém volání pokud jsou připojeny JS soubory grida, odscrolluje stránka až nahoru. Ve výsledku to pak vypadá jako by request ani nebyl ajaxový (ačkoli je). Pokud si připojím jen nette.ajax.js a ne soubory grida, tak se to neděje.
Bylo by možné se na to kouknout, prosím? Dělá to i sandbox co máte jako live ukázku.
Děkuji moc.
Editoval lunak83 (26. 7. 2013 17:53)
- lunak83
- Člen | 47
o5: Jak jednoduché, stačilo se zeptat hned ráno :-) Díky!
Ještě bych se chtěl zeptat na jednu věc, pokud tu zmíněnou volbu vypnu a v gidu klikám na stránkování, vše běží krásně ajaxově a nevyjíždí to nahoru. Když ale kliknu na stránku 1, odscrolluje to až nahoru. Je to tak, že dokud je za hashem nějaký parametr, je to v pořádku, ale když se grid vrátí do „vyýchozího stavu“, odscrolluje. Ověřeno na čistém sandboxu. Je to takto v pořádku? Děkuji!
Editoval lunak83 (27. 7. 2013 0:17)
- Pavel Kouřil
- Člen | 128
Zdravím, mám problém s doctriním DataSource.
Komponentu pro Grido tvořím následovně:
protected function createComponentGrid()
{
$grid = new Grid();
$grid->setModel(new Doctrine($this->dao->createQueryBuilder->select("o")->from("Foo", "o")));
$grid->addColumn('fullName', 'Full Name');
return $grid;
}
Getter „getFullName()“ ve třídě Foo existuje (a třída Foo dědí z Nette\Object), nicméně stále dostávám „InvalidArgumentException – Column ‚fullName‘ does not exist in datasource“.
Nesetkal se s tímto problémem někdo a byl by ochotný podělit se o řešení?
EDIT: Zvláštní poznatek – pokud si v metodě action udělám $this->dao->findAll(), popř. i třeba jen $this->dao->find(1) (naprázdno, bez přiřazení do proměnné), tak Grido se vykreslí správně.
Pokud pak ale přidám $grid->addActionHref('edit', 'Edit');
,
tak se dostanu k chybě „InvalidArgumentException – Primary key ‚id‘
not found.“
Tento datagrid se mi velmi líbí, ale bohužel netuším, jak jej zprovoznit. :(
Editoval Pajka (27. 7. 2013 17:47)
- Pavel Kouřil
- Člen | 128
@o5: Jo, už jsem to rozuzlil, řešení bylo vlastní IPropertyAccessor – jde o to, že tvůj nepočítá s tím, že fieldy ve třídě jsou private a využívá se properties z Nette\Object; a protože Doctrine využívá docela dost Proxies (a tam private fieldy nepodědíš), tak hasProperty háže ty chyby (pokud se mi to řešení bude zdát i po týdnu hezké, můžu z toho udělat pull request).
Jinak, už jsem to tedy rozchodil, vložil všech těch 5 js a jedno css, ale Grido nevypadá vůbec tak, jak na screenech; nesetkal se někdo s tímdle?
A dá se nějak vypnout „filtrování“? V docce ani kódu jsem to nenašel. V některých případech nechci možnost filtrování a ten vnější i vnitřní filtr docela překáží.
- pepakriz
- Člen | 246
Pajka, o5: Jsem pro, aby hasProperty
z accessoru zmizlo. Stejně se to nedá bezchybně naprogramovat (viz https://github.com/…rido/pull/43).
Místo toho může get/setProperty
vyhodit srozumitelnou výjimku,
pokud položka neexistuje.
- mere.gee
- Člen | 54
Ahoj, potřeboval bych vyhledávat ve více sloupcích. Podle dokumentace by to Grido mělo zvládat, ale v příkladě to nefunguje – mělo by se vyhledávat jak ve sloupci ‚firstname‘, tak ve sloupci ‚surname‘, ale vyhledává se pouze v tom prvním.
$grid->addFilterCustom('name', new \Nette\Forms\Controls\TextArea('Jméno nebo příjmení'))
->setColumn('firstname')
->setColumn('surname', Filter::OPERATOR_OR)
->setCondition('LIKE %s')
->setFormatValue('%%value%');
Pokud nakonfiguruji svůj filtr podobně, dostávám chybu „argument count does not match placeholder count“. Asi se očekávají dva stringy, pro každý sloupec jeden – takhle by to ale, pokud se nepletu, nemělo fungovat… Lze tedy vyhledávat ve více sloupích najednou? Předem dík za odpověď
- o5
- Člen | 416
Uff, jsem zralej na školení asertivity…
@sinner: jestli víš jak funguje nette.ajax.js (a ajax v nette obecně), tak víš jak si zajaxovat akce a operace.. u akcí ti napovím, že přidání třídy „ajax“ se dělá takto: $action->elementPrototype->class[] = ‚ajax‘;
@pepakriz: ad hasProperty(): kouknu na to
@mere.gee: tohle je bug v array source
@sinner: „Chová se mi to nějak divně“ :)) Zkus popsat problém znovu a třeba se chytnu.
Editoval o5 (31. 7. 2013 23:33)
- Felix
- Nette Core | 1196
lunak83 napsal(a):
Existuje prosím možnost jak na základě hodnoty
$item->neco `nastavit např. podbarvení celému řádku? Něco jako `setCustomRowRenderer()
na základě hodnoty sloupce?
Ja pouzivam toto:
$grid->setRowCallback(function ($item, $tr) {
if ($item->state == XY) {
$tr->class[] = 'xy';
}
return $tr;
});
- sinner
- Člen | 20
o5 napsal(a):
Uff, jsem zralej na školení asertivity…
@sinner: jestli víš jak funguje nette.ajax.js (a ajax v nette obecně), tak víš jak si zajaxovat akce a operace.. u akcí ti napovím, že přidání třídy „ajax“ se dělá takto: $action->elementPrototype->class[] = ‚ajax‘;
@sinner: „Chová se mi to nějak divně“ :)) Zkus popsat problém znovu a třeba se chytnu.
Omlouvám se za debilní dotazy.
Zjistil jsem, že mi nefunguje confirm dialog pokud má akce class
‚ajax‘.
Vypadá to, že zaajaxování přebije ten dialog.
- lukyn
- Člen | 20
gliny napsal(a):
Ahoj
composer jsem k zavedení do projektu nepoužil, tak snad jsem nic neopomněl, ale myslím že ne.
zdroj je Nette database
Nette 2.0.8 + PHP 5.41. Tak takhle vytvářím Grid, a tuhle chybu to hází při kliku na export.
protected function createComponentFakturyGrid($name) { $tasks = $this->taskRepository->findAllTasks(); $grid = new Grid($this, $name); $grid->setModel($tasks); $grid->addColumn('created', 'Vytvoreno', Column::TYPE_DATE) ->setDateFormat(Grido\Components\Columns\Date::FORMAT_DATE) ->setSortable() ->setFilter(Filter::TYPE_DATE) ->setCondition(Filter::CONDITION_CALLBACK, callback($this, 'gridBirthdayFilterCondition')); $grid->getColumn('created')->cellPrototype->class[] = 'center'; $grid->addColumn('text', 'Text')->setSortable(); $grid->addColumn('user', 'Vytvoril') ->setSortable(); //->setColumn('user->name'); $grid->setFilterRenderType($this->filterRenderType); $grid->setExporting(); $grid->translator->setLang('cs'); return $grid; }
2. Bylo by složité upravit grid aby vypisoval třeba array (nebo objekt)? Jdu se na tu možnost mrknout. Teoreticky bych mohl použít jiný grid, ale líbí se mi export do csv, který chci, tak možná bude jednodušší si ho dodělat u jiého gridu, pokud tohle bude nereálné.
3. Nevím jestli je to fičura nebo bug, ale když zapíšu
$grid->addColumn('user->name', 'Vytvoril')
tak to nefunguje, přes samotné database to funguje. Tabulky jsou stejne jako zde
mám pocit že jsem někde zahlédl dotaz na tohle téma, ale je možné že to bylo u jiného gridu.Díky za odpověd :) Doufám že už je to více česky ;)
Ahoj Gliny a o5,
mám stejný problém. Jinak výborný grid (o5), nicméně
nevím, jak napasovat column z jiné databáze. Relace jsou v pořádku,
s použitím v Nette to běží OK.
Použitelnost příkladu od o5 viz zde → https://forum.nette.org/…id-pro-nette?p=6
mě prostě nefunguje.
Prosím poraďte
Díky
Lukyn
VYŘEŠENO !!!!!!!
Editoval lukyn (9. 8. 2013 14:18)
- regy42
- Člen | 8
Ahoj,
datagrid je super, nedaří se mi ale zprovoznit clientside věci. Javascript
normálně includuju na konci stránky, ale zdá se mi, jako by vůbec
nereagoval. Javascript žádné chyby nehlásí, všechen ostatní javascript na
webu funguje.
Jde mi především o suggestion, tak jsem ho zkoušel dát normálně takhle:
<input type="text" class="span3" style="margin: 0 auto;" data-provide="typeahead" data-items="4" data-source="["Alabama","Arkansas"nois"]">
a to normálně funugje, takže z bootstrapem by problém být neměl.
Nevíte prosím, v čem bych mohl dělat chybu? Kdyžtak napíšu podrobnosti,
úplně nevím, co by bylo třeba říct k vyřešení problému.
Předem díky a pěknou neděli ;-).
Editoval regy42 (18. 8. 2013 16:16)
- JanB
- Člen | 21
xxxmisko – mozes prosim poslat cele svoje riesenie? Mam presne rovnaky problem. Dakujem.
Inak zatial sa mi podarilo rozbehat ten customrender pre datum ulozeny ako INT:
$grid->addColumnDate('date', 'date', \Grido\Components\Columns\Date::FORMAT_TEXT)
->setSortable()
->setCustomRender(function($item) {
return date("j.n.Y,H:i:s",$item->date);
})->cellPrototype->class[] = 'center';
Vdaka xxxmisko sa mi podarilo urobit aj search od-do pre datum ulozeny ako int. Davam tu uz funkcny kod, mozno to niekomu usetri cas.
$grid->addFilter('date', 'Dátum od', Filter::TYPE_DATE)
->setCondition(Filter::CONDITION_CALLBACK, function($value){
return array('[date] >=%i', strtotime($value));});
$grid->addFilterDate('dateTo', 'Datum do...')
->setColumn('date')
->setCondition(Filter::CONDITION_CALLBACK, function($value){
return array('date <= %i', strtotime($value."24:00:00"));});
xxxmisko napsal(a):
ahojte!
mám dotaz, mám stĺpce vo formáte unix timestamp v db, pričom by som tieto chcel nechať zobraziť v gride a aj podľa nich pekne filtrovať na základe klasického formátu ‚d.m.Y H:i:s‘. Vedeli by ste mi poradiť, ako na to? Teraz grido stále zobrazuje ROVNAKÝ/ZLÝ dátum v tvare: 01 Jan 1970, jeho definícia vyzerá nasledovne:
$grid->addColumnDate('zaciatok', 'Začiatok', Grido\Components\Columns\Date::FORMAT_TEXT) ->setSortable() ->setFilter();
EDIT!
Už som na to prišiel, na vykreslenie som použil setCustomRender, na filter ->setCondition(Filter::CONDITION_CALLBACK…
Možno by bolo dobré v dokumentácii zmeniť v callbacku asociativné pole za pole normálne, ako je to v príklade. Môj prípad:
(return array('[datum] =%s' => $value)) vrátilo v sql dotaze AND $value
(return array('[datum] =%s', $value)) vrátilo v sql dotaze AND [datum] = $value
Proste, čo je napísané v dokumentácii, mi nefunguje, prebral som to z funkcie gridBirthdayFilterCondition v sandboxe
Editoval JanB (2. 9. 2013 9:42)
- JanB
- Člen | 21
Je mozne nastavit fixnu (alebo minimalnu) sirku stlpca v Gride?
V manuale som nasiel getter getHeaderPrototype, ktory ked chapem spravne tak by mal nastavit css grid-header-„column“ kde „column“ je nazov stlcpa. Aj ked ma trocha myli preco sa to ma nastavovat getterom… Mate nejaky typ?
Editoval JanB (19. 8. 2013 12:50)
- JanB
- Člen | 21
Diki za ryhclu odpoved. Kod na callbacky mam tak ako je v mojom poste vyssie (ktory som editoval), ale momentalne mi to nerobi nic… Neviem ci tam este nechyba nejaka konverzia na date? Moja tabulka ma len jeden stlpec „date“ typu INT (PHP timestamp) ktory potrebujem odfiltrovat datumami od/do.
EDIT: nasiel som bug vo Fireloggeri, skusil som zmenit dodany datum na int ale ani to zatial nepomohlo – SQLSTATE[42000]: Syntax error or access violation: 1064
["SELECT COUNT(*) FROM `tabulka` WHERE (`date` >= %`d` = ?)" , ["10.8.2013"]]
["SELECT COUNT(*) FROM `tabulka` WHERE (`date` >= %`d` = ?)" , [1375135200]]
A tiez diki za css tip!
xxxmisko napsal(a):
toto si myslel?
$grid->addFilter('datum_od', 'Dátum od', Filter::TYPE_DATE) ->setCondition(Filter::CONDITION_CALLBACK, function($value){ return array('datum_od >= %d', $value);});
Editoval JanB (19. 8. 2013 15:38)
- NeMeFi
- Člen | 4
Pri pokuse o rozbehanie Grida dostávam chybu: Cannot read an undeclared property Grido\Grid::$handleFilter
<?php
namespace BackendModule;
use Grido;
use Grido\Components\Filters\Filter;
use Nette\Utils\Html;
class ColourPresenter extends BasePresenter
{
protected function createComponentGrid($name)
{
$grid = new Grido\Grid($this, $name);
$grid->setModel($this->context->database->table('colour'));
$grid->setDefaultPerPage(50);
$grid->addAction('edit', 'Edit');
$grid->addAction('delete', 'Delete');
$grid->addColumn('name', 'Name');
}
}
?>
PHP 5.3.9
Nette 2.0.3
Kde môže byť chyba?