Nextras\Datagrid – datagrid se vsim jak ma byt

hrach
Člen | 1834
+
0
-

@ali: diky moc, opraveno
@H0w4rd: diky za tip, pridano
@thorewi: diky moc za analyzu, byla to jeste jina chyba, opraveno

H0w4rd
Člen | 94
+
0
-

Zkoumal jsem inline editing a mám dotaz, zda to umí stejným způsobem i přidávat řádky?

EDIT:
Odkaz See demo zde a ani Try demo zde nefunguje.

EDIT2:
Pokousel jsem se pouzit inline editaci, bohuzel bez uspechu.
Ve chvili, kdy zavolam $grid->setEditFormFactory($this->createEditForm);
je uplne jedno, co je v te metode createEditForm, nestihne se zavolat, driv to totiz spadne kvuli memory limitu. Krokoval jsem to prikazem die() a nasel jsem, co pada:

DataGrid.php – metoda getData() – příkaz $this[‚form‘][‚filter‘]->getValues(TRUE)

Fatal error: Allowed memory size of NNN bytes exhausted

Mrzi me to, ale nemohu inline editaci pouzit, neb hori termin, ale bylo by dobre to nejak poladit pro priste.

hrach
Člen | 1834
+
0
-

HH0w4rd: add memory limit – vyzousel jsi na locale sve demo? A to ti taky nefunguje? Imo je to asi nejakou spatnou tvoji implementaci…

H0w4rd
Člen | 94
+
0
-

Ale vždyť píšu, že to moji funkci ani nezavola, spadne to dřív.

thorewi
Člen | 84
+
0
-

@hrach: co rikas na to, ze by se tento kod:

{formContainer edit}
	{input $column->name}
	{if $_form[$column->name]->hasErrors()}
		<p class="error" n:foreach="$_form[$column->name]->getErrors() as $error">{$error}</p>
	{/if}
{/formContainer}

upravil nasledovne:

{formContainer edit}
	{ifset #cell-$column->name}
		{include #"input-{$column->name}" form => $_form, _form => $_form, column => $column}
	{else}
		{input $column->name}
	{/if}
	{if $_form[$column->name]->hasErrors()}
		<p class="error" n:foreach="$_form[$column->name]->getErrors() as $error">{$error}</p>
	{/if}
{/formContainer}

abych si mohl k urcitemu sloupci vlozit input, ktery mam ale jinak pojmenovany nez ten sloupec, podobne jak mi to umoznuje #col-filter-{$column->name}?

hrach
Člen | 1834
+
0
-

Asi bych nechal na tobe i generovani toho error, bud to udelas cely, nebo nic. Za chvili nekdo prijde s zadosti vlastniho bloku na error…

thorewi
Člen | 84
+
0
-

j to mas pravdu. hodis to do masteru nebo ti mam hodit pull request?

hrach
Člen | 1834
+
0
-

pull a hlavne si to otestuj. jo, jeste mozna lepsi nazev toho blocku? cell-input-*.

thorewi
Člen | 84
+
0
-

Mam dotaz – kdyz zmenim hodnotu nejakeho filter inputu javascriptem a chci cely formular odeslat, co bych mel zavolat? V nextras.datagrid.js se to resi pres

$(this).parents('tr').find('[name=filter\\[filter\\]]').trigger(datagrid.createClickEvent($(this)));

ale verim ze se to da zavolat i jednoduseji :) Diky za radu.

EDIT:

vyreseno pres

$('#frm-clientsGrid-form-filter-filter').click();

Editoval thorewi (4. 5. 2014 13:20)

thorewi
Člen | 84
+
0
-

@hrach: potreboval jsem neco zavolat pred odeslanim a po odeslani requestu, tak jsem si do datagrid extension pridal volani this.before, this.after, cca takto:

before: function(xhr, settings) {
	this.grid = settings.nette.el.parents('.grid');
	if(this.before) this.before();
},
success: function() {
	this.load(this.grid);
	if(this.after) this.after();
}

pak staci jen $.nette.ext(‚datagrid‘).before = function() {} (to stejne pro after).

Co na to rikas? Mohlo by se udelat i neco sofistikovanejsiho, treba ze by slo pridat vice after/before funkci do fronty, ale prislo mi to zbytecne.

EDIT:

pridano osetreni, pokud nejsou after/before funkce definovany

Editoval thorewi (4. 5. 2014 21:54)

H0w4rd
Člen | 94
+
0
-

Prosím pěkně, dokázal bych nějak zajistit, aby položky ve filtru byly persistentní? Když jsem dělal tabulky po staru, stačilo do presenteru napsat

/** @persistent */
public $filter_name;

Jak to dokážu udělat z tímto datagridem? Velmi nutně to potřebuju. Jinak všechno perfektní.

thorewi
Člen | 84
+
0
-

@H0w4rd: pokud se dobre divam do zdrojoveho kodu, polozky ve filtru jsou persistentni

/** @persistent */
public $filter = array();

Editoval thorewi (9. 5. 2014 16:26)

H0w4rd
Člen | 94
+
0
-

Tak jeste doplnim, o co mi jde.

V akcnim sloupecku mam ikonku na aktivaci/deaktivaci zaznamu.
Na teto ikonce je odkaz n:href=„Invoice:switch“

V prezenteru mám toto:

public function actionSwitch($id)
{
    $this->invoiceRepository->switchActive($id);

    $this->flashMessage('Stav faktury byl změněn.', 'success');
    $this->redirect('Invoice:');
}

No a pote co se udela redirect, filtr je prazdny.

thorewi
Člen | 84
+
0
-

a nemohl bys to udelat ajaxove tu aktivaci/deaktivaci zaznamu? Tim padem bys toto nemusel resit.

H0w4rd
Člen | 94
+
0
-

Ano mohl, ale krome aktivacni ikonky tam mam jeste editacni ikonku, ktera vede na actionEdit($id) a po ulozeni formulare je zase redirect zpatky a i v tomto pripade se filtr vyprazdni. To bych musel uplne vsechno predelat do ajaxu / dialog boxu :)

