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