nur-sery/nur_src/v/bs3/vc/CVerticalTable.php

153 lines
3.9 KiB
PHP
Raw Normal View History

2023-12-03 22:10:18 +04:00
<?php
namespace nur\v\bs3\vc;
use Exception;
use nur\b\params\Tparametrable;
use nur\func;
use nur\iter;
use nur\v\v;
use nur\v\vo;
/**
* Class CVerticalTable: comme {@link CTable} mais les données sont affichées
* de façon verticale
*/
class CVerticalTable extends CTable {
use Tparametrable;
const TABLE_CLASS = "table-bordered table-auto";
const PARAMETRABLE_PARAMS_SCHEMA = [
"before_row" => ["?content", null, "Contenu à afficher pour chaque ligne avant le tableau s'il y a des lignes à afficher"],
"after_row" => ["?content", null, "Contenu à afficher pour chaque ligne après le tableau s'il y a des lignes à afficher"],
];
/** @var array|string */
protected $ppBeforeRow;
/** @var array|string */
protected $ppAfterRow;
function print(): void {
try {
$this->_rewindRows();
$this->rowIndex = 0;
$haveRows = false;
while ($this->_validRow()) {
$this->origRow = $this->nextRow();
try {
if ($this->origRow === null) continue;
$skipRow = false;
if (!$haveRows) $skipRow = $this->resolveColsHeaders($this->origRow);
if (!$skipRow) {
$this->row = $this->cookRow($this->origRow);
if (!$haveRows) {
$haveRows = true;
vo::print($this->beforeTable());
vo::stable(["class" => "table", $this->table()]);
vo::stbody($this->tbody());
}
$this->printBeforeRow();
$this->printRow($this->row);
$this->printAfterRow();
$this->rowIndex++;
}
} finally {
$this->_nextRow();
}
}
if ($haveRows) {
vo::etbody();
vo::etable();
vo::print($this->afterTable());
} else {
vo::print($this->noData());
}
} catch (Exception $e) {
$onException = $this->ppOnException;
if ($onException !== null) func::call($onException, $e);
else throw $e;
}
}
function tr(bool $rowContent): ?iterable {
return null;
}
/** contenu à afficher avant le tableau s'il y a des lignes à afficher */
function beforeRow(): ?iterable {
return $this->ppBeforeRow;
}
function printBeforeRow(): void {
$beforeRowContents = $this->beforeRow();
if ($beforeRowContents !== null) {
vo::tr([
$this->tr(false),
v::td([
"colspan" => 2,
$beforeRowContents,
]),
]);
}
}
/** contenu à afficher après le tableau s'il y a des lignes à afficher */
function afterRow(): ?iterable {
return $this->ppAfterRow;
}
function printAfterRow(): void {
$afterRowContents = $this->afterRow();
if ($afterRowContents !== null) {
vo::tr([
$this->tr(false),
v::td([
"colspan" => 2,
$afterRowContents,
]),
]);
}
}
function printRow(array $row): void {
$this->index = 0;
$headers = $this->headers;
$headerCol = 0;
$headerIndex = 0;
foreach ($this->cols as $this->col) {
vo::str($this->tr(true));
if ($headerCol == $this->index) {
if ($headerCol == 0) iter::rewind($headers);
else iter::next($headers);
if (iter::valid($headers)) {
$header = iter::current($headers, $key);
$label = $header["label"];
if ($label === null) $label = $header["name"];
$rowspan = $header["span"];
if ($key === $headerIndex) {
$headerIndex++;
$headerCol++;
} else {
$headerCol += $rowspan;
}
vo::print($this->colTh($label, $rowspan));
}
}
$value = $this->col !== null? $row[$this->col]: null;
vo::print($this->colTd($value));
vo::etr();
$this->index++;
}
}
function colTh($header, ?int $rowspan): array {
return v::th([
"rowspan" => $rowspan,
$header,
]);
}
}