Ublaboo – group a nepřekreslující se datagrid

Alsatian
Člen | 177
+
0
-

Ahoj.

Mám datagrid jako samostatnou komponentu (DatagridOfferControl). Přidal jsem si do něj hromadné mazání:

$grid->addGroupAction('Odstranit')->onSelect[] = [$this, 'groupDelete'];

Mazání potom vypadá nějak takto:

public function groupDelete(array $ids): void
	{
		...
		foreach ($ids as $id) {
			// proces mazání...
		}

		$this['offerGrid']->reload();

		if ($this->getPresenter()->isAjax()) {
			// V komponentě je datagrid jako komponenta: public function createComponentOfferGrid() {$grid = new DataGrid(); ...}
			$this->redrawControl('datagrid');
		}
		else ...
	}

Datagrid vykresluji šablonou opět komponenty (DatagridOfferControl.latte):

{snippet datagrid}
    {control offerGrid}
{/snippet}

Datagrid se ale při odstranění položky nepřekreslí. Překreslování snippetu ale funguje, při dalším mazání se zneviditelní předchozí mazání. Vycházel jsem z příkladu na oficiálních stránkách

Není to proto, že je voláno mazání pomocí …->onSelect[] = [$this, ‚groupDelete‘]; a není tam handle? Kterým by se mazání provedlo ještě před vykreslením datagridu?

Kdyby někdo věděl jak postupovat, budu moc rád :) Děkuji.

EDIT: dále jsem zjistil, že i když odstraňuji položky pomocí vytvořeného tlačítka:

$grid->addAction('delete', '', 'Delete!')
				->setIcon('trash')
				->setClass('btn btn-danger ajax')
				->setConfirmation(
					new StringConfirmation('Odstranit záznam ID %s?', 'id') // pro ID %s
				);

což jsem měl za to, že funguje správně – když vykreslím stránku s datagdidem a dám odstranit položku, odstraní se a správně se překreslí tabulka v níž odstraněný záznam již není. Pokud ale před odstraněním provedu změnu řazení sloupců nebo jen přejdu na další stránku a zpět, tak při odstranění záznamu datagrid po překreslení ponechá položku stále v seznamu…

Editoval Alsatian (8. 12. 2022 9:48)

v_wagner
Člen | 13
+
0
-

Mám prakticky stejný problém.

Řekl bych, že funkce pro hromadnou změnu se zavolá až po refreshi gridu, který se provede automaticky, pak se vyvolá samotná funkce na hromadnou změnu a i když je její součástí kód pro refresh, další se již nevyvolá.

$grid->addGroupTextAction('Nastavit poznámku')->onSelect[] = [$this, 'CommentMultiSet'];
    public function CommentMultiSet($ids, $comment )
    {
		foreach ($ids as $idjizdy) {
			$this->JizdyModel->UpdateComment($idjizdy, $comment);
        }
		if ($this->isAjax()) {
			$this['jizdy2Grid']->reload();
		} else {
			$this->redirect('this');
		}
    }

Vypozoroval jsem, že když označím položky pro změnu komentáře, tento nastavím, dojde k odznačení chcekboxů pro multiselect, v databázi jsou nové hodnoty, ale ukazují se ty staré.

Pak udělám stejnou operaci, ale použiju jiný text a najednou se v gridu objeví ten předchozí z první hromadné změny a v databázi je uložen ten, co jsem zadával v této druhé změně.

Pak udělám stejnou operaci, ale použiju opět jiný text a najednou se v gridu objeví ten předchozí z druhé hromadné změny a v databázi je uložen ten, co jsem zadával v této třetí změně.

a tak dále.

Když se podívám do Laděnky na SQL dotazy, tak i tam je vidět, že nejdříve se zpracují dotazy pro sestavení gridu a teprve pak se ve funkci CommentMultiSet provede změna dat těch komentářů.

Něco je špatně a nemůžu přijít na to co.

mskocik
Člen | 74
+
0
-

v_wagner napsal(a):

Když se podívám do Laděnky na SQL dotazy, tak i tam je vidět, že nejdříve se zpracují dotazy pro sestavení gridu a teprve pak se ve funkci CommentMultiSet provede změna dat těch komentářů.

Něco je špatně a nemůžu přijít na to co.

@v_wagner Ako máš definovaný datasource toho gridu? Ak je tvoj datasource klasické pole, tak je načítané už vopred a pri prekreslení snippetov sa použuje toto existujúce pole, nezískava sa znovu z DB, ak si to v medzičase updatol.

Editoval mskocik (28. 2. 12:57)

