diff --git a/main/inc/lib/javascript/pear/qfamsHandler-min.js b/main/inc/lib/javascript/pear/qfamsHandler-min.js new file mode 100644 index 0000000000..b6f2f5c8f7 --- /dev/null +++ b/main/inc/lib/javascript/pear/qfamsHandler-min.js @@ -0,0 +1 @@ +if(typeof QFAMS==="undefined"||!QFAMS){var QFAMS={}}QFAMS.env=QFAMS.env||{persistantSelection:false,persistantMove:true};QFAMS.updateCounter=function(c,v){var i;var nodeText=null;if(c!==null){if(c.childNodes){for(i=0;i0&&target.options[0].value===""){target.removeAttribute("disabled");target.options[0]=null}for(i=(maxFrom-1);i>=0;i--){if(action==='all'||action==='none'||action==='toggle'||source.options[i].selected===true){if(source.options[i].disabled===false){if(isIE){option=source.options[i].removeNode(true);option.selected=QFAMS.env.persistantSelection;target.appendChild(option)}else{option=source.options[i].cloneNode(true);option.selected=QFAMS.env.persistantSelection;target.options[target.options.length]=option}}}}if(!isIE){for(i=(maxFrom-1);i>=0;i--){if(action==='all'||action==='none'||action==='toggle'||source.options[i].selected===true){if(source.options[i].disabled===false){source.options[i]=null}}}}if(action==='toggle'){for(i=(maxTo-1);i>=0;i--){if(target.options[i].disabled===false){if(isIE){option=target.options[i].removeNode(true);option.selected=QFAMS.env.persistantSelection;source.appendChild(option)}else{option=target.options[i].cloneNode(true);option.selected=QFAMS.env.persistantSelection;source.options[source.options.length]=option}}}if(!isIE){for(i=(maxTo-1);i>=0;i--){if(target.options[i].disabled===false){target.options[i]=null}}}}c=document.getElementById(qfamsName+'_unselected');s=document.getElementById(qfamsName+'-f');QFAMS.updateCounter(c,s.length);c=document.getElementById(qfamsName+'_selected');s=document.getElementById(qfamsName+'-t');QFAMS.updateCounter(c,s.length);if(arrange!=='none'){QFAMS.sortList(target,QFAMS.compareText,arrange)}QFAMS.updateHidden(selectHidden,selectRight)};QFAMS.sortList=function(list,compareFunction,arrange){var i;var options=new Array(list.options.length);for(i=0;i0){QFAMS.moveSwap(l,indice,indice-1);QFAMS.updateHidden(h,l)}};QFAMS.moveDown=function(l,h){var indice=l.selectedIndex;if(indice<0){return}if(indice0){QFAMS.moveSwap(l,indice,indice-1);QFAMS.updateHidden(h,l);indice--}};QFAMS.moveBottom=function(l,h){var indice=l.selectedIndex;if(indice<0){return}while(indicej){l.insertBefore(node,l.options[j].nextSibling)}else{l.insertBefore(node,l.options[i])}if(QFAMS.env.persistantMove){l.selectedIndex=j}else{l.selectedIndex=-1}};QFAMS.init=function(elm){var e,i;for(e=0;e + * @copyright 2007-2009 Laurent Laville + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: qfamsHandler.js,v 1.13 2009/02/06 09:49:22 farell Exp $ + * @since File available since Release 1.3.0 + */ + +if (typeof QFAMS === "undefined" || !QFAMS) { + /** + * The QFAMS global namespace object. If QFAMS is already defined, the + * existing QFAMS object will not be overwritten so that defined + * namespaces are preserved. + * @class QFAMS + * @static + * @public + * @since 1.5.0 + */ + var QFAMS = {}; +} + +/** + * QFAMS.env is used to keep track of end-user preferences + * for persistant values. + * + * @class QFAMS.env + * @static + */ +QFAMS.env = QFAMS.env || { + /** + * Keeps the persistant selection preference when items are selected or unselected + * + * @property persistantSelection + * @type Boolean + */ + persistantSelection: false, + + /** + * Keeps the persistant selection preference when items are moved up or down + * + * @property persistantMove + * @type Boolean + */ + persistantMove: true +}; + +/** + * Uses QFAMS.updateCounter as a + * text tools to replace all childs of 'c' element by a new text node of 'v' value + * + * @param dom element c html element; is best use in most case + * @param string v new counter value + * + * @method updateCounter + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.updateCounter = function (c, v) { + var i; + var nodeText = null; + + if (c !== null) { + // remove all previous child nodes of 'c' element + if (c.childNodes) { + for (i = 0; i < c.childNodes.length; i++) { + c.removeChild(c.childNodes[i]); + } + } + // add new text value 'v' + nodeText = document.createTextNode(v); + c.appendChild(nodeText); + } +}; + +/** + * Uses QFAMS.updateLiveCounter as a + * standard onclick event handler to dynamic change value of counter + * that display current selection + * + * @method updateLiveCounter + * @static + * @return void + * @private + * @since 1.5.0 + */ +QFAMS.updateLiveCounter = function () { + var lbl = this.parentNode; + var selectedCount = 0; + + // Find all the checkboxes... + var div = lbl.parentNode; + var inputs = div.getElementsByTagName('input'); + for (var i = 0; i < inputs.length; i++) { + if (inputs[i].checked == 1) { + selectedCount++; + } + } + var e = div.id; + var qfamsName = e.substring(e.indexOf('_', 0) + 1, e.length); + // updates item count + var span = document.getElementById(qfamsName + '_selected'); + QFAMS.updateCounter(span, selectedCount + '/' + inputs.length); +}; + +/** + * Uses QFAMS.editSelection + * in single select box mode, to edit current selection and update live counter + * + * @param string qfamsName QuickForm advmultiselect element name + * @param integer selectMode Selection mode (0 = uncheck, 1 = check, 2 = toggle) + * + * @method editSelection + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.editSelection = function (qfamsName, selectMode) { + if (selectMode !== 0 && selectMode !== 1 && selectMode !== 2) { + return; + } + var selectedCount = 0; + + // Find all the checkboxes... + var ams = document.getElementById('qfams_' + qfamsName); + var inputs = ams.getElementsByTagName('input'); + + // Loop through all checkboxes (input element) + for (var i = 0; i < inputs.length; i++) { + if (selectMode === 2) { + if (inputs[i].checked == 0) { + inputs[i].checked = 1; + } else if (inputs[i].checked == 1) { + inputs[i].checked = 0; + } + } else { + inputs[i].checked = selectMode; + } + if (inputs[i].checked == 1) { + selectedCount++; + } + } + + // updates selected item count + var span = document.getElementById(qfamsName + '_selected'); + QFAMS.updateCounter(span, selectedCount + '/' + inputs.length); +}; + +/** + * Uses QFAMS.moveSelection + * in double select box mode, to move current selection and update live counter + * + * @param string qfamsName QuickForm advmultiselect element name + * @param dom element selectLeft Data source list + * @param dom element selectRight Target data list + * @param dom element selectHidden Full data source (selected, unselected) + * private usage + * @param string action Action name (add, remove, all, none, toggle) + * @param string arrange Sort option (none, asc, desc) + * + * @method moveSelection + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.moveSelection = function (qfamsName, selectLeft, selectRight, selectHidden, action, arrange) { + var isIE = /*@cc_on!@*/false; //IE detector + var source = null; + var target = null; + var option; + var c = null; + var s = null; + var i; + var maxFrom, maxTo; + + if (action === 'add' || action === 'all' || action === 'toggle') { + source = selectLeft; + target = selectRight; + } else { + source = selectRight; + target = selectLeft; + } + // Don't do anything if nothing selected. Otherwise we throw javascript errors. + if (source.selectedIndex === -1 && (action === 'add' || action === 'remove')) { + return; + } + maxFrom = source.options.length; + maxTo = target.options.length; + + // check if target list is empty and remove fake empty option (tip to be XHTML compliant) + if (maxTo > 0 && target.options[0].value === "") { + target.removeAttribute("disabled"); + target.options[0] = null; + } + + // Add items to the 'TO' list. + for (i = (maxFrom - 1); i >= 0; i--) { + if (action === 'all' || action === 'none' || action === 'toggle' || source.options[i].selected === true) { + if (source.options[i].disabled === false) { + if (isIE) { + option = source.options[i].removeNode(true); + option.selected = QFAMS.env.persistantSelection; + target.appendChild(option); + } else { + option = source.options[i].cloneNode(true); + option.selected = QFAMS.env.persistantSelection; + target.options[target.options.length] = option; + } + } + } + } + + // Remove items from the 'FROM' list. + if (!isIE) { + for (i = (maxFrom - 1); i >= 0; i--) { + if (action === 'all' || action === 'none' || action === 'toggle' || source.options[i].selected === true) { + if (source.options[i].disabled === false) { + source.options[i] = null; + } + } + } + } + + // Add items to the 'FROM' list for toggle function + if (action === 'toggle') { + for (i = (maxTo - 1); i >= 0; i--) { + if (target.options[i].disabled === false) { + if (isIE) { + option = target.options[i].removeNode(true); + option.selected = QFAMS.env.persistantSelection; + source.appendChild(option); + } else { + option = target.options[i].cloneNode(true); + option.selected = QFAMS.env.persistantSelection; + source.options[source.options.length] = option; + } + } + } + if (!isIE) { + for (i = (maxTo - 1); i >= 0; i--) { + if (target.options[i].disabled === false) { + target.options[i] = null; + } + } + } + } + + // updates unselected item count + c = document.getElementById(qfamsName + '_unselected'); + s = document.getElementById(qfamsName + '-f'); + QFAMS.updateCounter(c, s.length); + + // updates selected item count + c = document.getElementById(qfamsName + '_selected'); + s = document.getElementById(qfamsName + '-t'); + QFAMS.updateCounter(c, s.length); + + // Sort list if required + if (arrange !== 'none') { + QFAMS.sortList(target, QFAMS.compareText, arrange); + } + + // Set the appropriate items as 'selected in the hidden select. + // These are the values that will actually be posted with the form. + QFAMS.updateHidden(selectHidden, selectRight); +}; + +/** + * Uses QFAMS.sortList to + * sort selection list if option is given in HTML_QuickForm_advmultiselect class constructor + * + * @param dom element list Selection data list + * @param prototype compareFunction to sort each element of a list + * @param string arrange Sort option (none, asc, desc) + * + * @method sortList + * @static + * @return void + * @private + * @since 1.5.0 + */ +QFAMS.sortList = function (list, compareFunction, arrange) +{ + var i; + var options = new Array(list.options.length); + + for (i = 0; i < options.length; i++) { + options[i] = new Option(list.options[i].text, + list.options[i].value, + list.options[i].defaultSelected, + list.options[i].selected); + } + options.sort(compareFunction); + if (arrange === 'desc') { + options.reverse(); + } + list.options.length = 0; + for (i = 0; i < options.length; i++) { + list.options[i] = options[i]; + } +}; + +/** + * QFAMS.compareText + * is a callback function to sort each element of two lists A and B + * + * @param string option1 single element of list A + * @param string option2 single element of list B + * + * @method compareText + * @static + * @return integer -1 if option1 is less than option2, + * 0 if option1 is equal to option2 + * 1 if option1 is greater than option2 + * @private + * @since 1.5.0 + */ +QFAMS.compareText = function (option1, option2) { + if (option1.text === option2.text) { + return 0; + } + return option1.text < option2.text ? -1 : 1; +}; + +/** + * QFAMS.updateHidden + * updates the private list that handle selection of all elements (selected and unselected) + * + * @param dom element h hidden list (contains all elements) + * @param dom element r selection list (contains only elements selected) + * + * @method updateHidden + * @static + * @return void + * @private + * @since 1.5.0 + */ +QFAMS.updateHidden = function (h, r) { + var i; + + for (i = 0; i < h.length; i++) { + h.options[i].selected = false; + } + + for (i = 0; i < r.length; i++) { + h.options[h.length] = new Option(r.options[i].text, r.options[i].value); + h.options[h.length - 1].selected = true; + } +}; + +/** + * With QFAMS.moveUp + * end-user may arrange and element up to the selection list + * + * @param dom element l selection list (contains only elements selected) + * @param dom element h hidden list (contains all elements) + * + * @method moveUp + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.moveUp = function (l, h) { + var indice = l.selectedIndex; + if (indice < 0) { + return; + } + if (indice > 0) { + QFAMS.moveSwap(l, indice, indice - 1); + QFAMS.updateHidden(h, l); + } +}; + +/** + * With QFAMS.moveDown + * end-user may arrange and element down to the selection list + * + * @param dom element l selection list (contains only elements selected) + * @param dom element h hidden list (contains all elements) + * + * @method moveDown + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.moveDown = function (l, h) { + var indice = l.selectedIndex; + if (indice < 0) { + return; + } + if (indice < l.options.length - 1) { + QFAMS.moveSwap(l, indice, indice + 1); + QFAMS.updateHidden(h, l); + } +}; + +/** + * With QFAMS.moveTop + * end-user may arrange and element up to the top of selection list + * + * @param dom element l selection list (contains only elements selected) + * @param dom element h hidden list (contains all elements) + * + * @method moveTop + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.moveTop = function (l, h) { + var indice = l.selectedIndex; + if (indice < 0) { + return; + } + while (indice > 0) { + QFAMS.moveSwap(l, indice, indice - 1); + QFAMS.updateHidden(h, l); + indice--; + } +}; + +/** + * With QFAMS.moveBottom + * end-user may arrange and element down to the bottom of selection list + * + * @param dom element l selection list (contains only elements selected) + * @param dom element h hidden list (contains all elements) + * + * @method moveBottom + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.moveBottom = function (l, h) { + var indice = l.selectedIndex; + if (indice < 0) { + return; + } + while (indice < l.options.length - 1) { + QFAMS.moveSwap(l, indice, indice + 1); + QFAMS.updateHidden(h, l); + indice++; + } +}; + +/** + * With QFAMS.moveSwap + * end-user may invert two elements position in the selection list + * + * @param dom element l selection list (contains only elements selected) + * @param integer i element source indice + * @param integer j element target indice + * + * @method moveSwap + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.moveSwap = function (l, i, j) { + var node; + + node = l.replaceChild(l.options[i], l.options[j]); + if (i > j) { + l.insertBefore(node, l.options[j].nextSibling); + } else { + l.insertBefore(node, l.options[i]); + } + + if (QFAMS.env.persistantMove) { + l.selectedIndex = j; + } else { + l.selectedIndex = -1; + } +}; + +/** + * Uses QFAMS.init to + * initialize onclick event handler for all checkbox element + * of a QuickForm advmultiselect element with single select box. + * + * @method init + * @static + * @return void + * @public + * @since 1.5.0 + */ +QFAMS.init = function (elm) +{ + var e, i; + + for (e = 0; e < elm.length; e++) { + var div = document.getElementById('qfams_' + elm[e]); + if (div !== null) { + var inputs = div.getElementsByTagName('input'); + if (inputs !== null) { + for (i = 0; i < inputs.length; i++) { + inputs[i].onclick = QFAMS.updateLiveCounter; + } + } + } + } +}; + diff --git a/main/inc/lib/pear/HTML/QuickForm/advmultiselect.php b/main/inc/lib/pear/HTML/QuickForm/advmultiselect.php index 34e6f91311..c6013794e7 100755 --- a/main/inc/lib/pear/HTML/QuickForm/advmultiselect.php +++ b/main/inc/lib/pear/HTML/QuickForm/advmultiselect.php @@ -404,7 +404,7 @@ class HTML_QuickForm_advmultiselect extends HTML_QuickForm_select if (is_null($attributes)) { $this->_addButtonAttributes = array('name' => 'add', - 'value' => ' >> ', + 'value' => ' ', 'type' => 'button'); } else { $this->_updateAttrArray($this->_addButtonAttributes, @@ -415,7 +415,7 @@ class HTML_QuickForm_advmultiselect extends HTML_QuickForm_select if (is_null($attributes)) { $this->_removeButtonAttributes = array('name' => 'remove', - 'value' => ' << ', + 'value' => ' ', 'type' => 'button'); } else { $this->_updateAttrArray($this->_removeButtonAttributes, @@ -1013,23 +1013,25 @@ class HTML_QuickForm_advmultiselect extends HTML_QuickForm_select * @return string * @since version 0.4.0 (2005-06-25) */ - function getElementJs($raw = true, $min = false) + function getElementJs($raw = true, $min = true) { $js = '@data_dir@' . DIRECTORY_SEPARATOR - . '@package_name@' . DIRECTORY_SEPARATOR; - + . '@package_name@' . DIRECTORY_SEPARATOR; + + $js = api_get_path(LIBRARY_PATH).'javascript'.DIRECTORY_SEPARATOR.'pear'.DIRECTORY_SEPARATOR; + if ($min) { $js .= 'qfamsHandler-min.js'; } else { $js .= 'qfamsHandler.js'; } - if (file_exists($js)) { - $js = file_get_contents($js); + if (file_exists($js)) { + $js = file_get_contents($js); } else { $js = ''; } - + if ($raw !== true) { $js = '