EDIT: Jinak si budu muset udelat svou funkci redirect, ktera projede polozky ve filtru (ktere mam v poli) a vygeneruje redirect s takovymi parametry, aby zustaly. To ale budu v haji s hodinama, musi to jit nejak easy.

Editoval H0w4rd (9. 5. 2014 17:06)

H0w4rd
Člen | 94
+
0
-

Tak to mi reknete, jak mam zajistit persistentnost parametru, kdyz je v URL tohle:

?customerList-dataGrid-filter[name]=bagr
&customerList-dataGrid-filter[address]=test
&customerList-dataGrid-filter[ic]=999
&customerList-dataGrid-filter[active]=yes

Zkousel jsem davat do presenteru:

/** @persistent */
public $customerListDataGridFilter;

/** @persistent */
public $customerListDataGrid;

/** @persistent */
public $customerList;

Ani jedno nepomohlo. Ja nevim, co s tim. Jako nejvhodnejsi workaround se mi jevi v javascriptu povesit na filtrovaci tlacitko udalost click a tam nahazet hodnoty z filtru do cookies, pote pri dalsim zobrazeni stranky si php stav filtru obnovi.

Editoval H0w4rd (12. 5. 2014 15:31)

MW
Člen | 615
+
0
-

Prosím o radu.
Jak nejlépe zachovam stav gridu v ramci celého presenteru.

začal jsem tímto

/** @persistent */
   public $filter = array();

coz me navratove url generuje dobře, ale potřebuji ješte radu co dal.

Díky

EDIT: ted koumám, ze je to duplicitni dotaz.. ale není odpověď.. nejaka rada tedy prosim?

EDIT2: tak problém je v tom, ze když z komponenty odkazuju na presenter:

<a href="{plink edit $primary}"......

generuje me to URL ?filter[‚cokoliv‘]
kdezto, aby to fungovalo, musí to byt ?nazev_komponety-filter[‚cokoliv‘] ..

Prosím tedy o radu, jak to nejlépe osetrit…

Moc dekuji !

EDIT 3 – Vyřešeno !

/**
* @persistent(komponenta)
*/

ovšem jen veřím, že to je takto aspoň trochu správně… ale funguje to.

Editoval MW (13. 5. 2014 10:21)

