Nextras\Datagrid – datagrid se vsim jak ma byt
- hrach
- Člen | 1838
Pristup do db je plne v tve kontrole. Nevim na jaky form (container) ty submity pridavas, nicmene nejjednodussi bude udelat si uplne vlastni form v presenteru. vysledek si zpracujes sam a podle toho, na co se kliklo, nastavis v presenteru svou persistentni promennou. ta se pak bude prenaset i pri strankovani, atp.
Pokud bys chtel renderovat ty prepinaci tlacitka v gridu, tak pak idealne
pomoci odkazu, ne formu. Renderovat v blocku global-actions
–
dokumentace
- sepo
- Člen | 69
tak som to pridal do :
$grid->setFilterFormFactory(function() {
$form = new Nette\Forms\Container;
......
$form->addCheckbox('primaryDb','nDAT')->setDefaultValue(false);
$form->addSubmit('filter', 'Filter data')->getControlPrototype()->class = 'btn btn-primary';
$form->addSubmit('cancel', 'Cancel filter')->getControlPrototype()->class = 'btn';
return $form;
}
funguje je to ale teraz ako nastavím aby mi pri zmene checboxu odoslalo form
ajaxom ?
ak doplním
$form->addCheckbox('primaryDb','nDAT')->setDefaultValue(false)->getControlPrototype()->class = 'ajax';
+ príslušný javascript
<script>
$(function () {
$.nette.ext('onchange', {
load: function () {
$("input[type=checkbox].ajax").change(function () {
$(this).closest('form').submit();
});
}
});
</script>
posielam ajaxom
filter[filter]
filter[primaryDb] on
a mal by som posielať
filter[filter] Filter data
filter[primaryDb] on
- hrach
- Člen | 1838
- zmenu sablony pro pagination udelas novym nadefinovanim blocku, viz. napr. Daviduv styl – Vsimni si te finty, ktera hodi ten posledni block jako prvni
- neco jako
$this['datagrid']->invalidateControl()
v presenteru nestaci?
- ViPEr*CZ*
- Člen | 817
- udělal jsem to přes metodu addCellsTemplate a v šabloně jsem block předefinoval… jen mi to udělalo to, že jsem měl paginator nahoře nad tabulkou i dole pod tabulkou
- nepoužívám v Nette snipety, tak mě to takto nenapadlo… už jsem si poradil po svém
PS: teď z první ruky se mi nepovedlo filtrování… respektive cancel
filtru… ajax se provede, ale nepřekreslil se mi grid…zmizí jen všechny
řádky.
A teď ještě jedna věc… paginátor zmizí při filtru… Mám 10 položek
na stránku, celkem jich je 31… dám filtr a mělo by jich být 13…
10 vidím, ale zbytek je v tahu… nenastránkuju se k nim, protože nevidím
paginátor.
- tak storno pořešeno… jsem si pojmenoval ještě jednu proměnou stejně… jako používá grid a pak to při stornu stále filtrovalo… a nenašlo to nic, proto prázdno.
- předchozí problém vyřešil i paginátor
Editoval ViPEr*CZ* (30. 3. 2013 20:01)
- Prado
- Člen | 21
Ahoj,
narazil jsem na zajímavé chování.
V callbacku pro edit form jsem omylem zapomněl jeden SELECT navíc a
důsledky byly nepříjemné:
Po kliknutí na edit se otevřel formulář, po odeslání se poslal POST, ale
nebyl vyvolán callback pro zpracování, nebyla dokonce vyvolána ani metoda
processForm z datagridu a nikde žádná chyba.
A to poslední mi připadá jako problém.
Nasimulovat by to mělo jít snadno. U mne stačilo přidat do callbacku vytvářejícího edit form řádku:
$form->addSelect('navic', 'navic', array());
(používám poslední verzi z Githubu v kombinaci s Nette 2.1.*)
- duke
- Člen | 650
Předně díky za perspektivní komponentu.
Mám několik připomínek.
Při experimentování s inline editací jsem narazil na pár překážek. Jednak, v uvedeném příkladu na stránce addonu, je problematické volání setDefaults, které je třeba obalit podmínkou:
if ($row !== NULL) {
$form->setDefaults($row);
}
… neboť po odeslání formuláře, bude $row obsahovat NULL, což je pro setDefaults nepřípustná hodnota.
Další překážkou je to, že filtrovací a editační formulář je řešen jako jeden formulář. To má za následek to, že při editaci textových inputů vede stisk tlačítka enter na odeslání formuláře prvním submit tlačítkem, což je zpravidla filtrovací submit tlačítko (protože je v html kódu uvedeno jako první), nikoli ukládací tlačítko (které by bylo žádoucí)… Asi by to chtělo tyto formuláře řešit odděleně.
Dále jsem narazil na jisté problémy při filtrování a stránkování, pro které jsem vytvořil issue na githubu. Jen bych dodal, že podobný problém může nastat také v případě, kdy máme implementované mazání záznamu, a octneme se tak po proběhnuvším mazání na stránce, která je již zcela prázdná. Otázkou je, jak by to měl datagrid řešit. Možná by bylo nejlepší, kdyby prostě uměl zobrazit informaci, že se uživatel nalézá za poslední stránkou (a vhodně mu to znázornil např. i v paginátoru).
A konečně bych chtěl upozornit na chybějící uzavírací závorky (zcela na konci) v příkladech pro setFilterFormFactory a setEditFormFactory na stránce addonu.
Editoval duke (9. 4. 2013 13:55)
- hrach
- Člen | 1838
@duke díky :)
- manual na addons portalu opraven
- filtrovani vzdy resetuje na stranku 1
- pokud se grid nachazi na strance > 1 a nejsou data, presmeruje na 1. (resi problem pri smazani zaznamu).
- formular musi byt bohuzel jeden, protoze to
<table>
neni mozne vlozit<form>
tak, aby obaloval jen nektere<tr>
- defaultni submit button pri enter vyresen pomoci javascriptu
Editoval hrach (9. 4. 2013 14:57)
- hrach
- Člen | 1838
ViPErCZ napsal(a):
hrach napsal(a):
- neco jako
$this['datagrid']->invalidateControl()
v presenteru nestaci?Ozkoušel jsem to teď při mazání řádku. A toto nefunguje. Musel jsem toto udělat:
$this['grid']->invalidateControl('rows'); $this['grid']->getTemplate()->echoSnippets = TRUE;
Tak už by mělo fungovat jen toto :)
$this['datagrid']->invalidateControl();
- ViPEr*CZ*
- Člen | 817
hrach napsal(a):
ViPErCZ napsal(a):
hrach napsal(a):
- neco jako
$this['datagrid']->invalidateControl()
v presenteru nestaci?Ozkoušel jsem to teď při mazání řádku. A toto nefunguje. Musel jsem toto udělat:
$this['grid']->invalidateControl('rows'); $this['grid']->getTemplate()->echoSnippets = TRUE;
Tak už by mělo fungovat jen toto :)
$this['datagrid']->invalidateControl();
Díky. Až budu mít time, tak to 100% ozkouším.
Co mě napadlo, tak by mohlo být fajn zapracovat checkbox, kterým by se dali
vybírat řádky a jeden v záhlaví, který by zaškrtl všechny
checkboxy.
- vvoody
- Člen | 910
Ahoj, robím riadkovú editáciu a nefunguje mi validácia:
public function editFormFactory($row)
{
$container = new \Nette\Forms\Container;
$container->addText('url')->addRule(\Nette\Forms\Form::URL);
$container->addSubmit('save', 'Uložiť');
$container->addSubmit('cancel', 'Storno');
if ($row) {
$container->setDefaults($row);
}
return $container;
}
pri akomkoľvek vstupe sa vždy dostane k slovu editFormCallback bez ohľadu na validačné pravidlá. Niečo robí zle alebo by som mal validovať ručne v editFormCallback-u?
- duke
- Člen | 650
Možná by za to stálo zmínit v dokumentaci, že pokud chceme používat
vlastní inline editační odkazy, je u nich třeba vždy zadat atribut
data-datagrid-edit
. Teď jsem na tom strávil spoustu času…
Je toto vůbec třeba? Nešlo by ten atribut navázat na něco jiného, co bude už v základní šabloně?
Btw, zajímavé je, že včera mi to fungovalo i bez tohoto, ale dnes se to začlo chovat divně [konkrétně se mi přestaly zavírat otevřené inline edity při pokusu editovat jiný] (nechápu, jaká změna na to mohla mít vliv). Pomohlo až přidání tohoto atributu ke všem inline editačním linkům.
- ViPEr*CZ*
- Člen | 817
hrach napsal(a):
Tak používej Nette\DateTime. Nette\Database s ní nativně pracuje. Stejně asi ale budeš chtít vlastní format, přesně k tomu jsou určeny šablony.
Omlouvám se, nejedná se o Nette\DateTime, nýbrž o holou DateTime (zkouším Doctrine2). Přemýšlím jak to udělat, abych kvůli potřebě DateTime nemusel přepisovat vždy celou šablonu. Asi nejlepší bude upravit Entitu, tak aby vracela Nette\DateTime a ta pak umí _toString. Případně kdybych někdy chtěl vlastní formát do výpisu, tak bych musel upravit už šablonu. Díky. ;-)
- vvoody
- Člen | 910
hrach napsal(a):
@vvoody inline edit validace by mela jiz korektne fungovat :)
Ďakujem, funguje. Chvíľu som sa s tým trápil, lebo sa mi nezobrazovala chybová hláška. Problém (alebo skorej príčina) bol v tom že projekt ešte nemám zajaxovaný, čo spôsobilo redirect. Hackol som si to zatiaľ takto
if (!$this->presenter->isAjax() && !(isset($form['edit']) && !$form['edit']->isValid())) {
$this->redirect('this');
}
- ZZromanZZ
- Člen | 87
Mám pár dotazů, připomínek, atd..
Hned první řádek kódu v dokumentaci. Neměl by být ?:
$grid = new Nextras\Datagrid\Datagrid();
Dále, řekněme, že chci jenom jednoduchý výpis dat do sloupců bez filtrace, editace, stránkování atd…
$grid = new \Nextras\Datagrid\Datagrid();
$grid->addColumn("articleID", "ID");
$grid->addColumn("name", "Název článku");
$grid->addColumn("description", "Popis");
$grid->addColumn("insertTime", "Datum vložení");
$grid->addColumn("active", "Aktivní");
$grid->setDataSourceCallback($this->getDataSource);
Toto řešení mi spadne na chybě Call to a member function
invokeArgs() on a non-object Datagrid.php, řádek 286
A nutí mě to nastavit callback na stránkování
$grid->setPagination(10, function(){});
Ale co když stránkovat nechci ?
Dále mě napadlo (a všiml jsem si, že se tak chová i demo), že flash
message, zůstává při ajaxu už „navěky“.
Jak to řešit ?
Napadlo mě nějak evidovat interní snippety(pomocí pole), a značit u nich
zdali se mají invalidovat nebo ne. A do toho pole by si mohl uživatel přidat
další snippety, které by se mu automaticky invalidovaly.
Edit:
A v bootstrap šabloně by tag ul neměl mít class=„pagination“, ale měl
by být obalený divem a ten by měl mít class pagination. Jinak se mi to
nezobrazuje korektně.
Editoval ZZromanZZ (14. 4. 2013 18:45)
- hrach
- Člen | 1838
@vvoody: díky, fixed
@ZZromanZZ:
- díky, fixed
- díky, fixed
- díky, fixed, mrkni jak se to dá jednoduše vyřešit
- použij šablonu pro bootstrap 2, ne pro bootstrap 3 ;)
Editoval hrach (14. 4. 2013 20:02)
- Kori
- Člen | 73
ZZromaZZ: Tak presne tyhle chyby jsem chtel taky nahlasit :-)
Vcera jsem si s tim zacal hrat a nasel jsem dalsi chybicky. Mam stazenou posledni verzi z Gitu a objevil jsem toto:
V nejnovejsim Nette 2.0.10 to rve, ze to chce zmenit onSubmit na onSuccess.
Jquery 1.9.1 hlasi
TypeError: $.nette.ext is not a function v nextras.datagrid.js, radka 48
Nepodarilo se mi rozchodit filtrovani. Dmpoval jsem si pole $filter, ale nic se mi nepredava.
V prikladech na webu bych asi odstranil $form->addSearchInput(‚nickname‘, …); nebot soucasti datagridu neni a kde ho vzit, na to jsem neprisel ;-) A nebo je potreba a proto mi filtrovani s addText nefunguje?
Mozna by stalo za to zpristupnit take demo / sandbox ke stazeni na Gitu, aby se clovek na zacatku lepe zorientoval…
- hrach
- Člen | 1838
- Všechny dema jsou tu: https://github.com/nextras/demos
- Je nutne použít nette.ajax.js: https://github.com/…ette.ajax.js
- addSearchInput je jen ukazka, ze si tam muzes pridat co chces a nejses omezenej na to, co podporuje datagrid, jako je to u jinych datagridu
- kompatibilitu pro nette 2.0.x asi fixnu no :)
- MartinitCZ
- Člen | 580
Je tu někde jednoduchý example s použitím paginatoru?! Pořád to na mě řve Invalid callback. – Datagrid.php:192
- MartinitCZ
- Člen | 580
@**hrach**: Díky, ale nějak mi to stále nefunguje.
Nic jsem v examplu neměnil, ale po klknutí na filter to řve
Nette\Forms\Form->onSubmit changed its behavior; use onSuccess
instead.
- boob
- Člen | 21
Zdar, DataGrid vyzera skvelo (dakujeme :), ale potreboval by som poradit
s jednou vecou. Chcel by som mal 1 stlpec v tabulke, kde by boli vypisane (a
teda aj editovatelne) 2 hodnoty/inputy. Bol by napriklad stlpec „kredit“,
kde by bolo standardne vypisane 5.20 / 10
(to su 2 polozky) a po
kliknuti na EDIT by z toho bolo [ 5.20] / [ 10]
(teda
2 inputy). Je toto chovanie mozne nejako docielit?
Este jednu otazocku: ako by som pridal do editacneho formulara (pri inline
editacii) nejaky skryty input? pripadne moznost pridat stlpec, ktory sa
nezobrazi? Mam totiz 3 stlpce, ale pri editacii potrebujem napriklad
id_number
, ale nechcem ho mat vypisane v tabulke
Vdaka
Editoval boob (14. 5. 2013 11:05)
- David Ďurika
- Člen | 328
Zdravim,
ako invalidujem jeden riadok v gride po kliknuti na button ? v podstate nieco ako refresh ale len pre jeden riadok
dakujem
EDIT:
no ajax mi uz funguje, len neviem preco mi invaliduje kazdy riadok v gride,
pricom ja invalidujem len jeden riadok:
<?php
$this['grid']->invalidateRow($id);
?>
EDIT – uz to ide OK
mal som staru verziu datagridu, sry za spam :)
Editoval achtan (30. 5. 2013 10:47)
- MW
- Člen | 626
Zdravím,
seznamuji se s tímto gridem a moc se mě líbí ! Díky za něj.
Prosím jen o malé vysvětlení, zda-li se veškeré upravy jako např. přidání řádkové akce dějí v původním Datagrid.latte a nebo to lze nejak v šabloně, kde volam control ({control grid}) ?
Trosku tápu v tom renderu .
Například použitím
$grid->addCellsTemplate('./grid.columns.latte');
musím v onom grid.columns.latte nadefinovat vše co je i v Datagrid.latte? Nebo jsem nepochopil nejake provázání sablon ?
- hrach
- Člen | 1838
Neco jako globalni akce moc neexistuje, protoze neumoznuje vybrat konrektni radky, to teprve je v planu. Pokud ti jde o tu bunku, ktera je uplne vpravo nahore, tak ta editovatelna (prepsatelna sablonou) zatim neni. Zvlaste z duvodu, ze nemusi existovat pravy sloupec akci, respektive by existoval jen kvuli teto bunce → myslim si, ze se to da v UI navrhnout jinak a i lepe, kde maji byt globalni akce.
- MW
- Člen | 626
Zakomponovat pridani zaznamu do komponenty.. nic vic.. předtím jsem
pouzival Niftygrid a ten se tvaril fajn do doby nez clovek potreboval ovládat
dotaz dotazy do db…
Tento grid me prijde mnohem otevrenejsi, takze muj dotaz smeroval jen k tomu,
zda-li tam není jen nejaka podpora vkladani nového zaznamu, které jsem si
nevsiml :-)
Diky !
- MW
- Člen | 626
No mým cílem bude tento grid a napojeni na modální okna s vkládáním a editací záznamů. Toho jsem zatím u žádného gridu nedosáhl a věřím, že díky tomu jak je navržený by to mohlo jít.
Ano… nejdřív jsem hledal místo pro globální akci, ale to jsem pak zatím dal mimo. Ted bych rád zkusil ty modal okna a komplet ovládání gridu.
Diky
- MW
- Člen | 626
Co prosím dělám blbě?
Jde mě o paginator.. ačkoliv jsem proti němu, musim ho u této tabulky
implementovat…
SetPagination vytvoří objekt paginatoru, ale uz nic nepredavam do
$selection..
jak na to prosím ?
Díky
presenter:
class InfoPresenter extends BasePresenter {
public $userCount;
public function createComponentUsers() {
$grid = new \Nextras\Datagrid\Datagrid;
$grid->addColumn('id');
$grid->addColumn('email')->enableSort();
$grid->addColumn('name')->enableSort();
$grid->setDatasourceCallback($this->getData);
$grid->setPagination(5, $this->getDataSourceSum);
$grid->setFilterFormFactory(function() {
$form = new Nette\Forms\Container;
$form->addText('name');
$form->addSubmit('filter', 'Filtrovat')->getControlPrototype()->class = 'btn btn-primary';
$form->addSubmit('cancel', 'Zrušit filtr')->getControlPrototype()->class = 'btn';
return $form;
});
$grid->setEditFormFactory(function($row) {
$form = new Nette\Forms\Container;
$form->addText('email');
!$row ?: $form->setDefaults($row);
return $form;
});
$grid->setEditFormCallback($this->saveData);
$grid->addCellsTemplate(LIBS_DIR . '/Addons/Nextras-datagrid/Lattes/users.latte');
$grid->addCellsTemplate(LIBS_DIR . '/Addons/Nextras-datagrid/bootstrap-style/@bootstrap3.datagrid.latte');
$grid->addCellsTemplate(LIBS_DIR . '/Addons/Nextras-datagrid/bootstrap-style/@bootstrap3.extended-pagination.datagrid.latte');
return $grid;
}
public function getData($filter, $order) {
$filters = array();
foreach ($filter as $k => $v) {
if ($k == 'id' || is_array($v))
$filters[$k] = $v;
else
$filters[$k . ' LIKE ?'] = "%$v%";
}
$selection = $this->context->usersModel->getUsersD()->where($filters);
if ($order[0])
$selection->order(implode(' ', $order));
$this->userCount = $selection->count();
return $selection;
}
public function getDataSourceSum() {
return $this->userCount;
}
public function saveData($data)
{
$data = $data->getValues();
$this->context->usersModel->getUsersD()->where('id', $data->id)->update($data);
$this->flashMessage('Data ulozena.');
$this->invalidateControl('flash');
}
}