rmattr('type'); $this->optGroups[''] = new OptGroup(null, $options); $this->val(''); } /** * Add an `` and respective options * * @param string $label * @param array $options * @return OptGroup a reference to the added optgroup * @throws \Exception */ public function addOptGroup($label, $options) { if (empty($label)) { throw new \InvalidArgumentException(hsc(' must have a label!')); } $this->optGroups[$label] = new OptGroup($label, $options); return end($this->optGroups); } /** * Set or get the optgroups of an Dropdown-Element. * * optgroups have to be given as associative array * * the key being the label of the group * * the value being an array of options as defined in @see OptGroup::options() * * @param null|array $optGroups * @return OptGroup[]|DropdownElement */ public function optGroups($optGroups = null) { if ($optGroups === null) { return $this->optGroups; } if (!is_array($optGroups)) { throw new \InvalidArgumentException(hsc('Argument must be an associative array of label => [options]!')); } $this->optGroups = array(); foreach ($optGroups as $label => $options) { $this->addOptGroup($label, $options); } return $this; } /** * Get or set the options of the Dropdown * * Options can be given as associative array (value => label) or as an * indexd array (label = value) or as an array of arrays. In the latter * case an element has to look as follows: * option-value => array ( * 'label' => option-label, * 'attrs' => array ( * attr-key => attr-value, ... * ) * ) * * @param null|array $options * @return $this|array */ public function options($options = null) { if ($options === null) { return $this->optGroups['']->options(); } $this->optGroups[''] = new OptGroup(null, $options); return $this; } /** * Gets or sets an attribute * * When no $value is given, the current content of the attribute is returned. * An empty string is returned for unset attributes. * * When a $value is given, the content is set to that value and the Element * itself is returned for easy chaining * * @param string $name Name of the attribute to access * @param null|string $value New value to set * @return string|$this */ public function attr($name, $value = null) { if (strtolower($name) == 'multiple') { throw new \InvalidArgumentException( 'Sorry, the dropdown element does not support the "multiple" attribute' ); } return parent::attr($name, $value); } /** * Get or set the current value * * When setting a value that is not defined in the options, the value is ignored * and the first option's value is selected instead * * @param null|string $value The value to set * @return $this|string */ public function val($value = null) { if ($value === null) return $this->value; $value_exists = $this->setValueInOptGroups($value); if ($value_exists) { $this->value = $value; } else { // unknown value set, select first option instead $this->value = $this->getFirstOption(); $this->setValueInOptGroups($this->value); } return $this; } /** * Returns the first options as it will be rendered in HTML * * @return string */ protected function getFirstOption() { $options = $this->options(); if (!empty($options)) { $keys = array_keys($options); return (string) array_shift($keys); } foreach ($this->optGroups as $optGroup) { $options = $optGroup->options(); if (!empty($options)) { $keys = array_keys($options); return (string) array_shift($keys); } } } /** * Set the value in the OptGroups, including the optgroup for the options without optgroup. * * @param string $value * @return bool */ protected function setValueInOptGroups($value) { $value_exists = false; /** @var OptGroup $optGroup */ foreach ($this->optGroups as $optGroup) { $value_exists = $optGroup->storeValue($value) || $value_exists; if ($value_exists) { $value = null; } } return $value_exists; } /** * Create the HTML for the select it self * * @return string */ protected function mainElementHTML() { if ($this->useInput) $this->prefillInput(); $html = ''; return $html; } }