H0w4rd
Člen | 94
+
0
-

Tomu reseni vubec nerozumim, co kam mam napsat? Muzes mi prosim poradit?

EDIT:
Tohle totiz u me vubec nic nedela:

/**
 * @persistent(customerList)
 */
public $filter;

Editoval H0w4rd (13. 5. 2014 10:30)

MW
Člen | 615
+
0
-

H0w4rd napsal(a):

Tomu reseni vubec nerozumim, co kam mam napsat? Muzes mi prosim poradit?

EDIT:
Tohle totiz u me vubec nic nedela:

/**
 * @persistent(customerList)
 */
public $filter;

Musis to dat před třidu:

    /**
    * @persistent(nazevKomponenty)
    */


class xxxPresenter extends BasePresenter {
........

jedná se o perzistentní komponentu…

Editoval MW (13. 5. 2014 13:14)

Honza_S
Člen | 12
+
0
-

voda napsal(a):

Úpravy datagridu už nejsou potřeba. Jinak DateInput nevrací \Nette\DateTime ale DateTime.

Tak jsem po 3 měsících narazil na pokračování tohoto problému v souvislosti s paginatorem – filtr s DateInput zafunguje, ale jen na první stránku. Odkaz na další stránku vypadá asi takto …

http://xxx/?verifGrid-page=2&verifGrid-filter%5Bdatum_zalozeni%5D%5Bdate%5D=2014-03-25+00%3A00%3A00&verifGrid-filter%5Bdatum_zalozeni%5D%5Btimezone_type%5D=3&verifGrid-filter%5Bdatum_zalozeni%5D%5Btimezone%5D=Europe%2FPrague&do=verifGrid-paginate

jsem trochu v koncích s fantazií co s tím udělat – najde se dobrá duše co poradí?

Díky

MW
Člen | 615
+
0
-

Honza_S napsal(a):

voda napsal(a):

Úpravy datagridu už nejsou potřeba. Jinak DateInput nevrací \Nette\DateTime ale DateTime.

Tak jsem po 3 měsících narazil na pokračování tohoto problému v souvislosti s paginatorem – filtr s DateInput zafunguje, ale jen na první stránku. Odkaz na další stránku vypadá asi takto …

http://xxx/?verifGrid-page=2&verifGrid-filter%5Bdatum_zalozeni%5D%5Bdate%5D=2014-03-25+00%3A00%3A00&verifGrid-filter%5Bdatum_zalozeni%5D%5Btimezone_type%5D=3&verifGrid-filter%5Bdatum_zalozeni%5D%5Btimezone%5D=Europe%2FPrague&do=verifGrid-paginate

jsem trochu v koncích s fantazií co s tím udělat – najde se dobrá duše co poradí?

Díky

A nestrankuje? Chova se me to stejne, ale strankovani funguje…

Honza_S
Člen | 12
+
0
-

A nestrankuje? Chova se me to stejne, ale strankovani funguje…

:) stačilo nakopnout … chyba byla samozřejmě u mne ve zpracování filtru – už to stránkuje

Budry
Člen | 88
+
0
-

Zdravím,

nejsem si úplně jistý tím, jestli nedělám někde chybu já, ale pravděpodobně jsem narazil na chybu. V případě, že použiji ve formuláři pro inline editaci validační pravidla a mám nalinkovaný netteForms.js validace se provádí i v případě že editaci zruším tlačítkem ‚Cancel‘

$datagrid = new Datagrid();
$datagrid->addColumn('email');
$datagrid->setRowPrimaryKey('id');
$datagrid->setDataSourceCallback(function () {
	$entity = new \stdClass();
	$entity->email = 'no-email';
	$entity->id = 1;
	return array(
		0 => $entity
	);
});
$datagrid->setEditFormFactory(function($row) {
	$form = new Container();
	$form->addText('email')
		->addRule(Form::EMAIL, 'Email is no correct');
	if ($row) $form->setDefaults((array)$row);

	return $form;
	});

	return $datagrid;
}

Pokud netteForms.js nemám nalinkovaný a zmáčknu ‚Cancel‘ editace se zruší a vše je ok, pokud ho ale mám tak vyskočí alert s tím, že email nemá správný formát, což opravdu nemá, ale ‚Cancel‘ by to měl ignorovat nebo se pletu?

