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

Felix
Nette Core | 1183
+
+3
-

Šaman napsal(a):

Fixed.

chemix
Nette Core | 1294
+
0
-

@iru @PavelJanda dnes jsem narazil na celkem inspirativni video

https://uimovement.com/…interaction/

Pavel Janda
Člen | 977
+
0
-

@chemix Wow, to je dost dobrý nápad, díky

jirkasi
Člen | 1
+
0
-

Ahoj,

začínám s nette a tímto datagridem, dělá se s tím super, ale narazil jsem na problém s gridem.

Pokud mám funkci createComponentGrid v BasePresenter, v hlavním presenteru přiřadím setDataSource a addFilterMultiSelect, tak mi grid nefiltruje. Pravděpodobně to bude tím, že UI\Presenter zpracuje signál a jako signalReceiver má komponentu (grid) která neexistuje a tak si jí vytvoří – tam ale není filter MiltiSelect, který jsem tam dodal až přes $this[‚grid‘].

Celý to dělám kvůli tomu, abych v options toho filtru MultiSelect měl DISTINCT hodnoty ze sloupce gridu. Tak jak je autofilter v excelu.

Může mi s tím prosím někdo pradit?

Děkuji.

d@rkWolf
Člen | 162
+
0
-

Zdravím, dá se v Datagridu nějak udělat true/false varianta Statusu, která by fungovala jen klikem na button? Přepnul by automaticky 0 na 1 nebo naopak podle aktuálního stavu.

Ten rozbalovací select je sice hrozně cool, když potřebujete výběr z více hodnot, ale pokud potřebuju jen On/Off, je to uživatelsky na prd, přebývá tam přesně 1 zbytečnej klik.

d@rkWolf
Člen | 162
+
0
-

@PavelJanda ahoj, prosímtě, nevíš, v čem může být problém – viz. předchozí příspěvek, udělal jsem si ten Status switch zatím podle návodu s rozbalovacím menu, ale $this[‚grid‘]->redrawItem($id); mi ve f-ci changeStatus odmítá překreslit řádek. Informace se odešlou dobře, ale vrátí se pouze údaje o nastavení gridu(počet na stránku atd.) + flash message.

Podle dema chybí snippet „snippet-grid-item-1“ a taky _datagrid_redrawItem_class: "" a _datagrid_redrawItem_id: 1

Grid mám v komponentně, injectuju do Presenteru továrničku registrovanou v configu, žádný speciality. Grid jako takový funguje, nastavení počtu zobrazených, filtrování v hlavičce sloupce funguje.

