1 <?php
2 /**
3 * Dropdown field, created from a <select> tag.
4 * @package forms
5 * @subpackage fields-basic
6 */
7 class DropdownField extends FormField {
8
9 /**
10 * @var boolean $source Associative or numeric array of all dropdown items,
11 * with array key as the submitted field value, and the array value as a
12 * natural language description shown in the interface element.
13 */
14 protected $source;
15
16 /**
17 * @var boolean $isSelected Determines if the field was selected
18 * at the time it was rendered, so if {@link $value} matches on of the array
19 * values specified in {@link $source}
20 */
21 protected $isSelected;
22
23 /**
24 * @var boolean $hasEmptyDefault Show the first <option> element as
25 * empty (not having a value), with an optional label defined through
26 * {@link $emptyString}. By default, the <select> element will be
27 * rendered with the first option from {@link $source} selected.
28 */
29 protected $hasEmptyDefault = false;
30
31 /**
32 * @var string $emptyString The title shown for an empty default selection,
33 * e.g. "Select...".
34 */
35 protected $emptyString = '';
36
37 /**
38 * Creates a new dropdown field.
39 * @param $name The field name
40 * @param $title The field title
41 * @param $source An map of the dropdown items
42 * @param $value The current value
43 * @param $form The parent form
44 * @param $emptyString mixed Add an empty selection on to of the {@link $source}-Array
45 * (can also be boolean, which results in an empty string)
46 * Argument is deprecated in 2.3, please use {@link setHasEmptyDefault()} and {@link setEmptyString()} instead.
47 */
48 function __construct($name, $title = null, $source = array(), $value = "", $form = null, $emptyString = null) {
49 $this->source = $source;
50
51 if($emptyString) $this->setHasEmptyDefault(true);
52 if(is_string($emptyString)) $this->setEmptyString($emptyString);
53
54 parent::__construct($name, ($title===null) ? $name : $title, $value, $form);
55 }
56
57 /**
58 * Returns a <select> tag containing all the appropriate <option> tags.
59 * Makes use of {@link FormField->createTag()} to generate the <select>
60 * tag and option elements inside is as the content of the <select>.
61 *
62 * @return string HTML tag for this dropdown field
63 */
64 function Field() {
65 $options = array();
66 $source = $this->getSource();
67 if($source) {
68 // For SQLMap sources, the empty string needs to be added specially
69 if(is_object($source) && $this->emptyString) {
70 $selected = ($this->value === '' || $this->value === null);
71 $options[] = new ArrayData(array(
72 'Value' => '',
73 'Title' => $this->getEmptyString(),
74 'Selected' => $selected,
75 ));
76 }
77 foreach($source as $value => $title) {
78 // Blank value of field and source (e.g. "" => "(Any)")
79 if($value === '' && ($this->value === '' || $this->value === null)) {
80 $selected = 'selected';
81 } else {
82 // Normal value from the source
83 if($value) {
84 $selected = ($value == $this->value) ? 'selected' : null;
85 } else {
86 // Do a type check comparison, we might have an array key of 0
87 $selected = ($value === $this->value) ? 'selected' : null;
88 }
89 $this->isSelected = ($selected) ? true : false;
90 }
91 $options[] = new ArrayData(array(
92 'Value' => $value,
93 'Title' => Convert::raw2xml($title),
94 'Selected' => $selected,
95 ));
96 }
97 }
98 $attributes = array(
99 'class' => ($this->extraClass() ? $this->extraClass() : ''),
100 'id' => $this->id(),
101 'name' => $this->name,
102 'tabindex' => $this->getTabIndex(),
103 );
104 return $this->createTag('select', $attributes, new DataObjectSet($options));
105 }
106
107 /**
108 * @return boolean
109 */
110 function isSelected(){
111 return $this->isSelected;
112 }
113
114 /**
115 * Gets the source array including any empty default values.
116 *
117 * @return array
118 */
119 function getSource() {
120 if(is_array($this->source) && $this->getHasEmptyDefault()) {
121 return array(""=>$this->emptyString) + (array)$this->source;
122 } else {
123 return $this->source;
124 }
125 }
126
127 /**
128 * @param array $source
129 */
130 function setSource($source) {
131 $this->source = $source;
132 }
133
134 /**
135 * @param boolean $bool
136 */
137 function setHasEmptyDefault($bool) {
138 $this->hasEmptyDefault = $bool;
139 }
140
141 /**
142 * @return boolean
143 */
144 function getHasEmptyDefault() {
145 return $this->hasEmptyDefault;
146 }
147
148 /**
149 * Set the default selection label, e.g. "select...".
150 * Defaults to an empty string. Automatically sets
151 * {@link $hasEmptyDefault} to true.
152 *
153 * @param string $str
154 */
155 function setEmptyString($str) {
156 $this->setHasEmptyDefault(true);
157 $this->emptyString = $str;
158 }
159
160 /**
161 * @return string
162 */
163 function getEmptyString() {
164 return $this->emptyString;
165 }
166
167 function performReadonlyTransformation() {
168 $field = new LookupField($this->name, $this->title, $this->source);
169 $field->setValue($this->value);
170 $field->setForm($this->form);
171 $field->setReadonly(true);
172 return $field;
173 }
174
175 function extraClass(){
176 $ret = parent::extraClass();
177 if($this->extraClass) $ret .= " $this->extraClass";
178 return $ret;
179 }
180 }
181 ?>