xref: /dokuwiki/inc/Form/DropdownElement.php (revision dbed6ed0c3ceda2d8f24a5c67f8e8aa2e79180e2)
1<?php
2namespace dokuwiki\Form;
3
4/**
5 * Class DropdownElement
6 *
7 * Represents a HTML select. Please note that this does not support multiple selected options!
8 *
9 * @package dokuwiki\Form
10 */
11class DropdownElement extends InputElement {
12
13    protected $options = array();
14
15    protected $value = '';
16
17    /**
18     * @param string $name The name of this form element
19     * @param string $options The available options
20     * @param string $label The label text for this element (will be autoescaped)
21     */
22    public function __construct($name, $options, $label = '') {
23        parent::__construct('dropdown', $name, $label);
24        $this->options($options);
25    }
26
27    /**
28     * Get or set the options of the Dropdown
29     *
30     * Options can be given as associative array (value => label) or as an
31     * indexd array (label = value).
32     *
33     * @param null|array $options
34     * @return $this|array
35     */
36    public function options($options = null) {
37        if($options === null) return $this->options;
38        if(!is_array($options)) throw new \InvalidArgumentException('Options have to be an array');
39        $this->options = array();
40
41        foreach($options as $key => $val) {
42            if(is_int($key)) {
43                $this->options[$val] = (string) $val;
44            } else {
45                $this->options[$key] = (string) $val;
46            }
47        }
48        $this->val(''); // set default value (empty or first)
49        return $this;
50    }
51
52    /**
53     * Gets or sets an attribute
54     *
55     * When no $value is given, the current content of the attribute is returned.
56     * An empty string is returned for unset attributes.
57     *
58     * When a $value is given, the content is set to that value and the Element
59     * itself is returned for easy chaining
60     *
61     * @param string $name Name of the attribute to access
62     * @param null|string $value New value to set
63     * @return string|$this
64     */
65    public function attr($name, $value = null) {
66        if(strtolower($name) == 'multiple') {
67            throw new \InvalidArgumentException('Sorry, the dropdown element does not support the "multiple" attribute');
68        }
69        return parent::attr($name, $value);
70    }
71
72    /**
73     * Get or set the current value
74     *
75     * When setting a value that is not defined in the options, the value is ignored
76     * and the first option's value is selected instead
77     *
78     * @param null|string $value The value to set
79     * @return $this|string
80     */
81    public function val($value = null) {
82        if($value === null) return $this->value;
83
84        if(isset($this->options[$value])) {
85            $this->value = $value;
86        } else {
87            // unknown value set, select first option instead
88            $keys = array_keys($this->options);
89            $this->value = (string) array_shift($keys);
90        }
91
92        return $this;
93    }
94
95    /**
96     * Create the HTML for the select it self
97     *
98     * @return string
99     */
100    protected function mainElementHTML() {
101        if($this->useInput) $this->prefillInput();
102
103        $html = '<select ' . buildAttributes($this->attrs()) . '>';
104        foreach($this->options as $key => $val) {
105            $selected = ($key == $this->value) ? ' selected="selected"' : '';
106            $html .= '<option' . $selected . ' value="' . hsc($key) . '">' . hsc($val) . '</option>';
107        }
108        $html .= '</select>';
109
110        return $html;
111    }
112
113}
114