February 17, 2017 by Christoff Truter PHP
In this post we're going to extend our select element to support optgroups and thereby complete our support for all select child elements.
Interestingly enough, the standard ASP.NET web control doesn't support optgroups for some reason, read more about it over here and how to fix it over here.
Firstly, know thy element
Attribute | Description |
---|---|
disabled | Specifies that an option-group should be disabled |
label | Specifies a label for an option-group |
class HtmlOptionGroupElement extends HtmlElement { private $Children; public $Disabled; public $Label; public function __construct($label, array $children = [], $disabled = false) { $this->Label = $label; $this->Disabled = $disabled; $this->Children = $children; } public function GetChildren() { return $this->Children; } }
class HtmlOptionGroupSerializer implements IHtmlElement, IHtmlInnerHtml { protected $element; public function __construct(HtmlOptionGroupElement $element) { $this->element = $element; } public function GetAttributes() { return [ 'disabled' => ($this->element->Disabled) ? '' : null, 'label' => $this->element->Label ]; } public function GetTagName() { return 'optgroup'; } public function GetInnerHtml() { return $this->element->GetChildren(); } }
class XHtmlOptionGroupSerializer extends HtmlOptionGroupSerializer { public function __construct(HtmlOptionGroupElement $element) { $this->element = $element; } public function GetAttributes() { return [ 'disabled' => ($this->element->Disabled) ? 'disabled' : null, 'label' => $this->element->Label ]; } }
class HtmlSerializer implements IHtmlSerializer { ... protected function getSerializer($element) { ... } else if ($element instanceof HtmlOptionGroupElement) { return new HtmlOptionGroupSerializer($element); } ... } ... }
class XHtmlSerializer extends HtmlSerializer { ... protected function getSerializer($element) { ... } else if ($element instanceof HtmlOptionGroupElement) { return new XHtmlOptionGroupSerializer($element); } ... } ... }
class HtmlSelectElement extends HtmlFormControlElement { ... private $OptionValues = []; ... private function setChild($child, $value) { $optionValue = (string)$child; $this->OptionValues[] = $optionValue; $child->Selected = ($optionValue == $value); if ($child->Selected) { $this->Value = $optionValue; } } ... public function SetValue($value) { $this->OptionValues = []; foreach($this->Children as $child) { if ($child instanceof HtmlOptionElement) { $this->setChild($child, $value); } else if ($child instanceof HtmlOptionGroupElement) { $groupChildren = $child->GetChildren(); foreach($groupChildren as $groupChild) { $this->setChild($groupChild, $value); } } else { throw new \Exception("Type of HtmlOptionElement expected in drop-down list $this->Name"); } } } ... public function SetChildren(array $children, $value = null) { $this->Children = $children; $this->SetValue($value); if (count($this->OptionValues) != count(array_unique($this->OptionValues))) { throw new \Exception("Non unique values assigned to drop-down list $this->Name"); } } }
$select = new HtmlSelectElement('friends', [ new HtmlOptionElement('Not Selected', 0), new HtmlOptionElement('Gerhardt Stander', 1), new HtmlOptionElement('Bronwen Murdoch', 2), new HtmlOptionGroupElement('Family', [ new HtmlOptionElement('Jurgens Truter', 4), new HtmlOptionElement('Marisa Truter') ]), new HtmlOptionElement('Maree Kleu') ], 'Marisa Truter');
February 15, 2017
PHP drop-down list - Part 4 (Cleaning things up a bit)February 14, 2017
PHP drop-down list - Part 3 (Maintaining State)February 14, 2017
PHP drop-down list - Part 2 (Serialization of elements to HTML)February 14, 2017
PHP drop-down list - Part 1 (Knowing thy elements)February 14, 2017
ASP.NET WebControl Critical Analysis: DropDownListJune 27, 2011
ASP.net (C#) DropDownList Optgroups (WebControlAdapter)March 11, 2010