Grido – DataGrid pro Nette
- o5
- Člen | 416
@pjoter: všichni se na tebe vyprdli co? To sou teda! ;)
Příště být tebou, bych nejprve zkusil tohle. Našel bys třeba tuto. Pak si upravíš click event odkazů akcí v gridu, aby aktuální „href“ atribut předával nějaký tvojí funkci (třeba modal()) a vrátíš false nebo e. preventDefault() atd… Ta tvoje funkce modal() bude obsahovat volání na uvedený plugin a v callbacku (který se volá když klikneš na „Confirm“) bude něco jako window.location = href;
Editoval o5 (21. 5. 2013 23:04)
- xxxmisko
- Člen | 140
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 xxxmisko (28. 5. 2013 10:48)
- Sonny
- Člen | 13
Zdravím,
mám problém s touto komponentou ve spojení s ajaxem (bez něj je vše ok). Všechno funguje normálně až na překreslování samotného gridu po odstranění záznamu. Záznam se odstraní a datagrid se překreslí. Bohužel se starými daty. Pokud odstraním druhou položku, tak se překreslí bez té první odstraněné, ale druhou pořád ukazuje. Prostě je o krok pozadu. Jinak filtrování i řazení funguje dobře.
Kde může být chyba? Nette 2.0.10 Grido ze 3. 6. 2013
Továrnička vypadá takto:
public function createComponentProductsGrid()
{
$grido = new Grido\Grid($this, 'productsGrid');
$grido->setPrimaryKey('productId');
$operations = array('delete' => 'Odstranit');
$grido->setOperations($operations, callback($this, 'productsOperationHandler'))
->setConfirm('delete', 'Opravdu chcete tyto položky odstranit?');
$grido->setModel($this->gridoRepo->getProductsInShop($this->shopName));
$grido->addColumn('title', 'Název:', Column::TYPE_TEXT)
->setSortable();
return $grido;
}
Obsluha:
public function productsOperationHandler($operation, $id)
{
if ($id) {
$row = implode(', ', $id);
$this->flashMessage("Probíhá operace '$operation' pro záznamy s id: $row...", 'info');
} else {
$this->flashMessage('Nebyly vybrány žádné záznamy.', 'error');
}
$handler = 'handleProduct'.ucfirst($operation);
$this->$handler($id);
if(!$this->isAjax())
$this->redirect('this');
else
{
$this->invalidateControl('flashes');
}
}
Editoval Sonny (7. 6. 2013 14:00)
- caslavak
- Člen | 7
Zdravím,
nedaří se mi rozchodit tento grid. Provede se komunikace s databází, ale
komponenta se nezobrazí (ani její náznak v html). Nějaký tip, kde by mohla
být chyba? Díky za rady
V template mám {control grid}
Kód továrničky:
protected function createComponentGrid($name)
{
$grid = new Grido\Grid($this, $name);
$grid->setModel($this->context->uzivateleRepository->findAll()); //findAll() vrací Nette\Database\Table\Selection
$grid->addColumnText('datum', 'Datum');
$grid->addColumnText('id', 'id');
}
- Petr Bugyík
- Člen | 4
pepakriz napsal(a):
caslavak napsal(a):
Zapomněl jsi na
return $grid;
.
Nemelo by byt treba..
- xtomeek
- Člen | 1
Děkuji autorovi za toto skvělé rozšíření, šetří to kopec práce.
Bohužel jsem narazil na problém s filtrováním datumu typu
FORMAT_DATE.
Používám stejnou implementaci jako v příkladu, níže uvádím kód.
V DB mám pod položkou date_entry hodnotu ‚2013–06–14‘ (typ DATE)
Zkouším níže pro kontrolu zachytit, co Grido přesouvá do pole a dostávám
stejnou hodnotu
Array ( [0] ⇒ [date_entry] = %s [1] ⇒ 2013–06–14 )
Ve výsledku se mi ale vyfiltruje prázdná tabulka
Velice by se mi hodilo vyhledávat podle datumu od do, není v plánu toto rozšíření? :-)
předem díky za rady, už mě to stálo skutečně dost nervům, je možné, že je v tom nějaký triviální háček.
public function gridDateEntryFilterCondition($value) {
$date = explode('.', $value);
$pole = array('[date_entry] = %s', "{$date[2]}-{$date[1]}-{$date[0]}");
print_r($pole);
return count($date) == 3 ? $pole : NULL;
}
protected function createComponentGrid($name) {
...
$grid->addColumnDate('date_entry', 'Nahlášeno', Grido\Components\Columns\Date::FORMAT_DATE)
->setSortable()
->setFilterDate()
->setCondition(Filter::CONDITION_CALLBACK, callback($this, 'gridDateEntryFilterCondition'));
...
}
Editoval xtomeek (17. 6. 2013 0:34)
- zimmi
- Člen | 94
Moc díky za Grido, úspěšně nasazeno do projektu.
Nicméně mám otázku ohledně generování checkboxů. V databázi jako uid
používám řetězec vygenerovaný funkcí uniqid() s more_entropy = True,tzn.
že řetězec obsahuje tečku, která je pro pojmenovávání inputů
zakázaná.
Jak to nejlépe vyřešit, aniž bych musel celou db měnit?
- libik
- Člen | 96
Diky za skvelou komponentu, primela me se podivat i na bootstrap fw :)
Mam dotaz ohledne filtru – nenasel jsem nikde moznost, jak jej uplne vypnout
(jen INNER/OUTER), ale i kdyz nemam pro zadny sloupec filtr nastaven, tak pri
OUTER je nad tabulkou pruh s RESETem a pri INNER zase zbytecny prostor mezi
headerem a prvnim radkem tabulky.
- libik
- Člen | 96
Tak kdybych mohl par poznamek, tak bylo by super kdyby se dal definovat
jednoduchuchy grid bez strankovani – potrebuju zobrazit informace najednou a
nechce se mi zadavat neco jako $grid->setDefaultPerPage(9999); Vyresil by se
i problem kam s resetem :)
V jednom projektu pouzivam jqgrid a tam ma tabulka nejen paticku (s infem
o poctu items a strankovanim), ale toto ma i v hlavicce pod headerem – a
ten reset by pak mohl byt zde s class btn-mini
Jeste mam dotaz – a omlouvam se, jestli jsem blbe nehledal – ohledne akci v jednotlivych radcich. Potrebuju zobrazovat nekolik buttonu na zaklade urcitych podminek ci s linkem na konkretni metodu, ted to resim pres setCustomRender ve vlastnim sloupecku akce, protoze addAction toto neumoznuje.
EDIT: addAction()->setCustomRender funguje taky, takze beru zpet. V pripade, ze nechci akci v radku zobrazit je lepsi vratit false nebo empty string?
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
Editoval libik (12. 7. 2013 11:15)
- George
- Člen | 8
Zdravim,
predne diky za skvely datagrid. Funguje skvele, ale ted jsem narazil na
problem, ktery nevim jak resit.
Zobrazuji na strance dva gridy a zobrazi se ok, ale nefunguje checkbox pro
hromadne zaskrtnuti/odskrtnuti zaznamu. Resp. funguje, ale pokud jej zaskrtnu
v jakemkoliv z obou gridu, tak se zaskrtnou radky v obou a select pro vyber
hromadne operace se zaktivni pouze ve druhem gridu.
Definice gridu i setOperations je prakticky stejna jako v sandboxu s tim, ze
tovarna pro definici gridu je v prezenteru dvakrat, pokazde s jinym nazvem ale
jinak pro oba gridy zobrazuje stejne sloupce ze stejne tabulky (data se lisi
pouze na zaklade WHERE podminky).
V obou gridech je operations definovano stejne
$grid->addActionHref('ack', 'Acknowledge')
->setIcon('ok')
->setConfirm(function($item) use ($translator) {
return $translator->translate('Are you sure you want to acknowledge warning ?');
});
$operations = array('ack' => 'Acknowledge');
$grid->setOperations($operations, callback($this, 'gridOperationsHandler'))
->setConfirm('ack', $this->translator->translate('Are you sure you want to acknowledge %i warnings ?'))
->setPrimaryKey('id');
A gridOperationsHandler je pro oba spolecna
public function gridOperationsHandler($operation, $id)
{
if ($id) {
$ids = implode(',', $id);
} else {
$this->flashMessage($this->translator->translate('No rows selected.'), 'error');
}
$this->redirect($operation, array('id' => $ids));
}
Je potreba v definici operations nejak jednotlive gridy odlisit ?
V sablone volam gridy nejak takhle
{block content}
{control grid1}
{control grid2}
{/block}
- o5
- Člen | 416
libik napsal(a):
Jeste mam dotaz – a omlouvam se, jestli jsem blbe nehledal – ohledne akci v jednotlivych radcich. Potrebuju zobrazovat nekolik buttonu na zaklade urcitych podminek ci s linkem na konkretni metodu, ted to resim pres setCustomRender ve vlastnim sloupecku akce, protoze addAction toto neumoznuje.
koukal si na setDisable()?
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
to opravím..
2k napsal(a):
Nechybí v podmínce regulárního výrazu mínus v Grido\Components\Filters\Number? Každopádně pěkná komponenta.
diky, fixed
Editoval o5 (25. 7. 2013 21:57)
- mere.gee
- Člen | 54
Zdravím,
v presenteru volám
public function createComponentDashboard(){
$dashboard = $this->createGrid('dashboard', $this->dashboardTable);
return $dashboard;
}
kde createGrid je metoda z BasePresenteru
public function createGrid($name, $table){
$grid = new Grido\Grid($this, $name);
$grid->setModel($table);
return $grid;
}
a dashboardTable je proměnná typu Nette\Database\Table\Selection. Pokud se pokusím v template komponentu dashboard vykreslit, dostanu chybu Component with name ‚columns‘ does not exist. Z té zprávy nemám tušení, o co se může jednat. Zkoušel jsem použít dibi, předávat array, vytvářet tu instanci přímo v createComponentDashboard, pořád stejná chyba. Nejedná se o bug? Díky moc.
- mere.gee
- Člen | 54
o5 napsal(a):
George napsal(a):
Nikdo nevi v cem tkvi muj problem ? Ani autor ? ;)
LOL, co to ma byt za popichovani? :) Ten tvuj problem vyresi refactoring klientske casti grida, dostanu se k tomu snad pristi tyden.
@mere.gee: nahod nekam klikatelnou ladenku..
Už jsem to vyřešil… Smažu to, a až si to přečteš, tohle můžeš smazat taky. Díky za skvělej doplněk, btw :)
- mshot
- Člen | 7
Mám drobný problém → obsluha operace -localhost OK na serveru $this ve statickem kontextu
<?php
$grid->setOperations(array('show' => 'Show')
, function($operation, $id) {
$this->actionShow(implode("_", $id));
});
public function actionShow($id) {
$this->getPresenter()->redirect('this', array("id_profils" => $id));
}
?>
Jak toto řešit?
GRIDO je v komponente a proto chci vzdy akci show u aktualniho presenteru.
Editoval mshot (18. 7. 2013 18:09)
- pepakriz
- Člen | 246
mshot napsal(a):
Myslíš takto?
<?php
$_this = $this;
$grid->setOperations(array('show' => 'Show')
, function($operation, $id) use ($_this) {
$_this->actionShow(implode("_", $id));
});
public function actionShow($id) {
$this->getPresenter()->redirect('this', array("id_profils" => $id));
}
?>
- raketoplan2005
- Člen | 147
Používáte někdo prosím Grido s nejnovějším netteForms.js? Stáhl jsem si sandbox a tam je použita poměrně stará verze, když ale použiji nejnovější JS z nette, přestanou mi v gridu chodit filtry a autocomplete. Díky moc
- o5
- Člen | 416
@raketoplan2005: netteForms.js tam je asi 4 mesice stary a IMHO se nic zasadniho nefixovalo. Kazdopadne autocomplete s tim nesouvisi. Mozna myslis nette.ajax.js, s nim to opravdu ted nefunguje. Jak jsem psal vyse, pristi tyden by mohla byt klientska cast refaktorovana a mozna to tedy prizpusobim „novemu“ nette.ajax.js (zatim jsem s tim nedelal).
- raketoplan2005
- Člen | 147
@o5: Omlouvám se, autocomplete funguje, resp. napoví, když ale vyberu položku, zavolá se filtr a nic se nestane, takže problém opravdu není v autocomplete. Filtrování ale fungovat přestane.
Jinak jsem opravdu myslel netteForms.js, verze ze sandboxu mi padá do HTML5 validace (chybí např. PATTERN). Ona je asi nová verze netteForms.js trochu jinak strukturovaná a nepovedlo se mi to na grido správně naroubovat.
Nicméně bych nerad aby to vyznělo jako výtka gridu, spíš je to jen věc se kterou se trápím :-)
Edit: Ad. refactoring – díky, to jsem úplně přehlédl.
Díky
Editoval raketoplan2005 (19. 7. 2013 1:54)
- zimmi
- Člen | 94
Zdravím,
je možné nějak vykreslit deaktivovaná tlačítka akcí? Na základě true a
false bych chtěl tlačítko mít buď aktivní, či deaktivované. Pomocí
metody setDisable() ho můžu úplně schovat, ale zajímalo by mě i to druhé
řešení.
Momentálně to mám implementované takto.
$grid->addActionHref('deactivate', 'Deaktivovat')
->setIcon('off')
->setConfirm(function($item) {
if ($item->active) {
return "Opravdu chcete deaktivovat účet {$item->username}?";
}
return "Účet {$item->username} dosud nebyl aktivován.";
})
->setDisable(function($item) {
return $item->active;
});
PS: Respektive ještě jinak. Je možné podle logické hodnoty vykreslit buď tlačítko aktivovat, nebo deaktivovat?
PPS: Tak nakonec jsem to vyřešil následovně:
$grid->addActionHref('deactivate', 'Deaktivovat')
->setIcon('off')
->setConfirm(function($item) {
if ($item->active) {
return "Opravdu chcete deaktivovat účet {$item->username}?";
}
return "Účet {$item->username} dosud nebyl aktivován.";
})
->setCustomRender(function($item, $el) {
if ($item->active) {
$el->href('deactivate', array('guid' => $item->guid));
} else {
$el->setHtml('<i class="icon-refresh"></i> Aktivovat</a>');
}
return $el;
});
Editoval zimmi (19. 7. 2013 15:38)
- looky
- Člen | 99
Mám problém s Grido s NDB modelem. Když v Selection joinuju tabulky, můžu výsledek nechat zobrazit, ale už nemůžu snadno sortovat (např. sort přes spojovací sloupec hlásí „Ambiguous column“) a filtrovat (např. filter podle sloupce z přijoinované tabulky hlásí „Undefined column“). Důvod je zřejmý, Grido neví, ze které tabulky daný sloupec pochází a tvoří nevalidní dotazy.
Nějaké rady co s tím? Možná jsem jen něco přehlédl?
- looky
- Člen | 99
s4muel napsal(a):
@looky: view bude asi naozaj lepsie riesenie, ale mne pomohlo toto:
Opravdu ti to pomohlo? Protože to jsem zkoušel jako první možnost, a dostávám z toho error Column does not exist in datasource.
Jinak k tomu view, ano tak by se to samozřejmě vyřešit dalo. Na straně databáze. Zajímá mě, jestli se to dá vyřešit i na staně Grida.
EDIT: Vyřešil jsem to vlastním PropertyAccessor.
EDIT2: Uvažuje se o nativní podpoře computed columns? Můžu ho sice udělat i teď, ale musím použít custom render (což bych asi musel vždycky) a hlavně ohnout datasource, jinak mi podle něj zase nepůjde řadit/filtrovat. Bylo by fajn mít tuhle možnost nějak už v základu. Nebo je to už moc velké zvěrstvo? :)
Editoval looky (22. 7. 2013 19:29)
- zimmi
- Člen | 94
Zdravím,
mohl bych požádat o pomoc s nastavením rout? Momentálně můj routelist
vypadá následovně.
$router[] = new Route('index.php', 'Admin:Login:default', Route::ONE_WAY);
$router[] = new Route('/admin/<presenter>/<action>[/<id>]', 'Admin:Login:default');
Když se s tímto nastavením pokusím spustit hromadnou akci Grida (na
jedné či několika označených položkách), pošle mě to na adresu http://example.com/…in.user/list?…[username]=&filters[email]=&operations[operations]=deactivate&buttons[operations]=OK&count=15&operations[51ee3793eb1a4188691784]=on&do=grid-form-submit
s chybou
rawurldecode() expects parameter 1 to be string, array given
. Pokud
zkusím použít routu z examplu, začnou sice hromadné akce fungovat, ale
přestanou fungovat akce pro jednotlivé řádky. Zkoušel jsem tedy něco
takového:
$router[] = new Route('index.php', 'Admin:Login:default', Route::ONE_WAY);
$router[] = new Route("/admin/<presenter>/<action>/<ajax>/", array(
'presenter' => 'Admin:Login:default',
'action' => 'default',
'ajax' => 'on',
));
$router[] = new Route('/admin/<presenter>/<action>[/<id>]', 'Admin:Login:default');
Ty dvě routy se mi však vždycky pobijí, takže buď funguje jedno, nebo funguje druhé.
- zimmi
- Člen | 94
Zkusil jsem, ale pořád fungují akorát hromadné akce. Ty řádkové mě směřují na http://www.example.com/…t/deactivate?…, přičemž bych potřeboval na http://www.example.com/…r/deactivate?….
- pepakriz
- Člen | 246
looky napsal(a):
EDIT: Vyřešil jsem to vlastním PropertyAccessor.
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!
- looky
- Člen | 99
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 )