Gridito (falešný datagrid) – komponenta

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

Falešný datagrid je budoucí konkurenční produkt k datagridu od Romana Sklenáře. A už se můžu pochlubit demem na http://griddemo.janmarek.net/document_root/.

despiq
Člen | 320
+
0
-

DibiDataSource nebo fluent ?

Honza Marek
Člen | 1664
+
0
-

Mělo by to být hodně univerzální, ale zatím OrmionCollection, když se ptáš ;)

despiq
Člen | 320
+
0
-

wunderbar, bring it on!

Jakub Šulák
Člen | 222
+
0
-

velice šikovné. dost se mi líbí, že je to postavené na jquery css

Lopata
Člen | 139
+
0
-

Honza Marek napsal(a):

Falešný datagrid je budoucí konkurenční produkt k datagridu od Romana Sklenáře. A už se můžu pochlubit demem na http://griddemo.janmarek.net/document_root/.

Proč to vyvíjíš „znova“? Ono je to postavené na PHP 5.3…?

despiq
Člen | 320
+
0
-

co ma php 5.3 tak noveho ze by to bylo tak dulezite?

Honza Marek
Člen | 1664
+
0
-

Lopata, despiq:

Můžete kouknout zhruba, jak se ten grid definuje: https://gist.github.com/346294

Oproti „velkému datagridu“ pro vlastní vykreslování buněk nebo vytvoření funkčních tlačítek potřebuju mnohem méně kódu. Nemusim definovat signály nebo zakládat šablony pohledům s formulářema na upravení či založení nového záznamu.

Dalším plusem mého řešení je témovatelnost pomocí jQuery UI a nezávislost na DibiDataSource.

Abych to shrnul, cílem není okopírovat kompletní funkčnost Romanova datagridu, ale abych já měl jednodušší práci, když budu vyrábět nějaké administrační rozhranní.

Honza Kuchař
Člen | 1662
+
0
-

Jé, to vypadá fajn. :)

jasir
Člen | 746
+
0
-

Tak to vypadá opravdu moc pěkně. Vyzkouším použít místo svého DataGridu. Jinak Ormion je boží. :) Díky.

v6ak
Člen | 206
+
0
-

A jede to i na PHP 5.2, když se tomu trošku pomůže :)

v6ak
Člen | 206
+
0
-

Mohl bych se zeptat, jak to vypadá s vývojem Gridita? Jsi již spokojen se současným stavem? Pokud ne, co orientačně plánuješ?

Honza Marek
Člen | 1664
+
0
-

Spokojen nejsem, ale teď jsem měsíc nebyl schopen naprogramovat ani čárku. Z velkejch věcí určitě budu potřebovat filtry a pak pár nějakejch detailů. Jinak nejsem moc spokojen s tím „CRUDem“. Když odešlu chybně vyplněný formulář a neodchytí to JS, tak přijdu o data. Ale tohle je bohužel koncepční, nikoliv implementační záležitost, takže řešení se musí vymyslet, nikoliv naklepat.

v6ak
Člen | 206
+
0
-

Tak to abych generování 5.2 verze plně zautomatizoval nebo se spokojil se starší verzí. Naštěstí ta automatizace nebude takový problém, k nejhorším asi bude kolize třídy Button s formuláři.

v6ak
Člen | 206
+
0
-

Měl bych ještě jeden dotaz: přidal jsem jeden formulář ke Griditu (předtím jsem používal Gridito jen read only) a celkem jsem se divil adrese: nazevKomponenty-toolbar-1-token=865f…(zbytek toho hausnumera). Co je to za token? Co umožňuje? Je citlivý?

Honza Marek
Člen | 1664
+
0
-

Při kliknutí na tlačítko se praktikuje automatická ochrana proti CSRF.

v6ak
Člen | 206
+
0
-

Aha, takže ve chvíli, kdy se ten token dostane do URL, přestává být citlivý, že? Pokud to dobře chápu, tak tím pádem se nemusím bát potenciálních odkazů ven z cílové stránky.

Ještě bych měl menší kritiku: mezi jednotlivá tlačítka by se hodilo nějaké whitespace, bez stylů to pak může bypadat jako jedno slovo, což není dobře.

v6ak
Člen | 206
+
0
-

Pokud bych k tomu měl nějaké třídy (zatím DibiModel, ale měly by přibýt další, chtěl bych něco jako EditableGrid, IEditableModel a další), mám je ti spíše poslat, nebo spíše je mám dát k dispozici zvlášť?

Honza Marek
Člen | 1664
+
0
-

Buď mi to pošli nebo na githubu vyrob fork.

v6ak
Člen | 206
+
0
-

