7. Nabídka hodnot – addSelect
addSelect($alias, $title, $options, $multi = true, $custom = false, $preserveKeys = false)
– pevná nabídka hodnot. Táž nabídka slouží jako filtr i jako překlad hodnoty
z databáze na popisek v buňce.
Ukázka
Platba má nabídku zapsanou v kódu, Stav složenou z databáze i s počty a Doprava je seznam bez popisků, do kterého smí uživatel dopsat vlastní hodnotu.
Zdrojový kód
<?php
declare(strict_types=1);
namespace App\Components\Docs\Columns\ColumnSelectGridControl;
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 7 – Nabídka hodnot (addSelect).
*
* Tytéž sloupce objednávky, jaké jinde v dokumentaci obsluhuje addEnum() – tady ale bez enumu,
* s nabídkou zapsanou polem a s nabídkou složenou z databáze.
*/
class ColumnSelectGridControl extends GridControl
{
public function createDataSource(): DataSource
{
return new SQLDataSource(__DIR__ . '/ColumnSelectGridControl.sql');
}
public function columns(ColumnManager $cm): void
{
$cm->add('number', 'Číslo');
// Asociativní pole: klíč je hodnota v databázi, hodnota popisek v buňce i v nabídce filtru.
$cm->addSelect('payment', 'Platba', [
'card' => 'Kartou online',
'transfer' => 'Bankovní převod',
'paypal' => 'PayPal',
'cash' => 'Hotově / Dobírka',
], multi: false);
// Nabídka složená z databáze – hodí se tam, kde číselník žije v tabulce, ne v kódu.
$cm->addSelect('status', 'Stav', $this->statusOptions());
// Seznam (ne asociativní pole) se převede na [hodnota => hodnota]; popisek je pak sama
// hodnota, takže se v buňce vypíše to, co je v databázi.
$cm->addSelect('shipping', 'Doprava', ['ppl', 'dpd', 'zasilkovna', 'post', 'pickup'], custom: true);
$cm->addNumber('total_price', 'Celkem', 2, 'Kč');
}
/**
* Nabídka pro sloupec „Stav“ – hodnoty, které v datech opravdu jsou, i s počtem objednávek.
* Čte se přes query() (v databázi sandboxu jsou rozbité pohledy, kvůli kterým padá table()).
*
* @return array<string, string>
*/
private function statusOptions(): array
{
$rows = $this->db->query(
'SELECT status, COUNT(*) AS count FROM `order` GROUP BY status ORDER BY status',
)->fetchAll();
$options = [];
foreach ($rows as $row) {
$options[(string) $row->status] = sprintf('%s (%d)', $row->status, $row->count);
}
return $options;
}
public function buttons(ButtonManager $bm): void
{
}
public function rows(Row $row): void
{
}
public function render(): void
{
$this->template->render(__DIR__ . '/ColumnSelectGridControl.latte');
}
}
SELECT
o.id,
o.number,
o.payment,
o.shipping,
o.status,
o.total_price / 100 AS total_price
FROM `order` o
Tvar nabídky
Asociativní pole [hodnota => popisek] je obvyklý zápis: klíč
musí sedět na to, co je v databázi, hodnota je to, co uvidí uživatel. Filtr pak posílá klíč,
buňka vypisuje popisek.
Seznam (['ppl', 'dpd', …]) se pro pohodlí převede na
[hodnota => hodnota] – popisek je tedy sama hodnota. Výjimka jsou číselné klíče
0 a 1: ty jsou v PHP k nerozeznání od seznamu, takže se pole
převede taky. Když je chcete zachovat, předejte $preserveKeys = true. Právě to
dělá addBoolean(), který je jinak celý jen addSelect() s nabídkou
['1' => 'Ano', '0' => 'Ne'].
Nabídka z databáze
Nabídka je obyčejné PHP pole, takže si ji stejně dobře načtete z tabulky – grid má z DI po
ruce $this->db:
$rows = $this->db->query('SELECT status, COUNT(*) AS count FROM `order` GROUP BY status')->fetchAll();
columns() se volá při každém požadavku na data, takže dotaz běží často – u velkého
číselníku se vyplatí výsledek cachovat. A pozor na hodnoty, které v datech nejsou: co v nabídce
chybí, to uživatel nevyfiltruje a v buňce zůstane syrová hodnota.
Parametry nabídky
$multi |
Zatrhnout jde víc hodnot naráz, podmínky se spojí přes OR.
Výchozí je zapnuto; false udělá z nabídky přepínač. |
$custom |
Uživatel smí do filtru dopsat hodnotu, která v nabídce není – k něčemu je to jen tam, kde data obsahují i něco mimo číselník. |
$preserveKeys |
Vypne převod seznamu na [hodnota => hodnota] a klíče nechá být. |
Když nabídka žije v PHP enumu, je na to addEnum() – kapitola 8. Filtr je v obou
případech tentýž AbstractSelectFilter, liší se jen tím, odkud se nabídka bere.