112a4e4d1SAndreas Gohr<?php 212a4e4d1SAndreas Gohrnamespace dokuwiki\Form; 312a4e4d1SAndreas Gohr 412a4e4d1SAndreas Gohr/** 512a4e4d1SAndreas Gohr * Class InputElement 612a4e4d1SAndreas Gohr * 7de19515fSAndreas Gohr * Base class for all input elements. Uses a wrapping label when label 8de19515fSAndreas Gohr * text is given. 912a4e4d1SAndreas Gohr * 1012a4e4d1SAndreas Gohr * @todo figure out how to make wrapping or related label configurable 1112a4e4d1SAndreas Gohr * @package dokuwiki\Form 1212a4e4d1SAndreas Gohr */ 1312a4e4d1SAndreas Gohrclass InputElement extends Element { 1412a4e4d1SAndreas Gohr /** 1512a4e4d1SAndreas Gohr * @var Label 1612a4e4d1SAndreas Gohr */ 17de19515fSAndreas Gohr protected $label = null; 1812a4e4d1SAndreas Gohr 1912a4e4d1SAndreas Gohr /** 2012a4e4d1SAndreas Gohr * @var bool if the element should reflect posted values 2112a4e4d1SAndreas Gohr */ 2212a4e4d1SAndreas Gohr protected $useInput = true; 2312a4e4d1SAndreas Gohr 2412a4e4d1SAndreas Gohr /** 2512a4e4d1SAndreas Gohr * @param string $type The type of this element 2612a4e4d1SAndreas Gohr * @param string $name The name of this form element 2712a4e4d1SAndreas Gohr * @param string $label The label text for this element 2812a4e4d1SAndreas Gohr */ 29de19515fSAndreas Gohr public function __construct($type, $name, $label = '') { 3012a4e4d1SAndreas Gohr parent::__construct($type, array('name' => $name)); 3112a4e4d1SAndreas Gohr $this->attr('name', $name); 32*08099e4fSAndreas Gohr $this->attr('type', $type); 33de19515fSAndreas Gohr if($label) $this->label = new Label($label); 34de19515fSAndreas Gohr } 35de19515fSAndreas Gohr 36de19515fSAndreas Gohr /** 37de19515fSAndreas Gohr * Returns the label element if there's one set 38de19515fSAndreas Gohr * 39de19515fSAndreas Gohr * @return Label|null 40de19515fSAndreas Gohr */ 41de19515fSAndreas Gohr public function getLabel() { 42de19515fSAndreas Gohr return $this->label; 4312a4e4d1SAndreas Gohr } 4412a4e4d1SAndreas Gohr 4512a4e4d1SAndreas Gohr /** 4612a4e4d1SAndreas Gohr * Should the user sent input be used to initialize the input field 4712a4e4d1SAndreas Gohr * 4812a4e4d1SAndreas Gohr * The default is true. Any set values will be overwritten by the INPUT 4912a4e4d1SAndreas Gohr * provided values. 5012a4e4d1SAndreas Gohr * 5112a4e4d1SAndreas Gohr * @param bool $useinput 5212a4e4d1SAndreas Gohr * @return $this 5312a4e4d1SAndreas Gohr */ 5412a4e4d1SAndreas Gohr public function useInput($useinput) { 5512a4e4d1SAndreas Gohr $this->useInput = (bool) $useinput; 5612a4e4d1SAndreas Gohr return $this; 5712a4e4d1SAndreas Gohr } 5812a4e4d1SAndreas Gohr 5912a4e4d1SAndreas Gohr /** 6012a4e4d1SAndreas Gohr * Get or set the element's ID 6112a4e4d1SAndreas Gohr * 6212a4e4d1SAndreas Gohr * @param null|string $id 6312a4e4d1SAndreas Gohr * @return string|$this 6412a4e4d1SAndreas Gohr */ 6512a4e4d1SAndreas Gohr public function id($id = null) { 66de19515fSAndreas Gohr if($this->label) $this->label->attr('for', $id); 6712a4e4d1SAndreas Gohr return parent::id($id); 6812a4e4d1SAndreas Gohr } 6912a4e4d1SAndreas Gohr 7012a4e4d1SAndreas Gohr /** 7112a4e4d1SAndreas Gohr * Adds a class to the class attribute 7212a4e4d1SAndreas Gohr * 7312a4e4d1SAndreas Gohr * This is the preferred method of setting the element's class 7412a4e4d1SAndreas Gohr * 7512a4e4d1SAndreas Gohr * @param string $class the new class to add 7612a4e4d1SAndreas Gohr * @return $this 7712a4e4d1SAndreas Gohr */ 7812a4e4d1SAndreas Gohr public function addClass($class) { 79de19515fSAndreas Gohr if($this->label) $this->label->addClass($class); 8012a4e4d1SAndreas Gohr return parent::addClass($class); 8112a4e4d1SAndreas Gohr } 8212a4e4d1SAndreas Gohr 8312a4e4d1SAndreas Gohr /** 8412a4e4d1SAndreas Gohr * Figures out how to access the value for this field from INPUT data 8512a4e4d1SAndreas Gohr * 8612a4e4d1SAndreas Gohr * The element's name could have been given as a simple string ('foo') 8712a4e4d1SAndreas Gohr * or in array notation ('foo[bar]'). 8812a4e4d1SAndreas Gohr * 8912a4e4d1SAndreas Gohr * Note: this function only handles one level of arrays. If your data 9012a4e4d1SAndreas Gohr * is nested deeper, you should call useInput(false) and set the 9112a4e4d1SAndreas Gohr * correct value yourself 9212a4e4d1SAndreas Gohr * 9312a4e4d1SAndreas Gohr * @return array name and array key (null if not an array) 9412a4e4d1SAndreas Gohr */ 9512a4e4d1SAndreas Gohr protected function getInputName() { 9612a4e4d1SAndreas Gohr $name = $this->attr('name'); 9712a4e4d1SAndreas Gohr parse_str("$name=1", $parsed); 9812a4e4d1SAndreas Gohr 9912a4e4d1SAndreas Gohr $name = array_keys($parsed); 10012a4e4d1SAndreas Gohr $name = array_shift($name); 10112a4e4d1SAndreas Gohr 10212a4e4d1SAndreas Gohr if(is_array($parsed[$name])) { 10312a4e4d1SAndreas Gohr $key = array_keys($parsed[$name]); 10412a4e4d1SAndreas Gohr $key = array_shift($key); 10512a4e4d1SAndreas Gohr } else { 10612a4e4d1SAndreas Gohr $key = null; 10712a4e4d1SAndreas Gohr } 10812a4e4d1SAndreas Gohr 10912a4e4d1SAndreas Gohr return array($name, $key); 11012a4e4d1SAndreas Gohr } 11112a4e4d1SAndreas Gohr 11212a4e4d1SAndreas Gohr /** 11312a4e4d1SAndreas Gohr * Handles the useInput flag and set the value attribute accordingly 11412a4e4d1SAndreas Gohr */ 11512a4e4d1SAndreas Gohr protected function prefillInput() { 11612a4e4d1SAndreas Gohr global $INPUT; 11712a4e4d1SAndreas Gohr 11812a4e4d1SAndreas Gohr list($name, $key) = $this->getInputName(); 11912a4e4d1SAndreas Gohr if(!$INPUT->has($name)) return; 12012a4e4d1SAndreas Gohr 12112a4e4d1SAndreas Gohr if($key === null) { 12212a4e4d1SAndreas Gohr $value = $INPUT->str($name); 12312a4e4d1SAndreas Gohr } else { 12412a4e4d1SAndreas Gohr $value = $INPUT->arr($name); 12512a4e4d1SAndreas Gohr if(isset($value[$key])) { 12612a4e4d1SAndreas Gohr $value = $value[$key]; 12712a4e4d1SAndreas Gohr } else { 12812a4e4d1SAndreas Gohr $value = ''; 12912a4e4d1SAndreas Gohr } 13012a4e4d1SAndreas Gohr } 13112a4e4d1SAndreas Gohr if($value !== '') { 13212a4e4d1SAndreas Gohr $this->val($value); 13312a4e4d1SAndreas Gohr } 13412a4e4d1SAndreas Gohr } 13512a4e4d1SAndreas Gohr 13612a4e4d1SAndreas Gohr /** 13712a4e4d1SAndreas Gohr * The HTML representation of this element 13812a4e4d1SAndreas Gohr * 13912a4e4d1SAndreas Gohr * @return string 14012a4e4d1SAndreas Gohr */ 14112a4e4d1SAndreas Gohr protected function mainElementHTML() { 14212a4e4d1SAndreas Gohr if($this->useInput) $this->prefillInput(); 14312a4e4d1SAndreas Gohr return '<input ' . buildAttributes($this->attrs()) . ' />'; 14412a4e4d1SAndreas Gohr } 14512a4e4d1SAndreas Gohr 14612a4e4d1SAndreas Gohr /** 14712a4e4d1SAndreas Gohr * The HTML representation of this element wrapped in a label 14812a4e4d1SAndreas Gohr * 14912a4e4d1SAndreas Gohr * @return string 15012a4e4d1SAndreas Gohr */ 15112a4e4d1SAndreas Gohr public function toHTML() { 152de19515fSAndreas Gohr if($this->label) { 15312a4e4d1SAndreas Gohr return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF . 154370c6450SAndreas Gohr '<span>' . hsc($this->label->val()) . '</span>' . DOKU_LF . 15512a4e4d1SAndreas Gohr $this->mainElementHTML() . DOKU_LF . 15612a4e4d1SAndreas Gohr '</label>'; 157de19515fSAndreas Gohr } else { 158de19515fSAndreas Gohr return $this->mainElementHTML(); 159de19515fSAndreas Gohr } 16012a4e4d1SAndreas Gohr } 16112a4e4d1SAndreas Gohr} 162