DataGrid (Nette 2.0, PHP 5.3, NotOrm)
- ricco24
- Člen | 141
DataGrid pre Nette 2.0 napísaný pre NotOrm (Nette\Database).
Ako datasource akceptuje Nette\Database\Table\Selection.
GitHub https://github.com/…o24/DataGrid
Príklady http://datagrid.riccos.sk/
State Datagridu funguje cez session aby sa príkazový riadok držal v čo najčistejšom stave. Aktuálne je datagrid bez implementovaného AJAX-u.
Vytvorenie DataGridu a predanie DataSource
$source = $this->model('Models\Data\Emp')->findAll();
$dg = new DataGrid();
$dg->setDataSource($source);
Stĺpce
$dg->addColumn('názov stĺpca v datasource', 'názov ktorý sa vykreslí');
//druhy stĺpcov
$dg->addColumn('id', 'ID');
$dg->addBoolColumn('have_car', 'Firemné auto');
$dg->addDateColumn('created', 'Dátum vytvorenia');
$dg->addCustomColumn('image', 'Náhľad');
//filtre
$dg->addColumn('name', 'Meno')->setTextFilter();
$dg->addColumn('name', 'Meno')->setBoolFilter();
$dg->addColumn('name', 'Meno')->setIntFilter();
$dg->addColumn('name', 'Meno')->setDateFilter();
//v prípade select filtra treba vložiť aj pole filtračných hodnôt
$filter = array(
'' => '',
'closed' => 'Uzavreté',
'open' => 'Otvorené',
'canceled' => 'Zrušené'
);
$dg->addColumn('status', 'Stav')->setSelectFilter($filter);
//date filter
//ak pridáte do svojej aplikácie jquery-ui bude sa po kliknutí na date filter automaticky zobrazovať datepicker
//int filter
//ovláda operácie ( =, >, <, <=, >=, <> )
//za operáciou treba urobiť medzeru (napr. <= 2) inak sa bude hľadať reťazec
//ak vkladáme datasource vytvorené z viacerých tabuliek (join) je potrebné pri nastavovaní filtra vložiť presný názov stĺpca podľa ktorého sa bude filtrovať.
$dg->addColumn('name', 'Meno')->setTextFilter(table.column);
//nastavenie css
$dg->addColumn('created', 'Vytvorené')->setStyle('width: 100px; font-weight: bold');
//custom column má ešte jednu metódu a to setHtml() ktorá ako parameter príjma callback na vytvorenie Html:el(). Vďaka tomu sa do DataGridu dajú vkladať odkazy, obrázky ...
$dg->addCustomColumn('dept_name', 'Dept')->setTextFilter('dept.name')->setHtml(function ($row) use ($self) {
$container = Html::el('a')->href($self->link('Homepage:dept', $row->dept_id))->target('_blank')->setText($row->dept_name);
return $container;
});;
Akcie
//globálna akcia
$dg->addGlobalAction('unikátny názov', 'title akcie', 'redirect');
$dg->addGlobalAction('add', 'Pridaj', 'Homepage:add');
//riadková akcia - parametre sa predávajú ako pole
$dg->addAction('unikátny názov', 'title akcie', 'redirect', parametre);
$dg->addAction('edit', 'Uprav', 'Homepage:edit', array('id'));
Počet položiek na stránke
//nastavenie počiatočného počtu (optional, default = 5)
$dg->setItemsPerPage('5');
//nastavenie výberového menu (optional, default = array('all', '5', '10', '15', '20', '50');)
$dg->setItemsPerPageDropdown('all', '5', '10');
Na začiatok je to všetko.
Do budúcna
- pridanie možnosti výberu prenášania stavu cez session alebo query string v URL.
- AJAX
- MultiActions pre viaceré riadky naraz (zatial som to pri žiadom projekte nepotreboval ale do budúcna s tým počítam)
Dúfam že komponenta aspoň niekomu pomôže.
Editoval ricco24 (5. 3. 2012 22:48)
- ricco24
- Člen | 141
Kódy datagridov z príkladov
public function createComponentDataGridEmp() {
$source = $this->model('Models\Data\Emp')->findAll();
$dg = new DataGrid();
$dg->setDataSource($source);
$dg->addColumn('id', 'ID');
$dg->addColumn('name', 'Name');
$dg->addColumn('surname', 'Surname');
$dg->addColumn('address', 'Address');
$dg->addColumn('city', 'City');
$dg->addColumn('income', 'Income');
$dg->addDateColumn('hiredate', 'Hiredate');
return $dg;
}
public function createComponentDataGridEmp2() {
$source = $this->model('Models\Data\Emp')->findAll()->select('emp.*, dept.name AS dept_name');
$dg = new DataGrid();
$dg->setDataSource($source);
$dg->addColumn('id', 'ID');
$dg->addColumn('name', 'Name')->setTextFilter('emp.name');
$dg->addColumn('surname', 'Surname')->setTextFilter('emp.surname');
$dg->addColumn('address', 'Address')->setTextFilter('emp.address');
$dg->addColumn('city', 'City')->setTextFilter('emp.city');
$dg->addColumn('income', 'Income')->setIntFilter('emp.income');
$dg->addColumn('dept_name', 'Dept')->setTextFilter('dept.name');
$dg->addBoolColumn('car', 'Car')->setBoolFilter('emp.car');
$dg->addDateColumn('hiredate', 'Hiredate')->setDateFilter('emp.hiredate');
return $dg;
}
public function createComponentDataGridEmp3() {
$self = $this;
$source = $this->model('Models\Data\Emp')->findAll()->select('emp.*, dept.name AS dept_name');
$dg = new DataGrid();
$dg->setDataSource($source);
$dg->addGlobalAction('add', 'Pridaj', 'Homepage:add');
$dg->addAction('edit', 'Uprav', 'Homepage:edit', array('id'));
$dg->addAction('delete', 'Odober', 'Homepage:delete', array('id', 'name'));
$dg->addColumn('id', 'ID');
$dg->addColumn('name', 'Name')->setTextFilter('emp.name');
$dg->addColumn('surname', 'Surname')->setTextFilter('emp.surname');
$dg->addColumn('address', 'Address')->setTextFilter('emp.address');
$dg->addColumn('city', 'City')->setTextFilter('emp.city');
$dg->addColumn('income', 'Income')->setIntFilter('emp.income');
$dg->addCustomColumn('dept_name', 'Dept')->setTextFilter('dept.name')->setHtml(function ($row) use ($self) {
$container = Html::el('a')->href($self->link('Homepage:dept', $row->dept_id))->target('_blank')->setText($row->dept_name);
return $container;
});;
$dg->addBoolColumn('car', 'Car')->setBoolFilter('emp.car');
$dg->addDateColumn('hiredate', 'Hiredate')->setDateFilter('emp.hiredate');
return $dg;
}
- Tomáš Votruba
- Moderator | 1114
Skvělá práce, tohle tu chybělo. Už se těším, až vyzkouším.
Díky.
EDIT: Minifork pro rozjetí v NotORM (!= NetteDatabase).
Editoval Schmutzka (17. 3. 2012 21:25)
- ricco24
- Člen | 141
Podporu DibiFluent a DibiDataSource má DataGrid od Romana Sklenára. Ten už je v niekolkých úpravách aj na Nette 2.0 / PHP 5.3. Táto komponenta je skôr pre tých ktorý používajú Nette\Database.
No ak by sa ozvalo viacero ľudí ktorí by komponentu chceli používať ale pracujú s Dibi poprípade Doctrine driver určite dopíšem.
- Lopo
- Člen | 277
DataGrid od Romana Sklenare ma DataSource s podporou dibi (fluent aj datasource), NetteDB, NotORM, Doctrine, PHP Array … teda aspon moj fork :)
Vcera som sa na jabberi pytal a kludne tu otazku polozim aj tu: pouziva niekto aj inu DB vrstvu nez tie co som napisal ? Ze by som dopisal prislusny driver …
- David Ďurika
- Člen | 328
Lopo napsal(a):
DataGrid od Romana Sklenare ma DataSource s podporou dibi (fluent aj datasource), NetteDB, NotORM, Doctrine, PHP Array … teda aspon moj fork :)
mas to aj na NotOrm ? tak posli link…
- Leinad
- Člen | 23
Díky, zdá se, že mě tento datagrid prozatím zachránil. Potřeboval jsem nějaký rychle vybrat a tento jako jediný šel opravdu jednoduše zprovoznit. Díky. Jinak, postřehy:
Klady:
- jednoduché zprovoznění, demo jede, příklady jsou srozumitelné, funguje s nejnovějším Nette
- výchozí grafika vypadá opravdu dobře
Připomínky:
- Ten AJAX by se fakt hodil, aby se nerefreshovala pořád celá stránka
- Hodila by se inline editace
- Hodilo by se, aby uživatel mohl měnit šířku sloupce
Chyby:
- Když dostane do Datasource model pracující nad prázdnou tabulkou, vypíše:
Undefined variable: result na řádku 38 souboru libs/datagrid/DataSource.php
- V tvém příkladu příklad 2 nefungují filtry na Enter, fungují až v příkladu 3 (když jsem nedal žádný sloupec addAction(), tak mi filtrování nefungovalo)
Editoval Leinad (14. 3. 2012 11:29)
- Leinad
- Člen | 23
spiider napsal(a):
Díky za tento grid. Jenom mám problém s předáním id když chci editovat řádek. Mám tam
$dg->addAction('edit', 'Upravit', 'edit', array('id'));
ale žádné id se nepředá. Pokud dám místo id např. fname tak se předává.
Díky za radu.
Řešil jsem stejný problém a zjistil jsem, že ten sloupec se nebere podle databáze, ale podle sloupce v gridu. Tj. musíš ho uvést např. $dg->addColumn(‚id‘, ‚ID‘); jinak se nebere
- Jan Suchánek
- Člen | 404
Je to moc pěkné! Pokud výpis obsahuje jen jednu stránku nepotřebuje
zobrazovat stránkování.
Bude i inline editace?
- svobodai
- Člen | 136
Jo tohle vypadá zajímavě.
Zatím používám Datagrid Romana Sklenáře, ale ani ten nemá vše co
bych chtěl.
Další věc je kterou potřebuju je kliknutí kamkoli na řádek a vykonat nějakou definovanou akci. Pokud možno AJAXem. A samozřejmně filtrování aby fungovalo ajaxem na enter.
Nebo jestli mi někdo může doporučit Datagrid, který by byl pro Nette2 a splňoval tyto mé požadavky budu rád.
Editoval svobodai (26. 3. 2012 0:14)
- ricco24
- Člen | 141
Vďaka za poskytnuté podnety. Určite sa v najbližšej dobe pozriem na vyskytnuté problémy.
predávanie parametrov do akcie bez vypísania stĺpca– vyriešené- reakcia na prázdny datasource
- filter bez action stlpca na enter – pod chrome
Leinad napsal(a):
V tvém příkladu příklad 2 nefungují filtry na Enter, fungují až v příkladu 3 (když jsem nedal žádný sloupec addAction(), tak mi filtrování nefungovalo)
Mne v druhom datagride na testovačke filtre fungujú.
Čo sa týka úprav do budúcna určite pribudne podpora ajaxu, nad inline editáciou ešte porozmýšlam.
Editoval ricco24 (29. 3. 2012 22:04)
- spiider
- Člen | 162
Díky za upgrade s těma parametrama do addAction, ještě se chci zeptat
jak udělat když chci předat parametrů více, tím nemyslím předat hodnotu
sloupce ale nějakou vlastní proměnou? Hodnoty sloupcu jdou předávat
normálně v poli, ale jiné proměnné ne. A také zda je nějak možné mezi
sebou propojovat tabulky v gridu? Např. table.column a ono by se to spojilo
přes cizí klíč.
Díky
Editoval spiider (28. 3. 2012 11:55)
- ricco24
- Člen | 141
spiider napsal(a):
Díky za upgrade s těma parametrama do addAction, ještě se chci zeptat jak udělat když chci předat parametrů více, tím nemyslím předat hodnotu sloupce ale nějakou vlastní proměnou? Hodnoty sloupcu jdou předávat normálně v poli, ale jiné proměnné ne. A také zda je nějak možné mezi sebou propojovat tabulky v gridu? Např. table.column a ono by se to spojilo přes cizí klíč.
Díky
Externé parametre ktoré neobahuje DataSource sa aktuálne do Datagrid predávať nedajú. Viem že takúto funkcionalitu je možné využiť no neviem si predstaviť reálny prípad kedy by to bolo naozaj nutné. Vieš mi nejaký uviesť ?
Čo sa týka druhej otázky tak DataGrid pracuje len s TableSelection ktorá sa mu predá. Ak chceš pracovať s viacrími tabuľkami musíš si spraviť join a vytiahnuť si všetky potrebné dáta ešte pred ich predaním do dg.
- ricco24
- Člen | 141
sepo napsal(a):
Ahoj
Funguje vám select fiter ?
..... $filter = array( 'msi' => 'MSI', 'ok' => 'OK', ); $dg->addColumn('name_cloud', 'Cloud KTZ')->setTextFilter('name_cloud'); $dg->addColumn('status', 'Stav')->setSelectFilter($filter); .....
nevykreslí select filter
SelectFilter sa mi korektne vykresluje. Tretí dg na datagrid.riccos.sk som upravil tak že na mesto je použitý select filter. Skús sem poprípade dať celý kód ako dg vytváraš.
Upravený kód
public function createComponentDataGridEmp3() {
$self = $this;
$source = $this->model('Models\Data\Emp')->findAll()->select('emp.*, dept.name AS dept_name');
$filter = array(
'' => '',
'Amsterdam' => 'Amsterdam',
'London' => 'London',
'Italy' => 'Italy'
);
$dg = new DataGrid();
$dg->setDataSource($source);
$dg->addGlobalAction('add', 'Pridaj', 'Homepage:add');
$dg->addAction('edit', 'Uprav', 'Homepage:edit', array('id'));
$dg->addAction('delete', 'Odober', 'Homepage:delete', array('id', 'name'));
//$dg->addColumn('id', 'ID');
$dg->addColumn('name', 'Name')->setTextFilter('emp.name');
$dg->addColumn('surname', 'Surname')->setTextFilter('emp.surname');
$dg->addColumn('address', 'Address')->setTextFilter('emp.address');
$dg->addColumn('city', 'City')->setSelectFilter($filter, 'emp.city');
$dg->addColumn('income', 'Income')->setIntFilter('emp.income');
$dg->addCustomColumn('dept_name', 'Dept')->setTextFilter('dept.name')->setHtml(function ($row) use ($self) {
$container = Html::el('a')->href($self->link('Homepage:dept', $row->dept_id))->target('_blank')->setText($row->dept_name);
return $container;
});;
$dg->addBoolColumn('car', 'Car')->setBoolFilter('emp.car');
$dg->addDateColumn('hiredate', 'Hiredate')->setDateFilter('emp.hiredate')->setStyle('text-align: center; font-style: italic');;
return $dg;
}
- sepo
- Člen | 69
ricco24 napsal(a):
SelectFilter sa mi korektne vykresluje. Tretí dg na datagrid.riccos.sk som upravil tak že na mesto je použitý select filter. Skús sem poprípade dať celý kód ako dg vytváraš.
sorry, select filter sa vykreslil len som mal nesprávne prekrytie
v css-ku
je to OK
vďaka za ochotu
- Leinad
- Člen | 23
ricco24 napsal(a):
Vďaka za poskytnuté podnety. Určite sa v najbližšej dobe pozriem na vyskytnuté problémy.
predávanie parametrov do akcie bez vypísania stĺpca– vyriešené- reakcia na prázdny datasource
Leinad napsal(a):
V tvém příkladu příklad 2 nefungují filtry na Enter, fungují až v příkladu 3 (když jsem nedal žádný sloupec addAction(), tak mi filtrování nefungovalo)Mne v druhom datagride na testovačke filtre fungujú.
Čo sa týka úprav do budúcna určite pribudne podpora ajaxu, nad inline editáciou ešte porozmýšlam.
Zkusil jsem teď i jiné prohlíže a pravda, pod FF a Operou funguje na enter. Pod Chrome to na enter ale nefunguje
- Leinad
- Člen | 23
sepo napsal(a):
>
Zkusil jsem teď i jiné prohlíže a pravda, pod FF a Operou funguje na enter. Pod Chrome to na enter ale nefunguje
Mne na Chrome 15.0.874.121 m Enter funguje :-)
Určitě v tabulce 2 (ne tabulka 3, ta jede)? Chrome 18.0.1025.142, ale nejelo to ani na předchozí 17. Zkoušel jsem radši i Windows, zda to není jen bug pod Linuxovou verzí Chrome, ale dělá to to samé.
- Sopta
- Člen | 12
Super práce.
Jen pár poznámek. Ikdyž se stav ukládá to session tak to má jeden dost velký problém a to takový, že když si něco vyfiltruji a budu to chtít poslat kolegovi, tak mám smůlu. Takže určitě by to chtělo do budoucna přidat stav do URL a to i v případě AJAXU (třeba klasickej hash) :-)
- Sopta
- Člen | 12
to: forkman
máš to hnedka nahoře tohoto vlákna.
<?php
$source = $this->model('Models\Data\Emp')->findAll();
$dg = new DataGrid();
$dg->setDataSource($source);
?>
kde metodě setDataSource předáváš jako parametr Nette\Database\Table\Selection. A jak si data vytáhneš už je na tobě :)
- ricco24
- Člen | 141
Úpravy v datagride:
- ošetrenie prázdneho datasource – už sa nevyhadzuje výnimka ale pekná hláška „Momentálne sa tu nenachádzajú žiadne záznami.“
- oprava fungovania ENTER-u pod Google Chrome a Safari
- pridaná funkcionalita vloženia formulára do každého riadku (potreboval som túto funkcionalitu pri vytváraní jednoduchého shopu takže sa môže hodiť) Ako na to:
// Najprv si vytvoríme callback na formulár
$callback = function($id, $control) use ($self) {
$form = new \Nette\Application\UI\Form($control, $id);
//.. ďalšie prvky formulára
//.. spracovanie formulára
return $form;
}
// Teraz už iba jednoducho zaregistrujeme formulár do datagridu -> implementovaný Multiplier sa už postará o všetko potrebné
$dg->addForms($callback);
// Takto sa nám na každom riadku za stĺpcom s akciami vykreslí formulár s vlastným spracovaním.
// Defaultne sa do $id callbacku formulára prenáša id záznamu, no ak chcete túto hodnotu zmeniť zmeniť nastavíte druhý parameter funkcie
$dg->addForms($callback, 'name');
- pridané poprípade opravené funkcie na nastavenie defaultného stavu Datagridu:
// Nastavenie počtu záznamov na stránku
$dg->setItemsPerPage(int);
// Nastavenie defaultného radenia
$dg->setDefaultOrder(column_name, way = 'asc');
// Nastavenie defaultného filtra na stĺpec
$dg->addColumn('name', 'Meno')->addIntFilter()->setDefaultFilter('Samuel');
Na stránku v krátkej dobe pridám nové príklady na ukážku nových funkcií.
- Filip Procházka
- Moderator | 4668
$dg->addForms($callback);
Nebylo by lepší, kdyby celý datagrid byl jeden formulář a vykládaly se pouze kontejnery? ;)
- mhh
- Člen | 2
Mám takový problém, v databází mám sloupec Datum(date), a
Čas(time).
V prezenteru mám pak:
$dg->addColumn('cas', 'Čas')->setTextFilter();
$dg->addColumn('udalost', 'Událost');
Jenže v gridu se mi zobrazuje datum
2012–05–08 00:00:00 a čas 2012–05–25 15:30:26 takto, nevíte, co může
být špatně? Díky
V db je datum 2012–05–08 a čas 15:30:26
Editoval mhh (25. 5. 2012 13:03)
- Ascaria
- Člen | 187
HosipLan napsal(a):
$dg->addForms($callback);
Nebylo by lepší, kdyby celý datagrid byl jeden formulář a vykládaly se pouze kontejnery? ;)
Podle mě ne. U DataGridu od Romana Sklenáře mi vadí, že když chci změnit stránku a odešlu to enterem, provede se filtrování na prázdno a stránka zůstane stejná.
- Saja
- Člen | 7
Bylo by možné upravit datagrid, aby jej bylo možno navěsit na mnohojazyčný web? Momentálně totiž je ve vývoji a pokud jej používám při každé aktualizaci to pro mě znamená porovnat soubory a přepsat slovenštinu na zástupné řetězce pro překlady. A ještě jeden dotaz.
Za jak dlouho vidíš podporu hromadných operací? Rád bych přesel na originál bez mých vlastních úprav… taktéž z důvodu aktualizace.
- mhh
- Člen | 2
Jak na grid přidám tlačítko Filtrovat, jako je to v třetím přikladu?
http://datagrid.riccos.sk/
Bohužel mi v ie nefunguje filtrování za pomocí enteru. Díky
edit
$dg->addAction('xx', 'xx', 'xx', array('xx'));
tímhle mi to funguje, ale kdybych to chtěl třeba umístit místo textfiltru, to asi nepůjde,co? Že by byl sloupec s daty a nahoře místo textfiltru bylo tlačítko filtrovat, takhle tam mám zbytečně jeden prázdný sloupec
Editoval mhh (30. 5. 2012 14:06)