ublaboo/datagrid: mocný, rychlý, rozšiřitelný, hezký, anglicky dokumentovaný datagrid
- Pavel Janda
- Člen | 977
@sibka
Nová malá verze – v3.1.0
Přidal jsem $column_callbacks
. To je pidivěc, která dovolí
šáhnout na sloupce těsně před vyrenderováním položek. Ukázka:
$grid->addColumnLink('link', 'Link', 'this#demo', 'name', ['id', 'surname' => 'name']);
$grid->addColumnStatus('status', 'Status')
->addOption(1, 'Online')
->setClass('btn-success')
->endOption()
->addOption(2, 'Standby')
->setClass('btn-primary')
->endOption()
->addOption(0, 'Offline')
->setClass('btn-danger')
->endOption()
->onChange[] = [$this, 'changeStatus'];
$grid->addColumnCallback('status', function($column, $item) {
if ($item->id == 2) {
$column->removeOption(2);
}
});
$grid->addColumnCallback('link', function($column, $item) {
if ($item->id == 2) {
$column->setRenderer(function() {
return '';
});
}
});
Tento příklad odebere option s hodnotou 2 pro položku s id == 2. Pro stejnou položku bude chybět sloupec s odkazem.
Lze manipulovat se všemi sloupci..
Dokumentace zde.
Editoval Pavel Janda (24. 3. 2016 10:28)
- pitr82
- Člen | 121
@PavelJanda Ahoj, jedu na masteru a přestalo mi fungovat potvrzování u akcí :
$grid->addAction('disable', '', 'disable!')
->setIcon('lock')
->setTitle("sdsdsd")
->setClass('btn btn-xs btn-warning ajax')
->setConfirm("Opravdu chcete odstranit");
Do html vygeneruje data-datagrid-confirm ale javascript se nezavolá
$grid->addAction('enable', '', 'enable!')
->setIcon('unlock')
->setTitle($this->translator->translate('admin.userGrid.enable'))
->setClass('btn btn-xs btn-success ajax')
->setConfirm(function($item) {
return "Id: $item->id - Opravdu odstaranit?";
Tak mi skončí chybou:** Illegal offset type in isset or empty **
/datagrid/src/Localization/SimpleTranslator.php:60
Změnilo se něco ?
- Pavel Janda
- Člen | 977
@pitr82 Omlouvám se, zapomněl jsem return
..
Přesně proto strávím víkend nad psaním testů.
Editoval Pavel Janda (24. 3. 2016 12:32)
- pitr82
- Člen | 121
Pavel Janda napsal(a):
@pitr82 Omlouvám se, zapomněl jsem
return
..Přesně proto strávím víkend nad psaním testů.
Prosímtě, nezmizel „data-datagrid-confirm“ z javasriptu ?
Neprovede se mi vyskakovací okno… aktualizoval jsem bover a vybral jsem verzi
nette-forms 2.3.0
nette-forms#>= 2.3.0 which resolved to 2.3.8 and is required by ublaboo-datagrid#2.3.11
- jurajvt
- Člen | 18
Ak agregujem dáta z cudzej tabuľky, paginator dostane nesprávne výsledky.
$orders = $this->arrived->findAll()
->select('SUM(arrived.weight) AS weight_sum')
->select('order.id, order.code AS order_code, order.amount AS order_amount')
->group('order_id');
Výsledkom sú dva dotazy:
SELECT COUNT(arrived.id)
FROM arrived
SELECT SUM(weight) AS weight_sum, order.id, order.code AS order_code, order.amount
AS order_amount
FROM arrived
LEFT JOIN order ON arrived.order_id = order.id
GROUP BY order_id
Správne by sa mali počítať výsledky po agregácii.
V Grido sa to dá vyriešiť takto:
$grid->model->callback['getCount'] = function() use ($orders) {
return $orders->count();
};
Ako to riešiť v tomto Datagrid-e?
Inak, Pavel – veľmi dobrá práca. Ďakujem.
Editoval jurajvt (26. 3. 2016 23:28)
- pitr82
- Člen | 121
Ahoj,
u statusu, když ho nechci odeslat ajaxově, nastavím
->setClass('btn-primary', 'btn btn-default btn-xs')
tak se mi zruší ajax u třídy button, ale ne
u a
pořád se to odesílá ajaxově
<div class="dropdown">
<button class="dropdown-toggle btn-danger btn btn-xs" type="button" data-toggle="dropdown">
Neaktuální </button>
<ul class="dropdown-menu">
<li>
<a **class="ajax"** href="#">
Aktuální
</a>
</li>
<li>
<a **class="ajax"** href="#">
Neaktuální
</a>
</li>
</ul>
</div>
- Pavel Janda
- Člen | 977
@Dark0ne Doporučuji si vytvořit vlastní template datagridu. Nebo
jen upravit. Já, pokud potřebuji responzivní administraci například,
vytvořím si vlastní template, kde vůbec nefiguruje element
<table>
.
- Dark0ne
- Člen | 47
@PavelJanda Díky za radu. Ještě jsem se chtěl zeptat, najednou mi začal blbnout filtr na datum. Stává se to, že když kliknu pro výběr konkrétního data z kalendáře, tak asi za sekundu se refreshne stránka a ten výběr zmizí a člověk tam musí najet znovu. Netušíš, čím by to mohlo být?
Editoval Dark0ne (2. 4. 2016 12:59)
- Pavel Janda
- Člen | 977
@Dark0ne To nevím. Na webu se to neděje. A nemělo by – sám datagrid překresluje při filtrování pouze vypisovaná data (+ stránkování) a nikoliv filtry. Právě proto, aby zůstal focus na inputech filtrů. Nepřekresluješ někde celý control manuálně?
- Pavel Kouřil
- Člen | 128
Pavel Janda napsal(a):
@PavelKouřil
1, No že by se mi chtělo používat pro templaty filtrů statické proměnné, to se říct nedá.
Konečně jsem se vrátil k projektu kde datagrid používám, a chci se vrátit k tomuto :)
Nešlo by ty filtry mít nějak taky na to přetížení vlastní šablonou?
Např. předefinování bloku {filterDateRange}
; a nebo
nastavování templatu filtru v gridu, a možnost konfigurace gridu
s vlastními defaultními templates filtrů.
- Pavel Kravčík
- Člen | 1195
Když nejdříve filtruji a pak řadím, přijdu o filtr. I v demu. To je feature? :)
- Pavel Janda
- Člen | 977
@PavelKouřil DataGridí filtry mohou mít vlastní šablonu. Co se týče definice šablon filtrů pomocí bloků, přidávám to do issues na githubu, taky se mi to líbí.
- Pavel Janda
- Člen | 977
@PavelKravčík Heh, díky. To je tím, že se nepřerenderovávají ajaxově ty sortící odkazy. Ale po druhém a dalším kliknutí už to zas jede. :D Fixnu o víkendu.
- Pavel Kravčík
- Člen | 1195
@PavelJanda: V pohodě díky, já už jim to vysvětlil jako feature, že si mají nejdřív řadit a pak až filtrovat a neotravovat programátory. :D
- Pavel Janda
- Člen | 977
@PavelKravčík :D Ježiš. Tak to opravím ještě dneska večer.
Editoval Pavel Janda (8. 4. 2016 15:04)
- Pavel Kravčík
- Člen | 1195
@PavelJanda: Nadsázka. :) Ví o tom, jak to dočasně obejít, sám se na to chtěl podívat hlouběji v neděli, pokud by to byla feature. Takže určitě se běž někam bavit radši večer.
- Pavel Janda
- Člen | 977
@pitr82 v3.1.5
Docílíš toho metodou
Status\Option::setClassInDropDown('' /* Nebo tvoje jina trida */)
:
$status->addOption(1, 'Online')
->setClassInDropDown(NULL); // By default 'ajax'
- Petr Steinbauer
- Člen | 26
Zdravím, je možné v doplňkové šabloně
`$grid->setTemplateFile(__DIR__ . '/templates/Datagrid/user.latte');
`
zavolat/vytvořit formulář?
Tedy cca toto:
{extends $original_template}
{block detail}
{control userDescription}
{/block}
Zkoušel jsem createComponentUserDescription
narvat všude
možně, dokonce i do BasePresenter.php
ale nedaří se.
Je vůbec možno zde použít formulář? A pokud ano, jak?
- Pavel Janda
- Člen | 977
@PetrSteinbauer To jistě takto nelze – formulář je vytvářen nad rodičovskou komponentou, tedy aktuálně DataGridem. Momentálně je nejjednodušší podědit si DataGrid, kde si vytvoříš továrničku formuláře.
Pokud vymyslíš nějaký podnětný příklad a ještě někdo se připojí s prosbou o implementaci nějakého dynamického řešení, založ issue na takovou feature.
Editoval Pavel Janda (11. 4. 2016 15:28)
- Petr Steinbauer
- Člen | 26
@PavelJanda
pokusím se to sepsat ještě jednou sem jako před-schválení:
Využívám vestavěnou ublaboo šablonu (oko) jako náhled na
uživatele – takový letecký panel.
Zobrazuji stav objednávek, a další stavy. Nově si zadavatel vymyslel, že by
rád přidával body přímo odsud a rovněž by si rád měnil stavy
objednávek odsud a také by rád připisoval poznámku k uživatelu.
Vše v této části a přijde mi to i logické. Takto to vypadá
vizuálně:
Bohužel to však nepůjde, v implementované šabloně nemohu použít nic
z tohoto:
<a n:href="Eshop:vyrobek"></a>
{Strings::webalize($item->title)}
<form n:name>
{control jmenoFormulare}
<a n:href="signal!"></a>
Předpokládám, že toto využití náhledu (jako „leteckého panelu“) by jistě využilo více lidí. Co vy na to?
- Pavel Janda
- Člen | 977
@PetrSteinbauer Tak pojďme to probrat bod po bodu:
- Makro
n:href
nelze používat, protože v komponentě se odkazuješ právě na tu komponentu. Musíš použít makroplink
, pokud chceš odkázat na presenter. To platí pro celé Nette a všechny komponenty, najdeš to v dokumentaci Nette. - Chybí ti tam namespace, hádám:
{Nette\Utils\Strings::webalize($item->title)}
- To už jsem psal v bodě 1
Je pravda, že bych mohl nějak udělat dynamické načítání component
ještě v datagridu. Zapřemýšlím nad tím. Do té doby (jak jsem už psal)
si můžeš jednoduše podědit DataGrid
a v tvé třídě
(class MyGrid extends Ublaboo\DataGrid\DataGrid
) si vytvoříš
továrnu potřebného formuláře. Pravděpodobně budeš časem chtít použít
i Nette\Application\UI\Multiplier
, k tomu třeba ještě napíšu
nějakou ukázku.
Super, tohle hoď do issue, akorát odeber ty odkazy a použití statické metody Strings::webalize.. :)
Editoval Pavel Janda (11. 4. 2016 21:12)
- Petr Steinbauer
- Člen | 26
@PavelJanda děkuji.
Potvrzuji, že body 1 a 2 jsou tak jak říkáš.
Dědění Datagridu: snad to zvládnu, návod je dost podrobný.
Issue jsem upravil pravopisně a odeslal.
Děkuji.
- exquis
- Člen | 83
Tušíte proč by mi mohl datagrid při exportu do CSV vyhazovat chybu:
Component '' is not attached to 'Nette\Application\UI\Presenter'
Kod:
function createComponentVyhledavaniNaWebu()
{
$Grid = new DataGrid();
$Grid->setDataSource($this->Searching->getTblSearching()->getAll());
$Grid->setItemsPerPageList($this->itemsPerPage);
$Grid->setDefaultSort(array("date" => "DESC"));
$Grid->addColumnDateTime("date", "Datum")->setSortable();
$Grid->addColumnText("term", "Pojem")->setSortable()->setFilterText();
$Grid->addColumnText("url", "Na URL")->setSortable()->setFilterText();
$Grid->addColumnText("ip", "Počet hledání")->setSortable()->setFilterText();
$Grid->addExportCsv('EXPORT', 'examples.csv');
return $Grid;
}
- Pavel Kravčík
- Člen | 1195
@exquis:
function createComponentVyhledavaniNaWebu($name)
{
$Grid = new DataGrid($this, $name);
Předpokládám, že na poslání souboru CSV je potřeba response a ta je navázána na presenter.
- Petr Steinbauer
- Člen | 26
@exquis : pěkná náhoda:
teď jsem viděl zmíněnou chybu:
Component '' is not attached
– měl jsem 2× jsAjax pracování
za sebou (v base a presentu) – jedno jsem vyřadil a vyřešeno. Asi to
nebude to samé, že ne?
- exquis
- Člen | 83
Petr Steinbauer napsal(a):
@exquis : pěkná náhoda:
teď jsem viděl zmíněnou chybu:Component '' is not attached
– měl jsem 2× jsAjax pracování za sebou (v base a presentu) – jedno jsem vyřadil a vyřešeno. Asi to nebude to samé, že ne?
bohužel, u mně je spouštěč přidání „$Grid->addExportCsv(‚EXPORT‘, ‚examples.csv‘);“ do kódu, dokud to tam není, tak vše běhá bez problému. Chybu vyhazoval už na verzích okolo 2.1.(nevím přesně), kdy byl export již zabudován, ale myslel jsem, že je to někde má chyba, tak jsem to neřešil s tím, že to zkusím později.
Bohužel ani později se to nepovedlo.
- pitr82
- Člen | 121
Pavel Janda napsal(a):
@PetrSteinbauer Tak pojďme to probrat bod po bodu:
- Makro
n:href
nelze používat, protože v komponentě se odkazuješ právě na tu komponentu. Musíš použít makroplink
, pokud chceš odkázat na presenter. To platí pro celé Nette a všechny komponenty, najdeš to v dokumentaci Nette.- Chybí ti tam namespace, hádám:
{Nette\Utils\Strings::webalize($item->title)}
- To už jsem psal v bodě 1
Je pravda, že bych mohl nějak udělat dynamické načítání component ještě v datagridu. Zapřemýšlím nad tím. Do té doby (jak jsem už psal) si můžeš jednoduše podědit
DataGrid
a v tvé třídě (class MyGrid extends Ublaboo\DataGrid\DataGrid
) si vytvoříš továrnu potřebného formuláře. Pravděpodobně budeš časem chtít použít iNette\Application\UI\Multiplier
, k tomu třeba ještě napíšu nějakou ukázku.Super, tohle hoď do issue, akorát odeber ty odkazy a použití statické metody Strings::webalize.. :)
Taky bych se přikláněl nějaké ukázce… Díky
- CZechBoY
- Člen | 3608
Tak jsem taky podlehl a konečně zkouším tento datagrid ;-)
Zkouším tu mini editaci a chtěl bych si dát místo textarea obyčejnej input[type=text]. Dokumentace se zmiňuje o
->setEditableInputType('text', ['class' => 'form-control']);
jenže žádnou takovou metodu mi php nenajde :(
Call to undefined method Ublaboo\DataGrid\Column\ColumnText::setEditableInputType().
- Pavel Janda
- Člen | 977
@CZechBoY Zatím je to v masteru, během pár dní (možná dnes) vyjde v3.2. V té to bude otagované.
- tatyalien
- Člen | 239
Ahoj,
mám dotaz, v projektech používám Dibi, ale nepoužívám fluent a DibiRow.
Sql si poskládám a vracím entity:
function getExampleData(){
$sql = '....';
$resource = $this->connection->query($sql);
$resource->setRowFactory(array($this, 'getRow'));
$data = $resource->fetchAll();
$resource->free();
return $data;
}
public function getRow($data)
{
$entity = new ExampleEntity();
$entity->hydrate($data);
return $entity;
}
ExampleEntity:
class ExampleEntity
{
private $id;
private $user;
//getter / setter
}
Jde to nějak napojit na datagrit? Nechtěl bych zbytečně data předávat do pole…
- Pavel Janda
- Člen | 977
@tatyalien Stačí si napsat vlastní datasource, který bude
implementovat Ublaboo\DataGrid\DataSource\IDataSource
(sortění,
filtrování, limitění apod, klasika).
Pokud s tím máš velký problém, můžeš dát někde na github svůj (kompletnější) způsob získávání dat a já se pokusím nastínit implementaci datasourcu.
Editoval Pavel Janda (17. 4. 2016 22:04)
- Pavel Janda
- Člen | 977
Nová verze – v3.2.0
- Schování sloupce by default (http://ublaboo.paveljanda.com/datagrid/column#…)
- Text input u group actions (http://ublaboo.paveljanda.com/…group-action?…), thx @Attanon
- Malá inline editace není limitována pouze na
<textarea>
; libovolné html atributy inputu malé editace (http://ublaboo.paveljanda.com/datagrid/edit#…) - Definice šablony filtru je již možná i pomocí bloku (http://ublaboo.paveljanda.com/datagrid/filter#…), @PavelKouřil
ItemDetail
může obsahovat vlastní formulář (http://ublaboo.paveljanda.com/datagrid/action#…) :), @PetrSteinbauer- Další maličkosti/fixy
Díky všem za nápady a spolupráci!
Editoval Pavel Janda (17. 4. 2016 22:32)
- Pavel Janda
- Člen | 977
Nová verze – v3.3.0
- Inline přidávání záznamů, http://ublaboo.paveljanda.com/datagrid/add
- David Grudl
- Nette Core | 8227
Narazil jsem na drobnost. Když filtru nastavím hodnotu:
$grid->addColumnText('status', 'Stav')
->setFilterSelect([...])
->setValue('value');
tak se sice zohlední při filtrování, ale ne při vykreslení selectboxu.
Btw, filtrování přes multiselect by bylo taky fajn.
- Pavel Janda
- Člen | 977
@DavidGrudl Metoda Filter::setValue()
je určena spíš
pro interní účely.. V momentě, kdy uživatel vyplní filtr
v prohlížeči, DataGrid
řekne filtru, že má nastavenou
hodnotu (::setValue()
) a data source si pak o tuto hodnotu řekne
($filter->isValueSet()
,
$filter->getCondition()
).
Píšu si issue – nastavení defaultních hodnot filtru.
Nějaké nápady na ověřenou JS knihovnu, která zpříjemní práci s multiselectem?
Editoval Pavel Janda (19. 4. 2016 9:20)
- Pavel Kouřil
- Člen | 128
Pavel Janda napsal(a):
Nová verze – v3.2.0
- Definice šablony filtru je již možná i pomocí bloku (http://ublaboo.paveljanda.com/datagrid/filter#…), @PavelKouřil
Skvělé!
Ale pořád se nedají změnit např. všechny filtry typu daterange, že?
Řídí se to podle parametru key
v metodách jako
addFilterDateRange()
, pokud jsem dobře pochopil?
- CZechBoY
- Člen | 3608
@PavelJanda Mně se celkem líbí https://silviomoreto.github.io/…ct/examples/ a neměl jsem s nim ani moc problémů :-)
- Pavel Janda
- Člen | 977
@PavelKouřil Ano, je to tak. Upřímně, do teď mi nedošlo, že by to mělo jít nastavit i takto globálně pro stejný TYP filtrů. Píšu si issue..
- Pavel Janda
- Člen | 977
@PavelKouřil Tak je to zatím v masteru. Dám to do další verze. Použití:
- Nastavíš šablonu, která extendí tu původní
- Každý filtr má svůj typ (
Filter::getType()
), jak se jmenuje si lze domyslet (text
,select
, …), nebo najít v property toho kterého filtru. - Nadefinuješ blok typu filtru:
{block filtertype-text}...{/block}
,{block filtertype-select}...{/block}
, …
Editoval Pavel Janda (19. 4. 2016 10:06)