H0w4rd
Člen | 94
+
0
-

Bylo by možné přidat volbu, aby paginator vypisoval kromě např. 2 / 8 i aktivní čísla stránek, aby se na ně dalo kliknout a přejít přímo na danou stránku?
Zákazník to chce a já tím pádem si to budu muset dobastlit přímo v DataGrid.latte.

H0w4rd
Člen | 94
+
0
-

Pozor, s Nette 2.0.15 to hází error:

Class ‚Nette\Utils\Callback‘ not found

136: public function setDataSourceCallback($dataSourceCallback)
137: {
138: Callback::check($dataSourceCallback);
139: $this->dataSourceCallback = $dataSourceCallback;
140: }

EDIT: A funguje mi vubec filtrovani, po kliknuti na Filtrovat se sice ajaxem zavola server, tam jsem si debugoval, ze se data vytahnou spravne, returnem vrati, ale datagrid nic neudela.

Editoval H0w4rd (12. 6. 2014 17:44)

hrach
Člen | 1834
+
0
-

S nette 2.0.15 je kopatibilni max. rada ~2.0.0.

H0w4rd
Člen | 94
+
0
-

Kdyz jsem tam nahral verzi 2.0.0, vubec nic nefungovalo, vracel se server error, ani ladenka tam nebyla.
Prohlizel jsem si kod, tohle treba nemuze fungovat v PHP 5.3:

$this->filterDefaults = [];

EDIT: A kdyz jsem si to opravil, zadna zmena, filtrovani nefunguje. Po kliku na tlacitko Filtrovat se nic nezmeni, ani do konzole se nevypise zadny error, na serveru se callback na ziskani dat spusti, vrati se spravne, ale datagrid nic neudela.

Editoval H0w4rd (13. 6. 2014 9:54)

hrach
Člen | 1834
+
0
-

zkus v2.0.1-RC1. Neni tam nic jineho, nez v aktualnim stablu, ktery je jenom pro nette 2.2.

David Klouček
Člen | 57
+
0
-

Jak se dostanu v továrně k šabloně? Potřebuju jednoduše zaregistrovat helper. $grid->template hází Component '' is not attached to ‚Nette\Application\UI\Presenter‘ a pomocí `templatePrepareFilters `to nefunguje.

hrach
Člen | 1834
+
+1
-

no kdyz komponentu zaregistrujes „po staru“, tak to pujde ;)

protected createComponentGrid($name)
{
	$grid = new Datagrid($this, $name);
	...
	return $grid;
}

nicmene asi zkusim neco vymyslet do budoucna :)

H0w4rd
Člen | 94
+
0
-

MW napsal(a):

Musis to dat před třidu:

    /**
    * @persistent(nazevKomponenty)
    */


class xxxPresenter extends BasePresenter {
........

jedná se o perzistentní komponentu…

Diky, funguje to.

Jeste pridam jeden postreh.
Mel jsem v metode actionNeco() napsany redirect a ten mi vzdycky zlikvidoval persistentni parametry.
Badal jsem proc a zjistil jsem, ze kdyz je redirect v komponente nebo v renderNeco() metode, tak je to OK.

knoxa
Člen | 16
+
0
-

Ahoj,
v aktuálních verzích Nette a Datagridu mně nefunguje makro redefine. Nainstalováno přes composer:

"nette/nette": "~2.2.0",
"nextras/datagrid": "2.1.1"

Definice komponenty:

<?php
        $grid = new Datagrid();
        $grid->addColumn('id');
        $grid->addColumn('title')->enableSort($grid::ORDER_ASC);

        $grid->setDataSourceCallback($this->getDataSource);