EDIT: zkoušel jsem to to i vyhodit z komponenty přímo do Presenteru a žádná změna
EDIT2: sem idiot, měl sem blbě nastavený DataSource, bohužel to nijak neinformuje, takže sem hledal úplně všude jinde :-(


PS: v Nette3 + NetteForms.js 3 + Datagrid nefungují Group actions. V demu to jde, ale v demu jsou připojené NetteForms 2.4. S NetteForms 3 se nezobrazí tlačítko pro potvrzení Group actions. Je stále display:none.

Editoval d@rkWolf (9. 4. 2020 18:17)

Čamo
Člen | 786
+
0
-

Prosím vás vie mi niekto povedať prečo mi tento kód za určitých okolností nefunguje?

	protected function setStatus(DataGrid $grid, $cDomain)
	{
		$grid->addColumnStatus('status', "$cDomain.statusActive")
			->addOption(1, "$cDomain.statusActive")
			->setClass('btn-success')
			->endOption()
			->addOption(2, "$cDomain.statusInactive")
			->setClass('btn-danger')
			->endOption()
			->setFilterSelect([
				3 => $this->translator->translate("$cDomain.statusAll"),
				1 => $this->translator->translate("$cDomain.statusActive"),
				2 => $this->translator->translate("$cDomain.statusInactive"),
			], 'active')
			->setCondition(function ($collection, $value) {
				if( (int)$value != 3 ) $collection->getQueryBuilder()->andWhere('status = %i', (int)$value);
			})
			->onChange[] = [$this, 'statusChange'];
	}

Problém je s tým filtrom setFilterSelect(). Filter ako taký funguje správne, ale popri ňom nefunguje onChange handler. Vôbec sa nezavolá. Keď ten filterSelect zakomentujem tak onChange začne správne fungovať. Táto implementácia je nad Naja knižnicou a NextrasOrm. Ďakujem.

EDIT:
Tak moja chyba. Treba to zrejme rozdeliť.

		$grid->addColumnStatus('status', "$cDomain.statusActive")
			->addOption(1, "$cDomain.statusActive")
			->setClass('btn-success')
			->endOption()
			->addOption(2, "$cDomain.statusInactive")
			->setClass('btn-danger')
			->endOption()
			->onChange[] = [$this, 'statusChange'];

		$grid->addFilterSelect('status', 'status', [
				3 => $this->translator->translate("$cDomain.statusAll"),
				1 => $this->translator->translate("$cDomain.statusActive"),
				2 => $this->translator->translate("$cDomain.statusInactive"),
			], 'active')
			->setCondition(function ($collection, $value) {
				if( (int)$value != 3 ) $collection->getQueryBuilder()->andWhere('status = %i', (int)$value);
			});

Editoval Čamo (13. 4. 2020 17:23)

jAkErCZ
Člen | 321
+
0
-

Mám dotaz.

Je nějaká možnost udělat že třeba uživatel z nějaké jiné šablony by se proklikl do šablony kde je grid a rovnou by to našlo to co hledá( Třeba na jedné šabloně bude id nějakého projektu a po prokliku na stránku kde je grid mu to rovnou to ID najde)
Díky

dTTb
Člen | 30
+
+1
-

@jAkErCZ melo by stacit v prislusnym renderu:

<?php
public function renderXy($id=null){
	if(!is_null($id)){
		$this['xyGrid']->setFilter(['id'=>$id]);
	}
}
?>
TonnyVlcek
Člen | 31
+
+1
-

@jAkErCZ Pokud nechceš, nebo nemůžeš nastavovat jen filtr jak píše @dTTb (např. uživatel nesmí vidět data z jiných projektů), tak můžeš tohle základní filtrování udělat nad kolekcí kterou pak předáváš do datagridu ($grid->setDataSource($someCollection);.

Třeba si do továrničky gridu předat id toho projektu a ještě předtím než nastavíš kolekci ji podle toho id vyfiltrovat ($someCollection->findBy(['id' => $id]): takhle nějak by to mohlo být třeba v Nextras ORM).

d@rkWolf
Člen | 162
+
0
-

Zdravím, nemáte někdo problém se StringConfirmation v aktuální verzi Datagridu? Mám tohle klasicky u delete buttonu

<?php
->setConfirmation(
		new StringConfirmation('Do you really want to delete row %s?', 'name') // Second parameter is optional
	);
?>

Alert sice vyskočí, ale je fuk, na co kliknu, položka vždy skončí smazaná(je to poněkud zrádné chování), storno akce alertu se nechytá/ignoruje/nevím co.

Updatnul jsem datagrid na aktuální verzi(6.2.17, updatnul přiložené JS scripty(nepoužívám js balíčky), používám Naju(1.7). Už jsem dříve použil starší verzi 5.7.x s nette.ajax u Nette 2.4. a tam mi confirmy fungovaly v pořádku.

Editoval d@rkWolf (6. 5. 2020 10:30)

Pavel Janda
Člen | 977
+
0
-

Udělal bys na to, prosím, issue na GH? Díky!

d@rkWolf
Člen | 162
+
+1
-

@PavelJanda Jo, vloženo do issues na GH.

jAkErCZ
Člen | 321
+
0
-

Je nějaká možnost abych v

->addAction('blah', 'Blahblah2', 'blah!')

Předal nějak vlastní parametr? Abych to mohl lépe idetifikovat? [‚id‘ ⇒ ‚1‘]

jikki
Člen | 73
+
+1
-

jAkErCZ napsal(a):

Je nějaká možnost abych v

->addAction('blah', 'Blahblah2', 'blah!')

Předal nějak vlastní parametr? Abych to mohl lépe idetifikovat? [‚id‘ ⇒ ‚1‘]

Mě funguje

$grid->addAction('show_role', '', 'showRole!', ['role_id' => 'id'])
jikki
Člen | 73
+
0
-

Ahoj lidi, v datagridu zobrazuji ve sloupcích položky, jejich vlastnosti a počet. Počet dělám pomoci count v SQL. Když zobrazím či skryju nějaký sloupec, tak se mi změní group by v SQL dotazu a tedy i počet. Funguje mi to dobře. Předpokládal jsem, že i export pomocí $grid->addExportCallback s $filtered=true mi vrátí data ve stejné podobě. Nicméně vrací to jinak. Vrací mi data podle výchozího group by, který byl v createComponent datagridu. Tzn. pokud si zobrazím/skryju některé sloupce, tak zobrazené data a exportované se liší.

Netuší někdo, jak to udělat správně?

Děkuji

jAkErCZ
Člen | 321
+
0
-

Nějaký nápad jak se dotazovat v datagridu?

0 =>
	id => 9
    date =>
    date => "2020-06-01 12:48:41.000000"
    timezone_type => 3
    timezone => "Europe/Prague"
    exhibitor_state_id => 1
    vs => "20110003"
    mail_id => 1
    price => 3000.0
    company => "Dominik Kočák"
    company_id => "09101209"
    company_vat => ""
    exhibitor_trader_id => null
    town => "Brno-Černé Pole"
    zip => "61300"
    contact_name => "Dominik Korčák"
    contact_email => "jakercz@email.cz"
    contact_phone => "702061966"
    trader_name => null

jelikož když použiju klasicky $grid->addColumnText(‚vs‘, ‚Číslo objednávky‘); Vím že to je tím že je arrey v arrey ale jak se to dá v datagridu ptát?
Tak mi to háže Trying to get property ‚vs‘ of non-object
Díky

Editoval jAkErCZ (1. 6. 2020 17:15)

Pavel Janda
Člen | 977
+
+1
-

@jAkErCZ Jakože máš pole položek a každý položka má pole 1 indexem? Navrhoval bych: Buď pole přemapovat na jednoduché dvourozměrné – pole položek. Nebo bych to navrhoval přemapovat na nějakou jinou strukturu – třeba pole objektů nebo nějakou kolekci objektů. Třeba pomocí array_map. WDYT?

mat.cerny3
Člen | 9
+
0
-

Ahoj, používám tento datagrid, avšak mám problém se stránkováním… Defaultně je tam 10, 20 a 50 předmětů na stránku, je tam také možnost zobrazit všechny – v url se mi zobrazí ?ticketsGrid-grid-per_page=all, ale nic to neudělá… 10, 20 a 50 funguje v pořádku… Nevíš co s tím? @PavelJanda

Vůbec nevím, čím by to mohlo být a čím začít :/

Editoval mat.cerny3 (17. 6. 2020 11:55)

Pavel Janda
Člen | 977
+
0
-

@mat.cerny3 jakou používáš verzi? Mně to funguje. I demo funguje.. 🤔

Používáš překlady do CZ?

mat.cerny3
Člen | 9
+
0
-

@PavelJanda používám starší verzi 5.7 a překlady do češtiny též používám

Editoval mat.cerny3 (17. 6. 2020 12:20)

Pavel Janda
Člen | 977
+
+1
-

@mat.cerny3 Yes, tam byla dřív nějaká chyba. Myslím, že ve verzi 6 je opravená. Večer se an to podívám. :)

Pavel Janda
Člen | 977
+
0
-

@mat.cerny3 Tohle by mělo zafungovat

jAkErCZ
Člen | 321
+
0
-

Našel jsem jeden problém snažím se rozjet tree view

Grid:

public function createComponentReasonGrid($name)
 {
     $grid = new DataGrid();
     $reasons = $this->settignsRepository->getReasonList();
     $this->addComponent($grid, $name);
     $grid->setPrimaryKey('reason_id');
     $grid->setDataSource($reasons);
     $grid->setTreeView([$this, 'getChildren'], 'has_children');
     $grid->setDefaultSort(['reason_id' => 'ASC']);

Model

public function getReasonList() {

       $join = $this->db->select('COUNT(reason_id) AS count, parent_reason_id')
           ->from(self::TABLE_REASON)
           ->groupBy('parent_reason_id');

       $fluent = $this->db
           ->select('c.*, c_b.count as has_children')
           ->from(self::TABLE_REASON, 'c')
           ->leftJoin($join, 'c_b')
           ->on('c_b.parent_reason_id = c.reason_id')
           ->where('c.parent_reason_id IS NULL');

       return $fluent;
   }

   public function getChildren($id) {
       $join = $this->db->select('COUNT(reason_id) AS count, parent_reason_id')
           ->from(self::TABLE_REASON)
           ->groupBy('parent_reason_id');

       $fluent = $this->db
           ->select('c.*, c_b.count as has_children')
           ->from(self::TABLE_REASON, 'c')
           ->leftJoin($join, 'c_b')
           ->on('c_b.parent_reason_id = c.reason_id')
           ->where('c.parent_reason_id = %i', $id);

       return $fluent;
   }

Ale hází mi to chybu…

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'GET REASON LIST ORDER BY `reason_id`' at line 1

SELECT c.*, c_b.count as has_children
FROM reason c
LEFT JOIN (
SELECT COUNT(reason_id) AS count, parent_reason_id
FROM `reason`
GROUP BY `parent_reason_id`) c_b ON c_b.parent_reason_id = c.reason_id
WHERE c.parent_reason_id IS NULL GET REASON LIST
ORDER BY `reason_id`

Dělám něco špatně?

Petr Parolek
Člen | 455
+
+2
-

Ahoj,

snad někomu pomůže moje rada – dvě hodiny jsem strávil bádáním, proč se mi při změně statusu přes $grid->addColumnStatus se mi najednou místo klikátka ukazovalo číslo.

Problém jsem měl v Doctrine entity u getteru a setteru bez type hintů, neněl jsem ani u parametru, ani u returnu. Po doplňění vše šlape ok.

Na Nette 2.4 nebyl problém s poslední veze datagridu 5.x, BC pozoruju v Nette 3 a Datagridu 6.x.

Editoval ppar (24. 6. 2020 17:59)

Failips
Člen | 54
+
0
-

Ahoj,

po vykonani update ublaboo/datagrid na verziu v6.2.26, som objavil chybu. Item Detail sa po kliknuti na tlacitko nezobrazil iba nacital. Chybu som u seba opravil a nachadza sa v datagrid.js na riadku 475, kedy sa do nazvu triedy nedoplnil nazov gridu. Oprava success callbacku vyzera nasledovne:

<script>
success: function(payload) {
    var id, name, row_detail;
    if (payload._datagrid_toggle_detail) {
      id = payload._datagrid_toggle_detail;
      name = payload._datagrid_name;
      row_detail = $('.item-detail-' + name + '-id-' + id);
      row_detail.toggleClass('toggled');
      return row_detail.find('.item-detail-content').slideToggle('fast');
    }
}
</script>
Pavel Janda
Člen | 977
+
0
-

@Failips Mohl bys, prosím, poslat PR s opravou? Díky moc!

Pavel Janda
Člen | 977
+
0
-

@Failips Člověče, tuto chybu se mi nedaří replikovat. Nemáš nějaké staré assety? Na řádku 475 je něco úplně jiného: https://github.com/…/datagrid.js#L475

Failips
Člen | 54
+
+1
-

Hej no, asi budem mat este staru verziu datagrid.js, lebo som tam nasiel straaasnu kopu bugov :D Ospravedlnujem sa, moja chyba :)

Václav Kraus
Člen | 77
+
0
-

Ahoj,

není někde popsáno, které bloky lze přepsat při tvorbě vlastní šablony? V dokumentaci jsme našli jen https://contributte.org/…emplate.html#…. Rádi bychom ale změnili více prvků, než je zde popsáno (například prvek pro nastavení počtu položek).

Díky za odpověď!

Pavel Janda
Člen | 977
+
+1
-

@VáclavKraus Šablonu datagridu najdete zde: https://github.com/…tagrid.latte

Vše, co začíná na {define nebo {block lze přepsat :) Případně můžeme přepsat celou šablonu. 👍

Editoval Pavel Janda (20. 7. 2020 14:06)

jAkErCZ
Člen | 321
+
0
-

Čau,
mám takový problém mám ublaboo/datagrid ve kterém se prokliknu do dalšího gridu do kterého si předám ID a v tom druhém si ID seberu $this->presenter->getParameter(‚id‘) jenže jsem si všiml že při reloadu se id přidá v pořádku ale v pozadí proběhne AJAX prvek refreshState! který mi ale předá null
Jak tohle mohu ošetřit?

Editoval jAkErCZ (23. 7. 2020 17:51)

Pavel Janda
Člen | 977
+
0
-

@jAkErCZ Možná pomůže zrušení refreshování statu – to je externí js script, který na této stránce třeba neuvedeš do layoutu. Případně vymyslíme jiné řešení

jAkErCZ
Člen | 321
+
0
-

Pavel Janda napsal(a):

@jAkErCZ Možná pomůže zrušení refreshování statu – to je externí js script, který na této stránce třeba neuvedeš do layoutu. Případně vymyslíme jiné řešení

No můj grid vypadá takto :) Jak tedy zruším ten refresh?

protected function createComponentExhibitorsGrid($name): DataGrid {
    $grid = $this->createComponentGrid($name);
    $flat = $this->exhibitorManager->getFlatGrid($this->presenter->getParameter('id'));
    $grid->setDataSource($flat->related('stand')->where('floor_id = ?',$flat['id'])->fetchAll());
    $grid->setColumnsHideable();

    $grid->addColumnText('id', 'ID')
        ->setDefaultHide()
        ->setSortable()
        ->setFilterText();
    $grid->addColumnText('name', 'Název plochy')
        ->setSortable()
        ->setFilterText();

    $grid->addColumnText('exposition', 'Akce')
        ->setRenderer(function ($flat) {
            $html = Html::el('span');

            $html->addHtml(Html::el('span')
                ->setAttribute('style', 'display: block; margin: 2px 0;')
                ->setText($flat->name));

            return  $html;

        });

    $grid->addColumnText('state', 'Stav plochy')
        ->setRenderer(function ($flat) {
            $state = $flat->related('exhibitor_exposition__stand')->fetch();

            $html = Html::el('span');

            if ($state == true){
                $html->addHtml(Html::el('span')
                    ->setAttribute('class', 'label label-success')
                    ->setAttribute('style', 'display: block; margin: 2px 0;')
                    ->setText('Obsazeno'));
            }else{
                $html->addHtml(Html::el('span')
                    ->setAttribute('class', 'label label-danger')
                    ->setAttribute('style', 'display: block; margin: 2px 0;')
                    ->setText('Volno'));
            }
            return  $html;

        });

    $grid->addColumnText('exhibitor', 'Partner')
        ->setRenderer(function ($flat) {
            $exhibitor = $flat->related('exhibitor_exposition__stand')->fetch();
            $html = Html::el('span');

            $html->addHtml(Html::el('span')
                ->setAttribute('style', 'display: block; margin: 2px 0;')
                ->setText($exhibitor['exhibitor_exposition']['order']['exhibitor']['company']));

            return  $html;

        });

    $grid->onRender[] = function (\Ublaboo\DataGrid\DataGrid $grid) use ($flat): void {
        $grid->setDataSource($flat->related('stand')->where('floor_id = ?',$flat['id'])->fetchAll());
    };

    return $grid;
}
Tomáš Vodička
Člen | 28
+
+1
-

jAkErCZ napsal(a):

Pavel Janda napsal(a):

@jAkErCZ Možná pomůže zrušení refreshování statu – to je externí js script, který na této stránce třeba neuvedeš do layoutu. Případně vymyslíme jiné řešení

No můj grid vypadá takto :) Jak tedy zruším ten refresh?

protected function createComponentExhibitorsGrid($name): DataGrid {
    $grid = $this->createComponentGrid($name);
    $flat = $this->exhibitorManager->getFlatGrid($this->presenter->getParameter('id'));
    $grid->setDataSource($flat->related('stand')->where('floor_id = ?',$flat['id'])->fetchAll());
    $grid->setColumnsHideable();

    $grid->addColumnText('id', 'ID')
        ->setDefaultHide()
        ->setSortable()
        ->setFilterText();
    $grid->addColumnText('name', 'Název plochy')
        ->setSortable()
        ->setFilterText();

    $grid->addColumnText('exposition', 'Akce')
        ->setRenderer(function ($flat) {
            $html = Html::el('span');

            $html->addHtml(Html::el('span')
                ->setAttribute('style', 'display: block; margin: 2px 0;')
                ->setText($flat->name));

            return  $html;

        });

    $grid->addColumnText('state', 'Stav plochy')
        ->setRenderer(function ($flat) {
            $state = $flat->related('exhibitor_exposition__stand')->fetch();

            $html = Html::el('span');

            if ($state == true){
                $html->addHtml(Html::el('span')
                    ->setAttribute('class', 'label label-success')
                    ->setAttribute('style', 'display: block; margin: 2px 0;')
                    ->setText('Obsazeno'));
            }else{
                $html->addHtml(Html::el('span')
                    ->setAttribute('class', 'label label-danger')
                    ->setAttribute('style', 'display: block; margin: 2px 0;')
                    ->setText('Volno'));
            }
            return  $html;

        });

    $grid->addColumnText('exhibitor', 'Partner')
        ->setRenderer(function ($flat) {
            $exhibitor = $flat->related('exhibitor_exposition__stand')->fetch();
            $html = Html::el('span');

            $html->addHtml(Html::el('span')
                ->setAttribute('style', 'display: block; margin: 2px 0;')
                ->setText($exhibitor['exhibitor_exposition']['order']['exhibitor']['company']));

            return  $html;

        });

    $grid->onRender[] = function (\Ublaboo\DataGrid\DataGrid $grid) use ($flat): void {
        $grid->setDataSource($flat->related('stand')->where('floor_id = ?',$flat['id'])->fetchAll());
    };

    return $grid;
}

Jak psal Pavel – nevkládat do stránky ten js pro refresh – datagrid-instant-url-refresh.js

Editoval Tomáš Vodička (24. 7. 2020 13:41)

zoool
Člen | 89
+
0
-

Ahoj dá se nějak při skupinové akci vytvořit vlastní formulář co se na daných položkách má změnit, třeba tato

$grid->addGroupTextAction('Přecenit ')
je super, ale já bych ty textové pole potřeboval 3, dá se to nějak ohnout?

Děkuji

Editoval zoool (27. 7. 2020 12:33)

akmt
Člen | 20
+
0
-

Ahoj,
už druhý den se pokouším nad DataGridem implementovat práci s vyfiltrovanými výsledky, ale netuším, zda to jde a jestli ano, jak to správně provést. V diskuzích jsem našel možnost podědění DataGridu a následně a vložení callbacků $this->dataModel->onAfterFilter, takže jeden z pokusů byl:

class MarkersDatagrid extends \Ublaboo\DataGrid\DataGrid {

	/** @var MarkerManager */
	private $markerManager;

	public function __construct(MarkerManager $markerManager) {
		parent::__construct();

		$this->markerManager = $markerManager;

		$this->setDataSource($this->markerManager->getAll());
		$this->addColumnText('name', 'Name');
		$this->addFilterText('name', 'Name');

		$this->addColumnText('address', 'Address');

		$this->dataModel->onAfterFilter[] = [$this, 'afterFilter'];
	}

	public function afterFilter() {
		test();
	}
}

ale test() se nezavolá…
Mohl by mě někdo „nakopnout“ jak dál? A hlavně jak se pak na úrovni presenteru dostat k samotným datům?
Děkuji!

zoool
Člen | 89
+
+1
-

Já to třeba používám takto a funguje.

$grid2 = $this['grid2'];
        $model2 = $grid2->getDataModel();
        $model2->onAfterFilter[] = function (NetteDatabaseTableDataSource $items) {
            $return2 = [];
            $data2 = [];
            $itemss2 = $items->getData();
            foreach ($itemss2 as $item) {
                if (array_key_exists($item->date1->format('m.Y'), $data2)) {
                    $data2[$item->date1->format('m.Y')] += $item->price;
                } else
                    $data2[$item->date1->format('m.Y')] = $item->price;
            }
            if (count($data2) > 2) {
                foreach ($itemss2 as $item) {
                    if (array_key_exists($item->date1->format('m.Y'), $return2)) {
                        $return2[$item->date1->format('m.Y')] += $item->price;
                    } else
                        $return2[$item->date1->format('m.Y')] = $item->price;
                }
            } else {
                foreach ($itemss2 as $item) {
                    if (array_key_exists($item->date1->format('d.m.Y'), $return2)) {
                        $return2[$item->date1->format('d.m.Y')] += $item->price;
                    } else
                        $return2[$item->date1->format('d.m.Y')] = $item->price;
                }
            }
            $this->payload->datagrafname2 = json_encode(array_keys($return2), JSON_NUMERIC_CHECK);
            $this->payload->datagrafvalue2 = json_encode(array_values($return2), JSON_NUMERIC_CHECK);
        };

akmt napsal(a):

Ahoj,
už druhý den se pokouším nad DataGridem implementovat práci s vyfiltrovanými výsledky, ale netuším, zda to jde a jestli ano, jak to správně provést. V diskuzích jsem našel možnost podědění DataGridu a následně a vložení callbacků $this->dataModel->onAfterFilter, takže jeden z pokusů byl:

class MarkersDatagrid extends \Ublaboo\DataGrid\DataGrid {

	/** @var MarkerManager */
	private $markerManager;

	public function __construct(MarkerManager $markerManager) {
		parent::__construct();

		$this->markerManager = $markerManager;

		$this->setDataSource($this->markerManager->getAll());
		$this->addColumnText('name', 'Name');
		$this->addFilterText('name', 'Name');

		$this->addColumnText('address', 'Address');

		$this->dataModel->onAfterFilter[] = [$this, 'afterFilter'];
	}

	public function afterFilter() {
		test();
	}
}

ale test() se nezavolá…
Mohl by mě někdo „nakopnout“ jak dál? A hlavně jak se pak na úrovni presenteru dostat k samotným datům?
Děkuji!

akmt
Člen | 20
+
0
-

@zoool díky, to mě posunulo, ale stále netuším, jak bych se mohl k $items dostat v presenteru, resp. jak $items poslat do šablony, poradíš prosím?

zoool napsal(a):

Já to třeba používám takto a funguje.

$grid2 = $this['grid2'];
$model2 = $grid2->getDataModel();
$model2->onAfterFilter[] = function (NetteDatabaseTableDataSource $items) {
    $return2 = [];
    $data2 = [];
    $itemss2 = $items->getData();
    foreach ($itemss2 as $item) {
        if (array_key_exists($item->date1->format('m.Y'), $data2)) {
            $data2[$item->date1->format('m.Y')] += $item->price;
        } else
            $data2[$item->date1->format('m.Y')] = $item->price;
    }
    if (count($data2) > 2) {
        foreach ($itemss2 as $item) {
            if (array_key_exists($item->date1->format('m.Y'), $return2)) {
                $return2[$item->date1->format('m.Y')] += $item->price;
            } else
                $return2[$item->date1->format('m.Y')] = $item->price;
        }
    } else {
        foreach ($itemss2 as $item) {
            if (array_key_exists($item->date1->format('d.m.Y'), $return2)) {
                $return2[$item->date1->format('d.m.Y')] += $item->price;
            } else
                $return2[$item->date1->format('d.m.Y')] = $item->price;
        }
    }
    $this->payload->datagrafname2 = json_encode(array_keys($return2), JSON_NUMERIC_CHECK);
    $this->payload->datagrafvalue2 = json_encode(array_values($return2), JSON_NUMERIC_CHECK);
};
stepos2
Člen | 51
+
0
-

Zdravím. Mám datagrid se dvěma sloupci: jméno a počet bodů. Výchozí řazení je abecedně podle jména.

$grid = new DataGrid;
$grid->setRememberState(false);
$grid->setDataSource($data);
$grid->addColumnText('name', 'Jméno')
	->setSortable();
$grid->addColumnNumber('score', 'Počet bodů')
	->setSortable();
$grid->setDefaultSort(['name' => 'ASC']);
return $grid;

Chci, aby první kliknutí na Počet bodů seřadilo data podle počtu sestupně od nejvyššího. Jak to udělat? Standardně se řadí vzestupně a je tam jen setter setDefaultSort pro výchozí řazení celého datagridu, což nechci.

Editoval stepos2 (17. 8. 2020 12:19)

Intapps
Člen | 8
+
0
-

Ahoj,
šířky sloupců nastavuju pomocí ->addAttributes(['style' => 'width: 320px;'])
Lze nějak nastavit i šířka sloupce Action?
A není nějaká možnost nastavit šířku celého gridu?

bezsebesam
Člen | 8
+
0
-

Ahoj,
je možné v presenteru zjistit skutečně aktuální stav filtrů na jednotlivých sloupcích?

Konkrétně mi jde o to, že chci zamezit změně pořadí (drag & drop), pokud je nastaven nějaký konkrétní filtr. Takže jsem chtěl v metodě handleSort() podle nastavení filtrů rozhodnout, zda povolit změnu pořadí nebo ne:

public function handleSort($item_id, $prev_id, $next_id)
{
	dump($this['grid']->filter);
}

Pokud nastavím nějaký filtr, správně se mi omezí řádky v gridu. Potom provedu drag & drop, ale metoda handleSort() mi vypíše stále to předchozí nastavení filtru. To aktuální nastavení se vypíše pouze v případě, že před změnou pořadí stisknu F5.

Díky za pomoc.

lubos
Člen | 22
+
0
-

Confirmace na toolbar button, jde to ? Mě to píše nedefinovaná metoda.

$grid->addToolbarButton('deleteAll', 'Vymaže všechny data!')
	->setConfirmation(...);
lubos
Člen | 22
+
0
-

Vím že si můžu udělat svoji šablonu, ale tohle by mi ušetřilo spoustu času. iconPrefix je ale bohužel jako statická proměná.

$grid = new DataGrid($this, $name);
$grid->iconPrefix = 'glyphicon glyphicon-';
IJVo
Člen | 38
+
+2
-

lubos napsal(a):

Vím že si můžu udělat svoji šablonu, ale tohle by mi ušetřilo spoustu času. iconPrefix je ale bohužel jako statická proměná.

$grid = new DataGrid($this, $name);
$grid->iconPrefix = 'glyphicon glyphicon-';

Já používám

DataGrid::$iconPrefix = 'glyphicon glyphicon-';

Mám to v konstruktoru komponenty, ještě před tím, než volám

$grid = new DataGrid($this, $name);

A funguje mi to :-)

