DataGrid

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

Tak jsem na srazu prislibil tak zverejnuji svuj DataGrid. No i kdyz je to kapku priohnuty puvodni Daviduv.

Jediny problem je ze to nefunguje AJAXove. Nemel jsem zatim cas to podrobne prozkoumat. Obecne s AJAXem v Nette si hraji par dni.

Dalsi vec co nejde je vykresleni paginatoru vicekrat (pod a nad tabulkou). Jako ono to jde, ale pri AJAXu to zlobi (2× stejne ID ve strance, coz neni Validni). Teoreticky neni problem ID nejak cislovat, ale ohledne AJAXu uz tapu.

Nevim zda mam psat ci nejak vice popisovat pouziti. Z prikladu je to snad jasne ne? Kdyztak se ptejte.

Rad bych nejakou odezvu. Napr kdo to kolikrat pouzil atd. co se mu libi a co by zmenil.

Jod
Člen | 701
+
0
-

Pekne pekne, v podstate to máme všetci podobné :) . Môj je ešte trochu nepodarený, už viem jak s ním naložím, len neni kedy .)

o5, keď si pozrieš zdroják tak v handleOrder si môžeš zmeniť na viacstĺpcové radenie, aj keď by sa asi zišlo spraviť to na prepínač.

PetrP
Člen | 587
+
0
-

phx napsal(a):

… 2× stejne ID ve strance …

Jen připomínám davidovi že to v sobotu chtěl řešit.

phx
Člen | 651
+
0
-

Razeni dle vice sloupku jsem umyslne deaktivoval. Je to, v PHP polsany kde jsem co menil + CSS ohledne sipecky. Osobne mi to prijde neuzivatelsky. Chci napr radit dle neceho jineho a musim 2× kliknout na to co se zrovna radi (obracene → deaktivovat) a pak az na to co chci.

Jineho je to, ze to nevypisuje DS, ale jen definovane sloupecky s popisky. Tz ze nazvy nejsou z DB, ale definovany tebou. (v praxi se to snad jinak nepouziva). Dale podpora sloupecku BEZ razeni, a skryte sloupecky (napr PK radku) a prazdne sloupecky (navaznost na callback dale). Dale muzes zaregistrovat callback pro konkretni sloupecky, kde data urcena do sloupecku upravis dle svych predstav. (napr: checkbox, img tuzky, true/false ⇒ ANO/NE)

A nazaver onen JS co podbarvuje radky pri prejezdu mysi, a pri zaskrtnuti checkboxu. Je to univerzalni a nezavisle na DG. Jen tomu reknes ID tabulky a na kolikaty checkbox na radku reagovat (pokud by jich tam bylo vice).

raketoplan2005
Člen | 147
+
0
-

Ahoj, vypadá to krásně, ale bohužel nejsem schopen to naimplementovat. I když udělám úplně čisté nette, kde dám jen tuten vzorový příklad, skončím na:

Notice: Undefined property: stdClass::$escape in /localhost/document_root/test/app/temp/cache-Nette.Template%0041002234ac0a45e6fb300f9cfb02244d1.grid.phtml.php on line 43

Fatal error: Method name must be a string in /localhost/document_root/test/app/temp/cache-Nette.Template%0041002234ac0a45e6fb300f9cfb02244d1.grid.phtml.php on line 43

pod čímž se mi zobrazí prázdná tabulka.

Můžete mi prosím poradit „how to“? Díky

phx
Člen | 651
+
0
-

Ukaz zdrojaky, z teto hlasky chybu neodhalim.

raketoplan2005
Člen | 147
+
0
-

Zdrojáky jsou originální, kompletně beze změny, pouze doplněny o nette a dibi + změněna cesta v bootstrapu.

PHP: 5.2.6
Nette+dibi: Poslední stable

Editoval raketoplan2005 (24. 4. 2009 13:36)

Honza Kuchař
Člen | 1662
+
0
-

PetrP napsal(a):

phx napsal(a):

… 2× stejne ID ve strance …

Jen připomínám davidovi že to v sobotu chtěl řešit.

