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

jAkErCZ
Člen | 321
+
0
-

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
+
0
-

@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š.

jAkErCZ
Člen | 321
+
-1
-

@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

iguana007
Člen | 970
+
0
-

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 | 321
+
0
-

@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)

iguana007
Člen | 970
+
0
-

Asi tam nemas ten element s classou navbar-header. Zmen si to na neco, co v layoutu mas…

jAkErCZ
Člen | 321
+
0
-

@iguana007 to není tím ;) nezná to funkci hide a show od spineru…

iguana007
Člen | 970
+
0
-

@jAkErCZ ale hide a show jsou funkce jQuery. Dle chyby co ti to pise mi to pripada, ze se ti nevytvori ten spinner element, proto ti hlasi, ze spinner je null

jAkErCZ
Člen | 321
+
0
-

@iguana007 ale proč se mi ten element nevytvoří?

Pavel Janda
Člen | 977
+
+2
-

@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
+
+1
-

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)

pitr82
Člen | 121
+
0
-

Zdravím,
jak počeštím FilterDate, který je defaultně v angličtině ?

Pavel Janda
Člen | 977
+
0
-

@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.

radas
Člen | 221
+
0
-

@pitr82 @PavelJanda Mi se stává, že filtr je česky, ale po změně řazení nad nějakým sloupcem je pak anglicky (asi defaultní nastavení).

pitr82
Člen | 121
+
0
-

@PavelJanda češtinu jsem načetl hned pod plugin, ale nepočeštilo mi to…
Máš někde sandbox s češtinou ?

Pavel Janda
Člen | 977
+
0
-

@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
+
0
-

@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?

Viz https://gfycat.com/…fectKangaroo

pitr82
Člen | 121
+
0
-

@radas můžeš někde vystavit sandbox na gitu ?
nette.ajax extension je úplně mimo mě.

Díky (-:

Pavel Janda
Člen | 977
+
+1
-

@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
+
0
-

@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)

  1. po vytvoreni zavolat „manualne“ handle $grid->link(‚inlineEdit!‘, [‚id‘ ⇒ $row->getId()])
  2. nejak to nacpat do nejakeho scriptu ktery se vypise pri novem zaznamu a ten to zavola ajaxove?

Diky

Pavel Janda
Člen | 977
+
0
-

@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
+
+1
-

@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)

Pavel Janda
Člen | 977
+
0
-

@raddy668 :D Prozkoumám večer

pitr82
Člen | 121
+
0
-

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
+
0
-

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
+
0
-

@marten_cz Úplně nerozumím tomu, proč by neměla fungovat vlastní callback jako condition filtru.. Zkusíš sem prdnout kousek kódu? :)

manwe
Člen | 44
+
0
-

@PavelJanda Jeste dotaz – na „velkou“ inline editaci se da udelat podminka, slo by nejak udelat aby ta podminka platila i pro „malou“ inline editaci? Nebo jde to nejak udelat? V manualu jsem to nedohledal.

Napr. mam vyfakturovanou polozku a nechcu aby sla nijak upravovat.

Diky

Pavel Janda
Člen | 977
+
0
-

@raddy668 It is not possible right now. You can send a PR though. :P

sevca79
Člen | 55
+
0
-

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í ;)

pitr82
Člen | 121
+
0
-

@PavelJanda
Zkoušel jsem extensi pro počeštění, ale provádí se pokaždé dvakrát, nějaký nápad proč to dělá ?

$.nette.ext('languageCS', {
    complete: function (payload) {
	console.log('Datepicker update');
	$('*[data-provide="datepicker"]').datepicker({
	    language: 'cs'
	});
    }
});
Petr Parolek
Člen | 455
+
0
-

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
+
+1
-

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
+
0
-

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
+
0
-

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
+
0
-

@sevca79 To je v šabloně napevno. Nejrychlejší bude asi podědění šablony a upravení bloku tbody.

jannemec
Člen | 78
+
0
-

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 | 321
+
0
-

@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 | 321
+
0
-

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
+
0
-

@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
+
0
-

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
+
+1
-

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)

jAkErCZ
Člen | 321
+
0
-

@PavelJanda
Čau, mám takový pocit že jsem našel asi chybu… Když používám

$grid->addColumnStatus

Tak mi nejde rozrolovat ta nabídka…

A mám tam všechno co je potřeba…

manwe
Člen | 44
+
0
-

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>
Pavel Janda
Člen | 977
+
+1
-

@raddy668 Díky za report! Fixed in v5.4.2

Ivorius
Nette Blogger | 119
+
0
-

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
+
0
-

@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.

nanuqcz
Člen | 822
+
0
-

Ahoj,
je nějak možné dostat do metody setConfirm hodnoty více sloupečků?

$grid->addAction('delete', '', 'delete!')
	->setConfirm(
		'Opravdu smazat uživatele %s %s?',  // Opravdu smazat uživatele Jan Novák?
		['name', 'surname']
	);

Každopádně díky za nejlepší datagrid :-)

Pavel Janda
Člen | 977
+
+2
-

@nanuqcz Jasně:

$grid->addAction('delete', '', 'delete!')
	->setConfirm(
		function($item) {
			return sprintf('Opravdu smazat uživatele %s %s?', $item->name, $item->surname);
		}
	);
jAkErCZ
Člen | 321
+
0
-

Zdravím chtěl bych se zeptat z jakého důvodu mi při používání

$grid->addColumnStatus

Kde mám možnost rozbalit nabídku a vybrat parametr který potřebuji se mi nechce rozbalit?
Všechno dle dokumentace mám od js,css atd…

Čím to může být způsobeno? nebo jak tento problém řešit?