ublaboo/datagrid: mocný, rychlý, rozšiřitelný, hezký, anglicky dokumentovaný datagrid
- jAkErCZ
- Člen | 322
Zdravím mám dotaz, je nějaká možnost nebo má datagrid v sobě spinner?
Chtěl bych udělat že když člověk začne vyhledávat spustí se spinner aby vyděl že se vyhledává?
Jelikož v naší db je asi něco kolem 1 500 000 záznamů a chvilku trvá než se něco najde tak aby ten dotyčný věděl.
- Pavel Janda
- Člen | 977
@jAkErCZ Je tam asi 10 různých spinnerů (item detail – očíčko se začne točit, stránkování má spinner dole, group action má spinner nahoře atp), ale vyhledávání je dost custom action. Zkus kouknout na nette.ajax.js spinner extension, které jsou v repu, inspirovat se a přidat svojí extension. Do 10 minut bys měl rozchodit vše, co potřebuješ.
- iguana007
- Člen | 970
jAkErCZ napsal(a):
@PavelJanda No jako našel jsem nějaké věci a to mi zase nejede vůbec vyhledávání… Já a js není moc dobrý :D
Ja to mam definovane takto:
(function($, undefined) {
$.nette.ext('spinner', {
init: function () {
this.spinner = this.createSpinner();
this.spinner.appendTo('.navbar-header');
},
start: function () {
this.counter++;
if (this.counter === 1) {
this.spinner.show(this.speed);
}
},
complete: function () {
this.counter--;
if (this.counter <= 0) {
this.spinner.hide(this.speed);
$(".alert").fadeTo(10000, 500).slideUp(500, function(){
$(".alert").slideUp(500);
});
}
}
}, {
createSpinner: function () {
return $('<div>', {
id: 'ajax-spinner',
css: {
display: 'none'
}
});
},
spinner: null,
speed: undefined,
counter: 0
});
})(jQuery);
- jAkErCZ
- Člen | 322
@iguana007 No zkusil sem to a když to tam dám tak se mi ani neotevře možnost vyhledávání…
https://ctrlv.cz/…/07/yp5B.png
Editoval jAkErCZ (7. 6. 2017 15:43)
- Pavel Janda
- Člen | 977
@jAkErCZ Ještě jednou tě poprosím, pokud máš problém s html,
css, js, php, jQuery nebo něčím podobným, zkus kontaktovat některého
z lektorů a mrknout na danou problematiku s ním. Tohle vlákno je hlavně
o komponentě ublaboo/datagrid
. Tvoje otázky jsou často mimo a
nesouvisí s tématem.
Neber to nijak špatně, chápu, že potřebuješ pomoci. Jen podotýkám, že je dost lidí, kteří studují zpětně zprávy tohoto vlákna. Jenže poslední dvě stránky nenesou žádnou důležitou informaci.
Díky ti.
- manwe
- Člen | 44
Resil jsem ted nedavno jak do Datagridu nacpat YetORM a udelal jsem si tak jednoduchou tridu pro YetORM (dalo by se to dalo udelat lip, but hey, it works).
<?php
class YetORMDataSource extends NetteDatabaseTableDataSource
{
/** @var Repository */
protected $repository;
public function __construct(Selection $data_source, $primary_key, Repository $repository)
{
parent::__construct($data_source, $primary_key);
$this->repository = $repository;
}
/**
* Apply limit and offset on data
* @param int $offset
* @param int $limit
* @return static
*/
public function limit($offset, $limit)
{
$this->data = $this->data_source->limit($limit, $offset);
return $this;
}
/**
* Get the data
* @return array
*/
public function getData()
{
$selection = $this->data ?: $this->data_source;
$rows = [];
foreach($selection as $row)
$rows[] = $this->repository->createEntity($row);
return $rows;
}
}
?>
Pouziti v presenteru (ClientRepository je YetORM repository):
<?php
/** @var \App\Model\Repository\ClientRepository @inject */
public $clientsRepo;
public function createComponentClientsRenderGrid($name){
$grid = new DataGrid($this, $name);
$grid->setPrimaryKey('clientId');
$selection = $this->clientsRepo->getTable()->select('*');
$dataSrc = new YetORMDataSource( $selection, $grid->getPrimaryKey(), $this->clientsRepo );
$grid->setDataSource( $dataSrc );
}
?>
Pote uz jednoduse funguji vsechny metody vasich YetORM entit.
Urcite by se to dalo predelat tak at tam staci poslat jen ten repozitar, ale
nebyl cas se moc ponorovat do toho jak si udelat cely svuj DataSource.
Jinak diky za ten datagrid, je to fakt uzitecna vecicka, jeste se s tim ucim :)
Editoval raddy668 (9. 6. 2017 11:10)
- Pavel Janda
- Člen | 977
@pitr82 Datagrid používá bootstrap-datepicker
, jeho
lokalizace by neměla dělat problém: https://bootstrap-datepicker.readthedocs.io/…st/i18n.html
Přemýšlím, zda to nějak nezkombinovat se slovníkem v datagridu. Hm.
- Pavel Janda
- Člen | 977
@radas Můžeš poradit @pitr82, jak jsi docílil toho, že to funguje?
@radas Je potřeba to aktualizovat při ajax callu, udělej si na to nette.ajax extension
- manwe
- Člen | 44
@PavelJanda Mam dotaz – mam grid, ve kterem mam inline editaci odkazu. Odkaz nicmene vykresluji jako htmlko (ikonka s odkazem). Jsem nejak schopny u male inline editace udelat nejaky filtr co se ma vepsat do toho pole? Aby tam byl ten link, ne HTML toho odkazu a ikonky?
- Pavel Janda
- Člen | 977
@raddy668 Jasně, už aespoň 5 minut je to hotové ve verzi 5.4.0
(k vyzkoušení v demu ve sloupci s tím linkem) :D
Dík za nápad
(je třeba aktualizace assetů..)
Editoval Pavel Janda (13. 6. 2017 10:20)
- manwe
- Člen | 44
@PavelJanda ficak, super – diky moc, funguje :)
Jeste jeden dotaz, jestli muzu :) jak by se dalo nejelegantneji resit toto:
- Mam input, pomoci ktereho vytvarim zaznam v DataGridu
- po vytvoreni zaznamu bych chtel zavolat „velkou“ inline editaci nove vlozeneho radku
problem je v tom, ze ten input je uplne jina komponenta nez ten datagrid,
funguje to takto:
https://gfycat.com/…glishpointer
Napadaji me 2 moznosti, nevim ktera je lepsi (nebo jestli neni nejaka lepsi co me nanapada)
- po vytvoreni zavolat „manualne“ handle $grid->link(‚inlineEdit!‘, [‚id‘ ⇒ $row->getId()])
- nejak to nacpat do nejakeho scriptu ktery se vypise pri novem zaznamu a ten to zavola ajaxove?
Diky
- Pavel Janda
- Člen | 977
@raddy668 Asi bych (jedno nebo druhé):
1, si udělal scriptík, který čapne data z tvého custom inputu, klikne
na ten button přidání záznamu a zkopčí do toho inline přidání jméno
toho usera z tvého inputu
2, si udělal scriptík, který mi bude našeptávat jména rovnou do inlie
přidávání :P
(Inline přidávání se nechá lehce vykreslit nahoře)
Editoval Pavel Janda (13. 6. 2017 10:48)
- manwe
- Člen | 44
@PavelJanda hm, ani jedno reseni se mi moc nehodi :D
jinak jeste si tam kdyztak fixni v
datagrid.coffee radek
input.find('option[value=' + $(this).val() + ']').prop('selected', true)
na
input.find('option[value=' + valueToEdit + ']').prop('selected', true)
aby fungovala ta transformace hodnoty u selectu :)
edit: hm, ted se divam do datagrid.js a tam to zase vybiras podle textu, tak nevim ted
Editoval raddy668 (13. 6. 2017 13:53)
- pitr82
- Člen | 121
Pavel Janda napsal(a):
@radas Můžeš poradit @pitr82, jak jsi docílil toho, že to funguje?
@radas Je potřeba to aktualizovat při ajax callu, udělej si na to nette.ajax extension
@PavelJanda
Nemohl bys udělat k tomu sandbox? Javascript jde mimo mě.
Byl bych ti moc vděčen.
Dík (-:
- marten_cz
- Člen | 10
Potrebuji nejak udelat filter pro 1:n zaznamu. Rekneme ze mam produkty, ke kazdemu produktu existuji varianty. Varianta rika, ze je to ve velikosti ‚small‘ a ‚cervene‘ plus dalsi kombinace. Do gridu pridam filter, kde muzu vybrat velikost a druhy kde muzu vybrat. Vypsat pak potrebuji ty produkty u kterych existuje tato varianta. Tedy nejjednoduseji jako ‚id IN (select product_id … WHERE size = „small“ and color = „red“)‘.
Jako db layer pouzivam dibi. Bohuzel subquery to prelozi pri prvnim zavolani setCondition a druhy uz neupravi tuto subquery. Druha moznost byla pouzit onAfterFilter v DataModel, bohuzel je privatni.
Je nejaka moznost filtrovat podle toho jestli existuje nejaky zaznam, nebo je nejaka moznost pridat neco do data source po uplatneni vsech filteru?
- Pavel Janda
- Člen | 977
@marten_cz Úplně nerozumím tomu, proč by neměla fungovat vlastní callback jako condition filtru.. Zkusíš sem prdnout kousek kódu? :)
- Petr Parolek
- Člen | 455
Ahoj, jak můžu přidat date picker při inline editaci do formuláře prosím? Přes firebug stačilo přidat k k inputu
data-provide="datepicker" data-date-orientation="bottom" data-date-format="d. m. yyyy" data-date-today-highlight="true" data-date-autoclose="true" data-autosubmit="" data-autosubmit-change=""
Ale do datagridu nevim, jak toto přidat.
- pitr82
- Člen | 121
sevca79 napsal(a):
ahoj,
asi to bude jednoduchý, ale nijak rychle na to nemůžu přijít, jak mám přiřadit barvu textu dle nějaký podmínky…např. do sloupce ->setColumnNumber když value>=0 barva textu zelená else barva textu červená..
díky za nakopnutí ;)
Přes callback
$grid->addColumnCallback('status', function($column, $item) {
if ($item->id > 1) {
$column->setClass('red');
}
});
Editoval pitr82 (16. 6. 2017 6:20)
- sevca79
- Člen | 55
Ahoj,
nějak se mi nepodařilo přijít na spojení big inline editace a možnosti
takto editovat jen některý řádky viz. allowRowsAction ..prostě aby se mi
tlačítko na big inline editaci zobrazilo jen na některých řádcích dle mé
podmínky…
a taktéž se mi nepodařilo (přes pořadí zápisu), aby tlačítko této akce
bylo před jiným tlačítkem normální akce..je toto taky možné???
děkuji za odpovědi :)
- sevca79
- Člen | 55
sevca79 napsal(a):
Ahoj,
nějak se mi nepodařilo přijít na spojení big inline editace a možnosti takto editovat jen některý řádky viz. allowRowsAction ..prostě aby se mi tlačítko na big inline editaci zobrazilo jen na některých řádcích dle mé podmínky…
a taktéž se mi nepodařilo (přes pořadí zápisu), aby tlačítko této akce bylo před jiným tlačítkem normální akce..je toto taky možné???děkuji za odpovědi :)
aha, stačilo se dotázat a přišel na první otázku sám přes allowRowsInlineEdit :) nu stane se…ale to tlačítko editace mám stále na posledním místě akcí, a já bych aby bylo ještě před tlačítkem delete :) je toto nějak možné???
- Pavel Janda
- Člen | 977
@sevca79 To je v šabloně napevno. Nejrychlejší bude asi
podědění šablony a upravení bloku tbody
.
- jannemec
- Člen | 78
Inline Add
dravím, měl bych prosbu – jak nastavit v inline add, aby se otevřel celý
formulář. V datagrifu mám jen omezený počet sloupců (ani je tam mít
nechci všechny) – rád bych inline add použil jen na potvrzení čísla
položky a následně zobrazil detali, který mám nastaven v
$grid->setItemsDetail() …
- jAkErCZ
- Člen | 322
@PavelJanda
Zdravím chci se zeptat využívám vyhledávání dle ID a to se pak
přenáší do dalšího gridu a v něm se dle toho ID které získalo vypíši
informace co potřebuji a to v reálném čase a to stejné že když přidám
nový řádek tak sem si zřídil že mi to reloadne a zůstane stále načtený
ten grid s tím ID
$p['webPagesIDGrid']->setDataSource($p->companyManager->getComponiesWebPages($values->CompanyID));
$p['webPagesIDGrid']->redrawControl();
Jenže teď jsem narazil na problém že když je na daném ID více položek tak se vytvoří stránkování což je v pořádku ale když kliknu na další stránku tak se mi grid načte defaultní hodnotu což je NULL ale já potřebuji aby si nechal stále to ID tak jak jsem psal výše u přidávání řádku… Tak se chci zeptat zda-li se to dá udělat nejak jednoduše jak třeba to přidávání kde sem si přidal 2 řádky a funguje to… nebo musím hlouběji do gridu?
Díky
Editoval jAkErCZ (28. 6. 2017 12:32)
- jAkErCZ
- Člen | 322
jannemec napsal(a):
Inline Add
dravím, měl bych prosbu – jak nastavit v inline add, aby se otevřel celý formulář. V datagrifu mám jen omezený počet sloupců (ani je tam mít nechci všechny) – rád bych inline add použil jen na potvrzení čísla položky a následně zobrazil detali, který mám nastaven v $grid->setItemsDetail() …
Tak pokud vím tak ve funkci
$grid->getInlineAdd()
Si přece řádky defunuješ sám ne?
$container->addText('DB', 'NÁZEV');
- Pavel Janda
- Člen | 977
@jannemec Hmm, zajímavý požadavek. Pokud to správně chápu,
chceš v inlineAdd
přidat záznam pouze s vyplněným jedním
číslem a potom hned otevřít itemDetail
? Zkus po přidání
záznamů poslat v payloadu spolu s ostatními hodnotami třeba nějaký
string itemAddedInline: <id>
+ udělat nette.ajax.js
extension, ve které odchytíš tuto property a přes JS spustíš stejnou akci,
jako by spustilo zmáčknutí tlačítka „očíčko“.
- Simtrix
- Člen | 15
Dobrý den,
v první řadě díky za super grid, který mi nejednou usnadnil život.
Momentálně se ale peru s následujícím:
Mám column status ve tvaru uvedeném níže. Při změně stavu se data v db
přepíší a všechno na pozadí proběhne v pohodě, ale nezmění se mi
buttonek. Tj. když změním z Active na Inactive, tak button nezčervená a
naopak.
Zajímavé je, že když kliknu zpět na Active, tak se button už přemění, ale mění se na Inactive. Takže překreslení je jakoby krok pozadu, ale data v db jsou vždy aktuální.
Nevíte, kde by mohl být problém?
Component
protected function createComponentResponsibilitiesGrid( $name ){
.
.
.
$grid->addColumnStatus( 'active', 'Active' )
->setSortable()
->addOption(1, 'Active' )
->endOption()
->addOption( 0, 'Inactive' )
->setClass('btn-danger')
->endOption()
->onChange[] = array( $this, 'activeBranchChange' );
.
.
.
}
Callback
public function activeBranchChange( $id, $new_status ){
$user = $this->getUser();
if( $user->isInRole( parent::BRANCHES_RW ) && in_array( $new_status, $this->statusArr ) ){
$branch = $this->branchesRepository->getSingleBranch( $id, $this->getMerchantId() );
//branch wasnt found
if( !$branch->fetch() ){
$this->flashMessage( 'You shall not pass', 'danger');
$this->redirect( 'Dashboard:' );
} else {
//update branch
$branch->update( array(
'active' => $new_status
) );
}
}
if( $this->isAjax() ){
$this['responsibilitiesGrid']->redrawItem( $id );
} else {
$this->redirect( 'this' );
}
}
- sevca79
- Člen | 55
ahoj,
nevím zda je to chyba resp. polochybka jen někde u mě, nebo v gridu :)
Když šoupnu do gridu inlineAdd a do formuláříku dám validační podmínku
setRequired, tak mi najednou přestane fungovat automatické filtrování..pokud
tam setRequired nemám, tak filtry běhaj tak jak maj, hned po stisku
kláves..avšak když tam mám setRequired, tak musím nejdřív ve filtru
naprázdno zaentrovat a pak se filtry rozběhnou…aspoň se to tak tedy chová
na mém příkladu..bo mi tam něco ještě chybí??
viz.něco jako
public function createComponentPlayersGrid() {
$playersData = $this->playersModel->getPlayersForGrid();
$grid=new \Ublaboo\DataGrid\DataGrid();
$grid->setPrimaryKey('id');
//set datasource
$grid->setDataSource($playersData);
//jednotlive sloupce
$grid->addColumnText('surname', 'příjmení')
->setSortable()
->setFilterText();
$grid->addInlineAdd()
->onControlAdd[] = function($container) {
$container->addText(PlayersModel::COLUMN_SURNAME, '')
->setRequired('chyba');
};
return $grid;
Editoval sevca79 (30. 6. 2017 11:37)
- manwe
- Člen | 44
Jeste jsem nasel drobny bug – kdyz mas hromadne zaskrtavatko na akce tak tam mas pocet zaskrtnutych checkboxu, trebas 5/5 … problem je v tom ze se tam pocita i ten checkbox pro hromadne zaskrtavani, takze pokud mam 3 polozky tak mi tam pise X/4 misto X/3 …
staci zmenit v datagrid.js tyhle 2 radky
<script>
checked_inputs = document.querySelectorAll('.datagrid-' + grid + ' input[data-check-all-datagrid]:checked'); // radek 149
total = document.querySelectorAll('.datagrid-' + grid + ' input[data-check-all-datagrid]').length; // radek 155
</script>
- Ivorius
- Nette Blogger | 119
Když používám groupAction, je nějak možné z toho vyrenderovat CSV pro stažení? Pro info, přehled objednávek kde chci vytvořit export pro poštu – podání online.
Udělal jsem
$grid->addGroupAction('export')->onSelect[] = [$this, 'postExport'];
public function postExport($ids) {
$exported = $this->export->setOrderIds($ids)->generate();
if(count($exported)) {
$name = 'CP-podani-online-'.date('d.m.Y').'.csv';
$csvResponse = new CSVResponse($exported, $name);
$presenter->sendResponse($csvResponse);
}
}
Což mi sice v ajax response vrátí data, ale jak mohu dát CSV ke stažení podobně jako je na https://ublaboo.org/datagrid/export ?
- Pavel Janda
- Člen | 977
@Ivorius Formulář se nyní submituje posílá ajaxově. Leda si upravit nette.ajax.js, popř to udělat nějakou nette.ajax.js extensions – aby se formulář nesubmitnul ajaxově v případě xxxx.
- Pavel Janda
- Člen | 977
@nanuqcz Jasně:
$grid->addAction('delete', '', 'delete!')
->setConfirm(
function($item) {
return sprintf('Opravdu smazat uživatele %s %s?', $item->name, $item->surname);
}
);