        $grid->addCellsTemplate(__DIR__ . '/../../vendor/nextras/datagrid/bootstrap-style/@bootstrap3.datagrid.latte');
        $grid->addCellsTemplate(__DIR__ . '/test.latte');
        return $grid;
?>

test.latte:

{redefine row-actions}
    <a href="#">akce</a>
{/redefine}

config.neon:

latte:
	macros:
		- Nextras\Latte\Macros\RedefineMacro::install

Nefunguje bootstrap style, což se dá přežít, ale nedostanu tam ani row-actions, což je větší problém. Je to chybka nebo mi uniká ještě nějaký nastavení, případně dělám něco blbě?

hrach
Člen | 1834
+
0
-

Je to BC break v Nette 2.2.2, Kdyžtak pouzij zatim 2.2.1…nez to fixnu. Viz issue na https://github.com/…latte-macros

knoxa
Člen | 16
+
0
-

Aha, nevšim jsem si toho issue v repu… Dík za info.

lpq
Člen | 10
+
0
-

Ahoj, mám takový problém

při použití:
$grid->addCellsTemplate(‚fType.latte‘);
mi hlásí chybu
Missing template file ‚/var/www/pujckaihned.dev/vendor/nextras/datagrid/src/fType.latte‘

Source file
File: …/vendor/latte/latte/src/Latte/Loaders/FileLoader.php:28

pokud doplním template do /vendor/nextras/datagrid/src
tak vše funguje.

Děkuji za radu.

nette 2.2.0

Editoval lpq (27. 6. 2014 11:06)

H0w4rd
Člen | 94
+
0
-

dej tam $grid->addCellsTemplate(__DIR__ . „/relativni/cesta/k/tvemu/latte/fType.latte“);

H0w4rd
Člen | 94
+
0
-

Diky za novou verzi kompatibilni s Nette 2.2.2.

Narazil jsem na problem, v gridu potrebuju vlastni helper.
Zatim jsem to „spravil“ takhle:

$this->template->setFile(__DIR__ . '/Datagrid.latte');
\Helpers::registerAll($this->template);
$this->template->render();

Samozrejme az bude nova verze, musim si to tam zase pridat. Mozna by bylo dobre reseni mit moznost registrovat nove helpery pres callback, kdyz se grid vytvari.

BTW kdyby bylo mozne registrovat helpery nejak globalne (treba v config.neon), bylo by to vyresene, ale to se mi nepodarilo vygooglit.

Editoval H0w4rd (3. 7. 2014 11:59)

Michal Vyšinský
Člen | 608
+
0
-

Ahoj,
je možné nějak vytvořit template buňky v závislosti na typu? Např. datum bych chtěl renderovat určitým způsobem – boolean hodnoty bych chtěl zase místo 1/0 renderovat určitou ikonkou atd. Takže nejlépe nějaký univerzální blok pro buňku nezávislý na jménu.

hrach
Člen | 1834
+
0
-

@MichalVyšinský ne, a asi bych to ani nechtel programovat. faktem je, ze aktualne si to moc jednoduse nemuzes upravit ani ty…asi by to chtelo block row-inner zrefaktorovat.

Michal Vyšinský
Člen | 608
+
0
-

@hrach ok, díky. Zkusím na to mrknout a případně poslat PR pokud se mi něco povede.

Drake
Člen | 13
+
0
-

Můžu poprosit o zdrojáky toho dema? Pro začátečníky je to užitečné, ať si to můžou vyzkoušet na něčem co funguje. Díky.

hrach
Člen | 1834
+
0
-

@Drake uz je to dlouho: https://github.com/nextras/demos

Jezour
Člen | 2
+
0
-

Ahoj, dnes jsem resil problem inline editace a nasledneho pridani erroru konkretnimu inputu na zaklade vlastniho validacniho pravidla (proti DB) a to po odeslani inline editacniho formulare. Myslim si, ze se tento postup bude par lidem urcite hodit.

public function validateGridForm($form) {
    $values = $form->getValues();
    //if (...) { // validační podmínka - v mem pripade zkontroluji name se jmeny v DB
        $form['name']->addError('Tato kombinace není možná.'); // nazev inputu, kteremu chci priradit error
    //}
}

    $grid->setEditFormFactory(function($row) {
        $form = new Nette\Forms\Container;
        $form->addText('name')->setRequired();
        // kod stejny jako vzorovy v prikladu ...
        $form->onValidate[] = array($this, 'validateGridForm');
        return $form;
    });

