112a4e4d1SAndreas Gohr<?php 212a4e4d1SAndreas Gohrnamespace dokuwiki\Form; 312a4e4d1SAndreas Gohr 412a4e4d1SAndreas Gohr/** 512a4e4d1SAndreas Gohr * Class Form 612a4e4d1SAndreas Gohr * 712a4e4d1SAndreas Gohr * Represents the whole Form. This is what you work on, and add Elements to 812a4e4d1SAndreas Gohr * 912a4e4d1SAndreas Gohr * @package dokuwiki\Form 1012a4e4d1SAndreas Gohr */ 1112a4e4d1SAndreas Gohrclass Form extends Element { 1212a4e4d1SAndreas Gohr 1312a4e4d1SAndreas Gohr /** 1412a4e4d1SAndreas Gohr * @var array name value pairs for hidden values 1512a4e4d1SAndreas Gohr */ 1612a4e4d1SAndreas Gohr protected $hidden = array(); 1712a4e4d1SAndreas Gohr 1812a4e4d1SAndreas Gohr /** 1912a4e4d1SAndreas Gohr * @var Element[] the elements of the form 2012a4e4d1SAndreas Gohr */ 2112a4e4d1SAndreas Gohr protected $elements = array(); 2212a4e4d1SAndreas Gohr 2312a4e4d1SAndreas Gohr /** 2412a4e4d1SAndreas Gohr * Creates a new, empty form with some default attributes 2512a4e4d1SAndreas Gohr * 2612a4e4d1SAndreas Gohr * @param array $attributes 2712a4e4d1SAndreas Gohr */ 2812a4e4d1SAndreas Gohr public function __construct($attributes = array()) { 2912a4e4d1SAndreas Gohr global $ID; 3012a4e4d1SAndreas Gohr 3112a4e4d1SAndreas Gohr parent::__construct('form', $attributes); 3212a4e4d1SAndreas Gohr 3312a4e4d1SAndreas Gohr // use the current URL as default action 3412a4e4d1SAndreas Gohr if(!$this->attr('action')) { 3512a4e4d1SAndreas Gohr $get = $_GET; 3612a4e4d1SAndreas Gohr if(isset($get['id'])) unset($get['id']); 376d0ceaf9SAndreas Gohr $self = wl($ID, $get, false, '&'); //attributes are escaped later 3812a4e4d1SAndreas Gohr $this->attr('action', $self); 3912a4e4d1SAndreas Gohr } 4012a4e4d1SAndreas Gohr 4112a4e4d1SAndreas Gohr // post is default 4212a4e4d1SAndreas Gohr if(!$this->attr('method')) { 4312a4e4d1SAndreas Gohr $this->attr('method', 'post'); 4412a4e4d1SAndreas Gohr } 4512a4e4d1SAndreas Gohr 4612a4e4d1SAndreas Gohr // we like UTF-8 4712a4e4d1SAndreas Gohr if(!$this->attr('accept-charset')) { 4812a4e4d1SAndreas Gohr $this->attr('accept-charset', 'utf-8'); 4912a4e4d1SAndreas Gohr } 5012a4e4d1SAndreas Gohr 5112a4e4d1SAndreas Gohr // add the security token by default 5212a4e4d1SAndreas Gohr $this->setHiddenField('sectok', getSecurityToken()); 5312a4e4d1SAndreas Gohr 546d0ceaf9SAndreas Gohr // identify this as a new form based form in HTML 556d0ceaf9SAndreas Gohr $this->addClass('doku_form'); 5612a4e4d1SAndreas Gohr } 5712a4e4d1SAndreas Gohr 5812a4e4d1SAndreas Gohr /** 5912a4e4d1SAndreas Gohr * Sets a hidden field 6012a4e4d1SAndreas Gohr * 6112a4e4d1SAndreas Gohr * @param $name 6212a4e4d1SAndreas Gohr * @param $value 6312a4e4d1SAndreas Gohr * @return $this 6412a4e4d1SAndreas Gohr */ 6512a4e4d1SAndreas Gohr public function setHiddenField($name, $value) { 6612a4e4d1SAndreas Gohr $this->hidden[$name] = $value; 6712a4e4d1SAndreas Gohr return $this; 6812a4e4d1SAndreas Gohr } 6912a4e4d1SAndreas Gohr 70ef0c211bSAndreas Gohr #region element query function 7164744a10SAndreas Gohr 7212a4e4d1SAndreas Gohr /** 73ef0c211bSAndreas Gohr * Returns the numbers of elements in the form 74ef0c211bSAndreas Gohr * 75ef0c211bSAndreas Gohr * @return int 76ef0c211bSAndreas Gohr */ 77ef0c211bSAndreas Gohr public function elementCount() { 78ef0c211bSAndreas Gohr return count($this->elements); 79ef0c211bSAndreas Gohr } 80ef0c211bSAndreas Gohr 81ef0c211bSAndreas Gohr /** 82ef0c211bSAndreas Gohr * Returns a reference to the element at a position. 83ef0c211bSAndreas Gohr * A position out-of-bounds will return either the 84ef0c211bSAndreas Gohr * first (underflow) or last (overflow) element. 85ef0c211bSAndreas Gohr * 86ef0c211bSAndreas Gohr * @param $pos 87ef0c211bSAndreas Gohr * @return Element 88ef0c211bSAndreas Gohr */ 89ef0c211bSAndreas Gohr public function getElementAt($pos) { 90ef0c211bSAndreas Gohr if($pos < 0) $pos = count($this->elements) + $pos; 91ef0c211bSAndreas Gohr if($pos < 0) $pos = 0; 92ef0c211bSAndreas Gohr if($pos >= count($this->elements)) $pos = count($this->elements) - 1; 93ef0c211bSAndreas Gohr return $this->elements[$pos]; 94ef0c211bSAndreas Gohr } 95ef0c211bSAndreas Gohr 96ef0c211bSAndreas Gohr /** 97ef0c211bSAndreas Gohr * Gets the position of the first of a type of element 98ef0c211bSAndreas Gohr * 99ef0c211bSAndreas Gohr * @param string $type Element type to look for. 100ef0c211bSAndreas Gohr * @param int $offset search from this position onward 101ef0c211bSAndreas Gohr * @return false|int position of element if found, otherwise false 102ef0c211bSAndreas Gohr */ 103ef0c211bSAndreas Gohr public function findPositionByType($type, $offset = 0) { 104ef0c211bSAndreas Gohr $len = $this->elementCount(); 105ef0c211bSAndreas Gohr for($pos = $offset; $pos < $len; $pos++) { 106ef0c211bSAndreas Gohr if($this->elements[$pos]->getType() == $type) { 107ef0c211bSAndreas Gohr return $pos; 108ef0c211bSAndreas Gohr } 109ef0c211bSAndreas Gohr } 110ef0c211bSAndreas Gohr return false; 111ef0c211bSAndreas Gohr } 112ef0c211bSAndreas Gohr 113ef0c211bSAndreas Gohr /** 114ef0c211bSAndreas Gohr * Gets the position of the first element matching the attribute 115ef0c211bSAndreas Gohr * 116ef0c211bSAndreas Gohr * @param string $name Name of the attribute 117ef0c211bSAndreas Gohr * @param string $value Value the attribute should have 118ef0c211bSAndreas Gohr * @param int $offset search from this position onward 119ef0c211bSAndreas Gohr * @return false|int position of element if found, otherwise false 120ef0c211bSAndreas Gohr */ 121ef0c211bSAndreas Gohr public function findPositionByAttribute($name, $value, $offset = 0) { 122ef0c211bSAndreas Gohr $len = $this->elementCount(); 123ef0c211bSAndreas Gohr for($pos = $offset; $pos < $len; $pos++) { 124ef0c211bSAndreas Gohr if($this->elements[$pos]->attr($name) == $value) { 125ef0c211bSAndreas Gohr return $pos; 126ef0c211bSAndreas Gohr } 127ef0c211bSAndreas Gohr } 128ef0c211bSAndreas Gohr return false; 129ef0c211bSAndreas Gohr } 130ef0c211bSAndreas Gohr 131ef0c211bSAndreas Gohr #endregion 132ef0c211bSAndreas Gohr 133ef0c211bSAndreas Gohr #region Element positioning functions 134ef0c211bSAndreas Gohr 135ef0c211bSAndreas Gohr /** 136ef0c211bSAndreas Gohr * Adds or inserts an element to the form 13712a4e4d1SAndreas Gohr * 13812a4e4d1SAndreas Gohr * @param Element $element 13912a4e4d1SAndreas Gohr * @param int $pos 0-based position in the form, -1 for at the end 14012a4e4d1SAndreas Gohr * @return Element 14112a4e4d1SAndreas Gohr */ 14212a4e4d1SAndreas Gohr public function addElement(Element $element, $pos = -1) { 143ef0c211bSAndreas Gohr if(is_a($element, '\dokuwiki\Form')) throw new \InvalidArgumentException('You can\'t add a form to a form'); 14412a4e4d1SAndreas Gohr if($pos < 0) { 14512a4e4d1SAndreas Gohr $this->elements[] = $element; 14612a4e4d1SAndreas Gohr } else { 14712a4e4d1SAndreas Gohr array_splice($this->elements, $pos, 0, array($element)); 14812a4e4d1SAndreas Gohr } 14912a4e4d1SAndreas Gohr return $element; 15012a4e4d1SAndreas Gohr } 15112a4e4d1SAndreas Gohr 15212a4e4d1SAndreas Gohr /** 153ef0c211bSAndreas Gohr * Replaces an existing element with a new one 154ef0c211bSAndreas Gohr * 155ef0c211bSAndreas Gohr * @param Element $element the new element 156ef0c211bSAndreas Gohr * @param $pos 0-based position of the element to replace 157ef0c211bSAndreas Gohr */ 158ef0c211bSAndreas Gohr public function replaceElement(Element $element, $pos) { 159ef0c211bSAndreas Gohr if(is_a($element, '\dokuwiki\Form')) throw new \InvalidArgumentException('You can\'t add a form to a form'); 160ef0c211bSAndreas Gohr array_splice($this->elements, $pos, 1, array($element)); 161ef0c211bSAndreas Gohr } 162ef0c211bSAndreas Gohr 163ef0c211bSAndreas Gohr /** 164ef0c211bSAndreas Gohr * Remove an element from the form completely 165ef0c211bSAndreas Gohr * 166ef0c211bSAndreas Gohr * @param $pos 0-based position of the element to remove 167ef0c211bSAndreas Gohr */ 168ef0c211bSAndreas Gohr public function removeElement($pos) { 169ef0c211bSAndreas Gohr array_splice($this->elements, $pos, 1); 170ef0c211bSAndreas Gohr } 171ef0c211bSAndreas Gohr 172ef0c211bSAndreas Gohr #endregion 173ef0c211bSAndreas Gohr 174ef0c211bSAndreas Gohr #region Element adding functions 175ef0c211bSAndreas Gohr 176ef0c211bSAndreas Gohr /** 17712a4e4d1SAndreas Gohr * Adds a text input field 17812a4e4d1SAndreas Gohr * 17912a4e4d1SAndreas Gohr * @param $name 18012a4e4d1SAndreas Gohr * @param $label 18112a4e4d1SAndreas Gohr * @param int $pos 18212a4e4d1SAndreas Gohr * @return InputElement 18312a4e4d1SAndreas Gohr */ 184de19515fSAndreas Gohr public function addTextInput($name, $label = '', $pos = -1) { 18512a4e4d1SAndreas Gohr return $this->addElement(new InputElement('text', $name, $label), $pos); 18612a4e4d1SAndreas Gohr } 18712a4e4d1SAndreas Gohr 18812a4e4d1SAndreas Gohr /** 18912a4e4d1SAndreas Gohr * Adds a password input field 19012a4e4d1SAndreas Gohr * 19112a4e4d1SAndreas Gohr * @param $name 19212a4e4d1SAndreas Gohr * @param $label 19312a4e4d1SAndreas Gohr * @param int $pos 19412a4e4d1SAndreas Gohr * @return InputElement 19512a4e4d1SAndreas Gohr */ 196de19515fSAndreas Gohr public function addPasswordInput($name, $label = '', $pos = -1) { 19712a4e4d1SAndreas Gohr return $this->addElement(new InputElement('password', $name, $label), $pos); 19812a4e4d1SAndreas Gohr } 19912a4e4d1SAndreas Gohr 20012a4e4d1SAndreas Gohr /** 20112a4e4d1SAndreas Gohr * Adds a radio button field 20212a4e4d1SAndreas Gohr * 20312a4e4d1SAndreas Gohr * @param $name 20412a4e4d1SAndreas Gohr * @param $label 20512a4e4d1SAndreas Gohr * @param int $pos 20612a4e4d1SAndreas Gohr * @return CheckableElement 20712a4e4d1SAndreas Gohr */ 208de19515fSAndreas Gohr public function addRadioButton($name, $label = '', $pos = -1) { 20912a4e4d1SAndreas Gohr return $this->addElement(new CheckableElement('radio', $name, $label), $pos); 21012a4e4d1SAndreas Gohr } 21112a4e4d1SAndreas Gohr 21212a4e4d1SAndreas Gohr /** 21312a4e4d1SAndreas Gohr * Adds a checkbox field 21412a4e4d1SAndreas Gohr * 21512a4e4d1SAndreas Gohr * @param $name 21612a4e4d1SAndreas Gohr * @param $label 21712a4e4d1SAndreas Gohr * @param int $pos 21812a4e4d1SAndreas Gohr * @return CheckableElement 21912a4e4d1SAndreas Gohr */ 220de19515fSAndreas Gohr public function addCheckbox($name, $label = '', $pos = -1) { 22112a4e4d1SAndreas Gohr return $this->addElement(new CheckableElement('checkbox', $name, $label), $pos); 22212a4e4d1SAndreas Gohr } 22312a4e4d1SAndreas Gohr 22412a4e4d1SAndreas Gohr /** 22512a4e4d1SAndreas Gohr * Adds a textarea field 22612a4e4d1SAndreas Gohr * 22712a4e4d1SAndreas Gohr * @param $name 22812a4e4d1SAndreas Gohr * @param $label 22912a4e4d1SAndreas Gohr * @param int $pos 23012a4e4d1SAndreas Gohr * @return TextareaElement 23112a4e4d1SAndreas Gohr */ 232de19515fSAndreas Gohr public function addTextarea($name, $label = '', $pos = -1) { 23312a4e4d1SAndreas Gohr return $this->addElement(new TextareaElement($name, $label), $pos); 23412a4e4d1SAndreas Gohr } 23512a4e4d1SAndreas Gohr 23612a4e4d1SAndreas Gohr /** 2378f0df229SAndreas Gohr * Adds a simple button, escapes the content for you 2388f0df229SAndreas Gohr * 2398f0df229SAndreas Gohr * @param string $name 2408f0df229SAndreas Gohr * @param string $content 2418f0df229SAndreas Gohr * @param int $pos 2428f0df229SAndreas Gohr * @return Element 2438f0df229SAndreas Gohr */ 2448f0df229SAndreas Gohr public function addButton($name, $content, $pos = -1) { 2458f0df229SAndreas Gohr return $this->addElement(new ButtonElement($name, hsc($content)), $pos); 2468f0df229SAndreas Gohr } 2478f0df229SAndreas Gohr 2488f0df229SAndreas Gohr /** 2498f0df229SAndreas Gohr * Adds a simple button, allows HTML for content 2508f0df229SAndreas Gohr * 2518f0df229SAndreas Gohr * @param string $name 2528f0df229SAndreas Gohr * @param string $html 2538f0df229SAndreas Gohr * @param int $pos 2548f0df229SAndreas Gohr * @return Element 2558f0df229SAndreas Gohr */ 2568f0df229SAndreas Gohr public function addButtonHTML($name, $html, $pos = -1) { 2578f0df229SAndreas Gohr return $this->addElement(new ButtonElement($name, $html), $pos); 2588f0df229SAndreas Gohr } 2598f0df229SAndreas Gohr 2608f0df229SAndreas Gohr /** 261*a453c16bSAndreas Gohr * Adds a label referencing another input element, escapes the label for you 262*a453c16bSAndreas Gohr * 263*a453c16bSAndreas Gohr * @param $label 264*a453c16bSAndreas Gohr * @param string $for 265*a453c16bSAndreas Gohr * @param int $pos 266*a453c16bSAndreas Gohr * @return Element 267*a453c16bSAndreas Gohr */ 268*a453c16bSAndreas Gohr public function addLabel($label, $for='', $pos = -1) { 269*a453c16bSAndreas Gohr return $this->addLabelHTML(hsc($label), $for, $pos); 270*a453c16bSAndreas Gohr } 271*a453c16bSAndreas Gohr 272*a453c16bSAndreas Gohr /** 273*a453c16bSAndreas Gohr * Adds a label referencing another input element, allows HTML for content 274*a453c16bSAndreas Gohr * 275*a453c16bSAndreas Gohr * @param string $content 276*a453c16bSAndreas Gohr * @param string|Element $for 277*a453c16bSAndreas Gohr * @param int $pos 278*a453c16bSAndreas Gohr * @return Element 279*a453c16bSAndreas Gohr */ 280*a453c16bSAndreas Gohr public function addLabelHTML($content, $for='', $pos = -1) { 281*a453c16bSAndreas Gohr $element = new LabelElement(hsc($content)); 282*a453c16bSAndreas Gohr 283*a453c16bSAndreas Gohr if(is_a($for, '\dokuwiki\Form\Element')) { 284*a453c16bSAndreas Gohr /** @var Element $for */ 285*a453c16bSAndreas Gohr $for = $for->id(); 286*a453c16bSAndreas Gohr } 287*a453c16bSAndreas Gohr $for = (string) $for; 288*a453c16bSAndreas Gohr if($for !== '') { 289*a453c16bSAndreas Gohr $element->attr('for', $for); 290*a453c16bSAndreas Gohr } 291*a453c16bSAndreas Gohr 292*a453c16bSAndreas Gohr return $this->addElement($element, $pos); 293*a453c16bSAndreas Gohr } 294*a453c16bSAndreas Gohr 295*a453c16bSAndreas Gohr /** 296de19515fSAndreas Gohr * Add fixed HTML to the form 297de19515fSAndreas Gohr * 298de19515fSAndreas Gohr * @param $html 299de19515fSAndreas Gohr * @param int $pos 30064744a10SAndreas Gohr * @return HTMLElement 301de19515fSAndreas Gohr */ 302de19515fSAndreas Gohr public function addHTML($html, $pos = -1) { 303de19515fSAndreas Gohr return $this->addElement(new HTMLElement($html), $pos); 304de19515fSAndreas Gohr } 305de19515fSAndreas Gohr 30664744a10SAndreas Gohr /** 30764744a10SAndreas Gohr * Add a closed HTML tag to the form 30864744a10SAndreas Gohr * 30964744a10SAndreas Gohr * @param $tag 31064744a10SAndreas Gohr * @param int $pos 31164744a10SAndreas Gohr * @return TagElement 31264744a10SAndreas Gohr */ 31364744a10SAndreas Gohr public function addTag($tag, $pos = -1) { 31464744a10SAndreas Gohr return $this->addElement(new TagElement($tag), $pos); 31564744a10SAndreas Gohr } 31664744a10SAndreas Gohr 31764744a10SAndreas Gohr /** 31864744a10SAndreas Gohr * Add an open HTML tag to the form 31964744a10SAndreas Gohr * 32064744a10SAndreas Gohr * Be sure to close it again! 32164744a10SAndreas Gohr * 32264744a10SAndreas Gohr * @param $tag 32364744a10SAndreas Gohr * @param int $pos 32464744a10SAndreas Gohr * @return TagOpenElement 32564744a10SAndreas Gohr */ 32664744a10SAndreas Gohr public function addTagOpen($tag, $pos = -1) { 32764744a10SAndreas Gohr return $this->addElement(new TagOpenElement($tag), $pos); 32864744a10SAndreas Gohr } 32964744a10SAndreas Gohr 33064744a10SAndreas Gohr /** 33164744a10SAndreas Gohr * Add a closing HTML tag to the form 33264744a10SAndreas Gohr * 33364744a10SAndreas Gohr * Be sure it had been opened before 33464744a10SAndreas Gohr * 33564744a10SAndreas Gohr * @param $tag 33664744a10SAndreas Gohr * @param int $pos 33764744a10SAndreas Gohr * @return TagCloseElement 33864744a10SAndreas Gohr */ 33964744a10SAndreas Gohr public function addTagClose($tag, $pos = -1) { 34064744a10SAndreas Gohr return $this->addElement(new TagCloseElement($tag), $pos); 34164744a10SAndreas Gohr } 34264744a10SAndreas Gohr 34364744a10SAndreas Gohr /** 34464744a10SAndreas Gohr * Open a Fieldset 34564744a10SAndreas Gohr * 34664744a10SAndreas Gohr * @param $legend 34764744a10SAndreas Gohr * @param int $pos 34864744a10SAndreas Gohr * @return FieldsetOpenElement 34964744a10SAndreas Gohr */ 35064744a10SAndreas Gohr public function addFieldsetOpen($legend = '', $pos = -1) { 35164744a10SAndreas Gohr return $this->addElement(new FieldsetOpenElement($legend), $pos); 35264744a10SAndreas Gohr } 35364744a10SAndreas Gohr 35464744a10SAndreas Gohr /** 35564744a10SAndreas Gohr * Close a fieldset 35664744a10SAndreas Gohr * 35764744a10SAndreas Gohr * @param int $pos 35864744a10SAndreas Gohr * @return TagCloseElement 35964744a10SAndreas Gohr */ 36064744a10SAndreas Gohr public function addFieldsetClose($pos = -1) { 36164744a10SAndreas Gohr return $this->addElement(new FieldsetCloseElement(), $pos); 36264744a10SAndreas Gohr } 36364744a10SAndreas Gohr 36464744a10SAndreas Gohr #endregion 36564744a10SAndreas Gohr 3661f5d8b65SAndreas Gohr /** 3671f5d8b65SAndreas Gohr * Adjust the elements so that fieldset open and closes are matching 3681f5d8b65SAndreas Gohr */ 369de19515fSAndreas Gohr protected function balanceFieldsets() { 3701f5d8b65SAndreas Gohr $lastclose = 0; 3711f5d8b65SAndreas Gohr $isopen = false; 3721f5d8b65SAndreas Gohr $len = count($this->elements); 3731f5d8b65SAndreas Gohr 3741f5d8b65SAndreas Gohr for($pos = 0; $pos < $len; $pos++) { 3751f5d8b65SAndreas Gohr $type = $this->elements[$pos]->getType(); 3761f5d8b65SAndreas Gohr if($type == 'fieldsetopen') { 3771f5d8b65SAndreas Gohr if($isopen) { 37880b13baaSGerrit Uitslag //close previous fieldset 3791f5d8b65SAndreas Gohr $this->addFieldsetClose($pos); 3801f5d8b65SAndreas Gohr $lastclose = $pos + 1; 3811f5d8b65SAndreas Gohr $pos++; 3821f5d8b65SAndreas Gohr $len++; 3831f5d8b65SAndreas Gohr } 3841f5d8b65SAndreas Gohr $isopen = true; 3851f5d8b65SAndreas Gohr } else if($type == 'fieldsetclose') { 3861f5d8b65SAndreas Gohr if(!$isopen) { 3871f5d8b65SAndreas Gohr // make sure there was a fieldsetopen 3881f5d8b65SAndreas Gohr // either right after the last close or at the begining 3891f5d8b65SAndreas Gohr $this->addFieldsetOpen('', $lastclose); 3901f5d8b65SAndreas Gohr $len++; 3911f5d8b65SAndreas Gohr $pos++; 3921f5d8b65SAndreas Gohr } 3931f5d8b65SAndreas Gohr $lastclose = $pos; 3941f5d8b65SAndreas Gohr $isopen = false; 3951f5d8b65SAndreas Gohr } 3961f5d8b65SAndreas Gohr } 3971f5d8b65SAndreas Gohr 3981f5d8b65SAndreas Gohr // close open fieldset at the end 3991f5d8b65SAndreas Gohr if($isopen) { 4001f5d8b65SAndreas Gohr $this->addFieldsetClose(); 4011f5d8b65SAndreas Gohr } 402de19515fSAndreas Gohr } 403de19515fSAndreas Gohr 404de19515fSAndreas Gohr /** 40512a4e4d1SAndreas Gohr * The HTML representation of the whole form 40612a4e4d1SAndreas Gohr * 40712a4e4d1SAndreas Gohr * @return string 40812a4e4d1SAndreas Gohr */ 40912a4e4d1SAndreas Gohr public function toHTML() { 410de19515fSAndreas Gohr $this->balanceFieldsets(); 411de19515fSAndreas Gohr 41212a4e4d1SAndreas Gohr $html = '<form ' . buildAttributes($this->attrs()) . '>' . DOKU_LF; 41312a4e4d1SAndreas Gohr 41412a4e4d1SAndreas Gohr foreach($this->hidden as $name => $value) { 41512a4e4d1SAndreas Gohr $html .= '<input type="hidden" name="' . $name . '" value="' . formText($value) . '" />' . DOKU_LF; 41612a4e4d1SAndreas Gohr } 41712a4e4d1SAndreas Gohr 41812a4e4d1SAndreas Gohr foreach($this->elements as $element) { 41912a4e4d1SAndreas Gohr $html .= $element->toHTML() . DOKU_LF; 42012a4e4d1SAndreas Gohr } 42112a4e4d1SAndreas Gohr 42212a4e4d1SAndreas Gohr $html .= '</form>' . DOKU_LF; 42312a4e4d1SAndreas Gohr 42412a4e4d1SAndreas Gohr return $html; 42512a4e4d1SAndreas Gohr } 42612a4e4d1SAndreas Gohr} 427