Nevím jestli jste to už vyřešili, ale já to vyřešil nádledovně (funguje i s AJAXem) (můžu si tam těch paginatorů vyrenderovat kolik chci :) )
Používám dataGrid co tu byl na ukázku s jQuery.
jde o to, že paginatory pojmenuju jako paginator1 až paginatorN

Tzn.:

class DataGrid extends Control
{
  ...
  /** @var int */
  protected $paginatorCount = 1;
  ...
  public function renderPaginator()
  {
  ...
  $template->snippetName = "paginator".$this->paginatorCount;
  ...
  }
  ...
}

v šabloně:

{snippet $snippetName}
...
{/snippet}

Pokud jsem na něco zapomněl, postnu někam celej zdroják. ;)

phx
Člen | 651
+
0
-

raketoplan2005 napsal(a):

Zdrojáky jsou originální, kompletně beze změny, pouze doplněny o nette a dibi + změněna cesta v bootstrapu.

Ted jsem to testoval s nette a dibi z SVN a vse je OK. Tak nevim. Posli zdrojaky…

honzakuchar napsal(a):

Nevím jestli jste to už vyřešili, ale já to vyřešil nádledovně (funguje i s AJAXem) (můžu si tam těch paginatorů vyrenderovat kolik chci :) ) Používám dataGrid co tu byl na ukázku s jQuery. jde o to, že paginatory pojmenuju jako paginator1 až paginatorN

Vim o tom. Toto reseni jsem navrhoval na minule PS. Je to nouzovka a sam veliky David se vyjadril, ze by to chtelo resit nejak komplexneji. Ale do te doby asi jina moznost neni.

mkoubik
Člen | 728
+
0
-

Jelikož vždycky zobrazuji paginator jenom nad, nebo pod tabulkou, tak jsem to „vyřešil“ následovně:

  • Tabulka i paginator(y) jsou v jednom snippetu
  • Renderuje se pomocí:
<?php
$grid->render(DataGrid::TOP | DataGrid::BOTTOM);
//nebo:
$grid->render(DataGrid::BOTH);
//apod
?>
  • Zároveň pokud se nezobrazí ani jeden paginator, tak se automaticky vypne stránkování.
phx
Člen | 651
+
0
-

Hod sem zdrojaky:) Muzeme to pouzit jako dalsi verzi:)

romansklenar
Člen | 655
+
0
-

Malá ochutnávka mého DataGridu před vydáním jak jsem na PS slíbil, stay tuned!

Jod
Člen | 701
+
0
-

Kua, kua, je to drsné !!! Presne to som potreboval a chcel spraviť, som rád, že už nemusím :D

jasir
Člen | 746
+
0
-

romansklenar napsal(a):

Malá ochutnávka mého DataGridu před vydáním jak jsem na PS slíbil, stay tuned!

Parádní… Zastavuji práce na svém DataGridu :) Díky!

Jod
Člen | 701
+
0
-

Tak tak, mažem :D

Patrik Votoček
Člen | 2221
+
0
-

A jak to vydíš s vydáním? Daří se profilování?

syky01
Člen | 25
+
0
-

romansklenar: WOW

vlki
Člen | 218
+
0
-

Myslím, že by to mohlo mít trochu tvrdší validaci parametrů, aby se pak toho pak nevyužívalo k nějakému byznysu:)

http://demo.datagrid.romansklenar.cz/?…

by se třeba mělo přesměrovat na

http://demo.datagrid.romansklenar.cz/?…

Editoval vlki (17. 5. 2009 11:15)

Tomik
Nette Evangelist | 485
+
0
-

Jak jsem již psal na Twitteru, naprosto skvělá práce!

Jen takový malý dotaz: jde nějak nastavit, zda bude možné řadit pouze podle jednoho sloupce (tak jak to má ve svém DG phx) nebo podle více sloupců, tak jak to je v těch příkladech.

Jinak co se týče toho „prázdného řádku“ s inputy pro vkládání nových položek, myslím, že by to udělat šlo, jen by uživatel nastavil, jakou metodou, v jaké třídě se mají data z formuláře zpracovat… něco jako $datagrid->handleNewRow = 'PagesModel::newPage';. A takhle fce by byla jen předaná formuláři, který bys (pokud by to bylo nastavené) generoval do toho prázdného řádku. Jasně, není to nic složitého, a dá se to jednoduše dodělat, ale bylo by fajn, kdyby to ten DG uměl sám. ;)

