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

marek-m
Člen | 66
+
+1
-

Pavel Janda napsal(a):

@cujan Jaký používáš primární klíč? Pokud ne ID, tak ho můžeš nastavit metodou DataGrid::setPrimaryKey

@rumcais1 Hmm, jdu se na to podívat, díky za report.

@marek-m Jakou používáš verzi?

ublaboo/datagrid": „^4.4“, som si nevsimol novsiu verziu

rumcais1
Člen | 80
+
0
-

@PavelJanda v souboru datamodel.php https://github.com/…ataModel.php přidávám na řádku 74

} else if ($driver instanceof \Dibi\Drivers\SqlsrvDriver) {
    $source = new DataSource\DibiFluentMssqlDataSource($source, $primary_key);
Pavel Janda
Člen | 977
+
0
-

@rumcais1 Zatím v masteru – můžeš, prosím, otestovat?

rumcais1
Člen | 80
+
0
-

@PavelJanda Funguje díky :)

rumcais1
Člen | 80
+
0
-

Můžu se ještě zeptat jak udělat addaction odkaz na jiný na jiný presenter s attributem jiným než primarní klíč? Díky

Pavel Janda
Člen | 977
+
+3
-

@rumcais1 $grid->addAction('edit', '', 'Users:edit', ['userId' => 'id', 'deleted']) :)

Editoval Pavel Janda (1. 2. 2017 12:46)

pitr82
Člen | 121
+
0
-

Zdravím @PavelJanda ,
mám takový návrh, jestli by šlo rozšířit datagrid, konkrétně group action.
Potřeboval bych současně upravit poznámku a datum (datum si zvolí uživatel).
Takže bych potřeboval dva inputy z toho jeden by byl textarea a druhý datetimepicker

rumcais1
Člen | 80
+
0
-

@PavelJanda Díky. A ještě jeden dotaz. Dá se u group action přidat confirm ?

Pavel Janda
Člen | 977
+
0
-

@rumcais1 Zatím ne. Mohl bych přidat. Otázka je, jak to udělat, aby při každé akci byl jiné confirm. Založíš issue? Zamyslím se nad tím.

rumcais1
Člen | 80
+
0
-

@PavelJanda Našel jsem tenhle issue. https://github.com/…d/issues/101 Neřešil jsi to už? :-)

Pavel Janda
Člen | 977
+
0
-

@rumcais1 A asi zavrhnul proto, že to nebylo úplně jednoduché. :) Máš nějaký nápad? Pošleš PR? :)

flamengo
Člen | 131
+
0
-

@PavelJanda Ahoj, navazuji na příspěvek ohledně špatného paginatoru po filtrování.

Provedl jsem čistou instalaci (composer, bower), nalinkoval soubory dle http://ublaboo.org/datagrid/#…, vymazal cache prohlížeče a výsledek je opravdu bohužel stejný: po filtrování se paginator nezmění a ukazuje nesmysl :(

Nevím, zda to má souvislost, ale console mi hlásí:

NetworkError: 404 Not Found - http://127.0.0.1/nazev-projektu/components/bootstrap-select/dist/js/bootstrap-select.js"

EDIT:
Ani po „ručním“ stažení bootstrap-select se nic nezměnilo. Ale asi bude chybka v boweru, když to nestáhne bootstrap-select.

EDIT2:
Když jsme provedl composer require ublaboo/datagrid:4.4.9 a nic víc (JS jsem nechal původní z pětkové verze), tak paginator funguje správně. Poslední čtyřková verze 4.4.22 v pořádku, od pětkové mi to již nefunguje.

Editoval flamengo (3. 2. 2017 20:27)

flamengo
Člen | 131
+
0
-

@PavelJanda Budu asi otravný hehe, ale rozhodl jsem se pro verzi 4.4.22, která se mi jevila funkčně. Bohužel jsme narazil a to na následující chybu:

Ublaboo\DataGrid\Exception\DataGridException
Session filter: Filter [_grid_has_sorted] not found

Netuším, proč to. V jednom presenteru datagrid jede a úplně ten samý grid v dalším presenteru vykazuje tuto chybu. Netušíte prosím někdo, jak z toho ven?
Verze 4.4.21 mi tuto chybu neukazuje, tak kdyžtak použiji tuto verzi.
Předem díky za radu.

Pavel Janda
Člen | 977
+
0
-