Fork you! ;-)

Kromě DibiModelu bych to označil zatím spíše za experimentální. DibiModel ve starší verzi (pro PHP 5.2, neobsahuje create, neumí třídit a má natvrdo primary key ‚id‘) používám už i na ostrém webu a zatím OK.

Měl bych pár dotazů k implementaci:

  • Gridito\IModel::setSorting(…) má počítat jenn s řazením podle jednoho sloupce?
  • Má Gridito\IModel::setupGrid(Gridito\Grid) dělat i něco kromě nastavení primárního klíče?

Chtěl bych, aby se na mě sesypala kritika za Gridito\IEditableModel a použití ArrayAccess včetně návratových hodnot (vizte Gridito\DibiEditableModel). Je to ještě OK, nebo radši k tomu nemám ohýbat ArrayAccess a definovat vlastní metody? Anebo to mám udělat ještě jinak? Variantu použít IModel a k tomu nějaký IEditableRecord jsem zavrhl kvůli vetší volnosti, byl by k tomu potřeba ohýbat např. i Ormion, což nechci.

Měl bych drobnou výhradu k názvu IModel – možná by to mělo být spíše IRepository.

Dále bych měl určitou výhradu k tomu, že IModel je ohledně stránkování apod. brán jako mutable. To znamená, že je vpodstatě potřeba pokažé vrátit novou instanci.

Dále jsem proti generování ID v podobě ++$this->toolbarButtonId. Takto někomu pod rukama přehodím pořadí tlačítek (třeba zveřejnit vs. smazat) a je v háji. Asi by to chtělo explicitní uvádění id.

Pak bych měl i jedno řešení potenciálních problémů: Gridito mi nechtělo stránkovat. Zjistil jsem, že v @layout.phtml (víceméně původní ze skeletonu) je k {include #content} potřeba přidat zavináč.

V příkladu Ti chybí addProtection.

Jo, do názvu tématu PLS přidej i název ‚Gridito‘, třeba i „Gridito – Falešný datagrid – komponenta“.

Honza Marek
Člen | 1664
+
0
-

v6ak napsal(a):

Fork you! ;-)

Super,

Měl bych pár dotazů k implementaci:

  • Gridito\IModel::setSorting(…) má počítat jenn s řazením podle jednoho sloupce?

Ano. Pro uživatele je řazení podle jednoho sloupce většinou lepší. Pokud budu implementovat řazení podle více sloupců, asi přidám metodu setMultiSorting nebo něco takového.

  • Má Gridito\IModel::setupGrid(Gridito\Grid) dělat i něco kromě nastavení primárního klíče?

Můžeš si tam dělat co chceš. Slouží to k libovolné inicializaci komponenty.

Chtěl bych, aby se na mě sesypala kritika za Gridito\IEditableModel a použití ArrayAccess včetně návratových hodnot (vizte Gridito\DibiEditableModel). Je to ještě OK, nebo radši k tomu nemám ohýbat ArrayAccess a definovat vlastní metody? Anebo to mám udělat ještě jinak? Variantu použít IModel a k tomu nějaký IEditableRecord jsem zavrhl kvůli vetší volnosti, byl by k tomu potřeba ohýbat např. i Ormion, což nechci.

Neměl jsem čas to zatím prozkoumat, ale jinak bych asi ArrayAccess v tomhle případě nepoužil.

Měl bych drobnou výhradu k názvu IModel – možná by to mělo být spíše IRepository.

Proč?

Dále bych měl určitou výhradu k tomu, že IModel je ohledně stránkování apod. brán jako mutable. To znamená, že je vpodstatě potřeba pokažé vrátit novou instanci.

Asi nerozumím.

Dále jsem proti generování ID v podobě ++$this->toolbarButtonId. Takto někomu pod rukama přehodím pořadí tlačítek (třeba zveřejnit vs. smazat) a je v háji. Asi by to chtělo explicitní uvádění id.

Možná by to šlo nějak volitelně.