romansklenar
Člen | 655
+
0
-

vrtak-cz napsal(a):

A jak to vydíš s vydáním? Daří se profilování?

No já nevím, co myslíte, schválně jsem tam nechal profiler ať jde vidět čas, pohybuje se to okolo 150~300ms. Ale localhostu pouze s čistým apachem mi to běhá i 10× déle.

vlki napsal(a):

Myslím, že by to mohlo mít trochu tvrdší validaci parametrů, aby se pak toho pak nevyužívalo k nějakému byznysu:)

Zas nějak moc to hrotit nebudu, všechny chybové stavy jsou snad ošetřeny a na vstupní hodnoty slouží inputy :)

Tomik napsal(a):

Je tam něco jako $grid->multiOrder čím se to dá vypnout (default je zapnuto).

S těmi inputy na nový řádek je to takové ošemetné: vazba na model se dá řešit tak jak píšeš, ale musí na to uživatel myslet + v té přehledové tabulce nemusí být zobrazeny všechny sloupce taky (zase je třeba na to myslet v modelu).
Ale klidně takový odvozený grid napíšu (počítám, že se jich objeví i více časem), problém to snad nebude, grid má vlastní vykreslovač, který se jen na jednom místě upraví a mimo jiné podporuje i manuální vykreslení jako formuláře:

{? $grid->render('begin')}
{? $grid->render('errors')}
{? $grid->render('body')}
{? $grid->render('end')}

// plus např.
{? $grid->render('paginator')}
{? $grid->render('info')}

Dopíšu k tomu nějaké how-to a celou tu demo aplikaci i grid zvlášť pak hodím tady do repozitáře komponent. Nejspíš v úterý k večeru by to tam mohlo být.

EDIT: a co se týče definice, bylo to psáno s důrazem na to aby člověk nemusel kvůli dosažení nějaké malé úpravy např. ve formátování hnedka dědit a přepisovat, takže se s tím dá docelá vyhrát.

Od jednoduchých gridů: (1. example)

$model = new DatagridModel('customers');
$grid = new DataGrid;
$grid->bindDataTable($model->getCustomerAndOrderInfo());

// if no columns are defined, take all cols from given data source
$this->addComponent($grid, 'baseGrid');

Až po takovéto plně customiznuté: (3. example)

$model = new DatagridModel('customers');
$grid = new DataGrid;
$translator = new Translator(Environment::expand('%templatesDir%/customersGrid.cs.mo'));
$grid->setTranslator($translator);

$renderer = new DataGridRenderer;
$renderer->paginatorFormat = '%input%'; // customize format of paginator
$grid->setRenderer($renderer);

$grid->itemsPerPage = 10; // display 10 rows per page
$grid->bindDataTable($model->getCustomerAndOrderInfo());
$grid->multiOrder = FALSE; // order by one column only

$operations = array('delete' => 'delete', 'deal' => 'deal', 'print' => 'print', 'forward' => 'forward'); // define operations
$callback = array($this, 'gridOperationHandler');
$grid->allowOperations($operations, $callback, 'customerNumber'); // allows checkboxes to do operations with more rows


/**** add some columns ****/

$grid->addColumn('customerName', 'Name')->addFilter();
$grid->addColumn('contactLastName', 'Surname')->addFilter();
$grid->addColumn('addressLine1', 'Address')->getHeaderPrototype()->style('width: 180px');
$grid->addColumn('city', 'City')->addSelectboxFilter();
$grid->addColumn('country', 'Country')->addSelectboxFilter();
$grid->addColumn('postalCode', 'Postal code')->addFilter();
$caption = Html::el('span')->setText('O')->title('Has orders?')->class('link');
$grid->addCheckboxColumn('orders', $caption)->getHeaderPrototype()->style('text-align: center');
$grid->addDateColumn('orderDate', 'Date', '%m/%d/%Y')->addDateFilter();
$grid->addColumn('status', 'Status')->addSelectboxFilter();
$grid->addNumericColumn('creditLimit', 'Size', 0)->addFilter();

