/** * JavaScript functions to handle standard behaviors of a QuickForm advmultiselect element * * @category HTML * @package HTML_QuickForm_advmultiselect * @author Laurent Laville * @copyright 2007-2008 Laurent Laville * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ * @since File available since Release 1.3.0 */ /** * - qfamsInit - * * initialize onclick event handler for all checkbox element * of a QuickForm advmultiselect element with single select box. * * @return void * @public * @since 1.3.0 */ function qfamsInit() { if (window.qfamsName) { for (var e = 0; e < window.qfamsName.length; e++) { var div = document.getElementById('qfams_' + window.qfamsName[e]); if (div !== null) { var inputs = div.getElementsByTagName('input'); for (var i = 0; i < inputs.length; i++) { inputs[i].onclick = qfamsUpdateLiveCounter; } } } } } /** * - qfamsUpdateCounter - * * 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 * * @return void * @public * @since 1.3.0 */ function qfamsUpdateCounter(c, v) { if (c != null) { // remove all previous child nodes of 'c' element if (c.childNodes) { for (var i = 0; i < c.childNodes.length; i++) { c.removeChild(c.childNodes[i]); } } // add new text value 'v' var nodeText = document.createTextNode(v); c.appendChild(nodeText); } } /** * - qfamsUpdateLiveCounter - * * standard onclick event handler to dynamic change value of counter * that display current selection * * @return void * @private * @since 1.3.0 */ function qfamsUpdateLiveCounter() { 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'); qfamsUpdateCounter(span, selectedCount + '/' + inputs.length); } /** * - qfamsEditSelection - * * in single select box mode, 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) * * @return void * @public * @since 1.3.0 */ function qfamsEditSelection(qfamsName, selectMode) { if (selectMode !== 0 && selectMode !== 1 && selectMode !== 2) { return; } var selectedCount = 0; // Find all the checkboxes... var fruit = document.getElementById('qfams_' + qfamsName); var inputs = fruit.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'); qfamsUpdateCounter(span, selectedCount + '/' + inputs.length); } /** * - qfamsMoveSelection - * * in double select box mode, 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) * * @return void * @public * @since 1.3.0 */ function qfamsMoveSelection(qfamsName, selectLeft, selectRight, selectHidden, action, arrange) { if (action == 'add' || action == 'all' || action == 'toggle') { var source = selectLeft; var target = selectRight; } else { var source = selectRight; var target = selectLeft; } // Don't do anything if nothing selected. Otherwise we throw javascript errors. if (source.selectedIndex == -1 && (action == 'add' || action == 'remove')) { return; } // check if target list is empty and remove fake empty option (tip to be XHTML compliant) if (target.length > 0 && target.options[0].value == "") { target.removeAttribute("disabled"); target.options[0] = null; } var maxTo = target.length; // Add items to the 'TO' list. for (var i = 0; i < source.length; i++) { if (action == 'all' || action == 'none' || action == 'toggle' || source.options[i].selected == true ) { target.options[target.length]= new Option(source.options[i].text, source.options[i].value); } } // Remove items from the 'FROM' list. for (var i = (source.length - 1); i >= 0; i--){ if (action == 'all' || action == 'none' || action == 'toggle' || source.options[i].selected == true) { source.options[i] = null; } } // Add items to the 'FROM' list for toggle function if (action == 'toggle') { for (var i = 0; i < maxTo; i++) { source.options[source.length]= new Option(target.options[i].text, target.options[i].value); } for (var i = (maxTo - 1); i >= 0; i--) { target.options[i] = null; } } // updates unselected item count var c = document.getElementById(qfamsName + '_unselected'); var s = document.getElementById(qfamsName + '-f'); qfamsUpdateCounter(c, s.length); // updates selected item count var c = document.getElementById(qfamsName + '_selected'); var s = document.getElementById(qfamsName + '-t'); qfamsUpdateCounter(c, s.length); // Sort list if required if (arrange !== 'none') { qfamsSortList(target, qfamsCompareText, arrange); } // Set the appropriate items as 'selected in the hidden select. // These are the values that will actually be posted with the form. qfamsUpdateHidden(selectHidden, selectRight); } /** * - qfamsSortList - * * 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) * * @return void * @private * @since 1.3.0 */ function qfamsSortList(list, compareFunction, arrange) { var options = new Array (list.options.length); for (var 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 (var i = 0; i < options.length; i++) { list.options[i] = options[i]; } } /** * - qfamsCompareText - * * 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 * * @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.3.0 */ function qfamsCompareText(option1, option2) { if (option1.text == option2.text) { return 0; } return option1.text < option2.text ? -1 : 1; } /** * - qfamsUpdateHidden - * * update 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) * * @return void * @private * @since 1.3.0 */ function qfamsUpdateHidden(h, r) { for (var i = 0; i < h.length; i++) { h.options[i].selected = false; } for (var 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; } } /** * - qfamsMoveUp - * * User-End 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) * * @return void * @public * @since 1.3.0 */ function qfamsMoveUp(l, h) { var indice = l.selectedIndex; if (indice < 0) { return; } if (indice > 0) { qfamsMoveSwap(l, indice, indice - 1); qfamsUpdateHidden(h, l); } } /** * - qfamsMoveDown - * * User-End 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) * * @return void * @public * @since 1.3.0 */ function qfamsMoveDown(l, h) { var indice = l.selectedIndex; if (indice < 0) { return; } if (indice < l.options.length - 1) { qfamsMoveSwap(l, indice, indice + 1); qfamsUpdateHidden(h, l); } } /** * - qfamsMoveSwap - * * User-End 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 * * @return void * @public * @since 1.3.0 */ function qfamsMoveSwap(l, i, j) { var valeur = l.options[i].value; var texte = l.options[i].text; l.options[i].value = l.options[j].value; l.options[i].text = l.options[j].text; l.options[j].value = valeur; l.options[j].text = texte; l.selectedIndex = j; }