Nextras\Datagrid – datagrid se vsim jak ma byt
- MartinitCZ
- Člen | 580
1. Dá se jednoduše upravit {define row-head-colums} ale
jen pro jeden sloupec, jedno th?
Zkoušel jsem toto {define row-head-colum-name}, ale nic to
neřeší.
2. Dá se přidat sloupec, který není v db? Potřebuji sloupec „setting“, kde budou nějaké odkazy.
3. Jak do templaty přidané přes „$grid->addCellsTemplate()“ přidat nějaké proměnné?
Editoval MartinitCZ (9. 11. 2014 17:20)
- abc
- Člen | 92
Je možné ve filtru používat nextras/datepicker, kde jako datepicker
použiju doporučený datepicker (odkaz)
Zkusil jsem to, ale bohužel při filtrování dostanu chybu:
Value must be scalar or NULL, array given in field 'date_from'
Zestručněný kód:
public function createComponentSpacesGrid() {
$g = new Datagrid();
$g->addColumn("date_from", "Datum od")
->enableSort();
$g->setFilterFormFactory(function() {
$f = new \Nette\Forms\Container;
$f->addDatePicker("date_from", "Datum od");
return $f;
});
return $g;
}
- H0w4rd
- Člen | 96
Ja pouzivam DateInput od Vodacka a bez problemu to funguje.
Odpoved na 2 – normalne sloupec pridej pomoci $grid->addColumn(„nejaky_sloupec“, „Blabla“), na tom nezalezi, ze neni v DB. Ale potom v sablone musis definovat jeho obsah
{define col-nejaky_sloupec}
<td>Obsah sloupce, {$row->jiny_existujici_sloupec} - {$row->dalsi_existujici_sloupec}</td>
{/define}
Odpoved na 3 – v DataGrid.php si najdi metodu
render() a před
$this->template->render(); si připiš, co chceš.
Samozřejmě je potřeba na to myslet, až budeš nahrávat novou verzi.
Jiné řešení – vytvoř v nějaké třídě statickou proměnnou a k té
se dostaneš i z latte. Příklad:
<td>{\App\Model\UserRepository::$nejakaStatickaPromenna}</td>
- abc
- Člen | 92
@H0w4rd díky, ale chtěl jsem používat ten dateInput, který je doporučený a líbí se mi o dost víc
@hrach bude to fungovat?
https://forum.nette.org/…m-jak-ma-byt?p=8
- svobodai
- Člen | 136
Pro jeden projekt bych potřeboval k tomuto gridu použí formulář, který by předával filtrační parametry. Samostatný formulář potřebuji protože, se jeden parametr se dá ovlivnit púomocí dvou závislých selectů. Např. skladby jsou vázámy na skupiny a skupiny jsou vázány na umělce. Zobrazuji jen skladby, ale filtruji podle skupiny, ale přehled skupin se dá omezit vybráním umělce.
Jak by se to dalo udělat? Děkuji za rady.
- tttpapi
- Člen | 100
Ahoj, je tu možné nějak udělat výpis, kde bych měl výpis jednotlivých řádků a v 1 buňce by byl součet?
Př. Mám výpis zákazníků (všichni zákazníci po jednotlivých fakturách).
<table>
<tr>
<td>Id</td><td>Zákazník</td><td>č. faktury</td><td>dluh</td><td>celkový dluh</td>
</tr>
<tr>
<td>1</td><td>Test</td><td>123</td><td>500</td><td>1000</td>
</tr>
<tr>
<td>2</td><td>Test</td><td>256</td><td>500</td><td>1000</td>
</tr>
</table>
- szurke
- Člen | 3
Ahoj,
mam problem s instalaciou.
natiahnute je cez composer:
"require": {
"php": ">= 5.3.7",
"nette/nette": "~2.2.0",
"tracy/tracy": "~2.2",
"tecnick.com/tcpdf": "~6.2",
"nextras/datagrid": "~2.1",
"nextras/latte-macros": "~1.1"
},
následne je len chyba marka redefine.
potom nastavene aj v config.neon
latte:
macros:
- Nextras\Latte\Macros\RedefineMacro::install
chyba „Found sections ‚latte‘ in configuration, but corresponding extensions are missing.“
Samotny GRID aj nette sami páči, som „5 days beginer“.
- MW
- Člen | 626
Zdravím,
něco jsem si krokoval a narazil jsem na něco, co mě není jasné a prosím
v někoho o malé objasnění.
Díky mé neznalosti mě to asi uniká, ale kde se v této fázi presenteru
veme hodnota pro anonymní funkci $row ?
$grid->setEditFormFactory(function($row) {
$form = new Nette\Forms\Container;
$form->addText('email')->setRequired('Zadat!');
!$row ? : $form->setDefaults($row);
return $form;
});
Moc děkuji !
- tomhrb
- Člen | 23
tady to vlakno neni prilis aktivni :D
mozna hledas toto https://github.com/…Datagrid.php#L438 ?
MW napsal(a):
Zdravím,
něco jsem si krokoval a narazil jsem na něco, co mě není jasné a prosím v někoho o malé objasnění.
Díky mé neznalosti mě to asi uniká, ale kde se v této fázi presenteru veme hodnota pro anonymní funkci $row ?$grid->setEditFormFactory(function($row) { $form = new Nette\Forms\Container; $form->addText('email')->setRequired('Zadat!'); !$row ? : $form->setDefaults($row); return $form; });
Moc děkuji !
- tomhrb
- Člen | 23
technicky ano (v tomto okamziku se vylovi pozadovany radek z dataSource). na L:438 je pak predan do callback, ktery je tovarna na kontejner (zde formular), a to prave s jednim parametrem – zde $data do anonymni funkce se dosadi za Tve $row, ale muze se to jmenovat klidne $radek :) shoda jmen neni nutna
MW napsal(a):
To $row tedy znikne tady?
- Tirus91
- Člen | 199
@hrach
Měl bych dotaz. Z nějakého důvodu se mi ve filtru objekty DateTime
převádějí na pole.
jedná se přímo v třídě Datagrid metoda render
if ($this->filterFormFactory) {
\Tracy\Debugger::barDump($this->filter); // zde je následně datetime jako pole
$this['form']['filter']->setDefaults($this->filter);
}
Stalo se to např. @abc v tomto příspěvku
A ještě menší věc. Nevím proč mi nejde stránkování. V případě, že si zavolám metodu loadState a jako parametr uvedu prázdné pole, tak již funguje.
protected function createComponentPostsGrid($name) {
$grid = new \Nextras\Datagrid\Datagrid($this, $name);
$grid->setTranslator($this->getTranslator());
$grid->addColumn('title', 'Název')->enableSort();
$grid->addColumn('author', 'Autor')->enableSort();
$grid->addColumn('createdAt', 'Vytvořeno')->enableSort();
$grid->addColumn('publishedAt', 'Vytvořeno')->enableSort();
$grid->addColumn('deletedAt', 'Vytvořeno')->enableSort();
$grid->setDataSourceCallback($this->getDataSource);
$grid->setPagination(2, $this->getDataSourceSum);
$grid->setFilterFormFactory(function() {
$form = new \Nette\Forms\Container;
$form->addText('title');
$form->addText('author');
$form->addDatePicker('createdAt');
$form->addDatePicker('publishedAt');
$form->addDatePicker('deletedAt');
return $form;
});
$grid->addCellsTemplate(__DIR__ . '/../templates/Posts/@cells.latte');
$grid->loadState([]);
return $grid;
}
Editoval Tirus91 (22. 3. 2015 23:25)
- MW
- Člen | 626
Jak lze prosim nastavit vychozi filter při zobrazeni gridu? Myslim jinak nez primo do URL.
Nastavit nejak vychozi promenou $grid-filter[‚aktivni‘]=1 ???, kde nejlepe?
Zatím jsem nemel problém to pridat primo do url, ale zde se to nehodi, pristupuje se z vice mist a nechci to všude prepisovat…
Diky!
- kikinet
- Člen | 35
Nemůžu to nikde najít, snad se nebudu opakovat.
Pokud použiju filtry, vytvoří se mi sloupec navíc s buttonem filter (a
cancel) ⇒ grid-col-actions
.
Jak využiju prázdné buňky pod tím?
Zkoušela jsem makro {redefine row-actions}
, což vytvoří
další sloupec, a makro {redefine col-actions}
, což neudělá
vůbec nic.
Pro jistotu, chci to pro přidání tlačítek pro editaci – delete, edit button na každém řádku.
Díky :)
- kikinet
- Člen | 35
MW napsal(a):
kikinet napsal(a):
Nemůžu to nikde najít, snad se nebudu opakovat.
…no přesně tak {define row-actions}
To ale není to co chci. {define row-actions}
vytvoří NOVÝ
sloupec s tlačítky. Já chci dát tlačítka do sloupce
grid-col-actions
, který se vytvoří při nastavení filtru.
Ukázka na kódu. Grid pouze s filtrem.
<thead>
<tr class="grid-columns">
<th class="grid-col-username">Username</th>
<th class="grid-col-actions"></th>
</tr>
<tr class="grid-filters">
<th class="grid-col-username"><input type="text"></th>
<th class="grid-col-actions"><input type="submit" value="Filter"></th> //Btn Filter
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td class="grid-col-actions"></td> //Prázdná buňka
</tr>
<tr>
<td>B</td>
<td class="grid-col-actions"></td> //Prázdná buňka
</tr>
<tr>
<td>C</td>
<td class="grid-col-actions"></td> //Prázdná buňka
</tr>
</tbody>
Ukázka na kódu. Grid s filtrem a přidaným
{define row-actions}
.
<thead>
<tr class="grid-columns">
<th class="grid-col-username">Username</th>
<th class="grid-col-actions"></th>
</tr>
<tr class="grid-filters">
<th class="grid-col-username"><input type="text"></th>
<th class="grid-col-actions"><input type="submit" value="Filter"></th> //Btn Filter
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td class="grid-col-actions"></td> //Pořád prázdná buňka
<td>Update</td> //DALŠÍ buňka
</tr>
<tr>
<td>B</td>
<td class="grid-col-actions"></td> //Pořád prázdná buňka
<td>Update</td> //DALŠÍ buňka
</tr>
<tr>
<td>C</td>
<td class="grid-col-actions"></td> //Pořád prázdná buňka
<td>Update</td> //DALŠÍ buňka
</tr>
</tbody>
Chci, aby se „DALŠÍ buňka“ nevytvářela a „Update“ se vložil do „Pořád prázdná buňka“
Editoval kikinet (11. 4. 2015 20:56)
- BigCharlie
- Člen | 283
Chtěl bych zkusit přidat adhoc vlastní signály pro datagrid, ale trochu jsem narazil. Kod ve zkratce podobný tomuto:
továrna
$grid = new DataGrid();
// ...
$grid->addExtensionMethod('handleTry', funtion() {
// ...
});
v šabloně
{redefine row-actions}
<a href="{link try! $row->id}">Try it</a>
{/redefine}
Takto je výsledkem chyba
Invalid link: Unknown signal 'try', missing handler Nextras\Datagrid\Datagrid::handletry()
;
Pokud datagrid podědím a natvrdo tam metodu napíšu, funguje to dle očekávání. Nějaký nápad, co s tím?
- H0w4rd
- Člen | 96
No tak vyřešil jsem to takhle nehezky:
Do DataGrid.latte jsem přidal odkazy na refreshování:
- když má grid více než jednu stránku, je nutné volat signál paginate, aby zůstal na stejné stránce i po refreshi,
- když má jen jednu stránku, signál paginate nefunguje, tak je nutné volat signál sort
{if $paginator->pageCount > 1}
<a href=„{link paginate!, ‚page‘ ⇒ $paginator->page}“
class=„dn ajax refresh-link“ title=„Obnovit“>R</a>
{else}
<a href=„{link sort!}“ class=„dn ajax refresh-link“
title=„Obnovit“>R</a>
{/if}
A javacsript, který refreshuje grid, vypadá takhle:
setInterval("$('#frm-dataGrid-form .refresh-link').click();", {$campaignGridRefresh});
- n.u.r.v.
- Člen | 485
Ahoj, chtěl jsem dát tabulce „gridu“ nějaké ID, myslel jsem si, že když v souboru grid.columns.latte (který je nastaven pomocí addCellsTemplate) udělám toto:
{define table-open-tag}
<table id="admin_table_datagrid">
{/define}
{define table-close-tag}
</table>
{/define}
tak že se do tabulky vloží to ID, ale nefunguje to – začne to fungovat, až když smažu v souboru Nextras\Datagrid\src\Datagrid.latte blok {define table-open-tag}…
Co dělám špatně, že to nejde předefinovat? Protože do originálního Datagrid.latte se mi nechce zasahovat…
Editoval n.u.r.v. (5. 6. 2015 23:07)
- n.u.r.v.
- Člen | 485
áá, díky, zkusím… ale zajímavé je, že když jsem potřeboval jednomu sloupci (<td>) dát class, tak define stačilo… trochu matoucí
Edit: aha, tak je něco špatně: Latte\CompileException Unknown macro {redefine}
Používám nejnovější nette a nejnovější datagrid (vše přes composer).
Edit2: Tak jsem našel na straně 6 že se musí nainstalovat nextras/latte-macros
To bych dal do dokumentace k datagridu
Editoval n.u.r.v. (6. 6. 2015 9:21)
- TomasG
- Člen | 23
Zdravím, už delší dobu se pokouším „zprovoznit“ tento grid, ale nějak se mi to nedaří…
v Presenteru mám:
public function createComponentStaticPagesGrid(){
$grid = new Nextras\Datagrid\Datagrid;
$grid->addColumn('page_id', 'ID');
$grid->addColumn('page_insert_date', 'Datum vložení');
$grid->addColumn('page_active', 'Aktivní');
$grid->addColumn('edit', 'Editovat');
$grid->addColumn('delete', 'Smazat');
$grid->setDataSourceCallback($this->getDataSource);
return $grid;
}
public function getDataSource(){
$selection = $this->spModel->getPages();
return $selection;
}
a Grid vykreslím pomocí:
{control staticPagesGrid}
Ale já potřebuji grid vykreslovat ručně, protože chci do buněk přidat odkazy na action. Takže přidám:
$grid->addCellsTemplate(__DIR__ . 'templates/StaticPages/default.latte');
Ale už se mi nedaří manuálně vykreslovat, zkoušel jsem například
{define col-page_id}
<td>
{$row->page_id}
</td>
{/define}
Ale nic se nevykreslí… věřím, že to bude úplná banalita, ale já na
to prostě nemůžu přijít…
Díky moc :o)
Editoval TomasG (8. 6. 2015 22:14)
- H0w4rd
- Člen | 96
Chybi lomeno za __DIR__, tzn:
$grid->addCellsTemplate(__DIR__ . '/templates/StaticPages/default.latte');
A doporucuju pro prehlednost latte soubor s definicemi sloupcu nejak
odlisit, napriklad ja davam suffix _grid, tzn. default_grid.latte.
A dale mrkni na dokumentaci, na editaci a mazani se sloupec nepridava, k tomu
tam je
{define row-actions}...{/define}
- TomasG
- Člen | 23
Do addCellsTemplate jsem to lomítko přidal.
Přidal jsem si přes composer https://github.com/…latte-macros
a zaregistroval do configu
nette:
latte:
macros:
- Nextras\Latte\Macros\RedefineMacro::install
V latte vypisuji takto, ale pořád se nic nevykresluje…
{redefine col-page_id}
<td>
{$row->page_id}
</td>
{/redefine}
- H0w4rd
- Člen | 96
Řešil jsem chybu
TypeError: settings.nette is undefined`
v nextras.datagrid.js.
Používal jsem verzi, která se stáhla composerem. Ale když jsem si ji
stáhnul ručně odtud:
https://github.com/…ee/master/js
tak to funguje. Nebylo by možné, aby i ve vendor byla opravená
verze JS?
- Azathoth
- Člen | 495
Právě jsem dal pullrequest, který řeší bug https://github.com/…id/issues/41, tedy když chci přidat stránkování a zároveň chci v createComponent metodě sahat na template (kvůli registraci vlastních fiktrů nebo posílání dalších proměnných do template). Tak to sem píšu, kdyby to náhodou zůstalo na githubu bez povšimnutí.
- n.u.r.v.
- Člen | 485
Ahoj, nevíte jak datagridu předám do template proměnnou z presenteru?
Co potřebuji:
Vypisuji data z db a na konci řádku chci přidat ještě status, který ale získám z externí webové služby. Mám tedy pole:
[id_polozky] = stav;
dále mám v šabloně datagridu:
{redefine col-stav}
<td>{$stavy[$row->ID]}</td>
{/redefine}
ale když dám v presenteru $this->template->stavy = $stavy;
tak stejně dostanu chybu Undefined variable: stavy
Díky za pomoc
- petrf
- Člen | 15
Také s tím zápasím
Proměnná se dá dostat pomocí:
*presenter.php
$grid = new Grid($this, $name);
..
$grid->template->stavy = ‚hodnoty‘;
..
→ Jenže zjistil jsem, že takto přestanou fungovat odkazy v Paginatoru
A druhá varianta mi zatím nechce fungovat vůbec
@cells.latte
..
{var $stavy = $presenter->getParameter(‚stavy‘)}
..
- Azathoth
- Člen | 495
když si stahnete nejnovější verzi datagridu, najdete tam event onRender. Ten se spustí před vykreslením, tedy hned po připojení do stromu komponent. Tehdy už je datagrid inicializovaný a template k dispozici. tak proměnnou do template pošlete v callbacku, který dáte do eventu onRender. asi takhle:
$grid = new Datagrid();
...
$grid->onRender[] = function(Datagrid $datagrid) {
$datagrid->template->stavy = $this->stavy;
}
řešení je rychlé a elegantní. v dokumentaci tenhle event není,
protože je z mého asi týden starého pullrequestu.
@petrf @H0w4rd udělejte to takhle, je to čisté a leší než
statická proměnná.
Editoval Azathoth (12. 7. 2015 11:53)
- petrf
- Člen | 15
Azathoth napsal(a):
když si stahnete nejnovější verzi datagridu, najdete tam event onRender. Ten se spustí před vykreslením, tedy hned po připojení do stromu komponent. Tehdy už je datagrid inicializovaný a template k dispozici. tak proměnnou do template pošlete v callbacku, který dáte do eventu onRender. asi takhle:
$grid = new Datagrid(); ... $grid->onRender[] = function(Datagrid $datagrid) { $datagrid->template->stavy = $this->stavy; }
řešení je rychlé a elegantní. v dokumentaci tenhle event není, protože je z mého asi týden starého pullrequestu.
@petrf @H0w4rd udělejte to takhle, je to čisté a leší než statická proměnná.
Díky, konečně jsem to mohl předělat dynamicky
composer require nextras/datagrid dev-master
(jinak se použije verze 2.1, kde to ještě není)
NewsPresenter.php:
use Nextras\Datagrid\Datagrid as Grid,
…
$grid->onRender[] = function(Grid $grid) {
$grid->template->LANGUAGES = $this->languages; // array of IDs
languages
};
…
$grid->addCellsTemplate(__DIR__ .
'/templates/News/@cells.latte');
…
@cells.latte:
{define cell-language_id}
{ifset $LANGUAGES}
{foreach $LANGUAGES as $key ⇒ $val}
{if $row->language_id == $key}
{$val}
{/if}
{/foreach}
{else}
{$row->language_id}
{/ifset}
{/define}
- petrf
- Člen | 15
hrach napsal(a):
secmi napsal(a):
Pokud však stejnou věc udělám takto$grid->addColumn('vozidla', 'rz');
a pak v šabloně
{define col-vozidla} <td> {$row->vozidla->rz} </td> {/define}
tak je vše v pořádku.
Přesně tak (a jen tak) to má fungovat.
Mám takový zajímavý problém, který řeším. Výpis hodnoty sloupce z jiné tabulky se zdařil díky tomuto příspěvku. ALE co když budu chtít dané hodnoty i filtrovat? Možná je to asi problém NotORM přístupu na něco, na co se to tak úplně nasadit nedá.
Po callbacku $this->model->getDataSource, $this->model->getDataSourceSum aplikace spadne na PDO exception, protože sloupce dotažené z jiných tabulek přes klíč fakticky neexistují, i když je nazvu v gridu stejně.
Daný model dědící od BaseModel:
<?php
public function getDataSource($filter, $order, Paginator $paginator = NULL)
{
$selection = $this->prepareDataSource($filter, $order);
if ($paginator) {
$selection->limit($paginator->getItemsPerPage(), $paginator->getOffset());
}
return $selection;
}
public function getDataSourceSum($filter, $order)
{
return $this->prepareDataSource($filter, $order)->count('*');
}
private function prepareDataSource($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->db->table($this->table)->where($filters);
$selection->order(implode(' ', $order));
return $selection;
}
?>
Nevím si úplně rady, co s tím teď: Předělávat dotazy přes více
tabulek na views a ty poslat do gridu?
Dokázal by někdo poradit? Díky.
- secmi
- Člen | 19
Ahoj,
no já to dělám tak, že rozšířím ten if pro filtr:
<?php
foreach ($filter as $k => $v) {
if ($k === ID || is_array($v)) {
$filters[$k] = $v;
} elseif ($k == 'sloupec_cizi_tabulky') {
$filters['cizi_tabulka.sloupec_cizi_tabulky LIKE ?'] = "%$v%";
} else {
$filters[$k. ' LIKE ?'] = "%$v%";
}
}
?>
Sice používám NBD, ale myslím, že princip bude stejný.
- sd
- Člen | 87
Zdravím,
je nějaká možnost jak použít cizí klíče?
Konkrétně mám tabulku, kterou primárně vypisuji a k tomu potřebuji přidat jména uživatelů (druhá tabulka propojená cizím klíčem).. Úplně dokonalé by bylo, kdyby fungovalo i vyhledávání podle jména :).
Děkuji moc za pomoc.
Editoval sd (17. 8. 2015 1:52)