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

sikulam
Člen | 12
+
+1
-

@PavelJanda jj pomohlo. Díky moc za radu.

IJVo
Člen | 38
+
0
-

@PavelJanda Díky moc, je to perfektní. Jak je to jednoduché :-)

Domki
Člen | 310
+
0
-

Dá se v datagridu nějak nastavit způsob vypisování stránkování?

  1. Aby se nevypisovalo jen 1 2 3…20 Ale: 1 2 3 4 5 Prostě všechny stranky (přechazení po 3 je zdlouhave)
  2. Aby se blok se strankovaním zobrazil (i) nad datagridem?

Díky

Pavel Janda
Člen | 977
+
0
-

@Domki

Ad a, jasně, nastav paginatoru datagridu vlastní šablonu, případně vyměň celý paginator.
Paginator najdeš zde: $grid['paginator']->setTemplateFile($myTemplate). Vyměníš ho třeba takto:

$grid->onRender[] = function() use (DataGrid $grid) {
	$grid->addComponent(new MyPaginator($grid->page, $grid->per_page), 'paginator');
}

Tak nějak jdou moje myšlenky. Třeba to bude ve skutečnosti malinko jinak. :)

Ad b, jasně, poděď si výchozí šablonu datagridu a uprav.

Petr Parolek
Člen | 455
+
0
-

Ahoj, jak mám omezit vstupní data z Doctrine v modelu prosím?

<?php
return $this->repository->createQueryBuilder('er');
?>

funguje správně

<?php
return $this->repository->createQueryBuilder('er')
                ->select('d')->from(\App\Model\Entities\InvoiceItem::class, 'd')
                ->where('d.invoice = :id')->setParameter("id", $id)->getQuery()->getResult();
?>
<?php
return $this->repository->findBy(Array("invoice"=>$id));
?>

u těchto dvou variant se nepřekreslí datagrid.

Díky moc za pomoc

Editoval ppar (24. 2. 2017 19:05)

Petr Parolek
Člen | 455
+
0
-

entity

<?php
namespace App\Model\Entities;use Doctrine\ORM\Mapping AS ORM;
use Kdyby\Doctrine\Entities\BaseEntity;
use Kdyby\Doctrine\Entities\Attributes\Identifier;

/**
* @ORM\Entity
* @ORM\Table(name="invoice_items")
*/
class InvoiceItem extends BaseEntity
{
   /**
    * @ORM\Id
    * @ORM\Column(type="integer")
    * @ORM\GeneratedValue
    */
   protected $id;    /**
    * @ORM\Column(type="string", nullable=false)
    * @var string
    */
   protected $title;

   /**
    * @ORM\ManyToOne(targetEntity="Invoice")
    * @ORM\JoinColumn(name="invoice_id", nullable=false, referencedColumnName="id", onDelete="RESTRICT")
    */
   protected $invoice;

   /**
    * @ORM\Column(type="decimal", precision=9, scale=2, nullable=false)
    */
   protected $quantity;

   /**
    * @ORM\Column(type="string", nullable=false)
    * @var string
    */
   protected $unit;

   /**
    * @ORM\Column(type="decimal", precision=9, scale=2, nullable=false)
    */
   protected $unitPrice;

   protected $price;    public function __construct()
   {
       $this->invoice = new Invoice();
   }

   public function getInvoice()
   {
       return $this->invoice;
   }

   public function getPrice() {
       $price = $this->quantity * $this->unitPrice;

       return number_format((float)$price, 2, '.', '');
   }
}
?>
<?php
namespace App\Model\Entities;use Doctrine\ORM\Mapping AS ORM;
use Kdyby\Doctrine\Entities\BaseEntity;
/**
* @ORM\Entity
* @ORM\Table(name="invoices")
*/
class Invoice extends BaseEntity
{
   /**
    * @ORM\Id
    * @ORM\Column(type="integer")
    * @ORM\GeneratedValue
    */
   protected $id;    /**
    * @ORM\Column(type="string", nullable=false)
    * @var string
    */
   protected $no;

   /**
    * @ORM\Column(type="string", nullable=false)
    * @var string
    */
   protected $type;

   /**
    * @ORM\Column(type="string", nullable=false)
    * @var string
    */
   protected $subject;

   /**
    * @ORM\Column(type="decimal", precision=9, scale=2, nullable=false)
    */
   protected $price;