$grid['addressLine1']->addFilter();
$grid['orders']->addSelectboxFilter(array('?' => '?', '0' => "Don't have", '1' => "Have"), TRUE);


/**** column content affecting ****/

// by css styling
$grid['orderDate']->getCellPrototype()->style('text-align: center');

// by replacement of given pattern
$el = Html::el('span')->style('margin: 0 auto');
$grid['status']->replacement['Shipped'] = clone $el->class("icon icon-shipped")->title("Shipped");
$grid['status']->replacement['Resolved'] = clone $el->class("icon icon-resolved")->title("Resolved");
$grid['status']->replacement['Cancelled'] = clone $el->class("icon icon-cancelled")->title("Cancelled");
$grid['status']->replacement[''] = clone $el->class("icon icon-no-orders")->title("Without orders");

// by callback(s)
$grid['creditLimit']->formatCallback[] = 'TemplateHelpers::bytes';


/**** add some actions ****/

$grid->addActionColumn('Actions')->getHeaderPrototype()->style('text-align: center; width: 98px');
$icon = Html::el('span');
$grid->addAction('Copy', 'Customer:copy', clone $icon->class('icon icon-copy'));
$grid->addAction('Detail', 'Customer:detail', clone $icon->class('icon icon-detail'));
$grid->addAction('Edit', 'Customer:edit', clone $icon->class('icon icon-edit'));
$grid->addAction('Delete', 'Customer:delete', clone $icon->class('icon icon-del'));

$this->addComponent($grid, 'customersGrid');
Honza Marek
Člen | 1664
+
0
-

Pokusím se ti aspoň zaktualizovat ten ajaxový plugin pro jQuery než to vydáš :)

LuKo
Člen | 116
+
0
-

Výborná práce! K dokonalosti už chybí jen skrývatelné sloupce – mám tabulku s 50 sloupci a chci zobrazit jen některé. To, které se zobrazí, mám možnost ovlivnit flexibilně přímo na stránce, nikoli natvrdo v kódu. Ve filtrovacím řádku by možná přišla vhod možnost zvolit rozsah hodnot, ale to už je příliš komplikované. Hezky to má vyřešené Jakub Vrána v PhpMinAdminu.

Ola
Člen | 385
+
0
-

Jde u toho datagridu čerpat data z více tabulek (JOIN)? Aby šlo např. u gridu se všema článkama zobrazit kategorii příp. autora apod. a nemuselo bejt všechno nacpaný do jedný tabulky

Tomik
Nette Evangelist | 485
+
0
-

Ola napsal(a):

Jde u toho datagridu čerpat data z více tabulek (JOIN)? Aby šlo např. u gridu se všema článkama zobrazit kategorii příp. autora apod. a nemuselo bejt všechno nacpaný do jedný tabulky

Zcela určitě, prostě pro DataSource použij select s joinem. :)

Ola
Člen | 385
+
0
-

Jé, já sem vůl :) Ten kód od Romana jsem jen letmo projížděl a zmátl mne řádek s bindDataTable :)

romansklenar
Člen | 655
+
0
-

LuKo napsal(a):

Výborná práce! K dokonalosti už chybí jen skrývatelné sloupce – mám tabulku s 50 sloupci a chci zobrazit jen některé. To, které se zobrazí, mám možnost ovlivnit flexibilně přímo na stránce, nikoli natvrdo v kódu. Ve filtrovacím řádku by možná přišla vhod možnost zvolit rozsah hodnot, ale to už je příliš komplikované. Hezky to má vyřešené Jakub Vrána v PhpMinAdminu.

U NumericColumn-ů funguje filtrování pomocí >, >=, =, <> apod (link).

Můžeš mi ty skrývatelné sloupce ještě trochu víc rozepsat? Klidně i do mailu. Dokážu si představit všechno, až na to jakým způsobem sloupec znovu zviditelním.

EDIT: inspirován datagridem, který používá google na svém googlecode už mám bližší představu :)

Honza M. napsal(a):

