3 +--------------------------------------------------------------------+
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. |
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. |
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. |
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 +--------------------------------------------------------------------+
32 * @copyright U.S. PIRG Education Fund 2007
36 class CRM_Core_QuickForm_GroupMultiSelect
extends CRM_Core_QuickForm_NestedAdvMultiSelect
{
39 * Returns the HTML generated for the advanced multiple select component.
42 * @since version 0.4.0 (2005-06-25)
44 public function toHtml() {
45 if ($this->_flagFrozen
) {
46 return $this->getFrozenHtml();
49 $tabs = $this->_getTabs();
50 $tab = $this->_getTab();
53 if ($this->getComment() != '') {
54 $strHtml .= $tabs . '<!-- ' . $this->getComment() . " //-->" . PHP_EOL
;
57 $selectName = $this->getName() . '[]';
59 // placeholder {unselected} existence determines if we will render
60 if (strpos($this->_elementTemplate
, '{unselected}') === FALSE) {
61 // ... a single multi-select with checkboxes
63 $id = $this->getAttribute('id');
65 $strHtmlSelected = $tab . '<div id="' . $id . 'amsSelected">' . PHP_EOL
;
67 foreach ($this->_options
as $option) {
69 $_labelAttributes = ['style', 'class', 'onmouseover', 'onmouseout'];
70 $labelAttributes = [];
71 foreach ($_labelAttributes as $attr) {
72 if (isset($option['attr'][$attr])) {
73 $labelAttributes[$attr] = $option['attr'][$attr];
74 unset($option['attr'][$attr]);
78 if (is_array($this->_values
) && in_array((string) $option['attr']['value'], $this->_values
)) {
79 // The items is *selected*
80 $checked = ' checked="checked"';
83 // The item is *unselected* so we want to put it
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
;
88 $strHtmlSelected .= $tab . '</div>' . PHP_EOL
;
91 $strHtmlUnselected = '';
95 // build the select all button with all its attributes
96 $attributes = ['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
;
101 // build the select none button with all its attributes
102 $attributes = ['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
;
107 // build the toggle selection button with all its attributes
108 $attributes = ['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
;
114 $strHtmlMoveDown = '';
117 // ... or a dual multi-select
119 // set name of Select From Box
120 $this->_attributesUnselected
= [
121 'name' => '__' . $selectName,
122 'ondblclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'add')",
124 $this->_attributesUnselected
= array_merge($this->_attributes
, $this->_attributesUnselected
);
125 $attrUnselected = $this->_getAttrString($this->_attributesUnselected
);
127 // set name of Select To Box
128 $this->_attributesSelected
= [
129 'name' => '_' . $selectName,
130 'ondblclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'remove')",
132 $this->_attributesSelected
= array_merge($this->_attributes
, $this->_attributesSelected
);
133 $attrSelected = $this->_getAttrString($this->_attributesSelected
);
135 // set name of Select hidden Box
136 $this->_attributesHidden
= [
137 'name' => $selectName,
138 'style' => 'overflow: hidden; visibility: hidden; width: 1px; height: 0;',
140 $this->_attributesHidden
= array_merge($this->_attributes
, $this->_attributesHidden
);
141 $attrHidden = $this->_getAttrString($this->_attributesHidden
);
143 // prepare option tables to be displayed as in POST order
144 $append = count($this->_values
);
146 $arrHtmlSelected = array_fill(0, $append, ' ');
149 $arrHtmlSelected = [];
152 $options = count($this->_options
);
153 $arrHtmlUnselected = [];
155 $arrHtmlHidden = array_fill(0, $options, ' ');
157 foreach ($this->_options
as $option) {
158 if (is_array($this->_values
) &&
159 in_array((string) $option['attr']['value'], $this->_values
)
161 // Get the post order
162 $key = array_search($option['attr']['value'], $this->_values
);
164 // The items is *selected* so we want to put it in the 'selected' multi-select
165 $arrHtmlSelected[$key] = $option;
166 // Add it to the 'hidden' multi-select and set it as 'selected'
167 $option['attr']['selected'] = 'selected';
168 $arrHtmlHidden[$key] = $option;
171 // The item is *unselected* so we want to put it in the 'unselected' multi-select
172 $arrHtmlUnselected[] = $option;
173 // Add it to the hidden multi-select as 'unselected'
174 $arrHtmlHidden[$append] = $option;
183 // The 'unselected' multi-select which appears on the left
184 $strHtmlUnselected = "<select$attrUnselected>" . PHP_EOL
;
185 if (count($arrHtmlUnselected) > 0) {
186 foreach ($arrHtmlUnselected as $data) {
187 $strHtmlUnselected .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL
;
190 $strHtmlUnselected .= '</select>';
192 // The 'selected' multi-select which appears on the right
193 $strHtmlSelected = "<select$attrSelected>" . PHP_EOL
;
194 if (count($arrHtmlSelected) > 0) {
195 foreach ($arrHtmlSelected as $data) {
196 $strHtmlSelected .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL
;
199 $strHtmlSelected .= '</select>';
201 // The 'hidden' multi-select
202 $strHtmlHidden = "<select$attrHidden>" . PHP_EOL
;
203 if (count($arrHtmlHidden) > 0) {
204 foreach ($arrHtmlHidden as $data) {
205 $strHtmlHidden .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL
;
208 $strHtmlHidden .= '</select>';
210 // build the remove button with all its attributes
211 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'remove'); return false;"];
212 $this->_removeButtonAttributes
= array_merge($this->_removeButtonAttributes
, $attributes);
213 $attrStrRemove = $this->_getAttrString($this->_removeButtonAttributes
);
214 $strHtmlRemove = "<input$attrStrRemove />" . PHP_EOL
;
216 // build the add button with all its attributes
217 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'add'); return false;"];
218 $this->_addButtonAttributes
= array_merge($this->_addButtonAttributes
, $attributes);
219 $attrStrAdd = $this->_getAttrString($this->_addButtonAttributes
);
220 $strHtmlAdd = "<input$attrStrAdd />" . PHP_EOL
;
222 // build the select all button with all its attributes
223 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'all'); return false;"];
224 $this->_allButtonAttributes
= array_merge($this->_allButtonAttributes
, $attributes);
225 $attrStrAll = $this->_getAttrString($this->_allButtonAttributes
);
226 $strHtmlAll = "<input$attrStrAll />" . PHP_EOL
;
228 // build the select none button with all its attributes
229 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'none'); return false;"];
230 $this->_noneButtonAttributes
= array_merge($this->_noneButtonAttributes
, $attributes);
231 $attrStrNone = $this->_getAttrString($this->_noneButtonAttributes
);
232 $strHtmlNone = "<input$attrStrNone />" . PHP_EOL
;
234 // build the toggle button with all its attributes
235 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'toggle'); return false;"];
236 $this->_toggleButtonAttributes
= array_merge($this->_toggleButtonAttributes
, $attributes);
237 $attrStrToggle = $this->_getAttrString($this->_toggleButtonAttributes
);
238 $strHtmlToggle = "<input$attrStrToggle />" . PHP_EOL
;
240 // build the move up button with all its attributes
241 $attributes = ['onclick' => "{$this->_jsPrefix}moveUp(this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "']); return false;"];
242 $this->_upButtonAttributes
= array_merge($this->_upButtonAttributes
, $attributes);
243 $attrStrUp = $this->_getAttrString($this->_upButtonAttributes
);
244 $strHtmlMoveUp = "<input$attrStrUp />" . PHP_EOL
;
246 // build the move down button with all its attributes
247 $attributes = ['onclick' => "{$this->_jsPrefix}moveDown(this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "']); return false;"];
248 $this->_downButtonAttributes
= array_merge($this->_downButtonAttributes
, $attributes);
249 $attrStrDown = $this->_getAttrString($this->_downButtonAttributes
);
250 $strHtmlMoveDown = "<input$attrStrDown />" . PHP_EOL
;
253 // render all part of the multi select component with the template
254 $strHtml = $this->_elementTemplate
;
256 // Prepare multiple labels
257 $labels = $this->getLabel();
258 if (is_array($labels)) {
259 array_shift($labels);
261 // render extra labels, if any
262 if (is_array($labels)) {
263 foreach ($labels as $key => $text) {
264 $key = is_int($key) ?
$key +
2 : $key;
265 $strHtml = str_replace("{label_{$key}}", $text, $strHtml);
266 $strHtml = str_replace("<!-- BEGIN label_{$key} -->", '', $strHtml);
267 $strHtml = str_replace("<!-- END label_{$key} -->", '', $strHtml);
270 // clean up useless label tags
271 if (strpos($strHtml, '{label_')) {
272 $strHtml = preg_replace('/\s*<!-- BEGIN label_(\S+) -->.*<!-- END label_\1 -->\s*/i', '', $strHtml);
290 $this->getElementCss(FALSE),
291 $this->getElementJs(FALSE),
292 $this->_tableAttributes
,
294 $strHtmlSelected . $strHtmlHidden,
304 $strHtml = str_replace($placeHolders, $htmlElements, $strHtml);