   /**
    * @ORM\Column(type="date", nullable=false)
    */
   protected $issuedDate;

   /**
    * @ORM\Column(type="date", nullable=false)
    */
   protected $dueDate;

   /**
    * @ORM\Column(type="date", nullable=true)
    */
   protected $paymentDate;

   public function __construct()
   {
       $this->issuedDate = new \DateTime();
       $this->dueDate = new \DateTime();
   }
}
?>

Nebo je problém v entitě?

Editoval ppar (24. 2. 2017 20:24)

Petr Parolek
Člen | 455
+
0
-

vyřešeno

<?php
return $this->invoiceItemRepository->createQueryBuilder('er')
                ->select('d')
                ->add('from', '\App\Model\Entities\InvoiceItem d INNER JOIN d.invoice i')
                ->where('i.id = :id')->setParameter("id", $id);
?>
Domki
Člen | 310
+
0
-

@PavelJanda Díky jo to by šlo kouknu na to a zkusím.

Jen mě ted prekvapila ještě jedna věc, před ostrým nasazením. Na Data grid jsem pustil ostré data. A stránka s datagridem se načítá přiliš dlouho (Až do vyčerpání 30s limitu) Ladenka píše
Execution time 30 084.7 ms
Peak of allocated memory 40.44 MB
Included files 361

Jedná se cca o 6000 zaznamu v tabulce products, na které je navazano zaznamy z variant produktu + 1:1 kategorie a znacky. Pří 20000 byl čas 10s, při přidani dalších 1000 záznamu se čas zvyšší cca o 10 s.
Stejný problém i u jiné tabulky cca s 2500 záznamy.

Odkomentoval jsem vetsinu sloupcu, ale probém je stale. A laděnka vypisuje čas sql dotazu cca 154ms. Podle toho hadam ze to není složitym sql dotazem ale počtem zaznamu, protože to trvá tak dlouho i při jednoduchém

Nějaký nápad jestli bych mohl mít někde něco špatně nebo čím to? 6000 záznamu se mi nezdá tolik.

Editoval Domki (27. 2. 2017 15:22)

Pavel Janda
Člen | 977
+
0
-

@Domki To je dost divné. Není možné, že jsi vybral u počtu položek na stránku výpis všech produktů? Jiná možnost mě nenapadá.

Domki
Člen | 310
+
0
-

@PavelJanda Právě že ne, je zaškrtlý 20.
Ted jsem zmenil strankovani na : $grid->setItemsPerPageList([20, 50], false);
Vymazal cache ale porad stejne, na strance se jich zobrazi taky jen 20, dole se vypise strankovaní s 1–300 stránka. Vykresli se to fajn, ale dále stránka se načítá, a po pul minute vyskočí chyba vyprsení času.

Pavel Janda
Člen | 977
+
0
-

@Domki Můžeš zkusit krokovat kód a zjistit, kde dochází k alokaci takového množství paměti? Divil bych se, kdyby to bylo někde v datagridu.

bazo
Člen | 620
+
+1
-

ahoj,

slo by vykreslit datagrid v tree view naraz so vsetkymi (pod)polozkami, ak uz mam v array cely strom?
aby sa nemuseli children dotahovat ajaxom

diky

Pavel Janda
Člen | 977
+
0
-

@bazo Můžeš si na to napsat vlastní šablonu, která rovnou načte potomky. Momentálně je výchozí šablona stavěna právě na ajax.

Domki
Člen | 310
+
0
-

@PavelJanda Jo nebylo to uplně datagridem ale componentou volanou z datagridu už jde, super díky ;-)
Jen ještě k tomu stránkování, zjistil jsem že dříve už jsem to upravoval ale ve vendoru, kde se to pri aktualizaci smazalo =D
Jak to tedy mohu podedit?
Potřeboval bych ve tříde DataGridPaginator.php na řadku 119 zmenit $count = 1 za $count = 200;

/**
			 * Something to do with steps in tempale...
			 * [Default $count = 3;]
			 * @var int
			 */
			$count = 1;

a pak soubor datagrid.latte

Dá se nějak podedit to latte pomocí nastavení vlastní šablony: $grid->setTemplateFile a nasledne pomoci nejakeho makra?
Nebo na to musím jinak? Tyto upravy jsou jen pro jeden datagrid

Editoval Domki (27. 2. 2017 15:43)

Pavel Janda
Člen | 977
+
0
-