Pak bych měl i jedno řešení potenciálních problémů: Gridito mi nechtělo stránkovat. Zjistil jsem, že v @layout.phtml (víceméně původní ze skeletonu) je k {include #content} potřeba přidat zavináč.

Jasně, je to komponenta, která používá ajax.

Jo, do názvu tématu PLS přidej i název ‚Gridito‘, třeba i „Gridito – Falešný datagrid – komponenta“.

ok

v6ak
Člen | 206
+
0
-

Jé, já odpověď odložil a pak zasklil :-(
K setupGrid(): Jasně, jde mi o nějaké tipy na činnosti, které se zde mohou nacházet. Popravdě řečeno, při implementaci DibiModelu jsem se díval na OrmionModel.
ArrayAccess asi časem nahradím, asi to nebude velká změna. Ono mi to celkem čisté přijde až na návratové hodnoty offsetSet. Jinak klíč null u offsetSet není až takový výmysl, odpovídá to $foo []= bar.
K IRepository: http://www.phpguru.cz/…rstev-modelu – asi to není vyloženě nutné, ale bylo by to asi lepší.
K mutable IModelu: pokud budu mít někde nějakou továrnu na IModel, musí vždy vrátit novou instanci. Pokud by si instanci cacheovala, šlo by ji v rámci kontextu továrny „rozbít“ (nechtěně ovlivnit vše) nějakým setterem. Ale možná to takový problém není.
K id: Možná by bylo lepší za výchozí ID dosadit label, v případě změny tu nejsou nějaké katastrofické následky moc pravděpodobné. V případě přehození pořadí, řekněme, „Smazat“ a „Publikovat“, je to mnohem horší.
Jinak jsem si všiml jedné vlastnosti, kterou nezmiňuješ: specifické vykreslování typů \DateTime a boolean: https://github.com/…r/Column.php#L164 . To je důvod, proč v mém příkladu nefungují dva sloupce („Vytvořeno“ a „Je krásná“) korektně. Řešení mám v hlavě, půjde o nějaký Decorator, aby jej bylo možné použít i mimo DibiModel. V OrmionModelu to potřeba asi nebude, ale kdyby někdo chtěl třeba NotORMModel, tak by se mu to mohlo hodit.
Mimochodem, zatím to skoro vypadá, jako by Gridito používali jen dva programátoři (já a Honza). Můžete to někdo vyvrátit?

pave.kucera
Člen | 122
+
0
-

Já právě uvažuju o implementaci :)

Matúš Matula
Člen | 257
+
0
-

Tiez nad tym momentalne uvazujem, ale som odkazany na php 5.2 . V6ak ako si na tom s tou automatizaciou Gridita pre php5.2? :-)

v6ak
Člen | 206
+
0
-

No, částečně. Napsal jsem https://gist.github.com/430117 (na Windows jede pod Cygwinem), udělal pár ručních úprav (potřeboval jsem honem funkční Gridito) a tím to skončilo. Doma asi napíšu nějaký lepší skript. A pokud se budu nudit, implementuji i překlad anonymních funkcí na třídy, takže půjde přeložit i EditableGrid apod. BTW: On ten trochu lepší nástroj by mohl sloužit i k opačné portaci. A vlastně by se mi to asi taky hodilo.
Jinak, vzpomínám si na tyto ruční úpravy:

  • Přejmenování Button na Gridito_Button (kolize s \Nette\Forms\Button)
  • Názvy tříd s tlačítky byly ve stringu, asi ve třídě Grid. Bylo z nich potřeba odstranit namespace.
  • V nějakých renderovacích metodách tlačítek a asi i třídy Grid bylo potřeba se vyhnout použití method chainingu. Ale to jsem možná jen měl starou verzi Nette.

Pokud to chceš honem udělat, použij ten skript. Co bude potřeba dodělat, o to se PHP brzy přihlásí chybovou hláškou.

Matúš Matula
Člen | 257
+
0
-

Dik za bleskovu reakciu. Neponahlam sa s tym, teraz mam kopec roboty, len som si to chcel vyskusat :-)

v6ak
Člen | 206
+
0
-

Tak na vyzkoušení můžeš použít i PHP 5.3.

univerz
Člen | 7
+
0
-

gratulujem k vykonnostne pouzitelnemu rieseniu datagridu. vidim, ze vyvoj na githube ide dopredu, je nejaka moznost, ze fork od v6ak bude zluceny pred tym, nez sa zdrojaky priliz rozidu?

k dokonalosti mi chyba (mozno som jej existenciu prehliadol) moznost nastavit si sirku jednotlivych stlpcov, v zaujme zachovania vykonu v klude pekne jednoucelova, bez vyuzitia Nette\Web\Html. pripadne by sa hodilo nieco na styl PositionColumn stareho datagridu, nech nie je nutne vsetko davat do buttonov. samozrejme, pokial nie su v dohladnej dobe planovane BC breaky, rad prilozim ruku k dielu :).

v6ak
Člen | 206
+
0
-

Já bych teď asi už začal na autoportaci pro PHP 5.2. Pak bych jednu nezveřejněnou třídu z 5.2 upravil pro 5.3. Pak bych měl asi nějak sloučit svůj fork a upravit všechny modely kvůli jednomu menšímu BC breaku – jak to na GITu udělat co nejčistěji?