v_wagner
Člen | 13
+
0
-

mskocik napsal(a):

v_wagner napsal(a):

Když se podívám do Laděnky na SQL dotazy, tak i tam je vidět, že nejdříve se zpracují dotazy pro sestavení gridu a teprve pak se ve funkci CommentMultiSet provede změna dat těch komentářů.

Něco je špatně a nemůžu přijít na to co.

@v_wagner Ako máš definovaný datasource toho gridu? Ak je tvoj datasource klasické pole, tak je načítané už vopred a pri prekreslení snippetov sa použuje toto existujúce pole, nezískava sa znovu z DB, ak si to v medzičase updatol.

Pravda, je to pole, sestavuje se ve funkci createComponentJizdy2Grid poměrně složitě hned na začátku z API externího zdroje a kombinuje s SQL daty databáze. Toto celé proběhne po potvrzení hromadné operace jako první včetně refreshe dat v gridu, pak se spustí funkce na samotnou hromadnou operaci, na jejímž konci je požadavek na refresh, který se ale ignoruje. Navíc (to jsem pravda neuvedl) jsou takto hromadně měněná pole součástí inline editace.

v podstatě to vypadá takto:

protected function createComponentJizdy2Grid($name) {
        $grid = new DataGrid($this, $name);

******* vytvoření pole $data z externího API v kombinaci s lokálními daty v databázi inline i hromadná editace v této chvíli vrací již nové hodnoty do pole

		$grid->setPrimaryKey('id');
		$grid->setMultiSortEnabled($enabled = TRUE);
		$grid->setDefaultSort(['timefrom' => 'DESC']);
		$grid->setPagination(false);
		$grid->setRememberState(false);
		$grid->setDataSource($data);

******* založení sloupců včetně nastavení inline editace těch samých polí co jsou pak hromadně editované (Soukr a Comment)

		$grid->addGroupAction('Nastavit Soukromá / Služební', $typjizdy)->onSelect[] = [$this, 'SoukrMultiSet'];
		$grid->addGroupTextAction('Nastavit poznámku')->onSelect[] = [$this, 'CommentMultiSet'];

		$grid->setTranslator($this->translator);
}

mskocik
Člen | 74
+
0
-

Principialne by si to potreboval nejako takto. Mozes skusit, ci to riesi tvoj problem

protected function createComponentJizdy2Grid($name) {
        $grid = new DataGrid($this, $name);

		$grid->setPrimaryKey('id');
		$grid->setMultiSortEnabled($enabled = TRUE);
		$grid->setDefaultSort(['timefrom' => 'DESC']);
		$grid->setPagination(false);
		$grid->setRememberState(false);
		$grid->setDataSource([]);	// musi byt inak exception
		// presunut vytvaranie datasource do render metody
		$grid->onRender[] = function() {
			******* vytvoření pole $data z externího API v kombinaci s lokálními daty v databázi inline i hromadná editace v této chvíli vrací již nové hodnoty do pole
			$grid->setDataSource($data);
		};

******* založení sloupců včetně nastavení inline editace těch samých polí co jsou pak hromadně editované (Soukr a Comment)

		$grid->addGroupAction('Nastavit Soukromá / Služební', $typjizdy)->onSelect[] = [$this, 'SoukrMultiSet'];
		$grid->addGroupTextAction('Nastavit poznámku')->onSelect[] = [$this, 'CommentMultiSet'];

		$grid->setTranslator($this->translator);
}
v_wagner
Člen | 13
+
0
-

Vida – to vypadá funkčně. Samozřejmě

		$grid->onRender[] = function() use($grid) {

Jinak to uvnitř funkce nezná $grid a nemůže provést

			$grid->setDataSource($data);

Teď už jen škoda, že se teď to celé volá 2x – jednou před hromadnou změnou a jednou po. Ale to je malá daň za to, že to funguje. Ono se to až tak často používat nebude. Každopádně díky, tohle mě nenapadlo zkoušet.

Editoval v_wagner (4. 3. 10:49)

mskocik
Člen | 74
+
0
-

v_wagner napsal(a):

Vida – to vypadá funkčně. Samozřejmě

		$grid->onRender[] = function() use($grid) {

Jinak to uvnitř funkce nezná $grid a nemůže provést

			$grid->setDataSource($data);

Jinak to uvnitř funkce nezná $grid a nemůže provést

			$grid->setDataSource($data);

Pre uplnost: funkcia onRender predava parameter $grid, takze je mozne pouzit aj takto:

$grid->onRender[] = function(DataGrid $grid) {
  // kod
};