@Domki Fungoval ti příklad, který jsem nastínil v tom příspvěku https://forum.nette.org/…any-datagrid?p=17 Normálně tam šoupneš svojí instanci, odkud chceš.

datagrid.latte: https://ublaboo.org/…rid/template#… :)

Domki
Člen | 310
+
0
-

Ne, paginator vytvarim:

$grid->setColumnsHideable();
		$grid->setPagination(TRUE);
		$grid->setItemsPerPageList([20, 50, 100, 200, 500, 1000], TRUE);

		$grid->onRender[] = function() use ($grid) {
			$grid->addComponent(new MyDataGridPaginator($grid->getTranslator(), $grid->page, $grid->per_page), 'paginator');
		};

A MyDataGridPaginator vypada:
<?php
namespace App\AdminModule\Presenters;

use Tracy\Debugger;
use Ublaboo\DataGrid\Components\DataGridPaginator\DataGridPaginator;
use Ublaboo\DataGrid\DataGrid;
use Nette;
use Nette\ComponentModel\IContainer;

/**
 * Visual paginator control.
 *
 * @property-read Nette\Application\UI\ITemplate $template
 */
class MyDataGridPaginator extends DataGridPaginator
{

	private $page;
	private $perPage;

	public function __construct(
		$translator,
		$page = 1,
		$perPage,
		IContainer $parent = NULL,
		$name = NULL
	) {
		parent::__construct($translator, 'fa fa-', $parent, $name);
		$this->page = $page;
		$this->perPage = $perPage;
	}


	/**
	 * @var Nette\Utils\Paginator
	 */
	private $paginator;

	/**
	 * @var string
	 */
	private $template_file;


	public function setTemplateFile($template_file)
	{
		$this->template_file = (string) $template_file;
	}


	public function getTemplateFile()
	{
		return __DIR__ . '/../templates/Inventories/datagrid_inventory_products_paginator_template.latte';
	}


	/**
	 * Get paginator original template file
	 * @return string
	 */
	public function getOriginalTemplateFile()
	{
		return __DIR__.'/templates/data_grid_paginator.latte';
	}


	/**
	 * @return Nette\Utils\Paginator
	 */
	public function getPaginator()
	{
		if (!$this->paginator) {
			$this->paginator = new Nette\Utils\Paginator;
		}

		return $this->paginator;
	}


	/**
	 * Renders paginator.
	 * @return void
	 */
	public function render()
	{
		$paginator = $this->getPaginator();
		$paginator->setPage($this->page);
		$paginator->setItemsPerPage($this->perPage);
		$page = $paginator->page;

		if ($paginator->pageCount < 2) {
			$steps = array($page);

		} else {
			$arr = range(max($paginator->firstPage, $page - 2), min($paginator->lastPage, $page + 2));

			/**
			 * Something to do with steps in tempale...
			 * [Default $count = 3;]
			 * @var int
			 */
			$count = 200;

			$quotient = ($paginator->pageCount - 1) / $count;
			for ($i = 0; $i <= $count; $i++) {
				$arr[] = round($quotient * $i) + $paginator->firstPage;
			}
			sort($arr);
			$steps = array_values(array_unique($arr));
		}

		if (!isset($this->template->steps)) {
			$this->template->add('steps', $steps);
		}

		if (!isset($this->template->paginator)) {
			$this->template->add('paginator', $paginator);
		}

		//$this->template->add('icon_prefix', $this->icon_prefix);
		$this->template->icon_prefix = 'fa fa-';
		//$this->template->add('original_template', $this->getOriginalTemplateFile());
		$this->template->original_template = $this->getOriginalTemplateFile();
		$this->template->setFile($this->getTemplateFile());
		$this->template->render();
	}


	/**
	 * Loads state informations.
	 * @param  array
	 * @return void
	 */
	public function loadState(array $params)
	{
		parent::loadState($params);

		if ($this->getParent() instanceof DataGrid) {
			$this->getPaginator()->page = $this->getParent()->page;
		}
	}

}

Nyní mi to vypisuje paginator jak chci tedy co stranka to tlačítko. Ale nefunguje stránkování na jednotlivé řadky, na strance se zobrazuje 1 zaznam ač je nastavenu ve formulari 100 a strankovaní se také zobrazuje na 100. Nevím co by se presne melo udelat s promenymi $page, perPage, ja je nastavil v render metode do $paginatoru

