From d48160f7122e0f927fd4699314c1c4be8cfb0a3c Mon Sep 17 00:00:00 2001 From: Josh Bruce Date: Sat, 18 Mar 2023 13:19:16 -0400 Subject: [PATCH 1/2] add: Select dropdown, radio, checkbox --- src/Forms/Select.php | 162 +++++++++++++++++++++++++++++++++++++ tests/Forms/SelectTest.php | 121 +++++++++++++++++++++++++++ 2 files changed, 283 insertions(+) create mode 100644 src/Forms/Select.php create mode 100644 tests/Forms/SelectTest.php diff --git a/src/Forms/Select.php b/src/Forms/Select.php new file mode 100644 index 0000000..c22730d --- /dev/null +++ b/src/Forms/Select.php @@ -0,0 +1,162 @@ +wrapperProperties = $propperties; + return $this; + } + + public function dropdown(): self + { + $this->dropdown = true; + + $this->radio = false; + $this->checkbox = false; + return $this; + } + + public function radio(): self + { + $this->radio = true; + + $this->dropdown = false; + $this->checkbox = false; + return $this; + } + + public function checkbox(): self + { + $this->checkbox = true; + + $this->radio = false; + $this->dropdown = false; + return $this; + } + + private function hasSelected(): bool + { + if (is_string($this->selected) and strlen($this->selected) > 0) { + return true; + + } elseif (count($this->selected) > 0) { + return true; + } + return false; + } + + private function selected(): string|array + { + if ($this->checkbox) { + if (is_array($this->selected)) { + return $this->selected; + } + return [$this->selected]; + } + + if (is_array($this->selected)) { + return $this->selected[0]; + } + return $this->selected; + } + + private function isSelected(string $value): bool + { + if ($this->hasSelected() === false) { + return false; + } + + if ($this->checkbox) { + return in_array($value, $this->selected()); + } + return $value === $this->selected(); + } + + public function __toString(): string + { + if ($this->dropdown) { + return (string) $this->selectDropdown(); + } + return (string) $this->selectOther(); + } + + private function selectDropdown(): Element + { + $elements = []; + foreach ($this->options as $value => $content) { + $option = Element::option($content)->props('value ' . $value); + if ($this->isSelected($value)) { + $option = $option->prop('selected selected'); + } + $elements[] = $option; + } + + return Element::div( + Element::label( + $this->label + )->props('for ' . $this->name), + Element::select( + ...$elements + )->props('id ' . $this->name, 'name ' . $this->name) + )->props(...$this->wrapperProperties); + } + + private function selectOther(): Element + { + $elements = []; + $type = 'radio'; + if ($this->checkbox) { + $type = 'checkbox'; + } + foreach ($this->options as $value => $content) { + $id = $this->name . '-' . $value; + $label = Element::label($content)->props('for ' . $id); + $input = Element::input()->omitEndTag()->props( + 'id ' . $id, + 'type ' . $type, + 'value ' . $value + ); + if ($this->isSelected($value)) { + $input = $input->prop('checked checked'); + } + $elements[] = Element::div($input, $label); + } + return Element::fieldset( + Element::legend($this->label), + ...$elements + ); + } +} diff --git a/tests/Forms/SelectTest.php b/tests/Forms/SelectTest.php new file mode 100644 index 0000000..c478a1e --- /dev/null +++ b/tests/Forms/SelectTest.php @@ -0,0 +1,121 @@ +Select your option
+ html; + + $result = (string) Select::create( + 'Select your option', + 'select', + [ + 'value' => 'display', + 'value2' => 'display2' + ], + ['value', 'value2'] + )->checkbox(); + + $this->assertSame($expected, $result); + } + + /** + * @test + */ + public function can_be_radio_buttons(): void // phpcs: ignore + { + $expected = <<Select your option
+ html; + + $result = (string) Select::create( + 'Select your option', + 'select', + [ + 'value' => 'display' + ], + 'value' + )->radio(); + + $this->assertSame($expected, $result); + } + + /** + * @test + */ + public function can_add_properties_to_wrapper(): void // phpcs: ignore + { + $expected = << + html; + + $result = (string) Select::create( + 'Select your option', + 'select', + [ + 'value' => 'display' + ] + )->wrapperProps('id some-id', 'class some-token'); + + $this->assertSame($expected, $result); + } + + /** + * @test + */ + public function can_preselect_option(): void // phpcs:ignore + { + $expected = << + html; + + $result = (string) Select::create( + 'Select your option', + 'select', + [ + 'value' => 'display', + 'value2' => 'display2' + ], + 'value2' + ); + + $this->assertSame($expected, $result); + } + + /** + * @test + */ + public function is_expected_base(): void // phpcs:ignore + { + $expected = << + html; + + $result = (string) Select::create( + 'Select your option', + 'select', + [ + 'value' => 'display' + ] + ); + + $this->assertSame($expected, $result); + } +} From 56b1895ed6a5212455b5af96b85c967e271200b8 Mon Sep 17 00:00:00 2001 From: Josh Bruce Date: Sat, 18 Mar 2023 13:31:54 -0400 Subject: [PATCH 2/2] fix: Stan and tests --- src/Forms/Select.php | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/Forms/Select.php b/src/Forms/Select.php index c22730d..a3eb455 100644 --- a/src/Forms/Select.php +++ b/src/Forms/Select.php @@ -9,14 +9,19 @@ class Select implements Stringable { + /** + * @var string[] + */ private array $wrapperProperties = []; private bool $dropdown = true; - private bool $radio = false; - private bool $checkbox = false; + /** + * @param array $options + * @param string|string[] $selected + */ public static function create( string|Stringable $label, string|Stringable $name, @@ -26,6 +31,10 @@ public static function create( return new self($label, $name, $options, $selected); } + /** + * @param array $options + * @param string|string[] $selected + */ final private function __construct( private readonly string|Stringable $label, private readonly string|Stringable $name, @@ -43,16 +52,12 @@ public function wrapperProps(string ...$propperties): self public function dropdown(): self { $this->dropdown = true; - - $this->radio = false; $this->checkbox = false; return $this; } public function radio(): self { - $this->radio = true; - $this->dropdown = false; $this->checkbox = false; return $this; @@ -61,23 +66,26 @@ public function radio(): self public function checkbox(): self { $this->checkbox = true; - - $this->radio = false; $this->dropdown = false; return $this; } private function hasSelected(): bool { - if (is_string($this->selected) and strlen($this->selected) > 0) { + $selected = $this->selected(); + if (is_string($selected) and strlen($selected) > 0) { return true; - } elseif (count($this->selected) > 0) { + } elseif (is_array($selected) and count($selected) > 0) { return true; + } return false; } + /** + * @return string|string[] + */ private function selected(): string|array { if ($this->checkbox) { @@ -87,7 +95,7 @@ private function selected(): string|array return [$this->selected]; } - if (is_array($this->selected)) { + if (is_array($this->selected) and count($this->selected) > 0) { return $this->selected[0]; } return $this->selected; @@ -99,7 +107,7 @@ private function isSelected(string $value): bool return false; } - if ($this->checkbox) { + if (is_array($this->selected())) { return in_array($value, $this->selected()); } return $value === $this->selected();