diff --git a/nur_src/v/bs3/fo/ControlSelect.php b/nur_src/v/bs3/fo/ControlSelect.php index 3f40aec..9f15054 100644 --- a/nur_src/v/bs3/fo/ControlSelect.php +++ b/nur_src/v/bs3/fo/ControlSelect.php @@ -3,6 +3,7 @@ namespace nur\v\bs3\fo; use nur\A; use nur\b\params\Tparametrable; +use nur\b\values\Breaker; use nur\base; use nur\func; use nur\v\v; @@ -15,11 +16,13 @@ class ControlSelect extends ControlVisual { "items" => ["?iterable", null, "liste d'éléments à afficher"], "items_func" => ["?callable", null, "fonction fournissant une liste d'éléments à afficher"], "item_value_key" => ["?key", null, "clé de la valeur d'un élément"], - "item_value_func" => ["?callable", null, "fonction fournissant la clé de la valeur d'un élément"], + "item_value_func" => ["?callable", null, "fonction fournissant la valeur d'un élément"], "item_text_key" => ["?key", null, "clé du libellé d'un élément"], - "item_text_func" => ["?callable", null, "fonction fournissant la clé du libellé d'un élément"], + "item_text_func" => ["?callable", null, "fonction fournissant le libellé d'un élément"], "no_item_value" => ["?string", null, "valeur si aucun élément n'est sélectionné"], "no_item_text" => ["?content", null, "libellé si aucun élément n'est sélectionné"], + "group_key" => ["?key", null, "clé d'une valeur sur laquelle grouper les éléments"], + "group_func" => ["?callable", null, "fonction fournissant une valeur sur laquelle grouper les éléments"], "required" => ["?bool", null, "ce champ est-il requis?"], "show_required" => ["?bool", null, "faut-il afficher la marque de champ requis?"], "option_prefix" => ["?content", "\n", "contenu à afficher avant chaque option"], @@ -58,6 +61,12 @@ class ControlSelect extends ControlVisual { /** @var array|string */ protected $ppNoItemText; + /** @var string|int|null */ + protected $ppGroupKey; + + /** @var ?callable */ + protected $ppGroupFunc; + /** @var ?bool */ protected $ppRequired; @@ -113,14 +122,20 @@ class ControlSelect extends ControlVisual { "selected" => $value == $noItemValue, ]; } + $haveGroups = $this->ppGroupKey !== null || $this->ppGroupFunc !== null; foreach ($items as $key => $item) { $itemValue = $this->vof(null, $this->ppItemValueFunc, $item, $this->ppItemValueKey, 0, $item, $key); $itemText = $this->vof(null, $this->ppItemTextFunc, $item, $this->ppItemTextKey, 1, $item, $key); + $itemGroup = null; + if ($haveGroups) { + $itemGroup = $this->vof(null, $this->ppGroupFunc, $item, $this->ppGroupKey, null, $item, $key); + } if (!$itemText) $itemText = $itemValue; $options[] = array( "value" => $itemValue, "text" => $itemText, "selected" => $value == $itemValue, + "group" => $itemGroup, ); } @@ -136,7 +151,14 @@ class ControlSelect extends ControlVisual { "style" => $this->ppStyle, $this->ppAttrs, ]); + $breaker = new Breaker(); + $firstGroup = true; foreach ($options as $option) { + if ($haveGroups && $breaker->shouldBreakOn($option["group"])) { + if ($firstGroup) $firstGroup = false; + else $control[] = v::end("optgroup"); + $control[] = v::start("optgroup", ["label" => $option["group"]]); + } $control[] = $this->ppOptionPrefix; $control[] = v::tag("option", [ "value" => $option["value"], @@ -145,6 +167,9 @@ class ControlSelect extends ControlVisual { ]); $control[] = $this->ppOptionSuffix; } + if (!$firstGroup) { + $control[] = v::end("optgroup"); + } $control[] = v::end("select"); if ($this->ppNaked) return $control; diff --git a/src/db/sqlite/_query_select.php b/src/db/sqlite/_query_select.php index 4384c70..cb68f7d 100644 --- a/src/db/sqlite/_query_select.php +++ b/src/db/sqlite/_query_select.php @@ -36,8 +36,8 @@ class _query_select extends _query { if (($prefix = $query["prefix"] ?? null) !== null) $sql[] = $prefix; ## select - self::consume('select\s*', $tmpsql); - $sql[] = "select"; + self::consume('(select(?:\s*distinct)?)\s*', $tmpsql, $ms); + $sql[] = $ms[1]; ## cols $usercols = []; @@ -67,7 +67,7 @@ class _query_select extends _query { } } if (!$usercols && !$cols) $usercols = ["*"]; - $sql[] = implode(" ", $usercols); + $sql[] = implode(", ", $usercols); ## from $from = $query["from"] ?? null;