radas
Člen | 224
+
+1
-

Ahoj, používám vlastní renderování sloupce a narazil jsem na to, že bych tam potřeboval svůj Latte filtr. Je nějaká možnost, jak ho tam dostat pro tohle použití?

{extends $original_template}

{define col-mujSloupec}
  {$item->sloupec|mujLatteFiltr}
{/define}

Díky

Pavel Janda
Člen | 977
+
+2
-

@radas Jo, naprosto standardní cestou: $grid->getTempalte()->addFilter

radas
Člen | 224
+
0
-

@PavelJanda Super, díky moc.

flamengo
Člen | 135
+
0
-

@PavelJanda Ahoj, bohužel si opět nevím rady, co s tímto:

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

Změnil jsme pouze $grid->addFilterText('name', 'forms.inputs.name'); na $grid->addFilterText('P.name', 'forms.inputs.name');. Mám poslední čtyřkovou verzi (pětka mi nefunguje, nevím proč).

Jak toto opravím? Mám nějak vymazat session (jak)?

Předem díky za radu.

Pavel Janda
Člen | 977
+
0
-

@flamengo Ano, pomůže smazání cache. Ve verzi 5 už se hláška nevyhazuje. Co ti nefunguje ve verzi 5?

  • ne cache, sessions

Editoval Pavel Janda (2. 3. 2017 14:00)

flamengo
Člen | 135
+
0
-

@PavelJanda Tak jeden problém vyřeším a je tu zase další a zase nevím jak z toho ven :(

$query = "SELECT P.*
	FROM players P";
$datasource = new NetteDatabaseDataSource($this->model->getDatabase(), $query, []);
$grid->setDataSource($datasource);
$grid->setSortable();
$grid->setDefaultSort(['name' => 'ASC']);
$grid->addFilterText('name', 'name');
$grid->addColumnText('name', 'forms.inputs.name')->setSortable();

Funguje. Ale když změním SQL – přidám JOIN:

$query = "SELECT P.*
	FROM players P
	LEFT JOIN buildings B ON P.id = B.players_id";

tak:

Nette\Database\DriverException #23000
SQLSTATE[23000]: Integrity constraint violation: 1052 Column ‚name‘ in where clause is ambiguous search►
Caused by PDOException

SQL

SELECT COUNT(*) AS count
FROM players P
LEFT JOIN buildings B ON P.id = B.players_id
WHERE (name LIKE '%jmeno%')

Napadla mě tato úprava:

$grid->addFilterText('P.name', 'name');

ale:

Nette\InvalidArgumentException
Component name must be non-empty alphanumeric string, ‚P.name‘ given

Verze gridu 4.4.21.
Předem díky moc za nějakou radu.

Pavel Janda
Člen | 977
+
+1
-

@flamengo Viz docu: https://ublaboo.org/datagrid/filter Hned první příklad: argumenty metody addFilterText() jsou: $key, $name, $columns, tedy napiš:

$grid->addFilterText('name', 'name', 'P.name');
VK
Člen | 10
+
0
-

Čau,

neřešil jste někdo problém s Multiplier?
Když se pokouším továrničku gridu zaregistrovat pro více komponent, tak mi vyhodí exceptionu: Ublaboo\DataGrid\Exception\DataGridFilterNotFoundException : Session filter: Filter [params] not found

		return new NetteApp\UI\Multiplier(function ($type) use($name){
    $component = $this->postTypeGridFactory->create();
    $component->setDataSource($exampleRepository->createQueryBuilder('e'));
    $component->addColumnNumber('id', 'grid.column.id');

    return $component;
});

EDIT:

Problém vyřešen. Do session se mi dostalo pole hodnot s klíčem „params“, což opravdu nebyl žádný filtr. Jak se to stalo netuším a nepodařilo se mi chybu znova replikovat.

@PavelJanda Při hledání problému jsem ale narazil na řádek #1843 v DataGrid.php. Nebylo by vhodnější toto upravit tak, že místo aby si hledal filtry dle hodnot ze session, tak budeš hledat hodnoty dle nadefinovaných filtrů, viz ukázka?

Nahradit:

		foreach ($this->getSessionData() as $key => $value) {
			$other_session_keys = [
				'_grid_per_page',
				'_grid_sort',
				'_grid_page',
				'_grid_has_sorted',
				'_grid_has_filtered',
				'_grid_hidden_columns',
				'_grid_hidden_columns_manipulated'
			];

			if (!in_array($key, $other_session_keys)) {
				try {
					$this->getFilter($key);

					$this->filter[$key] = $value;

				} catch (DataGridException $e) {
					if ($this->strict_session_filter_values) {
						throw new DataGridFilterNotFoundException("Session filter: Filter [$key] not found");
					}
				}
			}
		}

tímto:

		foreach ($this->filters as $key => $filter) {
    $this->filter[$key] = $this->getSessionData($key);
}

Zkusil jsem a vše mi funguje. Rozdíl je myslím patrný ;) a osobně si myslím, že je to logičtější, ale nevím, zda si k tomu neměl nějaký další důvod, proč si zvolil takový postup. No pokud ne a si pro, tak můžu poslat PR.