@flamengo Pravděpodobně jsi dřív sortoval nad sloupcem, který nyní již neexistuje. V session je však hodnota starého sloupce. V pozdějších verzích byla tato hláška potlačena a session se sama smaže při neexistujícím sloupci. Stejně to funguje u filtrů.

Edit: Hmm, to nebude úplně přesně totéž, ale bude to s tím souviset. Tak jako tak doporučuji updatnout na novější verzi (v5)

Editoval Pavel Janda (6. 2. 2017 15:14)

igor.pocta
Člen | 100
+
0
-

Ahoj, narazil jsem na takovou zvláštnost.

Mám skupiny a ty mají jednotlivé úkoly. Úkoly ve skupině vykresluji komponentou s datagridem. Když si v jedné skupině nastavím select filtr např. na řešitele, vyfiltruje se a výběr si zapamatuje.

Když jdu do skupiny jiné, kde řešitel z jiné skupiny neexistuje, laděnka zařve na chybu, že klíč není dostupný v hodnotách selectu.

Jde nějakým způsobem nastavit, aby si filtr pamatoval rozřazení filtrů a zároveň se nepřenášel do jiného? Např. nějakým unikátním řetězcem.

Díky,

I.

Pavel Janda
Člen | 977
+
0
-

@igor.pocta Pokud se jinak jmenují komponenty, měly by být oddělené filtry. Selá session storage se mění s názvem komponenty.. Můžeš ukázat nějaký kód?

igor.pocta
Člen | 100
+
0
-

@PavelJanda Zkusím to popsal: Mám různé skupiny úkolů a v každé skupině jsou vlastní úkoly. V zobrazení úkolů ve skupině používám datagrid. Protože u každého úkolu jsou různí řešitelé, musí být select filtru dynamický, který sestavuji z všech řešitelů úkolů. Ten předám do filtru. Když si nechám filtr aktivní a přejdu do jiné skupiny (stejná stránka, jiný obsah), zůstane v paměti a laděnka vytuhne (snaží se vložit id zvoleného uživatele do seznamu). V session storage jsou totiž data z předchozího gridu.

Kód: https://gist.github.com/…b06d704dcdfb

jan-stanek
Člen | 9
+
0
-

Ahoj, narazil jsem na problém při používání validací v inline přidávání, pokud je nějaké pole povinné, zablokuje se i odesílání formuláře pro inline editaci. Našel jsem, že už se to tu jednou řešilo, ale žádný výsledek. Existuje nějaké řešení?

Pavel Janda
Člen | 977
+
0
-

@igor.pocta Je to podle mě přesně o tom, o čem jsem mluvil. Session datagridu se volena podle názvu komponenty (plus předcích ve stromu komponent). Takže když se ti bude ta komponenta jmenovat pokaždé stejně, bude pokaždé stejná session. Když budeš používat stejné komponenty, ale jinak je pojmenuješ (jiné factory metody, stejné továrny), mělo by vše fungovat. :)

Pavel Janda
Člen | 977
+
0
-

@jan-stanek setValidationScope ti nepomůže, pokud zmáčkneš enter (datagrid je jeden velký formulář). Ale mohlo by pomoct při submitnutí tlačítkem. Mohl bys poslat PR?

sevca79
Člen | 55
+
+3
-

ahoj, prosím asi jednoduchá odpověd, ale nemůžu na to přijít..
jak jednoduše na začátku automaticky vyresetovat filtery v datagridu, aby se mi nezobrazovali ty, co sem použil posledně..když použiju $this->setRememberState(FALSE), tak zas nefunguje schovávání sloupců ale já chci schovávat sloupce a mít na začátku gridu filtery vyresetovaný..

dík za odpověd

PS. jinak super datagrid, moc mě baví ho používat ;)

Pavel Janda
Člen | 977
+
+5
-

@sevca79

Stačil by asi setter, který vypne session ukládání separátně pro filtry+sorrování+per_page a schovávání sloupců.

Pokud dá tvému příspěvku palec nahoru alespoň 5 lidí, tak to přidám. :P

Jinak můžeš zamozřejmě poslat PR, rád mergnu.

igor.pocta
Člen | 100
+
0
-

Pavel Janda napsal(a):

@igor.pocta Je to podle mě přesně o tom, o čem jsem mluvil. Session datagridu se volena podle názvu komponenty (plus předcích ve stromu komponent). Takže když se ti bude ta komponenta jmenovat pokaždé stejně, bude pokaždé stejná session. Když budeš používat stejné komponenty, ale jinak je pojmenuješ (jiné factory metody, stejné továrny), mělo by vše fungovat. :)