Pokusím se ti aspoň zaktualizovat ten ajaxový plugin pro jQuery než to vydáš :)

Právě jsem si říkal, že už bych mohl upgradenout :) ten nový způsob jsem totiž ještě nezkoušel.

Editoval romansklenar (30. 5. 2009 22:20)

phx
Člen | 651
+
0
-

KRASA KRASA:) Stydim se za svuj jednoduchy DG:) I kdyz asi bude kapku rychlejsi:)

Jen bych jeste dodelal pro filtrovani podporu * jako zastupny znak!

Kdy to bude verejne?

Editoval phx (17. 5. 2009 17:30)

pmg
Člen | 372
+
0
-

Dobrá práce. Fakt.

romansklenar
Člen | 655
+
0
-

phx napsal(a):

…I kdyz asi bude kapku rychlejsi:)

O něco je. Udělal jsem demo aplikaci se stejnou strukturou jako je na tvém demu a zprůměroval doby běhu celé app co údává profiler a průměrný výsledek je ~540ms vs. ~620ms. Samozřejmě čím složitější (množství filtrů, akcí/generování linků, apod.), tím delší bude vykreslování. Původní implementace ale byly dost pomalé, teď už snad moc slabých míst není.

Jen bych jeste dodelal pro filtrovani podporu * jako zastupny znak!

Nojo podpora pro regex se mi někde vytratila :)

Kdy to bude verejne?

V průběhu dneška snad už :)

Tomik
Nette Evangelist | 485
+
0
-

romansklenar napsal(a):

V průběhu dneška snad už :)

Držíme palce! :)

romansklenar
Člen | 655
+
0
-

Tak zdrojáky celé demo aplikace z http://demo.datagrid.romansklenar.cz můžete stahovat buďto z SVN repozitáře nebo přímo z archívu.

Se spuštěním by snad neměly být žádné problémy, je to all-in-one pack obsahujíci i současné poslední revize Nette a dibi. Všem dobře známá vzorová databáze birt z tutoriálu je přítomna i jako MySQL dump + databázích SQLite 2 a 3, takže je možnost výběru (viz adresář models).

Nějaký ten pokec sepíšu do dokumentace zítra (EDIT: no vlastně už dneska :)). Tak testujte, reportujte :) Enjoy!

Jod
Člen | 701
+
0
-

muheh, už to testujem na jednej aplikácii xD dík, fičí v pohode ,)

Tomik
Nette Evangelist | 485
+
0
-

Tak to nemá chybu! :)

A jestli nějakou najdu, budu reportovat. ;)

jasir
Člen | 746
+
0
-

Je to skvělý, krásný kód… Mám radost i z toho Translatoru :)

romansklenar
Člen | 655
+
0
-

Tak je to zdokumentováno, snad se tím vysvětlí případné nejasnosti pokud nějaké byly :)

PS: Mám ten Translator hodit do Extras zvlášť?

jasir
Člen | 746
+
0
-

romansklenar napsal(a):

Tak je to zdokumentováno, snad se tím vysvětlí případné nejasnosti pokud nějaké byly :)

PS: Mám ten Translator hodit do Extras zvlášť?

Hmmm, ještě jednou veliké díky, fakt perfektní práce!!! I ta dokumentace je špica!!!
Co se týče to ho Translátoru, jsem pro to ho tam dát zvlášť.

Editoval jasir (22. 5. 2009 20:44)

PaBi3
Bronze Partner | 62
+
0
-

romansklenar: Plánuješ napísať aj verziu pre PHP 5.3?

romansklenar
Člen | 655
+
0
-

Časem :) nejprve je třeba z bety udělat alespoň RC a dostatečně to prověřit, taky mě zajímá, jak se vám to zdá s rychlostí? Ikdyž je DataGrid primárně určen do administrací, kde nebude taková zátěž, mám pocit že tady bude ještě prostor ke zlepšování.

Pokud by to nevadilo, tak jelikož vznikla už i samotná stránka diskuze provázána přímo s dokumentací, tak bych přesunul diskusi přímo tam a téma uzavřel. Přece jen se to líp bude dohledávat novým lidem.