Editoval VK (4. 3. 2017 16:34)

FTCP
Člen | 6
+
0
-

@PavelJanda Ahoj, datagrid funguje naprosto perfektně. Jenom maličkost, šla by přidat funkčnost pro práci s celkovým summary, ne jen custom callback pro každý row. Př: mám sloupce hodiny a koruny za hodinu, další sloupec průměr korun za jednu hodinu a chtěl bych v sumárkách vyplivnout celkový průměr korun za jednu hodinu, tzn sum(koruny)/sum(hodiny)

Pavel Janda
Člen | 977
+
0
-

@FTCP Jop, k tomu slouží agregační funkce. Ublaboo\DataGrid\AggregationFunction\*. Ještě jsem to nestihl zdokumentovat, ale používá se to cca takto:

$grid->addColumnNumber('id', 'Id');

$grid->addAggregationFunction('id', new Ublaboo\DataGrid\AggregationFunction\FunctionSum('id'));

Můžeš si implementovat jakoukoliv svojí agregační funkci, je k tomu určen interface Ublaboo\DataGrid\AggregationFunction\IAggregationFunction.

Editoval Pavel Janda (6. 3. 2017 12:54)

Petr Parolek
Člen | 455
+
0
-

ahoj, mám takový problém s znovupoužití komponenty s datagridem.

<?php
public function render($pagination)
   {
       $this->template->render(__DIR__ . '/invoiceControl.latte');
   }
?>

hlasi mi:
Warning
Missing argument 1 for App\Components\AcceptedInvoiceControl::render(), called in /vendor/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php on line 85 and defined

Poradil by mi nekdo prosim? Bez promenne paginator vse funguje ok.

Chtěl jsem nastavit parametr přes latte šablonu, mám ho nastavovat přes parametr v url? Protože se k němu dostanu z továrničky gridu.

Editoval ppar (6. 3. 2017 13:50)

schnappi
Člen | 13
+
0
-

Ahoj,

pri načítaní stránky s komponentou mi prepisuje URL, čo nie je úplne pekné. Napríklad po prejdení na URL http://.../mypresenter/show?lesson=6 mi URL automaticky zmení na http://.../mypresenter/show?myDataGrid-6-sort%5Bupload_date%5D=ASC.

Pri prezentéroch bez parametrov to nerobí žiadny problém, ale keď mám prezentér s parametrom, tak tento parameter z URL zmizne, čo nie je to čo by som chcel.

Je možné tomu nejak zabrániť alebo prepisovať URL tak, aby ma pri znovunačítaní stránky (F5) naozaj presmerovalo na tú istú stránku?

Vďaka za každú radu!

Pavel Janda
Člen | 977
+
0
-

@schnappi Uděláš parametr $lesson persistentní, aby se přenášel v presenter statu :)

schnappi
Člen | 13
+
0
-

@PavelJanda Aj mi to napadlo, ale nechcel som to takto riešiť vzhľadom na to, že prezentér obsahuje aj defaultnú akciu (žiadne parametre sa tam nepredávajú). Ale to sa dá vyriešiť vyNULLovaním premennej pri každej default akcii, takže vďaka, už to funguje viacmenej pekne. :)

F.Vesely
Člen | 369
+
0
-

Pavel Janda napsal(a):

@schnappi Uděláš parametr $lesson persistentní, aby se přenášel v presenter statu :)

A nebylo by lepsi, kdyby se datagrid staral o sve parametry a na ostatni nesahal?

Pavel Janda
Člen | 977
+
0
-

@F.Vesely To by šlo, kdyby mohl mít datagrid svůj adresní řádek. :) :)

