aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--_test/tests/inc/form/dropdownelement.test.php69
-rw-r--r--inc/Form/DropdownElement.php113
-rw-r--r--inc/Form/Form.php13
3 files changed, 195 insertions, 0 deletions
diff --git a/_test/tests/inc/form/dropdownelement.test.php b/_test/tests/inc/form/dropdownelement.test.php
new file mode 100644
index 000000000..989469182
--- /dev/null
+++ b/_test/tests/inc/form/dropdownelement.test.php
@@ -0,0 +1,69 @@
+<?php
+
+use dokuwiki\Form;
+
+class form_dropdownelement_test extends DokuWikiTest {
+
+ function test_defaults() {
+ $form = new Form\Form();
+
+ // basic tests
+ $options = array ('first', 'second', 'third');
+ $element = $form->addDropdown('foo', $options, 'label text');
+ $this->assertEquals('first', $element->val());
+ $element->val('second');
+ $this->assertEquals('second', $element->val());
+ $element->val('nope');
+ $this->assertEquals('first', $element->val());
+
+ // associative array
+ $options = array ('first'=>'A first Label', 'second'=>'The second Label', 'third'=>'Just 3');
+ $element->options($options);
+ $this->assertEquals('first', $element->val());
+ $element->val('second');
+ $this->assertEquals('second', $element->val());
+ $element->val('nope');
+ $this->assertEquals('first', $element->val());
+
+ // HTML
+ $html = $form->toHTML();
+ $pq = phpQuery::newDocumentXHTML($html);
+
+ $select = $pq->find('select[name=foo]');
+ $this->assertTrue($select->length == 1);
+ $this->assertEquals('first', $select->val());
+
+ $options = $pq->find('option');
+ $this->assertTrue($options->length == 3);
+
+ $option = $pq->find('option[selected=selected]');
+ $this->assertTrue($option->length == 1);
+ $this->assertEquals('first', $option->val());
+ $this->assertEquals('A first Label', $option->text());
+
+ $label = $pq->find('label');
+ $this->assertTrue($label->length == 1);
+ $this->assertEquals('label text', $label->find('span')->text());
+ }
+
+ /**
+ * check that posted values overwrite preset default
+ */
+ function test_prefill() {
+ global $INPUT;
+ $INPUT->post->set('foo', 'second');
+
+ $form = new Form\Form();
+ $options = array ('first'=>'A first Label', 'second'=>'The second Label', 'third'=>'Just 3');
+ $element = $form->addDropdown('foo', $options, 'label text')->val('third');
+ $this->assertEquals('third', $element->val());
+
+ $html = $form->toHTML();
+ $pq = phpQuery::newDocumentXHTML($html);
+
+ $option = $pq->find('option[selected=selected]');
+ $this->assertTrue($option->length == 1);
+ $this->assertEquals('second', $option->val());
+ $this->assertEquals('The second Label', $option->text());
+ }
+}
diff --git a/inc/Form/DropdownElement.php b/inc/Form/DropdownElement.php
new file mode 100644
index 000000000..fc9ce54ec
--- /dev/null
+++ b/inc/Form/DropdownElement.php
@@ -0,0 +1,113 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class DropdownElement
+ *
+ * Represents a HTML select. Please note that this does not support multiple selected options!
+ *
+ * @package dokuwiki\Form
+ */
+class DropdownElement extends InputElement {
+
+ protected $options = array();
+
+ protected $value = '';
+
+ /**
+ * @param string $name The name of this form element
+ * @param string $options The available options
+ * @param string $label The label text for this element (will be autoescaped)
+ */
+ public function __construct($name, $options, $label = '') {
+ parent::__construct('dropdown', $name, $label);
+ $this->options($options);
+ }
+
+ /**
+ * Get or set the options of the Dropdown
+ *
+ * Options can be given as associative array (value => label) or as an
+ * indexd array (label = value).
+ *
+ * @param null|array $options
+ * @return $this|array
+ */
+ public function options($options = null) {
+ if($options === null) return $this->options;
+ if(!is_array($options)) throw new \InvalidArgumentException('Options have to be an array');
+ $this->options = array();
+
+ foreach($options as $key => $val) {
+ if(is_int($key)) {
+ $this->options[$val] = (string) $val;
+ } else {
+ $this->options[$key] = (string) $val;
+ }
+ }
+ $this->val(''); // set default value (empty or first)
+ 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;
+
+ if(isset($this->options[$value])) {
+ $this->value = $value;
+ } else {
+ // unknown value set, select first option instead
+ $keys = array_keys($this->options);
+ $this->value = (string) array_shift($keys);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Create the HTML for the select it self
+ *
+ * @return string
+ */
+ protected function mainElementHTML() {
+ if($this->useInput) $this->prefillInput();
+
+ $html = '<select ' . buildAttributes($this->attrs()) . '>';
+ foreach($this->options as $key => $val) {
+ $selected = ($key == $this->value) ? ' selected="selected"' : '';
+ $html .= '<option' . $selected . ' value="' . hsc($key) . '">' . hsc($val) . '</option>';
+ }
+ $html .= '</select>';
+
+ return $html;
+ }
+
+}
diff --git a/inc/Form/Form.php b/inc/Form/Form.php
index 7eaa53041..6f83e9014 100644
--- a/inc/Form/Form.php
+++ b/inc/Form/Form.php
@@ -222,6 +222,19 @@ class Form extends Element {
}
/**
+ * Adds a dropdown field
+ *
+ * @param $name
+ * @param array $options
+ * @param string $label
+ * @param int $pos
+ * @return DropdownElement
+ */
+ public function addDropdown($name, $options, $label = '', $pos = -1) {
+ return $this->addElement(new DropdownElement($name, $options, $label), $pos);
+ }
+
+ /**
* Adds a textarea field
*
* @param $name