/** * Multiple Selects - jQuery plugin for converting a multiple <select> into two, adding the ability to move items between the boxes. * http://code.google.com/p/jqmultiselects/ * * Copyright (c) 2007 Rob Desbois * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * * Version: 0.2 * * Changelog * 0.1 * initial release * * 0.2 * <option> elements can be automatically selected upon parent form submission * plugin options now passed as an array * all element identifiers now taken as jQuery selectors instead * added beforeMove and afterMove callback functions */ /** Adds multiple select behaviour to a <select> element. * This allows options to be transferred to a different select using mouse double-clicks, or multiple options at a time via another element. * * Syntax: * $(source).multiSelect(dest, options); * * Options: * * trigger: Selector for elements which will trigger the move on a click event. Default is none. * * autoSubmit: Whether to automatically select <option>s for submission with parent form submit. Default true. * * beforeMove: Before move callback function. Return true to continue/false to cancel the move operation. * * afterMove: After move callback function. * * @example $("#my_select_left").multiSelect("#my_select_right"); * @desc Sets up double-clicks on #my_select_left's options to move the option to #my_select_right * @example $("#my_select_left").multiSelect("#my_select_right", {trigger: "#my_move_right_button"}); * @desc Sets up double-clicks as above and also sets up #my_move_right_button to transfer multiple elements on click. * * @example * <form action="test-handler.php" method="get"> * <table> * <tr> * <td><select name="left[]" id="select_left" multiple="multiple" size="6"> * <option>Item 1</option> * <option>Item 2</option> * <option>Item 3</option> * <option>Item 4</option> * </select></td> * * <td> * <p><a id="options_right" href="#"> * <img src="arrow_right.gif" alt=">" /> * </a></p> * <p><a id="options_left" href="#"> * <img src="arrow_left.gif" alt="<" /> * </a></p> * </td> * <td><select name="right[]" id="select_right" multiple="multiple" size="6"> * <option>Item 5</option> * <option>Item 6</option> * <option>Item 7</option> * <option>Item 8</option> * </select></td> * </tr> * </table> * * <input type="submit" /> * </form> * * * <script type="text/javascript"><!-- * $(function() { * $("#select_left").multiSelect("#select_right", {trigger: "#options_right"}); * $("#select_right").multiSelect("#select_left", {trigger: "#options_left"}); * }); * // --></script> */ jQuery.fn.multiSelect = function(to, options) { // support v0.1 syntax if (typeof options == "string") options = {trigger: "#"+options}; options = $.extend({ trigger: null, // selector of elements whose 'click' event should invoke a move allTrigger:null, // select all of options autoSubmit: true, // true => select all child <option>s on parent form submit (if any) beforeMove: null, // before move callback function afterMove: null // after move callback }, options); // for closures var $select = this; // make form submission select child <option>s if (options.autoSubmit) this.parents("form").submit(function() { selectChildOptions($select); }); // create the closure var moveFunction = function() { moveOptions($select, to, options.beforeMove, options.afterMove); }; var moveAllFunction = function(){ jQuery("option", $select).each(function(){ jQuery(this).attr('selected',true); }); moveFunction(); }; // attach double-click behaviour this.dblclick(moveFunction); // trigger element behaviour if (options.trigger) jQuery(options.trigger).click(moveFunction); if (options.allTrigger) jQuery(options.allTrigger).click(moveAllFunction); return this; // moves the options function moveOptions(from, toSel, beforeMove, afterMove) { if (beforeMove && !beforeMove()) return; jQuery("option:selected", from).each(function() { jQuery(this) .attr("selected", false) .appendTo(toSel); }); afterMove && afterMove(); } // selects all child options function selectChildOptions($select) { $select.children("option").each(function() { this.selected = true; }); } };