radas
Člen | 224
+
0
-

Ahoj,
možná všetečný dotaz, ale proč DataGrid v zápatí vypisuje např. „Položky: 0 – 10 z …“ a ne „Položky 1 – 10 z …“? Díky.

Pavel Janda
Člen | 977
+
0
-

@radas Heh, dobrý postřeh. Pošleš PR?

Pavel Sláma
Člen | 2
+
0
-

Ahoj,
prvně musím pochválit za fantastickej datagrid.. Konečně něco použitelnýho co umí všechno.
Ale teď k problému co mám. Projel jsem si celé vlákno a dokonce se to tu jednou myslím řešilo, ale přišlo mi že nevyřešilo.

Mám komponentu

use Nette\Application\UI\Control;

class ProductGrid extends Control
{
	    /** @persistent int */
        public $categoryId;

		public function __construct($categoryId){
				$this->categoryId = $categoryId;
		}

		protected function createComponentProductGrid($name)
        {
                $grid = new DataGrid($this, $name);
                $grid->setDataSource(new DoctrineDataSource($this->productFacade->getProductsByCategory($this->categoryId), "id"));
		}

}

interface IProductGridFactory
{

        /**
		 * @param int $categoryId
         * @return ProductGrid
         */
        public function create($categoryId);
}

a presenter

class ProductPresenter extends AdminPresenter
{
		/**
         * @var Components\Grids\IProductGridFactory $productGridFactory
         * @inject
         */
        public $productGridFactory;

		protected function createComponentProductGrid()
        {
                $categoryId = $this->getParameter("categoryId");
                $grid = $this->productGridFactory->create(categoryId);

                return $grid;
        }
}

kde předám categoryId komponentě..
Když si zobrazím datagrid, tak to funguje správně, dokud nezačnu sortovat jakýkoliv sloupeček.
V url to vypadá takto /product/default/36?productGrid-productGrid-per_page=10

Pokud však udělám refresh stránky, tak do url se přidá parametr a url vypadá následovně /product/default/36?productGrid-categoryId=36&productGrid-productGrid-per_page=10

Nějaký nápad jak tam ten parametr nacpat dřív? nebo jak máte ve zvyku vymyslet ještě lepší řešení? :D

Editoval Pavel Sláma (10. 3. 2017 14:05)

Pavel Janda
Člen | 977
+
0
-

@PavelSláma Problém je v tom, že adresní řádek je jen jeden a komponent jsou spousty. Aby se držel stav presenteru (a komponent) v URL, jte potřeba nacpat je do global statu. Ideální je tak použít persistentní parametr categoryId v presenteru.

Pavel Sláma
Člen | 2
+
0
-

@PavelJanda tak přesně tohle jsem nechtěl slyšet :D o tom řešení vím, jen jsem doufal, že si to dokáže pořešit sama komponenta. Jediné čemu nerozumím je, proč se po tom, co udělám refresh stránky, vytvoří parametr productGrid-categoryId=36 se kterým už to funguje naprosto v pořádku.

Editoval Pavel Sláma (10. 3. 2017 14:35)

Pavel Janda
Člen | 977
+
0
-

@PavelSláma Jak by si to mohla vytvořit komponenta sama, když o tom parametru neví? :)

Editoval Pavel Janda (10. 3. 2017 14:43)

radas
Člen | 224
+
+1
-

Pavel Janda napsal(a):

@radas Heh, dobrý postřeh. Pošleš PR?

Jj, kouknu na to.

Petr Parolek
Člen | 455
+
0
-

Ahoj, záhadně mi nefungují flash zprávy, když mám datagrid v komponentě.

<?php
namespace App\Components;

use Nette;
use Nette\Application\UI\Control;
use Ublaboo\DataGrid\DataGrid;

class ItemControl extends Control
{
    public function render()
    {
        $this->template->render(__DIR__ . '/itemControl.latte');
    }


