ublaboo/datagrid: mocný, rychlý, rozšiřitelný, hezký, anglicky dokumentovaný datagrid
- Šaman
- Člen | 2659
Pavel Janda napsal(a):
@Šaman Tak by to jistě šlo. Tedy jich udělám 10. Jenže pak bude chtít někdo 15% šířku. Tak se přidá dalších 10. Pak bude chtít někdo 17,5%. :D Atp.
Bral bych to jako poslední možnost.
Takhle jsem to nemyslel. Měl jsem na mysli něco jako
<?php
$grid->addColumnText('name', 'Name')
->addAttribute('class', 'moje_super_trida');
?>
Ať si každý nadělá třídy jaké chce.
Editoval Šaman (2. 3. 2016 20:45)
- sibka
- Člen | 24
Díky za super grid. Jen mám jeden zádrhel. I ve tvém demu mi v IE nefungují věci okolo checkboxů. V jiných prohlížečích problém není. Jen ten IE zlobí.
- při zaškrtnutí se Group actions zůstávají zašedlé/nepřístupné
- checkbox „Select All“ neovlivní žádný řádek gridu
- vzhled „happy“ je deformován (místo „fajfky“ jsou jen dvě čárky)
V souboru libraries.js mi to vyhazuje Objekt tuto akci nepodporuje (return i=„svg“===t.target.tagName?t.target.parentNode:„rect“===t.target.tagName?t.target.parentNode.parentNode:t.target,i&&i.classList.contains(„happy-checkbox“)?(t.preventDefault(),s=‚input[type=checkbox][name=„‘+i.getAttribute("data-name“)+‚„]‘,n=document.querySelector(s),n?(i.classList.contains("active“)?(n.checked=!1,i.classList.remove(„active“)):(n.checked=!0,i.classList.add(„active“)),e=new Event(„change“,{bubbles:!0}),n.dispatchEvent(e)):void 0):void 0}).
- Pavel Janda
- Člen | 977
@sibka Díky za report. Mrknu na to večer. Snad se mi podaří někde
sehnat komp s Win. :D
Můžeš mi pls poslat verzi IE, ve které jsi na to narazil?
- Pavel Janda
- Člen | 977
@exquis @Šaman Verze v2.2.0
přidává
renderování elementů th
a td
pomocí
Nette\Utils\Html
. Je možné k těmto elementům přistupovat:
$th = $grid->addColumnText('name', 'Name')
->getElementPrototype('td'); // Nebo element <td> pomocí Column::getElementPrototype('td')
$th->data('foo', 'bar');
$th->class('super-column')
Nebo je možné nastavovat atributy pro oba elementy najednou:
$grid->addColumnText('name', 'Name')
->addAttributes(['class' => 'text-center']);
@CZechBoY Přidáno, díkes za tip.
- exquis
- Člen | 83
Pavel Janda napsal(a):
@exquis @Šaman Verze
v2.2.0
přidává renderování elementůth
atd
pomocíNette\Utils\Html
. Je možné k těmto elementům přistupovat:$th = $grid->addColumnText('name', 'Name') ->getElementPrototype('td'); // Nebo element <td> pomocí Column::getElementPrototype('td') $th->data('foo', 'bar'); $th->class('super-column')
Nebo je možné nastavovat atributy pro oba elementy najednou:
$grid->addColumnText('name', 'Name') ->addAttributes(['class' => 'text-center']);
@CZechBoY Přidáno, díkes za tip.
Perfektní, díky moc
- exquis
- Člen | 83
Tak další postřeh, aktualizoval jsem na v2.2.0 a změna funkce getCount() na
$selection->getName() . '.' . $selection->getPrimary();
ukázala další problém a to ve chvíli, kdy využíváte v MySQL pohledy. Jelikož se data_source snaží brát dle primárního klíče a pohled žádný primární klíč nemá, tak vyhodí chybu. S normální tabulkou běhá perfektně.
- exquis
- Člen | 83
Možná se to někomu bude hodit – při provádění hromadných akcí (konkrétně změna stavu objednávky, kdy se odesílají i emaily), kdy akce trvá nějakou dobu, to díky ajaxu vypadá, že se nic neděje a nezkušený uživatel nepozná může na tlačítko potvrzení hromadné akce kliknout znovu. Tomu jde zabránit jednoduchým skriptíkem:
$.nette.ext('callbacks', {
start: function () {
$("#group_action_submit").after("<span class='mass-action-confirmation'><i class='fa fa-spin fa-2x fa-spinner'></i> čekejte prosím, pracuji... </span>");
},
complete: function () {
$(".mass-action-confirmation").hide();
}
})
CSS:
.mass-action-confirmation i{position:relative; top:5px; left:5px; margin-right:10px; color:black}
EDIT: upraveno i s odstraněním
Editoval exquis (3. 3. 2016 12:29)
- Pavel Janda
- Člen | 977
@exquis Super nápad. Sice ti tam chybí odstranění spinneru po
success
eventu, ale píšu si issue „navázat volitelné spinnery
na ajaxové akce“. :)
- Pavel Janda
- Člen | 977
@CZechBoY Jeez.
No, musím trochu na podpoře složených klíčů zapracovat.
Jo a nesouhlasím s tím. :D Pokud budu chtít primary key
(::getPrimary()
) po NDBT, nedá mi pole cizích klíčů. Začne na
mě křičet, že mi teda nic dát nechce:
Table 'a' does not have a primary key.
Edit: cache..
Editoval Pavel Janda (3. 3. 2016 16:34)
- Pavel Janda
- Člen | 977
@Arty Zatím je podporována taková malá inline editace, kde se prostě zavolá callback s novou hodnotou a primárním klíčem. Je to rychlé a popsané v docu.
Velkou inline editaci přes celý řádek plánuji, byť mám na pořadu dne věci, kterým přikládám vyšší prioritu (ColumnStatus a animované spinnery – viz issues na githubu).
Do konce týdne bych mohl mít hotové výše zmíněné, tak se pak pustím do té větší inline editace. Už tam leží delší dobu, pravda. :)
Editoval Pavel Janda (4. 3. 2016 9:00)
- Pavel Janda
- Člen | 977
@sibka To jsem to ale oslík, pořadí vyhodnocování operátorů mě přechytračilo. Fixed, updatni composer..
- Pavel Janda
- Člen | 977
Mám to v úkolníčku. Bohužel jsem se nedostal ani k Win kompu, ani k rozjetí virtualboxu. O víkendu :)
- Pavel Janda
- Člen | 977
Nová verze – v2.3.0
- Přidán script (datagrid-spinners.js) s nette.ajax.extension. Tento script bude zobrazovat u některých ajaxových akcí spinnery. Více zde.
- Přidán sloupec
ColumnStatus
. Vykreslí bootstrap dropdown, takže pokud ho chcete používat, je třeba bootstrap.js. Více zde.
Na pořadu dne je velká inline editace a fluent interface pro okamžité
nastavení stejnojmenného filtru sloupce (jako to znáte z jiných gridů:
$grid->addColumn()->setFilter()
).
Editoval Pavel Janda (7. 3. 2016 11:43)
- Pavel Janda
- Člen | 977
@sibka Konečně díval. Fixnul jsem event dispatching pro IE, ale bohužel, Explorer neumí rotovat elementy v svg, takže jsou ty checkboxy rozsypané.
Zkusím nahradit rotovaný <rect> širokou čárou. To by asi mohlo zafungovat.
- pitr82
- Člen | 121
Mám sloupec s referenci @ManyToOne a nejde mi podle tohoto sloupce
řadit.
Entita User
/**
* Vazba role N:1 na sysRole.
* @ORM\ManyToOne(targetEntity="SysRole")
* @ORM\JoinColumn(name="sysRole_id", referencedColumnName="id")
*/
protected $role;
Zobrazení mi jde vpohodě
$grid->addColumnText('role.name','Role uzivatele')
->setSortable();
Ale nejde mi podle něj třídit.
Všiml sem si, že už to tady řešil @Hurass.
Pokud udělám stejný dotaz jako @Hurass a dám:
$grid->addColumnText('role2','Role uzivatele','ur.name')
->setSortable();
Tak dostanu chybu: Cannot read an undeclared property App\Model\Entities\SysUser::$ur
$grid->addColumnText('role2','Role uzivatele','role.name')
->setSortable();
Tak mi to zase vyhodí špatný dotaz.
SELECT u
FROM App\Model\Entities\SysUser u
LEFT JOIN App\Model\Entities\SysRole ur WITH ur.id = u.role
ORDER BY role.name ASC
Jak to tedy donutit řadit?
Používám master.
Dík za nakopnutí
Editoval pitr82 (8. 3. 2016 1:56)
- Hurass
- Člen | 114
@pitr82 ukaž jak předáváš QueryBuilder do datagridu.
Já tam mám toto:
$grid->setDataSource(
$this->userRepository->createQueryBuilder("u")
->leftJoin(\App\Model\UserRole::class, "ur", \Kdyby\Doctrine\Dql\Join::WITH, "ur.id = u.userRole")
);
Jinak můj příklad funguje bez problému.
Editoval Hurass (8. 3. 2016 7:19)
- pitr82
- Člen | 121
@Hurass
dokonce jsem to přepsal podle tebe.
$this->em->getRepository(SysUser::class)->createQueryBuilder('u')
->leftJoin(\App\Model\Entities\SysRole::class, "ur", \Kdyby\Doctrine\Dql\Join::WITH, "ur.id = u.role");
Mám tady problem u tohoto:
$grid->addColumnText('role2','Role uzivatele','ur.name')
->setSortable();
Tak dostanu chybu: Cannot read an undeclared property App\Model\Entities\SysUser::$ur
Editoval pitr82 (8. 3. 2016 10:33)
- Pavel Kouřil
- Člen | 128
Hmm, tak jsem jej konečně pořádně otestoval a použil, upravil si šablony aby seděly k šabloně (metronic) a datepickeru co používáme, a narazil jsem na následující:
- dají se nějak líp změnit šablony filtrů než si dělat vlastní fork? je to popravdě docela nepraktické
- pamatování filtrů a řazení v session je supr věc, ale v momentě co má člověk více datagridů, skládá to queries špatně; lze nějak nastavit název datagridu který by sloužil jako session „namespace“ a tedy každý datagrid by měl vlastní „paměť“?
- jak dostat přes vlastní render do sloupce HTML?
Jinak skvělá práce!
PS: Doporučoval bych vypsat závislosti i jinak než v boweru (stačí linky na knihovny v README/dokumentaci), ať člověk může datagrid jednoduše použít i bez něj. Nejhorší bylo dohledání happy.js. :)
- Pavel Janda
- Člen | 977
@pitr82 Můžeš pls zkusit master?
Totiž:
1, datagrid si bere tečkovou notaci jako přístup k objektům, což je
žádoucí chování, abys mohl při výpisu dat přistupovat k objektům.
2, Pokud se sortí, nešel do teď nastavit sloupec pro řazení, který by
používal alias (pokud chceš vypisovat data pomocí
$navazany_objekt
->property).
3, Měj nastavený grid tak, jak jsi psal v prvním komentáři, ale
přidej:
$grid->addColumnText('role2','Role uzivatele','role.name')
->setSortable('ur.name')
Editoval Pavel Janda (8. 3. 2016 11:47)
- Pavel Janda
- Člen | 977
@PavelKouřil
1, Ano: $filter->setTemplate(...)
(Je to v docu)
2, Jakou používáš verzi? Každý DataGrid si skládá data do vlastní
session. Je to ukázané například na úvodní stránce na webu (dolní grid
je ale jen stránkovaný), nebo na stránce filter
(oba jsou filtrované a do vlastní session).
3, $column->setTemplateEscaping(FALSE)
(Je to v docu)
PS: Jo díky, dám tam i jiný způsob načítání assetů, než přes bower.
Editoval Pavel Janda (8. 3. 2016 11:49)
- Pavel Janda
- Člen | 977
@harmim Kruci já už to dal do souboru vedle a zapomněl jsem to zdokumentovat. Děkuju.
- Pavel Kouřil
- Člen | 128
Pavel Janda napsal(a):
@PavelKouřil
1, Ano:$filter->setTemplate(...)
(Je to v docu)
No, a nějak „globálně“? Aby každý „FilterDateRange“ používal ve výchozím nastavení můj template? U gridu to mám vyřešené tak, že mám prostě grid factory, která jej konfiguruje – ale filtr takto nemůžu ovlivnit, ne?
2, Jakou používáš verzi? Každý DataGrid si skládá data do vlastní session. Je to ukázané například na úvodní stránce na webu (dolní grid je ale jen stránkovaný), nebo na stránce filter (oba jsou filtrované a do vlastní session).
Verzi používám v2.2.5
– a dokonce ty dva gridy nejsou na
jedné stránce, ale jsou vytvořený v naprosto jiných presenterech, a
stejně tam ta kolize vzniká. Jak se tedy grid rozhoduje ke kterému gridu
uložené data v session patří?
3,
$column->setTemplateEscaping(FALSE)
(Je to v docu)
Omlouvám se, todle jsem přehlédl :) díky, funguje!
- Pavel Janda
- Člen | 977
@PavelKouřil
1, No že by se mi chtělo používat pro templaty filtrů statické proměnné,
to se říct nedá.
Buď tedy můžeš extendit DatagGid::addFilterDateRange, nebo to nějak pošolíchat s Nette\Object::extensionMethod, ale to je dost kekel.
Máš nějaký jiný nápad, jak to tam držet i „globálně“ a přesto hezky/šikovně?
2, Aha, no bere se jméno komponenty. Takže pokud se datagridy jmenují stejně, asi tam může nastat kolize. Ale nevím, jestli se mi chce psát issue. Mohu mít dva usersGridy v různých částech appky a chtít stejné session úložiště.. Naopak se mi líbí víc toto chování.
- LeonardoCA
- Člen | 296
ad 2. podle mne je logictejsi, praktictejsi a min WTF pouzivat jedinecny identifikator pro ulozeni stavu a je na to jednoduchy fix – viz Nette\Application\UI\PresenterComponent->getUniqueId()
v tvem DataGridu:
<?php
/**
* Find some unique session key name
* @return string
*/
public function getSessionSectionName()
{
//return $this->getPresenter()->getName().':'.$this->getName();
return $this->getUniqueId();
}
?>
Editoval LeonardoCA (9. 3. 2016 13:47)
- Pavel Janda
- Člen | 977
Mýlil jsem se, Jak je napsáno výše, za klíč session section se považuje <Jméno presenteru>:<jméno komponenty>.
@LeonardoCA $this->getUniqueId()
je
nedostatečné.
@PavelKouřil Tím pádem je klíč session dat datagridu určitě
unikátní. Můžeš pls zkontrolovat, že pod jakým klíčem se ti ukládají
session? například pomocí kdyby/nette-session-panel
(fajn tool
pro debugování session dat).
Editoval Pavel Janda (10. 3. 2016 0:04)
- Pavel Janda
- Člen | 977
@Attanon Jsou potřeba víceméně 2 jiné queries.
1, $grid->setDataSource($q1)
: Query, která získá top-level
rodiče
2, $grid->setTreeView([$this, 'getChildren'], 'has_children');
:
$this->getChildren
dostane jako parametr
$parent_category_id
– s tímto parametrem a nějakou další
query vrátíš potomky toho žádaného rodiče
3, has_children
– druhý parametr metody
setTreeView
je nějaký „truthy“ sloupec, který určuje, zda
mají položky potomky či nikoliv. Buď je to sloupec, nebo to taky může být
callback, který bude vracet true/false (dostane tu item jako argument)
Kdybys to chtěl v konkrétním příklady, tak až přijdu domu, pošlu ti ukázku s doctrine.
- Pavel Janda
- Člen | 977
@Attanon Už ano. v2.3.8
1, Nastav datagidu vlastní šablonu:
$grid->setTemplateFile(__DIR__ . '/a.latte');
2, V šabloně poděď původní šablonu a přepiš
{block chevron-icon}
:
{extends dirname($original_template) . '/datagrid_tree.latte'}
<i n:block="chevron-cion" class="{$icon_prefix}user"></i>
- Pavel Janda
- Člen | 977
@Attanon Koukám, že je tam občas <i>
a občas
<span>
. Sjednotím to na i
.
Edit: composer update
Editoval Pavel Janda (10. 3. 2016 20:15)