lubos
Člen | 22
+
0
-

Umíte někdo nějak spacifikovat setConfirmation aby mi nevyskakoval klasický alert, ale nějaký rozumný dialog?

Pavel Janda
Člen | 977
+
0
-

@lubos Nyní je v JavaScriptu datagridu hardcoded confirm(). Určitě by šel upravit JS, aby šla přidat custom funkci, která by nahradila ten confirm(). Pošleš PR? :)

lubos
Člen | 22
+
0
-

lubos napsal(a):

Confirmace na toolbar button, jde to ? Mě to píše nedefinovaná metoda.

$grid->addToolbarButton('deleteAll', 'Vymaže všechny data!')
	->setConfirmation(...);

Je to dementní, ale jde to:

$grid->addToolbarButton('deleteAllRegistrationData')
	->setIcon('ban')
	->setClass('btn btn-xs btn-danger')
	->addAttributes(['data-datagrid-confirm' => 'Pozor, vymažeš naprosto všechny registrace!!!!'])
	->setTitle('Výmaz kontakních údajů');
Pavel Janda
Člen | 977
+
0
-

@lubos Můžeš v PR kód vylepšit, pokud se ti zdá „dementní“, budeme rádi. :)

lubos
Člen | 22
+
0
-

Pavel Janda napsal(a):

@lubos Můžeš v PR kód vylepšit, pokud se ti zdá „dementní“, budeme rádi. :)

Promiň, tvůj datagrid je naprosto báječná záležitost, vůbec jako kdybych nic neřekl. S těmi PR to bude se mnou těžké, vůbec netuším co to je :D (teda tuším, ale neumím to pěkně v angličtině popsat)