@PavelJanda Spíš si myslím, že si vůbec nerozumíme. :D Zkusím to přepsat na jiný případ.

Mám jeden presenter, jednu akci a jednu komponentu (articlesGrid) pro výpis (jen) článků podle toho, v jaké kategorii jsem. Pro info, nesnažím se tuto komponentu znásilnit pro výpis všeho možného, jen články.

Do této komponenty podstrčím entitu kategorie, o kterou se jedná a v této komponentě si sestavím Query Builder, který zajistí, že se v gridu vypíšou pouze články dané kategorie. Také si rovnu sestavím výčet autorů, které chci umožnit filtrovat. Do toho výčtu dávat pouze autory těch článků, které jsou v kategorii, ne všechny na webu. Výčet předám do filtru (select) a všechno doteď jede.

Problém je v té dynamice, … Když si v kategorii A vyberu ve filtru autora, nechám ten filtr aktivní a přejdu do kategorie B (která má své články). Ta si totiž opět sestavuje vlastní výčet autorů pro filtr podle článků, které jsou v ní. A autor vybraný v předchozí kategorii, který je uložen v session storage, v ní neexistuje.
V tuto chvíli to zařve na chybu, protože datagrid dosazuje výchozí hodnotu, která ale ve výčtu chybí.

Ale asi to vzdávám a dám tam klasický textfiltr :D

PS: Co takhle čtu příspěvek od sevca pod tímto formulářem, tak by mi to problém nejspíš vyřešilo ?D – mít možnost odstranit filtry při načtení gridu. :D

Editoval igor.pocta (7. 2. 2017 20:15)

kralik
Člen | 230
+
0
-

Ahoj,
prosím o radu, je možné předat addColumnStatus do addOption pole.
Existuje tato možnost nebo nějaký fígl?
Rád bych data do addOption načetl z DB.

Pužívám toto, funkčně super:

<?php
...
$grid->addColumnStatus('role', 'Role')
                ->addOption('admin', 'admin')
                    ->endOption()
                ->addOption('member', 'member')
                    ->endOption()
                ->addOption('pilot', 'pilot')
                    ->endOption()
                ->addOption('sere', 'sere')
                    ->endOption()
                ->onChange[] = function($id, $value) {
                    $data['role']=$value;
                    $this->spravaModel->saveUsers($id,$data);
                };
...
?>

Rád bych toto:

<?php
...
$kat = $this->mainModel->getAdmKategorieGrid();
...
$grid->addColumnStatus('kat', 'Kategorie')
                ->addOption($kat)
                   ->endOption()
                ->onChange[] = function($id, $value) {
                    $data['Kategorie_id']=$value;
                    $this->mainModel->saveProdukt($id,$data);
                };
...
?>

Moc díky

Pavel Janda
Člen | 977
+
0
-

@igor.pocta Už chápu! Tu máš závislé selecty. Jasně. No, asi nedokážu vymyslet rychle fíčuru, která by nějak geniálně dokázala přehazovat session storages datagridu v závilsosti na nějakém filtru. Asi by to šlo, ale je to dost ojedinělý příad.. Napíšu si to jako možnou featuru do další big verze.

Dále:
DateGrid::$strict_session_filter_values. Změň to false. :P

Pavel Janda
Člen | 977
+
0
-

@kralik Stačí mrknou do kódu, :P

ColumnStatus::setOptions(array $options)

alNath
Člen | 17
+
0
-

AHoj, ja sa chcem spytat ci sa da grid renderovat s dvoma action stlpcami, jeden v lavo a druhy v pravo. Dost mi prekaza mat buttony na zobrazenie hned vedla Delete

Pavel Janda
Člen | 977
+
0
-

Setter na to žádný není, ale možností, jak tohoto docílit, je několik:

  1. Upravit si šablonu a podědit datagrid – nepříliš rychlá cesta, kterou se asi nevydáš.
  2. Přidáš si sloupec, kterému definuješ v šabloně {block}. V tom blocku máš k dispozici normálně položku a jejích idčka, takže v tomto sloupci můžeš vykreslit naprosto cokoliv. Klidně obrázek, klidně další tabulku, klidně několik vlastních tlačítek zastupujících jiné akce, které nechceš mít v tom posledním sloupci. :)
  3. Můžeš si vytvořit v presetneru/komponentě, která implementuje továrničku datagridu, pár instancí třídy Action, které předáš do své šablony datagridu. Opět si vytvoříš {block} pro sloupec s jinými akcemi a necháš tam ty třídy typu Action vyrenderovat.

