ublaboo/datagrid: mocný, rychlý, rozšiřitelný, hezký, anglicky dokumentovaný datagrid

ali
Člen | 342
+
0
-

Nakonec jsem to vyresil redirectem na action, kde se ten download provede jiz normalne, @PavelJanda netusis proc se tohle stava?

jAkErCZ
Člen | 322
+
+1
-

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
+
0
-

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
+
0
-

@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)

Pavel Janda
Člen | 977
+
0
-

@d@rkWolf Určitě je potřeba datagrid.js.. funguje ti jinak nette.ajax.js?

d@rkWolf
Člen | 167
+
0
-

@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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
+4
-

v6.0.0 – roadmap

Nova rada datagridu se pripravuje, budeme radi kdyz se zapojite, ukolu je tam dost.

http://bit.ly/2ELrEvg

dady
Člen | 12
+
0
-

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
+
+1
-

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
+
0
-

@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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

@Š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
+
0
-

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
+
+2
-

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

Petr Parolek
Člen | 455
+
-6
-

Ahoj, taky by mě zajímalo, kdy se toto opraví konečně

jikki
Člen | 73
+
0
-

Zkoušel jsem vypnout autoSubmit a nastavit tomu tlačítku validationScope na filter container, ale nefunguje to. Nakopne někdo? :)

ondrusu
Člen | 118
+
0
-

Ahojte, slyšel jsem, že nové Nette 3.0 už nepodporuje Kdyby\Doctrine, ale mají náhradu Netrine\ORM. Bude tento datagrid podporovat i tuhle knihovnu? Případně v jaké verzi se o očekává.

Díky

ali
Člen | 342
+
0
-

@ondrusu Netterine muzes pouzivat s Datagridem jiz nyni

Felix
Nette Core | 1197
+
+1
-

ondrusu napsal(a):

Ahojte, slyšel jsem, že nové Nette 3.0 už nepodporuje Kdyby\Doctrine, ale mají náhradu Netrine\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
+
0
-

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
+
0
-

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() 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 :)

Č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
+
0
-

@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
+
0
-

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);
        };
 ?>
nuller
Člen | 3
+
0
-

Ahoj,
dokázal byste mě prosím někdo „nakoupnout“, jak vyřešit hromadné stahování souborů přes Group-action? V akci vytvářím Zipstream (maennchen/ZipStream-PHP), ale tím, že se jedná o ajaxový požadavek, nedojde ke stažení žádného souboru. Díky moc

chladekt
Člen | 10
+
0
-

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
+
0
-

@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?

IJVo
Člen | 38
+
0
-

Ahoj,
proč v nejnovější verzi Datagrid zmizela funkce setConfirm()? Jak ji lze nahradit?

Pavel Janda
Člen | 977
+
0
-

@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
+
+9
-

contributte/datagrid v6 is here!


Contributte děkuje všem za pomoc! :)

Editoval Pavel Janda (27. 5. 2019 8:37)

jikki
Člen | 73
+
0
-

Ahoj, mám PHP 7.2 a vytvořil jsem si projekt nette/sandbox. Do něj chci require contributte/datagrid. Ale composer piše, že takový balíček nenašel. Co dělám špatně? :)

Ondřej Kubíček
Člen | 494
+
+1
-

musíš se podívat do dokumentace – https://contributte.org/…te/datagrid/ ten balík se jmenuje ublaboo/datagrid

Pavel Janda
Člen | 977
+
+1
-

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.

jikki
Člen | 73
+
0
-

Ahoj, pokud mám v databázi sloupec datetime, tak při hodnotě NULL vyhodí datagrid chybu DateTime::createFromFormat() expects parameter 2 to be string, null given. Ve starší verzi NULL nebyl problém. V testovacím sandboxu se to chová stejně.

Pavel Janda
Člen | 977
+
+1
-

@jikki Jj, je to fixed v masteru. :)

kedarus
Člen | 3
+
0
-

Ahoj, funguje řazení pro více sloupců při použití NetteDatabaseDataSource? Je to vůbec možné? Jak by měl vypadat vlastní callback pro řazení podle více sloupců, ale bez zapnutí multisortu?

Pavel Janda
Člen | 977
+
0
-

@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
+
0
-

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
+
0
-

@magenzajin

$grid->addColumnNumber($primaryKey, 'ID')
	->setFilterText()
	->setExactSearch()

:)

magenzajin
Člen | 9
+
0
-

Grazie, Signore!! :)