    $grid->setEditFormCallback(function ($form) {
        $values = $form->getValues();
        // akce po validaci, napr. $this->database-> ...
    });

Editoval Jezour (12. 8. 2014 11:58)

nanuqcz
Člen | 822
+
0
-

Ahoj,
používám Nextras/Datagrid a jeho šablonu pro Bootstrap 3. A snažím se v poděděné šabloně změnit způsob vykreslování filtrů:

<!-- /app/templates/@datagrid.upraveny.latte -->
{extends '...cesta_k_nextras_datagridu.../@bootstrap3.datagrid.latte'}


{define col-filter}
	{input $column->name, class => "form-control"}
{/define}

Toto ale bohužel nic neudělá a ve filtru se pořád vykresluje input s třídou "input-sm". Zkoušel jsem i {redefine col-filter}, ale výsledek stejný.

Děkuji za radu.

hrach
Člen | 1834
+
0
-

@nanuqcz

  • urcite redefine
  • sablony k dedeni predavej v tovarnicce (nevim jestli to extends funguje, mozna prave proto ne)
  • col-filter se nic nejmenuje… uz. ocichej si blocky zde https://github.com/…tagrid.latte, a ikdyby si mel tu starsi verzi, kde to bylo, tak se tim delalo neco jineho.
nanuqcz
Člen | 822
+
0
-

@hrach

sablony k dedeni predavej v tovarnicce (nevim jestli to extends funguje, mozna prave proto ne)

Makro {extends} mi funguje, přepisuju tím bloky jednotlivých sloupečků s daty ({col-*}) a blok {row-actions}, což funguje perfektně. Ale {redefine col-filter} prostě nic nedělá. Ty šablony v továrničce zkusím.

col-filter se nic nejmenuje… uz. ocichej si blocky zde https://github.com/…tagrid.latte

Ale právě zde vidím, že jmenuje:

…a zde se tam pak dostává class="input-sm", který chci přepsat: https://github.com/…tagrid.latte#L12.

Díky.

Editoval nanuqcz (22. 8. 2014 14:38)

abc
Člen | 92
+
0
-

Ahoj,

prosím o radu. V datagridu ve filtru bych chtěl používat filtr na datum.
Na date jsem použil tuto komponentu: https://componette.org/search/?…

Všechno funguje správně až do provedení filtrace, po filtraci se prvek překreslí na HTML 5 input date.
Mohu s tím něco udělat, aby se to nepřekreslovalo?

Vytvoření komponenty:

public function createComponentCustomerDatagrid() {
 $grid = new Datagrid;
 $grid->addColumn("action_date", "Další akce");

 $grid->setFilterFormFactory(function() {
 $form = new Nette\Forms\Container;
 $form->addDate("action_date", "Příští akce", DateInput::TYPE_DATE);
}

Model:

private function prepareDataSource($filter, $order) {
    $filters = array();
    foreach ($filter as $k => $v) {
        if ($k === 'action_date') {
            $filters["$k <= ?"] = $v->format("Y-m-d");
hrach
Člen | 1834
+
0
-

asi nechapu, co se ti deje.

abc
Člen | 92
+
0
-

Když načtu stránku, tak je ve filtru na tom místě normálně input, který po poklepání otevře jQuery UI datepicker – tj. ta komponenta od „voda“.
Zvolím datum přes datepicker, datum se vloží do inputu, klepnu na filtrovat, z DB se vytáhnou správné záznamy, Datagrid se překreslí, ale místo datepickeru, který tam byl původně je tam najednou input=date z prohlížeče a po poklepání už na něm nefunguje datepicker.
Pro jistotu přidávám 2× screen, kde je možnost náhledu.

  1. před filtrací je ve filtru datepicker

http://tinypic.com/r/21ammbm/8

  1. Po filtraci už ve filtru nefunguje datepicker a je tam normální input date z prohlížeče

http://tinypic.com/r/23k51ro/8

Případně nevíš o nějaké komponentě, kterou bych mohl takto použít a „nerozbila“ se při filtraci?

Editoval abc (22. 8. 2014 17:31)

MartinitCZ
Člen | 580
+
+1
-

Což není problém datapickeru nýbrž toho, že po ajaxovém requestu znovu ten datepicker neinicializuješ. ;)