12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004 |
- <?php
- /**
- * Copyright (c) 2005-2009, Laurent Laville <pear@laurent-laville.org>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the authors nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * PHP versions 4 and 5
- *
- * @category HTML
- * @package HTML_QuickForm_advmultiselect
- * @author Laurent Laville <pear@laurent-laville.org>
- * @copyright 2005-2009 Laurent Laville
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version CVS: $Id: advmultiselect.php,v 1.36 2009/04/05 07:03:39 farell Exp $
- * @link http://pear.php.net/package/HTML_QuickForm_advmultiselect
- * @since File available since Release 0.4.0
- */
- /**
- * Basic error codes
- *
- * @var integer
- * @since 1.5.0
- */
- define('HTML_QUICKFORM_ADVMULTISELECT_ERROR_INVALID_INPUT', 1);
- /**
- * @todo clean class to use only with the multiselect.js library
- *
- * Element for HTML_QuickForm that emulate a multi-select.
- *
- * The HTML_QuickForm_advmultiselect package adds an element to the
- * HTML_QuickForm package that is two select boxes next to each other
- * emulating a multi-select.
- *
- * @category HTML
- * @package HTML_QuickForm_advmultiselect
- * @author Laurent Laville <pear@laurent-laville.org>
- * @copyright 2005-2009 Laurent Laville
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version Release: @package_version@
- * @link http://pear.php.net/package/HTML_QuickForm_advmultiselect
- * @since Class available since Release 0.4.0
- */
- class HTML_QuickForm_advmultiselect extends HTML_QuickForm_select
- {
- /**
- * Associative array of the multi select container attributes
- *
- * @var array
- * @access private
- * @since 0.4.0
- */
- public $_tableAttributes;
- /**
- * Associative array of the add button attributes
- *
- * @var array
- * @access private
- * @since 0.4.0
- */
- public $_addButtonAttributes;
- /**
- * Associative array of the remove button attributes
- *
- * @var array
- * @access private
- * @since 0.4.0
- */
- public $_removeButtonAttributes;
- /**
- * Associative array of the select all button attributes
- *
- * @var array
- * @access private
- * @since 1.1.0
- */
- public $_allButtonAttributes;
- /**
- * Associative array of the select none button attributes
- *
- * @var array
- * @access private
- * @since 1.1.0
- */
- public $_noneButtonAttributes;
- /**
- * Associative array of the toggle selection button attributes
- *
- * @var array
- * @access private
- * @since 1.1.0
- */
- public $_toggleButtonAttributes;
- /**
- * Associative array of the move up button attributes
- *
- * @var array
- * @access private
- * @since 0.5.0
- */
- public $_upButtonAttributes;
- /**
- * Associative array of the move up button attributes
- *
- * @var array
- * @access private
- * @since 0.5.0
- */
- public $_downButtonAttributes;
- /**
- * Associative array of the move top button attributes
- *
- * @var array
- * @access private
- * @since 1.5.0
- */
- public $_topButtonAttributes;
- /**
- * Associative array of the move bottom button attributes
- *
- * @var array
- * @access private
- * @since 1.5.0
- */
- public $_bottomButtonAttributes;
- /**
- * Defines if both list (unselected, selected) will have their elements be
- * arranged from lowest to highest (or reverse)
- * depending on comparaison function.
- *
- * SORT_ASC is used to sort in ascending order
- * SORT_DESC is used to sort in descending order
- *
- * @var string ('none' == false, 'asc' == SORT_ASC, 'desc' == SORT_DESC)
- * @access private
- * @since 0.5.0
- */
- public $_sort;
- /**
- * Associative array of the unselected item box attributes
- *
- * @var array
- * @access private
- * @since 0.4.0
- */
- public $_attributesUnselected;
- /**
- * Associative array of the selected item box attributes
- *
- * @var array
- * @access private
- * @since 0.4.0
- */
- public $_attributesSelected;
- /**
- * Associative array of the internal hidden box attributes
- *
- * @var array
- * @access private
- * @since 0.4.0
- */
- public $_attributesHidden;
- public $selectAllCheckBox = false;
- /**
- * Default Element template string
- *
- * @var string
- * @access private
- * @since 0.4.0
- */
- public $_elementTemplate;
- /**
- * Default Element stylesheet string
- *
- * @var string
- * @access private
- * @since 0.4.0
- */
- public $_elementCSS = '';
- /**
- * Class constructor
- *
- * @param string $elementName Dual Select name attribute
- * @param mixed $elementLabel Label(s) for the select boxes
- * @param mixed $options Data to be used to populate options
- * @param mixed $attributes Either a typical HTML attribute string or
- * an associative array
- * @param integer $sort Either SORT_ASC for auto ascending arrange,
- * SORT_DESC for auto descending arrange, or
- * NULL for no sort (append at end: default)
- *
- * @access public
- * @return void
- * @since version 0.4.0 (2005-06-25)
- */
- public function __construct(
- $elementName = null,
- $elementLabel = null,
- $options = null,
- $attributes = null,
- $sort = null
- ) {
- $opts = $options;
- $options = null; // prevent to use the default select element load options
- parent::__construct($elementName, $elementLabel, $options, $attributes);
- $this->selectAllCheckBox = isset($attributes['select_all_checkbox']) ? $attributes['select_all_checkbox'] : false;
- // allow to load options at once and take care of fancy attributes
- $this->load($opts);
- // add multiple selection attribute by default if missing
- $this->updateAttributes(array('multiple' => 'multiple'));
- if (is_null($this->getAttribute('size'))) {
- // default size is ten item on each select box (left and right)
- $this->updateAttributes(array('size' => 10));
- }
- if (is_null($this->getAttribute('class'))) {
- // default width of each select box
- $this->updateAttributes(array('class' => 'form-control'));
- }
- $this->removeAttribute('class');
- $this->setAttribute('class','form-control');
- // set default add button attributes
- $this->setButtonAttributes('add');
- // set default remove button attributes
- $this->setButtonAttributes('remove');
- // set default selectall button attributes
- $this->setButtonAttributes('all');
- // set default selectnone button attributes
- $this->setButtonAttributes('none');
- // set default toggle selection button attributes
- $this->setButtonAttributes('toggle');
- // set default move up button attributes
- $this->setButtonAttributes('moveup');
- // set default move up button attributes
- $this->setButtonAttributes('movedown');
- // set default move top button attributes
- $this->setButtonAttributes('movetop');
- // set default move bottom button attributes
- $this->setButtonAttributes('movebottom');
- // set select boxes sort order (none by default)
- if (!isset($sort)) {
- $sort = false;
- }
- if ($sort === SORT_ASC) {
- $this->_sort = 'asc';
- } elseif ($sort === SORT_DESC) {
- $this->_sort = 'desc';
- } else {
- $this->_sort = 'none';
- }
- // set the default advmultiselect element template (with javascript embedded)
- $this->setElementTemplate();
- }
- /**
- * Sets the button attributes
- *
- * In <b>custom example 1</b>, the <i>add</i> and <i>remove</i> buttons
- * have look set by the css class <i>inputCommand</i>.
- *
- * In <b>custom example 2</b>, the basic text <i>add</i> and <i>remove</i>
- * buttons are now replaced by images.
- *
- * In <b>custom example 5</b>, we have ability to sort the selection list
- * (on right side) by :
- * <pre>
- * - <b>user-end</b>: with <i>Up</i> and <i>Down</i> buttons
- * - <b>programming</b>: with the QF element constructor $sort option
- * </pre>
- *
- * @param string $button Button identifier, either 'add', 'remove',
- * 'all', 'none', 'toggle',
- * 'movetop', 'movebottom'
- * 'moveup' or 'movedown'
- * @param mixed $attributes (optional) Either a typical HTML attribute string
- * or an associative array
- *
- * @return void
- * @throws PEAR_Error $button argument
- * is not a string, or not in range
- * (add, remove, all, none, toggle,
- * movetop, movebottom, moveup, movedown)
- * @access public
- * @since version 0.4.0 (2005-06-25)
- *
- * @example examples/qfams_custom_5.php
- * Custom example 5: source code
- * @link http://www.laurent-laville.org/img/qfams/screenshot/custom5.png
- * Custom example 5: screenshot
- *
- * @example examples/qfams_custom_2.php
- * Custom example 2: source code
- * @link http://www.laurent-laville.org/img/qfams/screenshot/custom2.png
- * Custom example 2: screenshot
- *
- * @example examples/qfams_custom_1.php
- * Custom example 1: source code
- * @link http://www.laurent-laville.org/img/qfams/screenshot/custom1.png
- * Custom example 1: screenshot
- */
- public function setButtonAttributes($button, $attributes = null)
- {
- if (!is_string($button)) {
- return PEAR::throwError('Argument 1 of HTML_QuickForm_advmultiselect::' .
- 'setButtonAttributes is not a string',
- HTML_QUICKFORM_ADVMULTISELECT_ERROR_INVALID_INPUT,
- array('level' => 'exception'));
- }
- switch ($button) {
- case 'add':
- if (is_null($attributes)) {
- $this->_addButtonAttributes = array(
- 'name' => 'add',
- 'value' => ' ',
- 'type' => 'button',
- 'class'=> 'btn btn-primary'
- );
- } else {
- $this->_updateAttrArray(
- $this->_addButtonAttributes,
- $this->_parseAttributes($attributes)
- );
- }
- break;
- case 'remove':
- if (is_null($attributes)) {
- $this->_removeButtonAttributes = array(
- 'name' => 'remove',
- 'value' => ' ',
- 'type' => 'button',
- 'class'=> 'btn btn-primary'
- );
- } else {
- $this->_updateAttrArray($this->_removeButtonAttributes,
- $this->_parseAttributes($attributes));
- }
- break;
- case 'all':
- if (is_null($attributes)) {
- $this->_allButtonAttributes = array(
- 'name' => 'all',
- 'value' => ' Select All ',
- 'type' => 'button'
- );
- } else {
- $this->_updateAttrArray($this->_allButtonAttributes,
- $this->_parseAttributes($attributes));
- }
- break;
- case 'none':
- if (is_null($attributes)) {
- $this->_noneButtonAttributes
- = array('name' => 'none',
- 'value' => ' Select None ',
- 'type' => 'button');
- } else {
- $this->_updateAttrArray($this->_noneButtonAttributes,
- $this->_parseAttributes($attributes));
- }
- break;
- case 'toggle':
- if (is_null($attributes)) {
- $this->_toggleButtonAttributes
- = array('name' => 'toggle',
- 'value' => ' Toggle Selection ',
- 'type' => 'button');
- } else {
- $this->_updateAttrArray($this->_toggleButtonAttributes,
- $this->_parseAttributes($attributes));
- }
- break;
- case 'moveup':
- if (is_null($attributes)) {
- $this->_upButtonAttributes
- = array('name' => 'up',
- 'value' => ' Up ',
- 'type' => 'button');
- } else {
- $this->_updateAttrArray($this->_upButtonAttributes,
- $this->_parseAttributes($attributes));
- }
- break;
- case 'movedown':
- if (is_null($attributes)) {
- $this->_downButtonAttributes
- = array('name' => 'down',
- 'value' => ' Down ',
- 'type' => 'button');
- } else {
- $this->_updateAttrArray($this->_downButtonAttributes,
- $this->_parseAttributes($attributes));
- }
- break;
- case 'movetop':
- if (is_null($attributes)) {
- $this->_topButtonAttributes
- = array('name' => 'top',
- 'value' => ' Top ',
- 'type' => 'button');
- } else {
- $this->_updateAttrArray($this->_topButtonAttributes,
- $this->_parseAttributes($attributes));
- }
- break;
- case 'movebottom':
- if (is_null($attributes)) {
- $this->_bottomButtonAttributes
- = array('name' => 'bottom',
- 'value' => ' Bottom ',
- 'type' => 'button');
- } else {
- $this->_updateAttrArray($this->_bottomButtonAttributes,
- $this->_parseAttributes($attributes));
- }
- break;
- default;
- return PEAR::throwError('Argument 1 of HTML_QuickForm_advmultiselect::' .
- 'setButtonAttributes has unexpected value',
- HTML_QUICKFORM_ADVMULTISELECT_ERROR_INVALID_INPUT,
- array('level' => 'error'));
- }
- }
- /**
- * Sets element template
- *
- * @param string $html (optional) The HTML surrounding select boxes and buttons
- * @param bool $js (optional) if we need to include qfams javascript handler
- *
- * @access public
- * @return string
- * @since version 0.4.0 (2005-06-25)
- */
- public function setElementTemplate($html = null, $js = true)
- {
- $oldTemplate = $this->_elementTemplate;
- if (isset($html) && is_string($html)) {
- $this->_elementTemplate = $html;
- } else {
- $this->_elementTemplate = '
- {javascript}
- <div class="row">
- <div class="col-sm"><!-- BEGIN label_2 -->{label_2}<!-- END label_2 --> {unselected}</div>
- <div class="col-sm-auto"><div class="text-center">{add}{remove}</div></div>
- <div class="col-sm"><!-- BEGIN label_3 -->{label_3}<!-- END label_3 -->{selected}</div>
- </div>
- ';
- }
- if ($js === false) {
- $this->_elementTemplate = str_replace('{javascript}', '',
- $this->_elementTemplate);
- }
- return $oldTemplate;
- }
- /**
- * Gets default element stylesheet for a single multi-select shape render
- *
- * In <b>custom example 4</b>, the template defined allows
- * a single multi-select checkboxes shape. Useful when javascript is disabled
- * (or when browser is not js compliant). In our example, no need to add
- * javascript code, but css is mandatory.
- *
- * @param boolean $raw (optional) html output with style tags or just raw data
- *
- * @access public
- * @return string
- * @since version 0.4.0 (2005-06-25)
- *
- * @example qfams_custom_4.php
- * Custom example 4: source code
- * @link http://www.laurent-laville.org/img/qfams/screenshot/custom4.png
- * Custom example 4: screenshot
- */
- public function getElementCss($raw = true)
- {
- $id = $this->getAttribute('name');
- $css = str_replace('{id}', $id, $this->_elementCSS);
- if ($raw !== true) {
- $css = '<style type="text/css">' . PHP_EOL
- . $css . PHP_EOL
- . '</style>';
- }
- return $css;
- }
- /**
- * Returns the HTML generated for the advanced mutliple select component
- *
- * @access public
- * @return string
- * @since version 0.4.0 (2005-06-25)
- */
- public function toHtml()
- {
- if ($this->_flagFrozen) {
- return $this->getFrozenHtml();
- }
- $tabs = $this->_getTabs();
- $tab = $this->_getTab();
- $selectId = $this->getName();
- $selectName = $this->getName().'[]';
- $selectNameFrom = $this->getName().'-f[]';
- $selectNameTo = $this->getName().'[]';
- $selected_count = 0;
- $rightAll = '';
- $leftAll = '';
- // placeholder {unselected} existence determines if we will render
- if (strpos($this->_elementTemplate, '{unselected}') === false) {
- // ... a single multi-select with checkboxes
- $id = $this->getAttribute('name');
- $strHtmlSelected = $tab . '<div id="qfams_'.$id.'">' . PHP_EOL;
- $unselected_count = count($this->_options);
- $checkbox_id_suffix = 0;
- foreach ($this->_options as $option) {
- $_labelAttributes
- = array('style', 'class', 'onmouseover', 'onmouseout');
- $labelAttributes = array();
- foreach ($_labelAttributes as $attr) {
- if (isset($option['attr'][$attr])) {
- $labelAttributes[$attr] = $option['attr'][$attr];
- unset($option['attr'][$attr]);
- }
- }
- if (is_array($this->_values) && in_array((string)$option['attr']['value'], $this->_values)) {
- // The items is *selected*
- $checked = ' checked="checked"';
- $selected_count++;
- } else {
- // The item is *unselected* so we want to put it
- $checked = '';
- }
- $checkbox_id_suffix++;
- $strHtmlSelected .= $tab
- .'<label'
- .$this->_getAttrString($labelAttributes).'>'
- .'<input type="checkbox"'
- .' id="'.$selectId.$checkbox_id_suffix.'"'
- .' name="'.$selectName.'"'
- .$checked.$this->_getAttrString($option['attr'])
- .' />'.$option['text'].'</label>'
- .PHP_EOL;
- }
- $strHtmlSelected .= $tab . '</div>'. PHP_EOL;
- $strHtmlHidden = '';
- $strHtmlUnselected = '';
- $strHtmlAdd = '';
- $strHtmlRemove = '';
- // build the select all button with all its attributes
- $attributes = [];
- $this->_allButtonAttributes = array_merge($this->_allButtonAttributes, $attributes);
- $attrStrAll = $this->_getAttrString($this->_allButtonAttributes);
- $strHtmlAll = "<input$attrStrAll />". PHP_EOL;
- // build the select none button with all its attributes
- $attributes = [];
- $this->_noneButtonAttributes
- = array_merge($this->_noneButtonAttributes, $attributes);
- $attrStrNone = $this->_getAttrString($this->_noneButtonAttributes);
- $strHtmlNone = "<input$attrStrNone />". PHP_EOL;
- // build the toggle selection button with all its attributes
- $attributes = [];
- $this->_toggleButtonAttributes = array_merge($this->_toggleButtonAttributes, $attributes);
- $attrStrToggle = $this->_getAttrString($this->_toggleButtonAttributes);
- $strHtmlToggle = "<input$attrStrToggle />". PHP_EOL;
- $strHtmlMoveUp = '';
- $strHtmlMoveDown = '';
- $strHtmlMoveTop = '';
- $strHtmlMoveBottom = '';
- // default selection counters
- $strHtmlSelectedCount = $selected_count . '/' . $unselected_count;
- } else {
- // set name of Select From Box
- $this->_attributesUnselected
- = array(
- 'id' => $selectId.'',
- 'name' => $selectNameFrom,
- );
- $this->_attributesUnselected = array_merge($this->_attributes, $this->_attributesUnselected);
- $attrUnselected = $this->_getAttrString($this->_attributesUnselected);
- // set name of Select To Box
- $this->_attributesSelected
- = array(
- 'id' => $selectId.'_to',
- 'name' => $selectNameTo,
- );
- $this->_attributesSelected = array_merge($this->_attributes, $this->_attributesSelected);
- $attrSelected = $this->_getAttrString($this->_attributesSelected);
- // set name of Select hidden Box
- $this->_attributesHidden
- = array(
- 'name' => $selectName,
- 'style' => 'overflow: hidden; visibility: hidden; width: 1px; height: 0;',
- );
- $this->_attributesHidden
- = array_merge($this->_attributes, $this->_attributesHidden);
- $attrHidden = $this->_getAttrString($this->_attributesHidden);
- // prepare option tables to be displayed as in POST order
- $append = empty($this->_values) ? 0 : count($this->_values);
- if ($append > 0) {
- $arrHtmlSelected = array_fill(0, $append, ' ');
- } else {
- $arrHtmlSelected = array();
- }
- $options = count($this->_options);
- $arrHtmlUnselected = array();
- if ($options > 0) {
- $arrHtmlHidden = array_fill(0, $options, ' ');
- foreach ($this->_options as $option) {
- if (is_array($this->_values) && in_array((string) $option['attr']['value'], $this->_values)) {
- // Get the post order
- $key = array_search(
- $option['attr']['value'],
- $this->_values
- );
- /** The items is *selected* so we want to put it
- in the 'selected' multi-select */
- $arrHtmlSelected[$key] = $option;
- /** Add it to the 'hidden' multi-select
- and set it as 'selected' */
- if (isset($option['attr']['disabled'])) {
- unset($option['attr']['disabled']);
- }
- $option['attr']['selected'] = 'selected';
- $arrHtmlHidden[$key] = $option;
- } else {
- /** The item is *unselected* so we want to put it
- in the 'unselected' multi-select */
- $arrHtmlUnselected[] = $option;
- // Add it to the hidden multi-select as 'unselected'
- $arrHtmlHidden[$append] = $option;
- $append++;
- }
- }
- }
- // The 'unselected' multi-select which appears on the left
- $unselected_count = count($arrHtmlUnselected);
- if ($unselected_count == 0) {
- $this->_attributesUnselected = array_merge($this->_attributes, $this->_attributesUnselected);
- $attrUnselected = $this->_getAttrString($this->_attributesUnselected);
- }
- $strHtmlUnselected = "<select$attrUnselected>". PHP_EOL;
- if ($unselected_count > 0) {
- foreach ($arrHtmlUnselected as $data) {
- $strHtmlUnselected
- .= $tabs.$tab
- .'<option'.$this->_getAttrString($data['attr']).'>'
- .$data['text'].'</option>'.PHP_EOL;
- }
- }
- $strHtmlUnselected .= '</select>';
- // The 'selected' multi-select which appears on the right
- $selected_count = count($arrHtmlSelected);
- if ($selected_count == 0) {
- $this->_attributesSelected = array_merge($this->_attributes, $this->_attributesSelected);
- $attrSelected = $this->_getAttrString($this->_attributesSelected);
- }
- $strHtmlSelected = "<select$attrSelected>";
- if ($selected_count > 0) {
- foreach ($arrHtmlSelected as $data) {
- if (!is_array($data)) {
- continue;
- }
- $attribute = null;
- if (isset($data['attr'])) {
- $attribute = $this->_getAttrString($data['attr']);
- }
- $text = null;
- if (isset($data['text'])) {
- $text = $data['text'];
- }
- $strHtmlSelected
- .= $tabs.$tab
- .'<option'.$attribute.'>'
- .$text.'</option>';
- }
- }
- $strHtmlSelected .= '</select>';
- $strHtmlHidden = '';
- $attributes = array('id' => $selectId.'_leftSelected');
- $this->_removeButtonAttributes
- = array_merge($this->_removeButtonAttributes, $attributes);
- $attrStrRemove = $this->_getAttrString($this->_removeButtonAttributes);
- $strHtmlRemove = "<button $attrStrRemove /> <em class='fa fa-arrow-left'></em></button>";
- // build the add button with all its attributes
- $attributes = array('id' => $selectId.'_rightSelected');
- $this->_addButtonAttributes = array_merge($this->_addButtonAttributes, $attributes);
- $attrStrAdd = $this->_getAttrString($this->_addButtonAttributes);
- $strHtmlAdd = "<button $attrStrAdd /> <em class='fa fa-arrow-right'></em></button><br /><br />";
- if ($this->selectAllCheckBox) {
- $attributes = array('id' => $selectId.'_rightAll');
- $this->_addButtonAttributes = array_merge($this->_addButtonAttributes, $attributes);
- $attrStrAdd = $this->_getAttrString($this->_addButtonAttributes);
- $rightAll = "<button $attrStrAdd /> <em class='fa fa-forward'></em></button><br /><br />";
- $attributes = array('id' => $selectId.'_leftAll');
- $this->_addButtonAttributes = array_merge($this->_addButtonAttributes, $attributes);
- $attrStrAdd = $this->_getAttrString($this->_addButtonAttributes);
- $leftAll = "<br /><br /><button $attrStrAdd /> <em class='fa fa-backward'></em></button>";
- }
- // build the select all button with all its attributes
- $strHtmlAll = '';
- // build the select none button with all its attributes
- $attributes = [];
- $this->_noneButtonAttributes
- = array_merge($this->_noneButtonAttributes, $attributes);
- $attrStrNone = $this->_getAttrString($this->_noneButtonAttributes);
- $strHtmlNone = "<input$attrStrNone />". PHP_EOL;
- // build the toggle button with all its attributes
- $attributes = [];
- $this->_toggleButtonAttributes
- = array_merge($this->_toggleButtonAttributes, $attributes);
- $attrStrToggle = $this->_getAttrString($this->_toggleButtonAttributes);
- $strHtmlToggle = "<input$attrStrToggle />". PHP_EOL;
- // build the move up button with all its attributes
- $attributes = [];
- $this->_upButtonAttributes
- = array_merge($this->_upButtonAttributes, $attributes);
- $attrStrUp = $this->_getAttrString($this->_upButtonAttributes);
- $strHtmlMoveUp = "<input$attrStrUp />". PHP_EOL;
- // build the move down button with all its attributes
- $attributes = [];
- $this->_downButtonAttributes
- = array_merge($this->_downButtonAttributes, $attributes);
- $attrStrDown = $this->_getAttrString($this->_downButtonAttributes);
- $strHtmlMoveDown = "<input$attrStrDown />". PHP_EOL;
- // build the move top button with all its attributes
- $attributes = [];
- $this->_topButtonAttributes
- = array_merge($this->_topButtonAttributes, $attributes);
- $attrStrTop = $this->_getAttrString($this->_topButtonAttributes);
- $strHtmlMoveTop = "<input$attrStrTop />". PHP_EOL;
- // build the move bottom button with all its attributes
- $attributes = [];
- $this->_bottomButtonAttributes
- = array_merge($this->_bottomButtonAttributes, $attributes);
- $attrStrBottom = $this->_getAttrString($this->_bottomButtonAttributes);
- $strHtmlMoveBottom = "<input$attrStrBottom />". PHP_EOL;
- // default selection counters
- $strHtmlSelectedCount = $selected_count;
- }
- $strHtmlUnselectedCount = $unselected_count;
- $strHtmlSelectedCountId = $selectId .'_selected';
- $strHtmlUnselectedCountId = $selectId .'_unselected';
- // render all part of the multi select component with the template
- $strHtml = $this->_elementTemplate;
- // Prepare multiple labels
- $labels = $this->getLabel();
- if (is_array($labels)) {
- array_shift($labels);
- }
- // render extra labels, if any
- if (is_array($labels)) {
- foreach ($labels as $key => $text) {
- $key = is_int($key) ? $key + 2 : $key;
- $strHtml = str_replace("{label_{$key}}", $text, $strHtml);
- $strHtml = str_replace("<!-- BEGIN label_{$key} -->", '', $strHtml);
- $strHtml = str_replace("<!-- END label_{$key} -->", '', $strHtml);
- }
- }
- // clean up useless label tags
- if (strpos($strHtml, '{label_')) {
- $strHtml = preg_replace('/\s*<!-- BEGIN label_(\S+) -->'.
- '.*<!-- END label_\1 -->\s*/i', '', $strHtml);
- }
- $placeHolders = array(
- '{stylesheet}',
- '{javascript}',
- '{class}',
- '{unselected_count_id}',
- '{selected_count_id}',
- '{unselected_count}',
- '{selected_count}',
- '{unselected}',
- '{selected}',
- '{add}',
- '{remove}',
- '{all}',
- '{none}',
- '{toggle}',
- '{moveup}',
- '{movedown}',
- '{movetop}',
- '{movebottom}',
- );
- $htmlElements = array(
- $this->getElementCss(false),
- $this->getElementJs(false),
- $this->_tableAttributes,
- $strHtmlUnselectedCountId,
- $strHtmlSelectedCountId,
- $strHtmlUnselectedCount,
- $strHtmlSelectedCount,
- $strHtmlUnselected,
- $strHtmlSelected.$strHtmlHidden,
- $rightAll.$strHtmlAdd,
- $strHtmlRemove.$leftAll,
- $strHtmlAll,
- $strHtmlNone,
- $strHtmlToggle,
- $strHtmlMoveUp,
- $strHtmlMoveDown,
- $strHtmlMoveTop,
- $strHtmlMoveBottom,
- );
- $strHtml = str_replace($placeHolders, $htmlElements, $strHtml);
- $comment = $this->getComment();
- if (!empty($comment)) {
- $strHtml = $tabs . '<!-- ' . $comment . " //-->" . PHP_EOL . $strHtml;
- }
- return $strHtml;
- }
- /**
- * Returns the javascript code generated to handle this element
- *
- * @param boolean $raw (optional) html output with script tags or just raw data
- * @param boolean $min (optional) uses javascript compressed version
- *
- * @access public
- * @return string
- * @since version 0.4.0 (2005-06-25)
- */
- public function getElementJs($raw = true, $min = true)
- {
- $name = $this->getName();
- $js = '';
- $search =
- '<input type="text" name="q" class="form-control mb-3" placeholder="'.addslashes(get_lang('Search')).'" />';
- $js .= '<script>
- $(function() {
- $(\'#'.$name.'\').multiselect({
- search: {
- left: \''.$search.'\',
- right: \''.$search.'\'
- },
- fireSearch: function(value) {
- return value.length > 2;
- }
- });
- });
- </script>'.PHP_EOL;
- return $js;
- }
- /**
- * Loads options from different types of data sources
- *
- * This method overloaded parent method of select element, to allow
- * loading options with fancy attributes.
- *
- * @param mixed &$options Options source currently supports assoc array or DB_result
- * @param mixed $param1 (optional) See function detail
- * @param mixed $param2 (optional) See function detail
- * @param mixed $param3 (optional) See function detail
- * @param mixed $param4 (optional) See function detail
- *
- * @access public
- * @since version 1.5.0 (2009-02-15)
- * @return PEAR_Error|NULL on error and TRUE on success
- * @throws PEAR_Error
- * @see loadArray()
- */
- public function load(&$options,
- $param1 = null, $param2 = null, $param3 = null, $param4 = null)
- {
- if (is_array($options)) {
- $ret = $this->loadArray($options, $param1);
- } else {
- $ret = parent::load($options, $param1, $param2, $param3, $param4);
- }
- return $ret;
- }
- /**
- * Loads the options from an associative array
- *
- * This method overloaded parent method of select element, to allow to load
- * array of options with fancy attributes.
- *
- * @param array $arr Associative array of options
- * @param mixed $values (optional) Array or comma delimited string of selected values
- *
- * @since version 1.5.0 (2009-02-15)
- * @access public
- * @return PEAR_Error on error and TRUE on success
- * @throws PEAR_Error
- * @see load()
- */
- public function loadArray($arr, $values = null)
- {
- if (!is_array($arr)) {
- return PEAR::throwError('Argument 1 of HTML_QuickForm_advmultiselect::' .
- 'loadArray is not a valid array',
- HTML_QUICKFORM_ADVMULTISELECT_ERROR_INVALID_INPUT,
- array('level' => 'exception'));
- }
- if (isset($values)) {
- $this->setSelected($values);
- }
- if (is_array($arr)) {
- foreach ($arr as $key => $val) {
- if (is_array($val)) {
- $this->addOption($val[0], $key, $val[1]);
- } else {
- $this->addOption($val, $key);
- }
- }
- }
- return true;
- }
- }
|