Nejméně práce dá bod 2

alNath
Člen | 17
+
0
-

Super, bod 2 vyzera byt fajn :)
akurat mi to pada na chybach pri n:href atribute. pomohlo

<a class="btn btn-xs btn-primary" href='{plink :Produkcia:detail $item->id}'>

Editoval alNath (9. 2. 2017 20:15)

jannemec
Člen | 78
+
0
-

Filtr v related table
Ahoj, mám dotaz, lze nějak filtr udělat i nad propojenou tabulkou – v gridu mám smlouvy a v připojené tabulce přes smlouva_id jsou dodatky (ty zobrazím v detailu) – a rád bych filtroval i přes obsah těch připojených dokumentů. Vazba je 1:N tedy k jedné smlouvě může být více dokumentů (smlouva, dodatek 1, obchodní podmínky, …) takže left join mi nepomůže – měl bych ten řádek se smlouvou vícekrát.
JN

Pavel Janda
Člen | 977
+
0
-

@jannemec Doporučuji použít vlastní podmínku filtru.

alNath
Člen | 17
+
0
-

Pavel Janda napsal(a):

@BuGeR Celý datagrid je jeden velký formulář. Nemůžeš dát dovnitř další formulář. není to validní HTML.

Momentálně by to chtělo poslat nějaký geniální pull request do nette, aby bylo podporováno HTML5. Mohl bych pak rozsekat části datagridu do více formulářů a přitom používat formulářové prvky napříč celou stránkou.

Jediná možnost v nette je momentálně ošéfovat všechno JavaScriptem.

A slo by spravit datagrid ako sucast parrent formulara? (t.j. neobalovat grid do <form></form>)

Pavel Janda
Člen | 977
+
0
-

@alNath To nevím, muselo by se předělat dost věcí. :) Spíš počkáme, zda to nějak časem nepostavíme na html5 formulářích. To by byla teprv sranda.

alNath
Člen | 17
+
0
-

To je skoda, v tomto pripade som to chcel pouzit na generovanie dat – add/edit/sort (vyuzitim Array data-source) a ich spracovanim v callbacku rodica.

Ale nevadi, na tento ucel to nebolo stavane :)

Pavel Janda
Člen | 977
+
0
-

@alNath Můžeš popsat detailněji ukázkový příklad? Věřím, že to půjde elegantně vyřešit s tímto přístupem. :)

alNath
Člen | 17
+
0
-

Napr. mam formular, a v nom zopar prvkov. V zavislosti od toho, ktory prvok je ako nastaveny robim rozny insert do DB po kliknuti na submit . V pripade nejakej konfiguracie potrebujem vlozit do DB data vytvorene v gride. Idealne by som si to predstavoval cez zapis:

	$form = $this->factory->create();
	$form->addTextArea('note', 'Poznámky:')
->setRequired(false);
	$form->addDataGrid('mydatagrid', 'Datagrid:')

A nasledne

$control->onSubmit[] = function (Form $form) {
$values = $form->getValues()->mydatagrid;
... # $values manupulation

Myslim ze v tomto pripade by nebolo nutne vytvarat „duplicitny“ form

sevca79
Člen | 55
+
0
-

koukám, že 5 palců mám ;) včetně teda jednoho mého…

Pavel Janda napsal(a):

@sevca79

Stačil by asi setter, který vypne session ukládání separátně pro filtry+sorrování+per_page a schovávání sloupců.

Pokud dá tvému příspěvku palec nahoru alespoň 5 lidí, tak to přidám. :P

Jinak můžeš zamozřejmě poslat PR, rád mergnu.

Pavel Janda
Člen | 977
+
+1
-

@sevca79 No tak to to budu muset přidat. :)
Očekávej v příští verzi. Dostanu se k tomu do konce týdne.

kocak86
Člen | 5
+
0
-

Ahoj. Lze nějakým způsobem zakázat možnost řazení setSortable() u některým řádků? Stejně jako lze omezit zobrazení akcí metodou allowRowsAction()? Děkuji.

Pavel Janda
Člen | 977
+
0
-

@kocak86 To nelze. Nedává mi to ani moc smysl. Nemůžu posunout položku 8 za položku 32? Ale můžu hýbat s 32? No tak to udělám obráceně..

