ublaboo/datagrid: mocný, rychlý, rozšiřitelný, hezký, anglicky dokumentovaný datagrid
- jAkErCZ
- Člen | 322
ali napsal(a):
@ondrejd bohuzel nepomohlo
U mě tohle řeším takto:
$grid->addActionCallback('pdf', 'PDF')
->setIcon('edit')
->setClass('btn btn-xs btn-info')
->onClick[] = function($item_id) {
$this->orderPresenter->renderPdf($item_id);
};
public function renderPdf($e_order_id){
// Vytváření šablony pro PDF.
/** @var Template $template */
$template = $this->createTemplate();
$template->setFile(dirname(__FILE__) . self::PDF_TEMPLATE);
$order = $this->fillTemplateWithOrderDetail($template, $e_order_id);
// Render PDF.
$mPdf = new mPDF();
$mPdf->WriteHTML(file_get_contents(dirname(__FILE__) . self::CSS_PDF_TEMPLATE), 1);
$mPdf->WriteHTML($template, 2);
// Return PDF.
$mPdf->Output('Faktura_' . $order[OrderManager::COLUMN_NUMBER] . '.pdf', 'D');
$this->terminate();
}
A funguje mi to bez jakýkoliv problémů :)
Třeba ti to nějak pomůže :)
Editoval jAkErCZ (20. 2. 2019 13:36)
- pavel_4
- Člen | 13
Ahoj, mám problém s filtrováním a řazením najednou u filtru mimo
grid.
Popis problému: vyfiltruju v gridu např jméno, pak seřadím podle názvu a
filtr se smaže. Pokud filtruju podle názvu, pak dám refresh stránky, tak
řazení funguje normálně. Pokud ale něco přidám do filtru a seřadím, ve
filtru se objeví minulá hodnota.
Dělá to i v examplu https://ublaboo.org/datagrid/filter#…. Jde tohle nějak
ošéfovat?
- d@rkWolf
- Člen | 167
@PavelJanda
Zdravím, dokázal by mi někdo poradit, kde může být problém s Tree-view,
zobrazím první úroveň, najde to položku, kde je podúroveň ale kliknutím
na to rozbalovací tlačítko místo, aby se rozbalily položky, se mi načte
znovu Tree-view jen s tou podúrovní.
Nejsem si jistý, zda to Tree-view nevyžaduje nějaký JS, který nemám, nebo něco podobného. Dokumentace je v tomhle poněkud nejasná-ukázka jen s Dibi taky moc nepomáhá. Vůbec nevím, kde hledat problém.
Tabulka je „pages“, nejvyšší úroveň má „parent“=0.
Používám pro setDataSource(mám to ve funkcích v modelu):
<?php
return $this->db->table('pages')->where('parent', 0);
?>
A potom pro Tree-view getChildren:
<?php
return $this->db->table('pages')->where('parent', $parentId);
?>
a hasChildren:
<?php
return $this->db->table('pages')->where('parent', $parentId)->count() > 0 ? true : false;
?>
v setTreeView mám toto:
<?php
$grid->setTreeView([$this, 'getChildren'], [$this, 'hasChildren']);
?>
Editoval d@rkWolf (28. 2. 2019 16:53)
- d@rkWolf
- Člen | 167
@PavelJanda Jo, nette.ajax funguje(mám ajaxované stránky adminu), mám tam jen $.nette.init(); , nic dalšího zatím , JS soubory mám připojení jquery3, nette ajax.js, history.ajax, datagrid.js, datagrid-instant-url-refresh.js, datagrid-spinners, happy.js, bootstrap-select.js + v balíku nějaké výchozí min scripty k admin šabloně, žádný js error v konzoli
- Pavel Janda
- Člen | 977
1, Jak mám uvést tady ve fóru tvůj nick v mention, když obsahuje
zavináč? :D
2, Mohl bys, prosím, zkusit sestavit sandbox-like repozitář, který by měl
tohle rozbité? Třeba nad nějakou sqlite databází v repozitáři.
Díky! 👍
- Croc
- Člen | 270
Zdravím,
je možné nějakým způsobem navázat vlastní JS na datagrid, který se vždy
spustí při jeho překreslení? Například po kliku na sort nějakého
sloupce? Jde o to, že po zobrazení datagridu provádím pomocí JS nějaké
operace a po sortování jsou data zase původní (JS po sortování
neproběhne).
Díky moc!
- Jurix
- Člen | 11
Croc napsal(a):
Zdravím,
je možné nějakým způsobem navázat vlastní JS na datagrid, který se vždy spustí při jeho překreslení? Například po kliku na sort nějakého sloupce? Jde o to, že po zobrazení datagridu provádím pomocí JS nějaké operace a po sortování jsou data zase původní (JS po sortování neproběhne).Díky moc!
čau, to by neměl být problém, ne? Řešil bych v jQuery nějak takto…
$(".datagrid a.sort").click(function(){
tvoje_funkce();
});
- Croc
- Člen | 270
Díky za typ, vyzkouším.
Aktuálně jsem zkoušel tuto cestu:
// v komponentě pro datagrid
$grid->onRedraw[] = function () use ($presenter) {
$presenter->redrawControl('xyz');
};
// v šabloně komponenty
{control datagrid}
{snippet xyz}
<script>
// můj script
</script>
{/snippet}
Snippet se refreshne a JS kód se spustí. Problém je, že ještě
předtím, než se překreslí samotný grid (respektive se překreslí snippet
xyz
a pak až snippet datagridu samotného). Potřeboval bych to
opačně…
EDIT: Vyzkoušel jsem, je tam vlastně stejný problém. Spustí se to hned po kliku, ale potřebuju tu funkci spustit až když jsou hodnoty v datagridu překresleny.
Editoval Croc (7. 3. 2019 9:22)
- Felix
- Nette Core | 1197
v6.0.0 – roadmap
Nova rada datagridu se pripravuje, budeme radi kdyz se zapojite, ukolu je tam dost.
- dady
- Člen | 12
Ahoj,
jako datasource datagridu předhazuji toto:
$queryBuilder
->select('c as company, c.id as id, c.name as name')
->addSelect('AVG(r.rating) as averageRating');
Existuje možnost, jak řadit podle sloupce averageRating?
EDIT:
Řešení jsem nakonec našel přes metodu setSortableCallback
nad sloupcem.
Editoval dady (8. 3. 2019 12:42)
- Croc
- Člen | 270
Zdravím,
mohu se prosím zeptat, z jakého důvodu se po načtení stránky
s datagridem volá ajaxový požadavek refresh-state?
Je nějaká možnost, jak zamezit tomu aby se volal?
Všude využívám datagrid plnohodnotně, kromě jedné stránky. Na té stránce se může vyskytovat 0-n datagridů (bez filtru, pouze zobrazení hodnot s paginatorem a sortem). V tomto případě se refresh-state zavolá jen pro ten první datagrid.
Rád bych se v tomto případě volání refresh-state zbavil, protože co jsem vypozoroval pro toto použití nemá žádnou funkci a navíc mi ukončí moje předchozí ajaxové volání, které potřebuji vykonat po načtění stránky.
$grid->setPagination(true);
$grid->setRememberState(true);
$grid->setStrictSessionFilterValues(false);
$grid->setAutoSubmit(false);
$grid->setRefreshUrl(false);
Moc děkuju
EDIT: Nakonec vyřešeno ostraněním
datagrid-instant-url-refresh.js
a nastavením
$grid->setRefreshUrl(false);
.
Editoval Croc (14. 3. 2019 9:31)
- d@rkWolf
- Člen | 167
@PavelJanda Jo tak to s tím nickem fakt netuším :D, už ho mám dost dlouho a myslím, že když sem ho zakládal, fórum tuhle funkci ani nemělo
Každopádně jsem se v tom trošku vrtal, bohužel nahodit ukázku se mi ještě nepodařilo, ale zdá se, že za to může JS, on se mi totiž provede ten XHR co by se provést měl k otevření té pod-úrovně, ale zároveň se hned potom provede normální přesměrování a načte se ta samotná podkategorie. V JS se neukazuje žádná chyba, v demu Datagridu jsem nezjistil verzi Nette.ajax, protože je to tam minifikované, abych to srovnal s tou, kterou používám já (2.3.0 asi ta poslední v releasech na githubu) a která jinak teda funguje, protože ajaxové přepínání stránek jde bez problému.
EDIT: 14.3.
Tak jsem na to přišel, předtím jsem to četl špatně-problém je Nette.ajax History, přesněji tohle(z návodu k rozšíření – https://componette.org/…ette.ajax.js):
To correctly update UI, use snippets. If you plan to ajaxify whole application, consider adding this snippet to your beforeRender() method in BasePresenter.
if ($this->isAjax()) {
$this->invalidateControl(‚title‘);
$this->invalidateControl(‚content‘);
}
Já tam mám tohle přidané, protože jsem to chtěl celé zajaxovat-a teď teda nevím, jak to vyřešit, když to zruším, tak funguje správně datagrid, ale nepřepnu stránky z menu a opačně.
Jak detekovat, zda jde o standardní ajaxový požadavek vs. požadavek od Datagridu?
Editoval d@rkWolf (14. 3. 2019 12:34)
- Pavel Janda
- Člen | 977
Teoreticky bys mohl odchytit v before ten request a zjistit, zda se
tlačítko nachází uvnitř nebo vně scopu .datagrid
? :D
- jAkErCZ
- Člen | 322
Mám dotaz v dokumentaci máš napsané že při změně itemu v gridu má být použit spinner ale u mě nefunguje. Mám změnu statusu která je závislá na příjem dat které vrátí zpět a občas to trvá třeba 1–2s a v tomto rozmezí bych rád měl spinner který zamezí znovu odeslání..
Je to nějak možné?
- rumcais1
- Člen | 80
Ahoj potřebuji udělat validaci na duplicitu, ale přes dva sloupce. Jakým způsobem to pošlu do té funkce. Zkoušel jsem jako treti argument $container[‚jiny_sloupec‘]. Ale pokud je skrytý tak tu hodnotu nevytáhnu. Možná by stačilo id primary_key. Ale to nevím jak tam poslat. Díky
<?php
$grid->addInlineEdit()->onControlAdd[] = function ($container) use($grid) {
$container->addText('Start_nr', '')
->addRule([$this,'duplicityStartNr'],'Uživatelské jméno již existuje')
->setRequired(False);
}
?>
- cafesk8
- Člen | 103
Zdravím,
jestli se to tu již řešilo, tak se omlouvám, nějak to nemůžu dohledat. Mám jednoduchý datagrid se 4 sloupci.
$grid->addColumnNumber('input_price', 'Pojištěná částka')
->setSortable()
->setRenderer(function($item) {
$cislo = number_format($item->input_price,0,'',' ');
return $cislo .' Kč';
})
->setFilterText('input_price');
$grid->addColumnNumber('output_price', 'Pojistné')
->setRenderer(function($item) {
$cislo = number_format($item->output_price,0,'',' ');
return $cislo .' Kč';
})
->setSortable()
->setFilterText('output_price');
$grid->addColumnText('package_id', 'Balíček')
->setRenderer(function($item){
return $this->householdPricesRepository->findOneBy(array('id' => $item->id))->ref('package_id')->name;
})
->setSortable()
->setFilterText('package_id');
$grid->addColumnText('company_id', 'Pojišťovna')
->setRenderer(function($item){
return $this->householdPricesRepository->findOneBy(array('id' => $item->id))->ref('package_id')->ref('company_id')->name;
})
->setSortable();
Potřeboval bych při inlineAdd aby si mohl uživatel ve sloupci „package_id“ vybrat ze selectboxu právě jednu z možností, které vrátí:
$this->householdPricesRepository->findAll();
// array [0 => 'Axa - Mini', 1 => 'Axa - Opti, 2 => 'ČPP - Mini', 3 => 'ČPP - Maxi', ...]
Mám to zatím takto:
$grid->addInlineAdd()
->onControlAdd[] = function($container) {
$container->addText('input_price', '');
$container->addText('output_price', '');
$container->addText('package_id', '');
// ale tady bych potřeboval spíš něco jako $container->addSelect('package_id', $this->householdPricesRepository->findAll());
};
Předem díky pokud Vás někoho něco napadne.
Editoval cafesk8 (18. 3. 2019 10:29)
- jikki
- Člen | 73
ppar napsal(a):
jikki napsal(a):
@PavelJanda Byla tato issue nějak vyřešená prosím? Nenašel jsem řešení.
díky moc
Pavel Janda napsal(a):
@chap Toto issue je už dlouho známé. Zmínil jsem to na Nette Campu.. Vysvětlím:
1, Inline editace se vyrenderuje do formuláře rovnou (pak se jen zviditelní při kliknutí na button)
2, Pokud je tam něco required, začne celý formulář při jakékoliv akci křičet, protože má formulář obalující datagrid blbě nastavený validation scope – zahrnuje InlineEdit/Add form (tuším, že v tom tkví jádro pudla).
3, Fix by měl být jednoduchý..
Jenže!
Přesto, že si na to lidé stěžují už delší dobu, ani jeden z těch cca 20 lidí, kteří o tom mluvili, neposlal PR, nepřišel diskutovat fix, nic.
Takže!
Kdyby byl alespoň nějaký náznak spolupráce, náznak toho, že chce do problému někdo strkat prstíky, budu moc rád nápomocen. Aktuálně to však na žádném svém projektu nepotřebuji, takže nechám toto issue ještě chvilku (třeba měsíc a kus) hnít jako takový průzkum opensource společnosti. Zpětně i předem se za to omlouvám a doufám, že se třeba najde někdo, kdo zlomek času, který třeba ušetřil použitím datagridu, věnuje pokusu o fixnutí validation scope.Tak jsem trošku se posunul a zkoušel jsem zjišťovat, od jaké verze datagridu se bug objevil. verze 4.4.9 je ještě ok, verze 4.4.10 má zmíněný bug. Předpokládám, že od této verze je bug ve všech verzí. Zkoušel jsem jen některé, abych zjistil od jaké verze je chyba.
EDIT
vypadá, že je viníkem toto https://github.com/…/datagrid.js#…EDIT:
Hurááá, vyřešno. Problém dělá AJAX https://github.com/…l-refresh.js . Řešením je nenačítat tento JS a vše jede ok.
EDIT:
nesmí se inicializovat v šabloně:
<!-- Initialize nette.ajax.js after loading the DOM. --> <script> $.nette.init(); </script>
Jinak se chyba projeví
@ppar
Ahoj, zkouším to udělat to stejně, ale nefunguje mi to dobře. Když
zruším ten instant-url-refresh.js, tak se mi při použítí filteru reloadne
celá stránka, což je nežádoucí. Chová se ti to stejně?
Zjistil jsem že, když otevřu inlineAdd nebo inlineEdit a dám Cancel, tak pak
funguje filter, tak jak má, dokud nedám reset filtru.
díky
Editoval jikki (18. 3. 2019 21:33)
- petaak
- Člen | 2
Ahoj. Jak prosím řešíte problém s tím, když vám do filteru na date
(nebo daterange) uživatel zadá nějaký náhodný string? Ve všech data
source kromě ArrayDataSource totiž vyletí z metody applyFilterDateRange
výjimka DataGridDateTimeHelperException, která není nikde chycená a vyletí
tedy až ven.
Jedno z řešení je napsat si vlastní condition callback, ve kterém si to
ošetřím sám, ale přijde mi, že by to mohlo být ošetřené přímo
v gridu. Třeba tak, že pokud se nepodaří datum naparsovat, tak by se filter
vůbec neaplikoval. Má smysl připravit takový PR? Nebo něco přehlížím a
problém má nějaké jednodušší řešení?
- Michal11
- Člen | 1
Zdravím,
nějak se mi nedaří rozběhat poslední verzi DataGrid (6.0.0) s Nette 3.0. PHP mám verzi 7.3.3.
Komponentu tvořím takto:
public function createComponentSimpleGrid($name)
{
$grid = new DataGrid($this, $name);
$grid->setDataSource([['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Joe']]);
//$grid->setDataSource($this->db->select('*')->from('ublaboo_example'));
$grid->addColumnText('id', 'ID');
$grid->addColumnText('name', 'Name');
}
Při spuštění mi to pak hodí chybu „Cannot call constructor“ v souboru „\vendor\ublaboo\datagrid\src\DataGrid.php:402“
400: public function __construct(?IContainer $parent = null, ?string $name = null)
401: {
402: parent::__construct();
Dělám něco špatně? Díky.
- Šaman
- Člen | 2659
Ahoj, je někde kompletní repozitář s funkčním demem? I když stáhnu všechny závislosti bowerem, tak výsledek nevypadá jako v demu (například tam úplě chybí šipky ohledně řazení, multiselect je rozrolovaný a nejde to zrušit [v bootstrap4], chybí onačení vybraných položek) a navíc se mi stáhne Bootstrap4, který pro multiselectboxy potřebuje ještě dalši knihovnu popper.js, ale i kdyz ji přidám, není výsledek uspokojující. Závislosti budu mít stejně v repozitáři, tak bych si rád natahal přesně ty, které používá demo. Zajímavé je, že vše vypadá funkční, ale jakoby mi tam chyběly nějaké CSS. Díky.
Editoval Šaman (4. 4. 2019 14:46)
- d@rkWolf
- Člen | 167
@Šaman S těma závislostma sem taky bojoval-na multiselect potřebuješ Bootstrap-select pro BS4 ( https://developer.snapappointments.com/…strap-select )
nakonec sem došel k CSS:
happy.min.css
bootstrap-select.min.css
datagrid.css
datagrid-spinners.css
a JS:
happy.min.js
jquery-ui-sortable.min.js
jquery.ui.touch-punch.min.js
datagrid.js
datagrid-instant-url-refresh.js
datagrid-spinners.js
bootstrap-select.min.js
plus jquery, samotný bootstrap 4, nette.ajax apod.
Repozitář s aktuální funkční verzí dema by nebyl na škodu.
Editoval d@rkWolf (4. 4. 2019 14:54)
- Šaman
- Člen | 2659
Díky. Tohle všechno jsem tam měl, ale asi byl problém ve fontu na šipky a glyphy.
Teď ale řeším ještě dvě věci na multiselectech (ale obecně to platí i pro selecty):
- mám tabulku nějakych vědeckych dat, které mohou obsahovat všechny možné znaky (nějaké geny dejme tomu)
- vytvořím si multiselect tím, že si načtu všechny unikátní hodnoty ze sloupce, seřadím a fetchPairs
- ale pokud obsahuje prázdnou hodnotu, filtr na ni nereaguje. Chtěl jsem si to řešit vlastní podmínkou (namísto LIKE nějaké IS NULL), ale zjistil jsem že se mi ani nevrátí hodnoty.
<?php
$columnGen1= $grid->addColumnText('gen_1', 'gen_1');
$columnGen1->setFilterMultiSelect(
$this->db->table('foo')
->select('gen_1')
->order('gen_1')
->fetchPairs('gen_1', 'gen_1')
)->setCondition(function($fluent, $values) {
// $fluent->where('name NOT LIKE %like', $value);
bdump($values); // <- dumpne se jen při zaškrtnutí neprázdné možnosti, i když v selectu se zaškrtne správně
});
?>
Teď to zkusím obejít nějakou zástupnou hodnotou, která by se v daném sloupci neměla vyskytovat, ale není to zrovna čisté řešení (navíc obecně tam může být jakákoliv hodnota). Dá se nějak vynutit odesláni hodnot (i prázdných) při každé změně toho selectboxu? (Mimochodem, pokud zaškrtnu nějakou další nenulovou možnost A tu nulovou, vyberou se mi i prázdné buňky, což je správně. Ale nefunguje zaškrtnout jen tu prázdnou možnost – nestane se nic.)
A druhá věc je, že pokud mám již nějaký filtr aplikovaný, je trochu
WTF že v ostatních multiselectech jsou všechny možné hodnoty, ačkoliv
s aktuálním filtrm nedávají smysl. Měl bych tedy při každém
překreslení také upravit hodnoty v selectboxech. Jak ale získám všechny
aktuální filtry celého datagridu? Nějak jsem to v dokumentaci nedohledal,
umím získat jen filtry jednotlivých sloupců. To by sice asi stačilo, ale
předpokládám, že to jde i elegantněji.
Díky.
Editoval Šaman (5. 4. 2019 0:18)
- jikki
- Člen | 73
Ahoj,
pomůže někdo vyřešit problém s filtry vs InlineAdd/Edit prosím? Sám
to nezvládnu.
https://github.com/…d/issues/762
Děkuji
- Felix
- Nette Core | 1197
ondrusu napsal(a):
Ahojte, slyšel jsem, že nové Nette 3.0 už nepodporuje
Kdyby\Doctrine
, ale mají náhraduNetrine\ORM
. Bude tento datagrid podporovat i tuhle knihovnu? Případně v jaké verzi se o očekává.Díky
ublaboo/datagrid podporuje obecne Doctrine, tzn. jakoukoli implementaci, ktera je postavena na Doctrine.
ali napsal(a):
@ondrusu Netterine muzes pouzivat s Datagridem jiz nyni
Presne tak. Uz to normalne pouzivame asi rok a pul. ;-)
- TonnyVlcek
- Člen | 31
TL;DR:
Reset stavu filtrů všech datagridů na jejich defaultní filtr, při jedné
události v aplikaci (změna oddělení).
Ahoj,
funkcionalita zapamatování stavu filtrů je super protože člověk může
třeba přijít na detail, vrátit se a pokračovat kde skončil. Já bych teď
ale potřeboval při specifické události v aplikaci naráz resetnout stavy
filtrů u všech datagridů (máme v aplikaci nějaká oddělení a každé
oddělení má jiný výchozí filtr pro daný datagrid, po přepnutí
oddělení, by se to mělo resetnout na nový výchozí filtr).
Volat handleResetFilter()
nebo deleteSessionData()
jde jenom nad konkrétním db (jasně, mají jiné SessionSections).
Nápad #1:
Koukal jsem že sessionSectionName se určuje podle jména komponenty, takže by
teoreticky šlo (při vyvolání té události) proiterovat session rozpoznat
všechny které patří nějakému datagridu a u nich smazat tu informaci
o filtru.
Jenže to mi přijde jako docela hackování a magie.
Nápad #2:
Zajistit, aby se defaultní filtr neukládal do session. (tj. dokud uživatel
nezmění filtr, tak se mu při přepnutí oddělení nastaví nový filtr,
pokud změní, tak se filtr zachová)
Toho bych bez nějakého extendování a přepisování vnitřností
datagridu asi nedosáhnul, takže to asi taky není schůdná cesta
Napadá vás prosím někoho jak by se na to dalo jít? Dík :)
- Jurix
- Člen | 11
TonnyVlcek napsal(a):
TL;DR:
Reset stavu filtrů všech datagridů na jejich defaultní filtr, při jedné události v aplikaci (změna oddělení).
Ahoj,
funkcionalita zapamatování stavu filtrů je super protože člověk může třeba přijít na detail, vrátit se a pokračovat kde skončil. Já bych teď ale potřeboval při specifické události v aplikaci naráz resetnout stavy filtrů u všech datagridů (máme v aplikaci nějaká oddělení a každé oddělení má jiný výchozí filtr pro daný datagrid, po přepnutí oddělení, by se to mělo resetnout na nový výchozí filtr).Volat
handleResetFilter()
nebodeleteSessionData()
jde jenom nad konkrétním db (jasně, mají jiné SessionSections).Nápad #1:
Koukal jsem že sessionSectionName se určuje podle jména komponenty, takže by teoreticky šlo (při vyvolání té události) proiterovat session rozpoznat všechny které patří nějakému datagridu a u nich smazat tu informaci o filtru.
Jenže to mi přijde jako docela hackování a magie.Nápad #2:
Zajistit, aby se defaultní filtr neukládal do session. (tj. dokud uživatel nezmění filtr, tak se mu při přepnutí oddělení nastaví nový filtr, pokud změní, tak se filtr zachová)
Toho bych bez nějakého extendování a přepisování vnitřností datagridu asi nedosáhnul, takže to asi taky není schůdná cestaNapadá vás prosím někoho jak by se na to dalo jít? Dík :)
Čau,
mám v úmyslu dělat něco podobného. Rozšíření s jednoduchým
formulářem, kterým si uživatel vybere z předdefinovaných filtrů, anebo
si nadefinuje a uloží vlastní filtr (který pak bude moci sdílet). Půjdu na
to přes session, tedy podobně jak popisuješ v nápadu #1. Nevnímám to jako
hackování, už vůbec ne magii. Zkrátka přizpůsobení svým potřebám.
I když zrovna tohle je obecně zajímavá funkcionalita pro datagrid…
Ano, budeš muset do střev (extend). Nicméně později budeš rád, že máš vlastní píseček, na kterém si upravíš a rozšíříš všechno co chceš. Například detail si přímo koleduje o rozšíření a jdou s tím dělat úžasná kouzla. :)
- TonnyVlcek
- Člen | 31
@Jurix 👍 Díky, zkusím na to mrknout s tím, že bych teda extendoval.
To ukládání a sdílení filtrů je funkcionalita na kterou se v týmu plánujem vrhnout v podstatě hned tady po tomhle. Máš v plánu to někde publikovat? Případně dalo by se na tom spolupracovat, a třeba i připravit MR do ublaboo? (Asi by bylo třeba napsat to nějak pěkně obecně, aby se to nechalo zakomponovat přímo do ublaboo – moc jsem nad tím ještě nepřemýšlel, takže nemám moc srovnaný v hlavě co všechno k tomu bude potřeba.)
Editoval TonnyVlcek (3. 5. 2019 19:48)
- emil54
- Člen | 19
Zdravim ve spolek,
dějou se mi nějaký pozoruhodnosti, se kterými si nějak ne a ne poradit.
Jeden grid mi začal dneska haprovat, aniž bych mu nějak ubližoval.
Skáče na mne hláška:
Tracy:
Component with name ‚_id‘ does not exist.
`
902: <td class=„col-action col-action-inline-edit“>
903: <?php
904: $_input = is_object($filter[‚inline_edit‘][‚cancel‘]) ?
$filter[‚inline_edit‘][‚cancel‘] :
end($this->global->formsStack)[$filter[‚inline_edit‘][‚cancel‘]];
905: echo
Nextras\Forms\Bridges\Latte\Macros\BS3InputMacros::input($_input->getControl()->addAttributes([‚class‘
⇒ ‚btn btn-sm btn-danger‘]), $_input, false);
906: $_input = is_object($filter[‚inline_edit‘][‚submit‘]) ?
$filter[‚inline_edit‘][‚submit‘] :
end($this->global->formsStack)[$filter[‚inline_edit‘][‚submit‘]];
907: echo
Nextras\Forms\Bridges\Latte\Macros\BS3InputMacros::input($_input->getControl()->addAttributes([‚class‘
⇒ ‚btn btn-sm btn-primary‘]), $_input, false);
908: $_input = is_object($filter[‚inline_edit‘][‚_id‘]) ?
$filter[‚inline_edit‘][‚_id‘] :
end($this->global->formsStack)[$filter[‚inline_edit‘][‚_id‘]];
909: echo
Nextras\Forms\Bridges\Latte\Macros\BS3InputMacros::input($_input->getControl()->addAttributes([]),
$_input, false);
910: $_input =
is_object($filter[‚inline_edit‘][‚_primary_where_column‘]) ?
$filter[‚inline_edit‘][‚_primary_where_column‘] :
end($this->global->formsStack)[$filter[‚inline_edit‘][‚_primary_where_column‘]];
911: echo
Nextras\Forms\Bridges\Latte\Macros\BS3InputMacros::input($_input->getControl()->addAttributes([]),
$_input, false) ?>
912: </td>
`
Dělá to podle všeho sloupec ‚device_type‘, a to při vzestupném
třídění. Jinak se to chová vcelku mravně.
Moje teorie: nějakej znakovej bordel v některém řádku tabulky DB (Jsou to
stará data z původní aplikace za posledních 12 let…)
Budu vděčnej zakaždej postřeh…
<?php
$query = $this->database->query('SELECT crm_customer.name AS customer, crm_customer.ico AS ico, crm_device.*
FROM crm_customer
LEFT JOIN crm_device
ON crm_customer.id = crm_device.customer_id ORDER BY id DESC
')->fetchAll();
...
$grid->addFilterText('device_type', 'Search', ['device_type'])->setSplitWordsSearch(FALSE);
...
$grid->addColumnText('device_type', 'Type')
->setSortable()
->setEditableCallback(function($id, $value) {
$this->saveDevice($id, ['device_type' => $value]);
$this->flashMessage("Record has been saved");
$this->redrawControl('flashes');
});
...
$grid->addColumnText('device_type', 'Type')
->setSortable()
->setEditableCallback(function($id, $value) {
$this->saveDevice($id, ['device_type' => $value]);
$this->flashMessage("Record has been saved");
$this->redrawControl('flashes');
});
$grid->addInlineEdit()
->onControlAdd[] = function($container) {
$container->addText('type', '');
$container->addText('manufacturer', '');
$container->addText('device_type', '');
$container->addText('device_serial_number', '');
$container->addText('year_of_production', '');
$container->addText('put_into_operation', '');
};
$grid->getInlineEdit()->onSetDefaults[] = function($container, $item) {
$container->setDefaults([
'type' => $item->type,
'manufacturer' => $item->manufacturer,
'device_type' => $item->device_type,
'device_serial_number' => $item->device_serial_number,
'year_of_production' => $item->year_of_production,
'put_into_operation' => $item->put_into_operation,
]);
};
$grid->getInlineEdit()->onSubmit[] = function($id, $values) {
$values['updated_at'] = date('Y-m-d H:i:s', time());
$values['updated_by'] = $this->user->identity->id;
$result = $this->database->table('crm_device')->where("id = ?", $id)->update($values);
$this->flashMessage("The record has been changed", 'success');
$this->redrawControl('flashes');
$this['deviceGrid']->redrawItem($id);
};
?>
- chladekt
- Člen | 10
Tady https://ublaboo.org/datagrid/filter u gridu dole dam u filtru ID 1. Pak mam u gridu nahore na konci URL pro usporadani podle sloupce Name do=filtersGridOuter-sort. Stava se mi to i u meho webu. Co s tim delat? Mozna se to tu uz resilo. Blbe se to hleda.
- Pavel Janda
- Člen | 977
@chladekt To je průšvih dávání 2 gridů na 1 stránku. Buď se musí refreshovat všechny gridy na stránce (což asi nechceme, byť by to bylo ideální řešení) nebo … můžeme dát dolní grid do iframu?
- Pavel Janda
- Člen | 977
@IJVo Nezmizela. :) Jen se přejmenovala kvůli PHP 7.2 a dědičnosti. A když už jsem dělal BC break, udělal jsem ho pořádně:
$grid->setConfirm('Do you really want to delete item %d?', 'id');
->
$grid->setConfirmation(new StringConfirmation('Do you really want to delete item %d?', 'id'));
A pro callback confirmation je tam CallbackConfirmation
.
Jakmile vydám verzi 6, pustím sem celé release notes. Už je to za dveřmi!!
Editoval Pavel Janda (17. 5. 2019 10:46)
- Pavel Janda
- Člen | 977
contributte/datagrid v6 is here!
- Release včetně BC breaků: https://github.com/…s/tag/v6.0.0
- Nová dokumentace od teď zde: https://contributte.org/…te/datagrid/
- Nový DEMO repozitář naleznete zde: https://github.com/…e/playground
(
/contributte-datagrid
) - DEMO běží online zde: http://examples.planette.io/…te/datagrid/ (bude zmíněno v dokumentaci)
Contributte děkuje všem za pomoc! :)
Editoval Pavel Janda (27. 5. 2019 8:37)
- Ondřej Kubíček
- Člen | 494
musíš se podívat do dokumentace – https://contributte.org/…te/datagrid/ ten balík se
jmenuje ublaboo/datagrid
- Pavel Janda
- Člen | 977
Yess. Dokud nebude umět Composer migrovat balíčky včetně statistik stažení, tak to asi zatím necháme jako ublaboo, ovšem od hlavičkou Contributte.
Jinak vřele jako sandbox doporučuji zmíněný repozitář https://github.com/…e/playground. Ještě voní novotou.
- Pavel Janda
- Člen | 977
@kedarus
1, Myslím, že by to fungovat mělo. Zkus testnout. :)
2, Proč by nebylo? Akorát se přidá další kousek SQL..
3, Do argumentu ti přijde SQL, které si budeš muset sám upravit.
- magenzajin
- Člen | 9
Ahoj,
potřeboval bych pomoc s filtrováním podle ID. V grid se mi filtruje podle
ID jako LIKE.. potřeboval bych aby to našlo jeden záznam ke konkrétnímu
user_id… Pokusil jsem se přidat setCondition(…), ale mám červeno s
„Call to a member function where() on array“ Metoda vypadá takto:
/**
* @param $name
* @param string $primaryKey
* @return MyDataGrid
* @throws \Ublaboo\DataGrid\Exception\DataGridException
*/
protected function create($name, string $primaryKey = 'id'): DataGrid
{
$primaryKey = $primaryKey ?: ($this->repository->getTableName() . '.id');
$grid = new MyDataGrid();
$grid->strict_session_filter_values = false;
$this->addComponent($grid, $name);
$grid->setColumnsHideable();
$grid->setMultiSortEnabled();
$grid->setPrimaryKey($primaryKey);
$grid->setDataRepository($this->repository, $this->condition, $this->orderColumn);
$grid->addColumnNumber($primaryKey, 'ID')
->setFormat(0)
->addAttributes(["width" => "5%"])
->setAlign('center')
->setFilterText()
->setCondition(function ($fluent, $value){
$fluent->where('id = ?', $value);
});
$grid->setAutoSubmit(false);
$grid->getFilterSubmitButton()->setAttribute('formnovalidate')->setText('');
$grid->setDefaultPerPage(20);
$grid->setItemsPerPageList([5, 10, 20, 50]);
/**
* Localization
*/
$translator = new SimpleTranslator([
'ublaboo_datagrid.no_item_found_reset' => 'Žádné položky nenalezeny. Filtr můžete vynulovat',
'ublaboo_datagrid.no_item_found' => 'Žádné položky nenalezeny.',
'ublaboo_datagrid.here' => 'zde',
'ublaboo_datagrid.items' => 'Položky',
'ublaboo_datagrid.all' => 'všechny',
'ublaboo_datagrid.from' => 'z',
'ublaboo_datagrid.reset_filter' => 'Resetovat filtr',
'ublaboo_datagrid.group_actions' => 'Hromadné akce',
'ublaboo_datagrid.show_all_columns' => 'Zobrazit všechny sloupce',
'ublaboo_datagrid.hide_column' => 'Skrýt sloupec',
'ublaboo_datagrid.action' => 'Akce',
'ublaboo_datagrid.previous' => 'Předchozí',
'ublaboo_datagrid.next' => 'Další',
'ublaboo_datagrid.choose' => 'Vyberte',
'ublaboo_datagrid.execute' => 'Provést',
'ublaboo_datagrid.save' => 'uložit',
'ublaboo_datagrid.cancel' => 'zrušit',
'ublaboo_datagrid.add' => 'přidat záznam',
'ublaboo_datagrid.edit' => 'upravit',
'ublaboo_datagrid.show_default_columns' => 'Zobrazit výchozí sloupce',
'Name' => 'Jméno',
'Inserted' => 'Vloženo'
]);
$grid->setTranslator($translator);
try {
if ($this->permission->isAllowedUser($this->getPresenter()->name, Permission::DEL)) {
$grid->addDelete()->setConfirm('Opravdu chcete odstranit řádek ID: %s?', $primaryKey);
}
} catch (PermissionException $e) {
} catch (DataGridException $e) {
}
return $grid;
Jak s tím????
Díky moc!
Editoval magenzajin (5. 6. 2019 14:18)
- Pavel Janda
- Člen | 977
@magenzajin
$grid->addColumnNumber($primaryKey, 'ID')
->setFilterText()
->setExactSearch()
:)