Jinak BC breaky – nedávno byl jeden BC break v IModelu, ale nevím, jaké jsou další plány Honzy. Já navrhoval změnu identifikace tlačítek („Dále jsem proti generování ID v podobě ++$this->toolbarButtonId. Takto někomu pod rukama přehodím pořadí tlačítek (třeba zveřejnit vs. smazat) a je v háji. Asi by to chtělo explicitní uvádění id.“), která by sice bez BC breaku šla, ale bylo by to dost kostrbaté. Nechci se do toho pouštět sám, protože řešením bez Honzova souhlasu bych riskoval vývoj dvou vzájemně nekompatibilních větví.

<EDIT n=„1“>Jo, asi časem upravím trošku IEditableModel tak, aby nepoužíval ArrayAccess.</EDIT>

Šířka jednotlivých sloupců – zajímavá poznámka, mělo by jít stejně jako barvení sudých a lichých řádků (vlastní šablonou), ale bylo by možná vhodné mít příjemnější cestu. Nechceš přiložit ruku k dílu zde?

<EDIT n=„2“>Jo, ještě by bylo asi dobré vymyslet nějaký dobrý způsob, jak předávat šablonám parametry tak, aby:

  • šlo využít nápověd IDE
  • šablona mohla mít svoje specifické vlastnosti
  • dědičnost nebyla zneužita

Co říkáte na toto?:

$grid->setTemplate(MyGreatGridTemplate::create()->setFoo(12)->setColumnSize('foo', '64px'));

Další věc je, že by se dalo toto nějak zakomponovat do Honzova návrhu o nastavení Gridita v šablonách . Bylo by to cooler.
</EDIT>

Editoval v6ak (22. 9. 2010 8:37)

univerz
Člen | 7
+
0
-

v6ak napsal(a):
Co říkáte na toto?:

$grid->setTemplate(MyGreatGridTemplate::create()->setFoo(12)->setColumnSize('foo', '64px'));

Další věc je, že by se dalo toto nějak zakomponovat do Honzova návrhu o nastavení Gridita v šablonách . Bylo by to cooler.

zrejme bude prezierave pockat si na vyjadrenie autora, kazdopadne som aj za variantu s quickfixom pomocou sablony – no idelane by som ju rad robil uz pre „spojene zrojaky“. aktualne robim s medziverziou s este vlastnou upravou pre namespaces a par upravami z gitu spred cca tyzdna.

Werkov
Člen | 17
+
0
-
  1. Bug report: v OrmionModel jsou špatně parametry u metody setLimit (přebývá offset).
  2. Feature request, dotaz: nebylo by lepší ukládat řazení a stránku do fragmentu? Uřivatelsky mi přijde lepší, když jsem se někam dolistoval, dám F5, ale nehodí mě to za defaultní pohled.

Jestli to budu hodně potřebovat, tak to možná někdy v budoucnu udělám. Proto by mě ještě zajímalo – neplánuje se toto řešit nějak centrálně v Nette (uložení/načtení parametrů ve fragmentu)?

v6ak
Člen | 206
+
0
-

Mám pocit, že se ten #fragment plánuje v Nete 1.0, ale krk za to nedám.

Patrik Votoček
Člen | 2221
+
0
-

Přesněji řečeno Nette 2… :-)

Honza Marek
Člen | 1664
+
0
-

v6ak napsal(a):

Jinak BC breaky – nedávno byl jeden BC break v IModelu, ale nevím, jaké jsou další plány Honzy. Já navrhoval změnu identifikace tlačítek (*"Dále jsem proti generování ID v podobě ++$this->toolbarButtonId. Takto někomu pod rukama přehodím pořadí tlačítek (třeba zveřejnit vs. smazat) a je v háji.

Určitě souhlasím s tím, že by tlačítka měla mít nějaké ID (ne jen číslo jako teď).

Dálě chci celkově předělat přidání sloupců a tlačítek. Zvažuju něco takového:

$column = $grid->addColumn("date", array(
	"sortable" => true,
	"text" => "Datum",
	...
));

$column->setOption("dateTimeFormat", "j.n.Y");

To je samozřejmě BC break jako prase, ale je potřeba v tom udělat pořádek i s ohledem na to alternativní nastavování v šablonách.

Další moje plány jsou k vidění v issues na githubu – https://github.com/…idito/issues#list

v6ak
Člen | 206
+
0
-

Někdy je lepší udělat BC break, než vláčet historii. Na druhou stranu, v takovém případě je lepší toho udělat více naráz.

Přiznám se, že:

  • Ten přistup s array se mi nelíbí, snadno se zde dělá chyba a IDE nenapovídá.
  • Byl bych pro více typů sloupců, zpracováni DateTime možná do obecného sloupce nepatří.
Honza Marek
Člen | 1664
+
0
-

v6ak napsal(a):

  • Ten přistup s array se mi nelíbí, snadno se zde dělá chyba a IDE nenapovídá.

To by se dalo vylepšit definováním konstant Column::NAME, Column::SORTABLE atd. Jinak to, že se ti to nelíbí znamená, že preferuješ klasické settery nebo se ti nelíbí ani jeden z těchto způsobů? .)

