Add missing comments in CRM/Core
[civicrm-core.git] / CRM / Core / QuickForm / GroupMultiSelect.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright U.S. PIRG Education Fund (c) 2007 |
7 | Licensed to CiviCRM under the Academic Free License version 3.0. |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License and the CiviCRM Licensing Exception along |
22 | with this program; if not, contact CiviCRM LLC |
23 | at info[AT]civicrm[DOT]org. If you have questions about the |
24 | GNU Affero General Public License or the licensing of CiviCRM, |
25 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
26 +--------------------------------------------------------------------+
27 */
28
29 /**
30 *
31 * @package CRM
32 * @copyright U.S. PIRG Education Fund 2007
33 * $Id$
34 *
35 */
36 class CRM_Core_QuickForm_GroupMultiSelect extends CRM_Core_QuickForm_NestedAdvMultiSelect {
37 /**
38 * Returns the HTML generated for the advanced mutliple select component
39 *
40 * @access public
41 * @return string
42 * @since version 0.4.0 (2005-06-25)
43 */
44 function toHtml() {
45 if ($this->_flagFrozen) {
46 return $this->getFrozenHtml();
47 }
48
49 $tabs = $this->_getTabs();
50 $tab = $this->_getTab();
51 $strHtml = '';
52
53 if ($this->getComment() != '') {
54 $strHtml .= $tabs . '<!-- ' . $this->getComment() . " //-->" . PHP_EOL;
55 }
56
57 $selectName = $this->getName() . '[]';
58
59 // placeholder {unselected} existence determines if we will render
60 if (strpos($this->_elementTemplate, '{unselected}') === FALSE) {
61 // ... a single multi-select with checkboxes
62
63 $id = $this->getAttribute('id');
64
65 $strHtmlSelected = $tab . '<div id="' . $id . 'amsSelected">' . PHP_EOL;
66
67 foreach ($this->_options as $option) {
68
69 $_labelAttributes = array('style', 'class', 'onmouseover', 'onmouseout');
70 $labelAttributes = array();
71 foreach ($_labelAttributes as $attr) {
72 if (isset($option['attr'][$attr])) {
73 $labelAttributes[$attr] = $option['attr'][$attr];
74 unset($option['attr'][$attr]);
75 }
76 }
77
78 if (is_array($this->_values) && in_array((string)$option['attr']['value'], $this->_values)) {
79 // The items is *selected*
80 $checked = ' checked="checked"';
81 }
82 else {
83 // The item is *unselected* so we want to put it
84 $checked = '';
85 }
86 $strHtmlSelected .= $tab . '<label' . $this->_getAttrString($labelAttributes) . '>' . '<input type="checkbox"' . ' id="' . $this->getName() . '"' . ' name="' . $selectName . '"' . $checked . $this->_getAttrString($option['attr']) . ' />' . $option['text'] . '</label>' . PHP_EOL;
87 }
88 $strHtmlSelected .= $tab . '</div>' . PHP_EOL;
89
90 $strHtmlHidden = '';
91 $strHtmlUnselected = '';
92 $strHtmlAdd = '';
93 $strHtmlRemove = '';
94
95 // build the select all button with all its attributes
96 $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}('" . $this->getName() . "', 1);");
97 $this->_allButtonAttributes = array_merge($this->_allButtonAttributes, $attributes);
98 $attrStrAll = $this->_getAttrString($this->_allButtonAttributes);
99 $strHtmlAll = "<input$attrStrAll />" . PHP_EOL;
100
101 // build the select none button with all its attributes
102 $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}('" . $this->getName() . "', 0);");
103 $this->_noneButtonAttributes = array_merge($this->_noneButtonAttributes, $attributes);
104 $attrStrNone = $this->_getAttrString($this->_noneButtonAttributes);
105 $strHtmlNone = "<input$attrStrNone />" . PHP_EOL;
106
107 // build the toggle selection button with all its attributes
108 $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}('" . $this->getName() . "', 2);");
109 $this->_toggleButtonAttributes = array_merge($this->_toggleButtonAttributes, $attributes);
110 $attrStrToggle = $this->_getAttrString($this->_toggleButtonAttributes);
111 $strHtmlToggle = "<input$attrStrToggle />" . PHP_EOL;
112
113 $strHtmlMoveUp = '';
114 $strHtmlMoveDown = '';
115 }
116 else {
117 // ... or a dual multi-select
118
119 // set name of Select From Box
120 $this->_attributesUnselected = array('name' => '__' . $selectName, 'ondblclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'add')");
121 $this->_attributesUnselected = array_merge($this->_attributes, $this->_attributesUnselected);
122 $attrUnselected = $this->_getAttrString($this->_attributesUnselected);
123
124 // set name of Select To Box
125 $this->_attributesSelected = array('name' => '_' . $selectName, 'ondblclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'remove')");
126 $this->_attributesSelected = array_merge($this->_attributes, $this->_attributesSelected);
127 $attrSelected = $this->_getAttrString($this->_attributesSelected);
128
129 // set name of Select hidden Box
130 $this->_attributesHidden = array('name' => $selectName, 'style' => 'overflow: hidden; visibility: hidden; width: 1px; height: 0;');
131 $this->_attributesHidden = array_merge($this->_attributes, $this->_attributesHidden);
132 $attrHidden = $this->_getAttrString($this->_attributesHidden);
133
134 // prepare option tables to be displayed as in POST order
135 $append = count($this->_values);
136 if ($append > 0) {
137 $arrHtmlSelected = array_fill(0, $append, ' ');
138 }
139 else {
140 $arrHtmlSelected = array();
141 }
142
143 $options = count($this->_options);
144 $arrHtmlUnselected = array();
145 if ($options > 0) {
146 $arrHtmlHidden = array_fill(0, $options, ' ');
147
148 foreach ($this->_options as $option) {
149 if (is_array($this->_values) &&
150 in_array((string)$option['attr']['value'], $this->_values)
151 ) {
152 // Get the post order
153 $key = array_search($option['attr']['value'], $this->_values);
154
155 // The items is *selected* so we want to put it in the 'selected' multi-select
156 $arrHtmlSelected[$key] = $option;
157 // Add it to the 'hidden' multi-select and set it as 'selected'
158 $option['attr']['selected'] = 'selected';
159 $arrHtmlHidden[$key] = $option;
160 }
161 else {
162 // The item is *unselected* so we want to put it in the 'unselected' multi-select
163 $arrHtmlUnselected[] = $option;
164 // Add it to the hidden multi-select as 'unselected'
165 $arrHtmlHidden[$append] = $option;
166 $append++;
167 }
168 }
169 }
170 else {
171 $arrHtmlHidden = array();
172 }
173
174 // The 'unselected' multi-select which appears on the left
175 $strHtmlUnselected = "<select$attrUnselected>" . PHP_EOL;
176 if (count($arrHtmlUnselected) > 0) {
177 foreach ($arrHtmlUnselected as $data) {
178 $strHtmlUnselected .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL;
179 }
180 }
181 $strHtmlUnselected .= '</select>';
182
183 // The 'selected' multi-select which appears on the right
184 $strHtmlSelected = "<select$attrSelected>" . PHP_EOL;
185 if (count($arrHtmlSelected) > 0) {
186 foreach ($arrHtmlSelected as $data) {
187 $strHtmlSelected .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL;
188 }
189 }
190 $strHtmlSelected .= '</select>';
191
192 // The 'hidden' multi-select
193 $strHtmlHidden = "<select$attrHidden>" . PHP_EOL;
194 if (count($arrHtmlHidden) > 0) {
195 foreach ($arrHtmlHidden as $data) {
196 $strHtmlHidden .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL;
197 }
198 }
199 $strHtmlHidden .= '</select>';
200
201 // build the remove button with all its attributes
202 $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'remove'); return false;");
203 $this->_removeButtonAttributes = array_merge($this->_removeButtonAttributes, $attributes);
204 $attrStrRemove = $this->_getAttrString($this->_removeButtonAttributes);
205 $strHtmlRemove = "<input$attrStrRemove />" . PHP_EOL;
206
207 // build the add button with all its attributes
208 $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'add'); return false;");
209 $this->_addButtonAttributes = array_merge($this->_addButtonAttributes, $attributes);
210 $attrStrAdd = $this->_getAttrString($this->_addButtonAttributes);
211 $strHtmlAdd = "<input$attrStrAdd />" . PHP_EOL;
212
213 // build the select all button with all its attributes
214 $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'all'); return false;");
215 $this->_allButtonAttributes = array_merge($this->_allButtonAttributes, $attributes);
216 $attrStrAll = $this->_getAttrString($this->_allButtonAttributes);
217 $strHtmlAll = "<input$attrStrAll />" . PHP_EOL;
218
219 // build the select none button with all its attributes
220 $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'none'); return false;");
221 $this->_noneButtonAttributes = array_merge($this->_noneButtonAttributes, $attributes);
222 $attrStrNone = $this->_getAttrString($this->_noneButtonAttributes);
223 $strHtmlNone = "<input$attrStrNone />" . PHP_EOL;
224
225 // build the toggle button with all its attributes
226 $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'toggle'); return false;");
227 $this->_toggleButtonAttributes = array_merge($this->_toggleButtonAttributes, $attributes);
228 $attrStrToggle = $this->_getAttrString($this->_toggleButtonAttributes);
229 $strHtmlToggle = "<input$attrStrToggle />" . PHP_EOL;
230
231 // build the move up button with all its attributes
232 $attributes = array('onclick' => "{$this->_jsPrefix}moveUp(this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "']); return false;");
233 $this->_upButtonAttributes = array_merge($this->_upButtonAttributes, $attributes);
234 $attrStrUp = $this->_getAttrString($this->_upButtonAttributes);
235 $strHtmlMoveUp = "<input$attrStrUp />" . PHP_EOL;
236
237 // build the move down button with all its attributes
238 $attributes = array('onclick' => "{$this->_jsPrefix}moveDown(this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "']); return false;");
239 $this->_downButtonAttributes = array_merge($this->_downButtonAttributes, $attributes);
240 $attrStrDown = $this->_getAttrString($this->_downButtonAttributes);
241 $strHtmlMoveDown = "<input$attrStrDown />" . PHP_EOL;
242 }
243
244 // render all part of the multi select component with the template
245 $strHtml = $this->_elementTemplate;
246
247 // Prepare multiple labels
248 $labels = $this->getLabel();
249 if (is_array($labels)) {
250 array_shift($labels);
251 }
252 // render extra labels, if any
253 if (is_array($labels)) {
254 foreach ($labels as $key => $text) {
255 $key = is_int($key) ? $key + 2 : $key;
256 $strHtml = str_replace("{label_{$key}}", $text, $strHtml);
257 $strHtml = str_replace("<!-- BEGIN label_{$key} -->", '', $strHtml);
258 $strHtml = str_replace("<!-- END label_{$key} -->", '', $strHtml);
259 }
260 }
261 // clean up useless label tags
262 if (strpos($strHtml, '{label_')) {
263 $strHtml = preg_replace('/\s*<!-- BEGIN label_(\S+) -->.*<!-- END label_\1 -->\s*/i', '', $strHtml);
264 }
265
266 $placeHolders = array(
267 '{stylesheet}', '{javascript}', '{class}',
268 '{unselected}', '{selected}',
269 '{add}', '{remove}',
270 '{all}', '{none}', '{toggle}',
271 '{moveup}', '{movedown}',
272 );
273 $htmlElements = array(
274 $this->getElementCss(FALSE), $this->getElementJs(FALSE), $this->_tableAttributes,
275 $strHtmlUnselected, $strHtmlSelected . $strHtmlHidden,
276 $strHtmlAdd, $strHtmlRemove,
277 $strHtmlAll, $strHtmlNone, $strHtmlToggle,
278 $strHtmlMoveUp, $strHtmlMoveDown,
279 );
280
281 $strHtml = str_replace($placeHolders, $htmlElements, $strHtml);
282
283 return $strHtml;
284 }
285 }
286