diff --git a/src/Html/FormBuilder.php b/src/Html/FormBuilder.php
index e4864da9..b0406cb4 100644
--- a/src/Html/FormBuilder.php
+++ b/src/Html/FormBuilder.php
@@ -407,6 +407,15 @@ protected function setQuickTextAreaSize(array $options): array
/**
* Create a select box field with empty option support.
+ *
+ * Supports several formats for the $list parameter:
+ * - Simple format: ['value' => 'Label']
+ * - With icon/image: ['value' => ['Label', 'icon-name']] or ['value' => ['Label', 'image.png']]
+ * - With optgroups: ['Group Name' => ['value' => 'Label', ...]]
+ * - Mixed format combining all of the above
+ *
+ * Icons are detected when the second array element doesn't contain a dot (.).
+ * Images are detected when the second array element contains a dot (.).
*/
public function select(string $name, array $list = [], string|array|null $selected = null, array $options = []): string
{
@@ -482,10 +491,15 @@ public function selectMonth(string $name, string|array|null $selected = null, ar
/**
* Get the select option for the given value.
+ *
+ * Determines whether to create a single option or an optgroup based on the $display parameter:
+ * - If $display is an array with string keys, creates an optgroup
+ * - If $display is an array with numeric keys (e.g., ['Label', 'icon']), creates a single option with icon/image
+ * - If $display is a string, creates a simple option
*/
public function getSelectOption(string|array $display, string $value, string|array|null $selected = null): string
{
- if (is_array($display)) {
+ if (is_array($display) && array_keys($display) !== [0,1]) {
return $this->optionGroup($display, $value, $selected);
}
@@ -508,16 +522,33 @@ protected function optionGroup(array $list, string $label, string|array|null $se
/**
* Create a select element option.
+ *
+ * If $display is an array in the format ['Label', 'icon-or-image'], adds data attributes:
+ * - data-icon: added if the second element doesn't contain a dot (e.g., 'icon-refresh')
+ * - data-image: added if the second element contains a dot (e.g., 'image.png')
*/
- protected function option(string $display, string $value, string|array|null $selected = null): string
+ protected function option(string|array $display, string $value, string|array|null $selected = null): string
{
$selectedAttr = $this->getSelectedValue($value, $selected);
$options = [
- 'value' => e($value),
+ 'value' => $value,
'selected' => $selectedAttr
];
+ if (is_array($display)) {
+ $label = array_get($display, 0);
+ $data = array_get($display, 1);
+
+ if (is_string($data) && $data !== '') {
+ if (strpos($data, '.') !== false) {
+ $options['data-image'] = $data;
+ } else {
+ $options['data-icon'] = $data;
+ }
+ }
+ $display = $label;
+ }
return '';
}
diff --git a/tests/Html/FormBuilderTest.php b/tests/Html/FormBuilderTest.php
index d5bcd740..dc601fa1 100644
--- a/tests/Html/FormBuilderTest.php
+++ b/tests/Html/FormBuilderTest.php
@@ -340,4 +340,255 @@ public function testSelectWithEmptyOption()
$this->assertStringContainsString('', $result);
$this->assertStringContainsString('', $result);
}
+
+ /**
+ * @testdox can create a select element with icon data attributes.
+ */
+ public function testSelectWithIcon()
+ {
+ $result = $this->formBuilder->select(
+ name: 'my-select',
+ list: [
+ '1' => 'Regular Option',
+ '2' => ['Option With Icon', 'icon-refresh'],
+ ],
+ selected: null,
+ options: []
+ );
+
+ $this->assertElementIs('select', $result);
+ $this->assertElementAttributeEquals('name', 'my-select', $result);
+ $this->assertStringContainsString('', $result);
+ $this->assertStringContainsString('', $result);
+ }
+
+ /**
+ * @testdox can create a select element with image data attributes.
+ */
+ public function testSelectWithImage()
+ {
+ $result = $this->formBuilder->select(
+ name: 'my-select',
+ list: [
+ '1' => 'Regular Option',
+ '2' => ['Option With Image', 'myImage.jpeg'],
+ ],
+ selected: null,
+ options: []
+ );
+
+ $this->assertElementIs('select', $result);
+ $this->assertElementAttributeEquals('name', 'my-select', $result);
+ $this->assertStringContainsString('', $result);
+ $this->assertStringContainsString('', $result);
+ }
+
+ /**
+ * @testdox can create a select element with image data attributes.
+ */
+ public function testSelectWithSelectedImage()
+ {
+ $result = $this->formBuilder->select(
+ name: 'my-select',
+ list: [
+ '1' => 'Regular Option',
+ '2' => ['Option With Image', 'myImage.jpeg'],
+ ],
+ selected: '2',
+ options: []
+ );
+
+ $this->assertElementIs('select', $result);
+ $this->assertElementAttributeEquals('name', 'my-select', $result);
+ $this->assertStringContainsString('', $result);
+ $this->assertStringContainsString('', $result);
+ }
+
+ /**
+ * @testdox can create a select element with optgroups.
+ */
+ public function testSelectWithOptgroups()
+ {
+ $result = $this->formBuilder->select(
+ name: 'my-select',
+ list: [
+ 'Group 1' => [
+ 'g1-opt1' => 'Group 1 Option 1',
+ 'g1-opt2' => 'Group 1 Option 2',
+ ],
+ 'Group 2' => [
+ 'g2-opt1' => 'Group 2 Option 1',
+ 'g2-opt2' => 'Group 2 Option 2',
+ ],
+ ],
+ selected: null,
+ options: []
+ );
+
+ $this->assertElementIs('select', $result);
+ $this->assertElementAttributeEquals('name', 'my-select', $result);
+ $this->assertStringContainsString('