v6ak
Člen | 206
+
0
-

Dal bych přednost klasickým setterům. Ty mi ostatně znemožní se snažit nastavovat sloupci něco, co mu nepatří.

Teda, ještě lepší je asi JavaFX-like deklarativní přístup, ale ten v PHP s plnou podporou IDE asi jen tak neuděláme.

Quinix
Člen | 108
+
0
-

Jde nějakým způsobem definovat, aby tlačítko v gridu bylo normální odkaz (tzn. Presenter:akce) a neotevíral se v jquery UI dialogu? form na přidání/úpravu je dost velký a do dialogu se moc nehodí…

Werkov
Člen | 17
+
0
-

Já to řešil takto (v PHP >= 5.3):

$pres = $this;
$grid->addButton("Upravit", null)->setLink(function ($row) use($pres)
				  {
					  return $pres->link("edit", array("id" => $row->id));
				  })->setIcon("pencil");
Honza Marek
Člen | 1664
+
0
-

Na stránku http://griddemo.janmarek.net/document_root/ jsem hodil nové ukázky. Nicméně v tuto chvíli je datagrid kompatibilní pouze s Nette 2.0 dev, což obnáší i nefunkční ajax (kromě jQuery UI oken).

colek
Člen | 59
+
0
-

Ahoj, chtěl bych se zeptat na asi elementární věc. Gridito mi funguje krásně, ale jen na homepage. Pokud se dostanu hlouběji ve struktuře webu, kde je zobrazení vázáno na nějaké id, toto id se nepředává ve vygenerovaných odkazech.

Pokud navštívím url: text/123, funguje vše v pořádku, id 123 se správně předá a vše se vykreslí.

    $router[] = new Route('text/<id>', array(
        'module'    => 'Front',
        'presenter' => 'Text',
        'action'    => 'showText',
        'id' => NULL,
    ));

...
$id = $this->getParam('id');
$grid->setModel(new Gridito\DibiFluentModel($model->getTextById($id)  ));

ale všechny vygenerované odkazy (stránkování, řazení) tvoří url text/?grid-sort…

můžete mi s tím nějak pomoci, díky.. :)

Honza Marek
Člen | 1664
+
0
-

Určitě by pomohl dát id jako persistentní parametr, ale to samozřejmě může dělat nějaký další bordel.

Honza Marek
Člen | 1664
+
0
-

Gridito je kompatibilní s Nette 2.0 alfa 2

TeeBee87
Člen | 14
+
0
-

Lze nějak jednodušeji přidat sloupec, který je z joinuté tabulky?

<?php
$qb->select(array('t', 'o'))
	->from('Helpdesk\Entities\Ticket', 't')
        ->leftJoin('t.owner', 'o')
;
?>

Potřeboval bych vypsat například sloupec o.login.

Momentálně to dělám takto:

<?php
$grid->addColumn("login", "Vlastník", array(
	'renderer' => function($row) {
        	echo $row->owner->login;
        }
));
?>
blacksun
Člen | 177
+
0
-

Ahoj,

chtěl bych se zeptat, než si začnu tvořit vlastní úpravu, jestli není někde třeba skryta verze se sloupcem checkboxů, jako používá datagrid pro hromadné akce?

Šel bych na to přes vlastní šablonu a obalení tabulky formulářem..

Díky za info

Michal

Honza Marek
Člen | 1664
+
0
-

Zatím to neexistuje. Když to vyrobíš, bude to fajn.

lactarius
Člen | 47
+
0
-

Ahoj,

má gridito vlastní konfirmační mechanismus ?

Honza Marek
Člen | 1664
+
0
-
$grid->addButton('name', 'Popisek')->setConfirmationQuestion('jo?');

// nebo

$grid->addButton('name', 'Popisek')->setConfirmationQuestion(function ($entity) {
	return "Zničit $entity->name?";
});

Pak to vyhodí klasickej JS confirm.

lactarius
Člen | 47
+
0
-

To je super – jenom tlačítka bych udělal menší – jenom ikony s nápovědným textem, takhle jsou zbytečně na úkor dat…