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()) {
|
2024-06-03 17:41:40 +04:00
|
|
|
$this->rawRow = $this->_currentRow($this->rowKey);
|
2023-12-03 22:10:18 +04:00
|
|
|
try {
|
2024-06-03 17:41:40 +04:00
|
|
|
$this->origRow = $this->nextRow();
|
2023-12-03 22:10:18 +04:00
|
|
|
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,
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|