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
35 class CRM_Core_QuickForm_GroupMultiSelect
extends CRM_Core_QuickForm_NestedAdvMultiSelect
{
38 * Returns the HTML generated for the advanced multiple select component.
41 * @since version 0.4.0 (2005-06-25)
43 public function toHtml() {
44 if ($this->_flagFrozen
) {
45 return $this->getFrozenHtml();
48 $tabs = $this->_getTabs();
49 $tab = $this->_getTab();
52 if ($this->getComment() != '') {
53 $strHtml .= $tabs . '<!-- ' . $this->getComment() . " //-->" . PHP_EOL
;
56 $selectName = $this->getName() . '[]';
58 // placeholder {unselected} existence determines if we will render
59 if (strpos($this->_elementTemplate
, '{unselected}') === FALSE) {
60 // ... a single multi-select with checkboxes
62 $id = $this->getAttribute('id');
64 $strHtmlSelected = $tab . '<div id="' . $id . 'amsSelected">' . PHP_EOL
;
66 foreach ($this->_options
as $option) {
68 $_labelAttributes = ['style', 'class', 'onmouseover', 'onmouseout'];
69 $labelAttributes = [];
70 foreach ($_labelAttributes as $attr) {
71 if (isset($option['attr'][$attr])) {
72 $labelAttributes[$attr] = $option['attr'][$attr];
73 unset($option['attr'][$attr]);
77 if (is_array($this->_values
) && in_array((string) $option['attr']['value'], $this->_values
)) {
78 // The items is *selected*
79 $checked = ' checked="checked"';
82 // The item is *unselected* so we want to put it
85 $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 $strHtmlSelected .= $tab . '</div>' . PHP_EOL
;
90 $strHtmlUnselected = '';
94 // build the select all button with all its attributes
95 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}('" . $this->getName() . "', 1);"];
96 $this->_allButtonAttributes
= array_merge($this->_allButtonAttributes
, $attributes);
97 $attrStrAll = $this->_getAttrString($this->_allButtonAttributes
);
98 $strHtmlAll = "<input$attrStrAll />" . PHP_EOL
;
100 // build the select none button with all its attributes
101 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}('" . $this->getName() . "', 0);"];
102 $this->_noneButtonAttributes
= array_merge($this->_noneButtonAttributes
, $attributes);
103 $attrStrNone = $this->_getAttrString($this->_noneButtonAttributes
);
104 $strHtmlNone = "<input$attrStrNone />" . PHP_EOL
;
106 // build the toggle selection button with all its attributes
107 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}('" . $this->getName() . "', 2);"];
108 $this->_toggleButtonAttributes
= array_merge($this->_toggleButtonAttributes
, $attributes);
109 $attrStrToggle = $this->_getAttrString($this->_toggleButtonAttributes
);
110 $strHtmlToggle = "<input$attrStrToggle />" . PHP_EOL
;
113 $strHtmlMoveDown = '';
116 // ... or a dual multi-select
118 // set name of Select From Box
119 $this->_attributesUnselected
= [
120 'name' => '__' . $selectName,
121 'ondblclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'add')",
123 $this->_attributesUnselected
= array_merge($this->_attributes
, $this->_attributesUnselected
);
124 $attrUnselected = $this->_getAttrString($this->_attributesUnselected
);
126 // set name of Select To Box
127 $this->_attributesSelected
= [
128 'name' => '_' . $selectName,
129 'ondblclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'remove')",
131 $this->_attributesSelected
= array_merge($this->_attributes
, $this->_attributesSelected
);
132 $attrSelected = $this->_getAttrString($this->_attributesSelected
);
134 // set name of Select hidden Box
135 $this->_attributesHidden
= [
136 'name' => $selectName,
137 'style' => 'overflow: hidden; visibility: hidden; width: 1px; height: 0;',
139 $this->_attributesHidden
= array_merge($this->_attributes
, $this->_attributesHidden
);
140 $attrHidden = $this->_getAttrString($this->_attributesHidden
);
142 // prepare option tables to be displayed as in POST order
143 $append = count($this->_values
);
145 $arrHtmlSelected = array_fill(0, $append, ' ');
148 $arrHtmlSelected = [];
151 $options = count($this->_options
);
152 $arrHtmlUnselected = [];
154 $arrHtmlHidden = array_fill(0, $options, ' ');
156 foreach ($this->_options
as $option) {
157 if (is_array($this->_values
) &&
158 in_array((string) $option['attr']['value'], $this->_values
)
160 // Get the post order
161 $key = array_search($option['attr']['value'], $this->_values
);
163 // The items is *selected* so we want to put it in the 'selected' multi-select
164 $arrHtmlSelected[$key] = $option;
165 // Add it to the 'hidden' multi-select and set it as 'selected'
166 $option['attr']['selected'] = 'selected';
167 $arrHtmlHidden[$key] = $option;
170 // The item is *unselected* so we want to put it in the 'unselected' multi-select
171 $arrHtmlUnselected[] = $option;
172 // Add it to the hidden multi-select as 'unselected'
173 $arrHtmlHidden[$append] = $option;
182 // The 'unselected' multi-select which appears on the left
183 $strHtmlUnselected = "<select$attrUnselected>" . PHP_EOL
;
184 if (count($arrHtmlUnselected) > 0) {
185 foreach ($arrHtmlUnselected as $data) {
186 $strHtmlUnselected .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL
;
189 $strHtmlUnselected .= '</select>';
191 // The 'selected' multi-select which appears on the right
192 $strHtmlSelected = "<select$attrSelected>" . PHP_EOL
;
193 if (count($arrHtmlSelected) > 0) {
194 foreach ($arrHtmlSelected as $data) {
195 $strHtmlSelected .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL
;
198 $strHtmlSelected .= '</select>';
200 // The 'hidden' multi-select
201 $strHtmlHidden = "<select$attrHidden>" . PHP_EOL
;
202 if (count($arrHtmlHidden) > 0) {
203 foreach ($arrHtmlHidden as $data) {
204 $strHtmlHidden .= $tabs . $tab . '<option' . $this->_getAttrString($data['attr']) . '>' . $data['text'] . '</option>' . PHP_EOL
;
207 $strHtmlHidden .= '</select>';
209 // build the remove button with all its attributes
210 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'remove'); return false;"];
211 $this->_removeButtonAttributes
= array_merge($this->_removeButtonAttributes
, $attributes);
212 $attrStrRemove = $this->_getAttrString($this->_removeButtonAttributes
);
213 $strHtmlRemove = "<input$attrStrRemove />" . PHP_EOL
;
215 // build the add button with all its attributes
216 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'add'); return false;"];
217 $this->_addButtonAttributes
= array_merge($this->_addButtonAttributes
, $attributes);
218 $attrStrAdd = $this->_getAttrString($this->_addButtonAttributes
);
219 $strHtmlAdd = "<input$attrStrAdd />" . PHP_EOL
;
221 // build the select all button with all its attributes
222 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'all'); return false;"];
223 $this->_allButtonAttributes
= array_merge($this->_allButtonAttributes
, $attributes);
224 $attrStrAll = $this->_getAttrString($this->_allButtonAttributes
);
225 $strHtmlAll = "<input$attrStrAll />" . PHP_EOL
;
227 // build the select none button with all its attributes
228 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'none'); return false;"];
229 $this->_noneButtonAttributes
= array_merge($this->_noneButtonAttributes
, $attributes);
230 $attrStrNone = $this->_getAttrString($this->_noneButtonAttributes
);
231 $strHtmlNone = "<input$attrStrNone />" . PHP_EOL
;
233 // build the toggle button with all its attributes
234 $attributes = ['onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'toggle'); return false;"];
235 $this->_toggleButtonAttributes
= array_merge($this->_toggleButtonAttributes
, $attributes);
236 $attrStrToggle = $this->_getAttrString($this->_toggleButtonAttributes
);
237 $strHtmlToggle = "<input$attrStrToggle />" . PHP_EOL
;
239 // build the move up button with all its attributes
240 $attributes = ['onclick' => "{$this->_jsPrefix}moveUp(this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "']); return false;"];
241 $this->_upButtonAttributes
= array_merge($this->_upButtonAttributes
, $attributes);
242 $attrStrUp = $this->_getAttrString($this->_upButtonAttributes
);
243 $strHtmlMoveUp = "<input$attrStrUp />" . PHP_EOL
;
245 // build the move down button with all its attributes
246 $attributes = ['onclick' => "{$this->_jsPrefix}moveDown(this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "']); return false;"];
247 $this->_downButtonAttributes
= array_merge($this->_downButtonAttributes
, $attributes);
248 $attrStrDown = $this->_getAttrString($this->_downButtonAttributes
);
249 $strHtmlMoveDown = "<input$attrStrDown />" . PHP_EOL
;
252 // render all part of the multi select component with the template
253 $strHtml = $this->_elementTemplate
;
255 // Prepare multiple labels
256 $labels = $this->getLabel();
257 if (is_array($labels)) {
258 array_shift($labels);
260 // render extra labels, if any
261 if (is_array($labels)) {
262 foreach ($labels as $key => $text) {
263 $key = is_int($key) ?
$key +
2 : $key;
264 $strHtml = str_replace("{label_{$key}}", $text, $strHtml);
265 $strHtml = str_replace("<!-- BEGIN label_{$key} -->", '', $strHtml);
266 $strHtml = str_replace("<!-- END label_{$key} -->", '', $strHtml);
269 // clean up useless label tags
270 if (strpos($strHtml, '{label_')) {
271 $strHtml = preg_replace('/\s*<!-- BEGIN label_(\S+) -->.*<!-- END label_\1 -->\s*/i', '', $strHtml);
289 $this->getElementCss(FALSE),
290 $this->getElementJs(FALSE),
291 $this->_tableAttributes
,
293 $strHtmlSelected . $strHtmlHidden,
303 $strHtml = str_replace($placeHolders, $htmlElements, $strHtml);