    public function createComponentInvoiceGrid($name)
    {
....
	    $grid->addGroupAction('Smazat')->onSelect[] = [$this, 'deleteItems'];
...

	public function deleteInvoices(array $ids)
    {
		foreach ($ids as $id) {
            $this->presenter->repository->deleteItem($id);
        }

	if ($this->presenter->isAjax()) {
            $this['itemGrid']->reload();
	}
        else {
            $this->presenter->redirect('this');
	}

        $this->presenter->flashMessage("Položky byly úspěšně odstraněny");
    }
}

interface IItemControlFactory
{
    /**
     * @return ItemControl
     */
    function create();
}
?>

Kde mám chybu prosím? V šabloně samozřejmě mám zprávy ve snippetu.

Editoval ppar (10. 3. 2017 21:57)

F.Vesely
Člen | 369
+
+1
-

Tak taky ten snippet musis invalidovat.

Petr Parolek
Člen | 455
+
0
-

Díky moc, zas taková blbost.

BigCharlie
Člen | 283
+
0
-

Ahoj,

neodolal jsem a zkouším tenhle grid ve spolupráci s Doctrine. Mám dva dotazy:

  • jak správně nastavit výchozí řazení gridu (setDefaultSort se záhadně neprojeví, řadí se podle jména)
  • mate mě, proč se při nastavení setItemsPerPageList a setDefaultPerPage v adrese v parametrech objevuje searchDatagrid-per_page=10, je to chyba, nebo jsem něco špatně nastavil?

Ukázka kódu:

$qb = $this
	->entityManager
	->getRepository(Company::class)
	->createQueryBuilder()
	->select('c')
	->from(Company::class, 'c');

$grid = $this->datagridFactory->create();	// translator, itemsPerPageList([20,50,100], FALSE), defaultPerPage(20)

$grid
	->setPrimaryKey('companyId')
	->setDataSource($qb)
	->setDefaultSort(['c.url' => 'ASC']);

$grid->addColumnText('name', 'company.name')
     ->setSortable();

$grid->addColumnText('url', 'company.url');

$grid->addColumnStatus('active', 'company.active')
     ->setSortable();

datagrid v. 5.1.1

Pavel Janda
Člen | 977
+
0
-

@BigCharlie

  • Pokud už jsi ten sloupec řadil, tak se bere hodnota ze session. Pokud smažeš session, bude tam default sort.
  • Nerozumím problému.. per_page je persistentní parametr datagridu, který se přenáší v url
BigCharlie
Člen | 283
+
0
-

@PavelJanda

Řazení – ha, už to vidím. Použil jsem alias tabulky z doctrine (c.url), bez něj (jen url) to funguje. Protože to bylo uloženo v session, změna se nepromítla. setRememberState jsem si měl všimnout dřív, to by mi pomohlo. Díky za postrčení!

per_page – defaultní per_page jsem nastavil na 20, per_page=10 není mezi mnou definovanými možnostmi (20,50,100), proto mě to v adrese mate.

johnnie
Člen | 54
+
0
-

Ahojte, mam problem s Tree-View, pouzivam Nette\Database

Ak pouzijem nasledujucu Seleciton

/**
 * @var \Ublaboo\DataGrid\DataGrid
 */
$grid = new DataGrid($this, $name);
$grid->setRememberState(FALSE);

$fluent= $this->db->table('page')
    ->select('page.id, page.parent_id, COUNT(page.parent_id) AS has_children')
    ->order('page.id')
    ->group('page.parent_id')->fetchAll();


$grid->setDataSource($fluent);
$grid->setTreeView([$this, 'getChildren'], 'has_children');

Dostanem Nette\MemberAccessException – Cannot read an undeclared column ‚has_children‘

Vie mi niekdo poradit ci sa to da nejako obist pripadne je tu niekdo kto rozbehal TreeView na Nette\Database ?

Pavel Janda
Člen | 977
+
0
-

@johnnie Ukaž pls metodu getChildren

johnnie
Člen | 54
+
+1
-

@PavelJanda

Tu som si neni moc isty ci postupujem spravne, vychadzal som z metody ktoru si tu napisal ako priklad na doctrine.

public function getChildren(int $pageId)
{
    return $this->db->table('page')->where(['parent_id' => $pageId])->fetchAll();
}

EDIT: prepac :) uplne som sa do toho zazral ze som si zabudol v actionDefault() setDataSource ktory to samozrejme prepisoval a preto undeclared column :) sorry este raz a diky za rychlu odpoved

Editoval johnnie (15. 3. 2017 13:06)

schnappi
Člen | 13
+
0
-

Ahoj, je nejak možné pre TreeView zobraziť implicitne celý strom?

Pavel Janda
Člen | 977
+
0
-

@schnappi Momentálně ne. Jsou na to otevřené issues a je to asi v plánu.

Můžeš poslat PR. :D