Nebo mi něco uniká?

kocak86
Člen | 5
+
0
-

Vykresluju v gridu strom kategorií a chci zafixovat kořenovou kategorii, s kterou z principu nelze hýbat. Případ, kdy někdo strčí před rootovskou kategorii jinou katageroii mám ošetřeno. Jde mi čistě o to, aby bylo pro uživatele zřejmé, že rootovská kategorii nejde editovat. Zkoušel jsem i Tree-View, ale tam jsem nepřišel na to, jak defaultně zobrazovat rozbalený strom kategorií.

Pavel Janda napsal(a):

@kocak86 To nelze. Nedává mi to ani moc smysl. Nemůžu posunout položku 8 za položku 32? Ale můžu hýbat s 32? No tak to udělám obráceně..

Nebo mi něco uniká?

Pavel Janda
Člen | 977
+
0
-

@kocak86 Hmm. Asi bude nejlepší skrýt to přes css..

sikulam
Člen | 12
+
0
-

Ahoj,
mohli by jste mi prosím poradit jak udělat tree-view nad Doctrine
V entitě mám:

<?php
    /**
     * @ORM\OneToMany(targetEntity="FoodMenu", mappedBy="parent")
     */
    protected $children;

    /**
     * @ORM\ManyToOne(targetEntity="FoodMenu", inversedBy="children")
     * @ORM\JoinColumn(name="id_parent", referencedColumnName="id")
     */
    protected $parent = null;
?>

V gridu pák dávám

<?php
$grid->setTreeView([$this, 'getChildren'], 'hasChildren');
?>

Hlásí mí to chybu Cannot read an undeclared property App\FoodMenu::$hasChildren.
A nevím jak to do té entity zapsat.

IJVo
Člen | 38
+
0
-

Ahoj,
můžete mi prosím poradit, jak u „Big inline editing“ v „Datagrid“ použít u některého sloupce textarea místo input?

Pavel Janda
Člen | 977
+
+1
-

@IJVo Viz dokumentace. Tam normálně přidáváš formulářové prvky:

$grid->addInlineEdit()
	->onControlAdd[] = function($container) {
		$container->addText(...);
		$container->addSelect(...);
		$container->addTextarea(...);
		$container->addRadioList(...);
	};
Pavel Janda
Člen | 977
+
0
-

@sikulam Například (byť ne úplně optimálně):

/**
 * @Doctrine\ORM\Mapping\Entity
 */
class Category
{

	/**
	 * @Doctrine\ORM\Mapping\ManyToOne(targetEntity="Category")
	 * @Doctrine\ORM\Mapping\JoinColumn(name="parent_category_id", referencedColumnName="id")
	 */
	protected $parentCategory;


	/**
	 * @Doctrine\ORM\Mapping\OneToMany(targetEntity="Category", mappedBy="parentCategory")
	 */
	protected $childCategories;

	public function hasChildren(): bool
	{
		return !$this->childCategories->isEmpty();
	}

}
sikulam
Člen | 12
+
0
-

@PavelJanda Díky, stránka už funguje, akorát nastal další problém když chci rozkliknout položky po jednou z kategorií.
Call to undefined method App\AdminModule\Presenters\FoodMenuPresenter::getChildren().
S doctrine teprve začínám tak v tom trošku plavu :-(

Pavel Janda
Člen | 977
+
0
-

@sikulam

$grid->setTreeView(function(int $categoryId) {
	return $this->getChildCategoriesFor($categoryId);
}, 'hasChildren');
public function getChildCategoriesFor(int $categoryId): QueryBuilder
{
	return $this->em->getRepository(Category::class)
		->createQueryBuilder('c')
		->where('c.parentCategoryId = :parentCategoryId')
		->setParameter('parentCategoryId', $categoryId);
}

Pomohlo?

igor.pocta
Člen | 100
+
0
-

Ahoj, chystá se podpora pro entity s více primárními klíči?

Nyní mi to v kombinaci s Doctrine/QB zařve na:
„Single id is not allowed on composite primary key in entity App\Alert\SupplyChainManager“

Pavel Janda
Člen | 977
+
0
-

@igor.pocta Klidně myšlenku víc rozveď. Já nic takového (momentálně) nepotřebuji, takže se k tomu nechystám. Ale rád pomůžu s případnou implementací. Ptej se, zkoumej kód, ptej se. :) Možná to bude lepší řešit na githubu v issues.