6. Sloupce a presety
add() vypíše hodnotu tak, jak přišla z datového zdroje. Všechny ostatní
add*() metody jsou jen add() s předvyplněným formátováním, filtrem
a typem pro export – nic víc v nich není.
Ukázka
Od každého presetu jeden sloupec. Dvojice Utraceno a Aktivní jsou pokaždé tatáž hodnota dvakrát – jednou s presetem, jednou bez něj.
Zdrojový kód
<?php
declare(strict_types=1);
namespace App\Components\Docs\Columns\ColumnTypesGridControl;
use Xart\Grid\Button\ButtonManager;
use Xart\Grid\Column\ColumnManager;
use Xart\Grid\Control\GridControl;
use Xart\Grid\DataOutput\Row;
use Xart\Grid\DataSource\DataSource;
use Xart\Grid\DataSource\SQL\SQLDataSource;
/**
* Dokumentace, kapitola 6 – Sloupce a presety.
*
* Seznam zákazníků, ve kterém je od každého presetu jeden sloupec. Dvojice sloupců nad touž
* hodnotou (spent/spent_raw a is_active/is_active_text) ukazují, co preset dělá navíc proti add().
*/
class ColumnTypesGridControl extends GridControl
{
public function createDataSource(): DataSource
{
return new SQLDataSource(__DIR__ . '/ColumnTypesGridControl.sql');
}
public function columns(ColumnManager $cm): void
{
// Bez presetu: hodnota jde do buňky tak, jak přišla z databáze, filtr je textový.
$cm->add('name', 'Zákazník');
$cm->addEmail('email', 'E-mail');
$cm->addPhone('phone', 'Telefon');
// Číslo bez desetinných míst a bez jednotky.
$cm->addNumber('orders_count', 'Objednávek', 0);
// Dvě desetinná místa a jednotka za číslem.
$cm->addNumber('spent', 'Utraceno', 2, 'Kč');
// Tatáž hodnota obyčejným add() – pro srovnání, co všechno preset udělá navíc.
$cm->add('spent_raw', 'Utraceno přes add()');
// Ano/ne jako ikona, a hned vedle totéž jako text.
$cm->addCheck('is_active', 'Aktivní');
$cm->addBoolean('is_active_text', 'Aktivní textem');
$cm->addDate('registered_on', 'Registrace');
// Sloupec typu TIME přijde z databáze jako DateInterval a preset pro něj formatter nemá –
// proto je čas složený už v dotazu (DATE_FORMAT), tedy jako řetězec „HH:MM“.
$cm->addTime('registered_at', 'Čas registrace');
// Odstup od teď („před 3 dny“); přesný okamžik je v titulku buňky.
$cm->addDatetime('last_order_at', 'Poslední objednávka', true);
}
public function buttons(ButtonManager $bm): void
{
}
public function rows(Row $row): void
{
}
public function render(): void
{
$this->template->render(__DIR__ . '/ColumnTypesGridControl.latte');
}
}
SELECT
c.id,
CONCAT(c.first_name, ' ', c.last_name) AS name,
c.email,
c.phone,
(SELECT COUNT(*) FROM `order` o WHERE o.id_customer = c.id) AS orders_count,
(SELECT COALESCE(SUM(o.total_price), 0) FROM `order` o WHERE o.id_customer = c.id) / 100 AS spent,
(SELECT COALESCE(SUM(o.total_price), 0) FROM `order` o WHERE o.id_customer = c.id) / 100 AS spent_raw,
c.is_active,
c.is_active AS is_active_text,
DATE(c.created_at) AS registered_on,
DATE_FORMAT(c.created_at, '%H:%i') AS registered_at,
(SELECT MAX(o.created_at) FROM `order` o WHERE o.id_customer = c.id) AS last_order_at
FROM `customer` c
Alias a titulek
První parametr je alias – musí odpovídat aliasu ve výsledku dotazu, jinak
grid skončí chybou (stejně jako dvakrát přidaný tentýž alias). Druhý je nepovinný
titulek; bez něj se v hlavičce vypíše alias. Nastavit ho jde i dodatečně
přes setTitle(), každá add*() metoda vrací vytvořený sloupec.
Dotaz musí vracet id, i když z něj sloupec neděláte – v ukázce v
columns() není.
Co sloupec umí hned
- filtr – u
add()textový (LIKE), u presetů ten, který se k typu hodí; operátor si uživatel u sloupcového filtru nevybírá, - řazení klikem na hlavičku (se Shiftem na víc úrovní) – řadí databáze podle původní hodnoty, ne podle toho, co preset vykreslil,
- místo v dialogu Zobrazení → Sloupce: skrytí, přesun, změna šířky,
- účast v globálním hledání a v exportu.
Presety
| Metoda | V buňce | Filtr | Export |
|---|---|---|---|
add() |
hodnota z databáze beze změny | text | text |
addNumber($a, $t, $decimals = 2, $unit = null) |
1 234,50 Kč – oddělené tisíce, pevný počet desetinných
míst, jednotka, zarovnání doprava |
rozsah od–do | číslo |
addDate($a, $t, $relative = false) |
24.08.2026 |
rozsah dat | datum |
addDatetime($a, $t, $relative = false) |
datum a pod ním čas | rozsah s časem | datum a čas |
addTime() |
hodnota beze změny | rozsah časů | čas |
addBoolean($a, $t, $yesLabel, $noLabel, $yesValue, $noValue) |
Ano / Ne textem | nabídka | text |
addCheck(…) |
zelená fajfka / červený křížek | nabídka | Ano / Ne |
addEmail() |
odkaz mailto: |
text | text |
addPhone($a, $t, $link = true) |
+420 777 123 456 – přeskládané do trojic, odkaz tel: |
text | text |
Sloupce pro nabídku hodnot (addSelect(), addEnum()), barvu, avatar
a systémový sloupec mají vlastní kapitoly.
Relativní datum
addDate() i addDatetime() berou třetí parametr
$relative: v buňce pak stojí „před 3 dny“ a přesný údaj se schová do
jejího titulku (najeďte myší na Poslední objednávku). Do exportu jde
vždy přesné datum – „před 3 dny“ by v sešitu za týden lhalo.
Sloupec bez času počítá jen celé dny, protože datum z databáze je půlnoc.
Na co si dát pozor
- Jednotka jde jen do buňky, ne do exportu – v sešitu má zůstat holé číslo, se kterým jde počítat (kapitola 40).
- Nečíselná hodnota (prázdno,
NULL, text) nechá buňkuaddNumber()prázdnou. - Zarovnání dělá třída
text-end; přebít ho jde vrows()přesremoveClass()(kapitola 15). - Co telefon nepřipomíná („777 123 456 kl. 22“, poznámka místo
čísla), se vypíše tak, jak přišlo, a odkaz nedostane. Totéž platí pro
addEmail():mailto:na nesmysl je horší než nic. addTime()zatím žádný formatter nemá. Sloupec typuTIMEvrací Nette Database jakoDateInterval, který se do buňky nemá jak vypsat – v ukázce proto čas skládá už dotaz (DATE_FORMAT(created_at, '%H:%i')).- Peníze dělí SQL (
total_price / 100); filtr se poskládá nad výrazem, řadí se podle aliasu – obojí databáze unese.