Skip to content

Instantly share code, notes, and snippets.

@mkkeck
Created May 28, 2010 20:17
Show Gist options
  • Save mkkeck/417672 to your computer and use it in GitHub Desktop.
Save mkkeck/417672 to your computer and use it in GitHub Desktop.
/**
* jQuery UI Multiselect Advanced
*
* Replaces the jQuery UI Multiselect from the page
* <http://www.quasipartikel.at/multiselect/>
*
*
* Author: Michael Keck
*
* Based on the original code from:
* <http://www.quasipartikel.at/multiselect/>
* written by
* - Michael Aufreiter (quasipartikel.at)
* - Yanick Rochon (yanick.rochon[at]gmail[dot]com)
* (c) Copyright: Michael Aufreiter and Yanick Rochon
*
*
* (c) Copyright: 2010, Michael Keck
* <http://www.michaelkeck.de/projects/jquery>
*
*
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt)
* licenses.
*
*
* Depends: ui.core.js
* ui.sortable.js
* ui.resizable.js (optional, but if you set the option
* 'resizable' to an value != false or ''
* you'll need this!)
*
* Usage: // INIT
* $('.selector').multiselect(
* // { your needed init options }
* );
* // UPDATE
* $('.selector').multiselect({
* 'optionname' : mixed option value
* });
*
* Documentation: NONE (at the moment)
*/
(function($) {
$.widget('ui.multiselect', {
// -------------------------------------------------------------------
// OPTIONS
// -------------------------------------------------------------------
options: {
// Icons
icons: {
removeItem: 'ui-icon-minus', // required
selectItem: 'ui-icon-plus', // required
selectAll: 'ui-icon-arrowthick-1-e', // optional (false to disable)
removeAll: 'ui-icon-arrowthick-1-w' // optional (false to disable)
},
// Layout
cssclass: '', // optional className
height: 'auto', // height, if 'auto': orginal elements height used
width: 'auto', // width, if 'auto': orginal elements width used
// Resizable
resizable: 'e,s,se', // set to false for disabling
// Searching
search: {
enabled: true, // true enable search, fals disables search
input: 'input' // input or select, if select you've to pass
// a complete select box with all required
// options
},
// Options to be added, removed or changed
data: {
empty: false, // Removes all options from multiselect
// Changes the select status of some options
// Supported selectors: *, $, !, ^ |
// See also <http://api.jquery.com/category/selectors/>
change: [
// Examples:
// as an object (best way):
// { value : 'your val 1', selected : true },
// { value : 'your val 2', selected : false },
// { value : '*your', selected : false },
// ...
// as an array (quick and dirty for only to revert the status):
// 'your val 1', 'your val 2', ...
],
// Adds some new options to the multiselect
insert: [
// Examples:
// as an object (best way):
// { value : 'your val 1', option: 'text to display 1', selected : true },
// { value : 'your val 2', option: 'text to display 2', selected : false },
// ...
// as an array (quick and dirty):
// ['your val 1', 'text to display 1', true],
// ['your val 2', 'text to display 2', false],
// ...
],
// Removes some options from the multiselect
// Supported selectors: *, $, !, ^ |
// See also <http://api.jquery.com/category/selectors/>
remove: [
// Examples:
// as an object (best way):
// { selected : true } // removes all selected
// { selected : false }, // removes all none selected
// { value : 'your val 1' }, // removes option with value
// { value : '*your' }, // removes option with value
// ...
// as an array (quick and dirty and only values are supported):
// 'your val 1', 'your val 2', ...
]
},
// Animation
// Note: the effects you can use for 'show' and 'hide' are listed
// at <http://jqueryui.com/demos/effect/>
animate: {
hide: 'drop', // see <http://jqueryui.com/demos/hide/>
show: 'slide', // see <http://jqueryui.com/demos/show/>
speed: 'fast', // set to 0 or false, 'fast', 'slow' or a int
},
// Callbacks
nodeComparator: function(n1, n2) {
var t1 = n1.text(), t2 = n2.text();
return t1 == t2 ? 0 : (t1 < t2 ? -1 : 1);
}
},
// -------------------------------------------------------------------
// PRIVATE FUNCTIONS
// -------------------------------------------------------------------
// Clones a DOMElement and returns it's clone
// @param object node DOMElement
// @return object clone DOMElement cloned
_copynode: function(node) {
var clone = node.clone();
clone.data('optionLink', node.data('optionLink'));
clone.data('idx', node.data('idx'));
return clone;
},
// Updates the Counter Message
_updcount: function() {
this.countInfo.text(
this.lang.countItems.replace(/{count}/, this.count)
);
},
// Set busy state
// @param boolean state true|false
_busy: function(state) {
if (state) {
this.countInfo.hide(); this.busyInfo.show();
}
else {
this.busyInfo.hide(); this.countInfo.show();
this._updcount();
}
},
// Filters available options
// @param object list DOMElement
_filter: function(list) {
var input = $(this), rows = list.children('li'),
cache = rows.map(function() {
return $(this).text().toLowerCase();
}),
term = $.trim(input.val().toLowerCase()),
scores = [];
if (!term) {
rows.show();
}
else {
rows.hide();
cache.each(function(i) {
if (this.indexOf(term)>-1) {
scores.push(i);
}
});
$.each(scores, function() {
$(rows[this]).show();
});
}
},
// Get an DOMElement from an option
// @param object option DOMElement
// @return object li DOMElement
_getnode: function(option) {
var node = $('<li class="ui-element ui-state-default" title="' + $(option).text() + '">' + $(option).text() + '<a href="#" class="action ui-icon">&#160;</a></li>').hide();
node.data('optionLink', $(option));
return node;
},
// Get the serach string for finding options with a special
// selectors: *, $, !, ^ |
// See also <http://api.jquery.com/category/selectors/>
// @param string value
// @return string jQuery selector string
_findvalue: function(value) {
var pre = value.substring(0, 1), returnVal = '';
if (pre !== '*' && pre !== '$' && pre !== '!' && pre !== '^' && pre != '|') {
returnVal = 'value="' + value + '"'
} else {
returnVal = 'value' + pre + '="' + value.substring(1, value.length) + '"';
}
return returnVal;
},
_initlists: function(data) {
var inp = this.element,
len = 0, num = 0, key = '', u = 'undefined', tmp;
// Remove all options from the multiselect
if (data.empty) {
inp.find('option').remove();
}
// Remove some options with given values from the multiselect
else if (typeof(data.remove) !== u && data.remove.length > 0) {
tmp = data.remove;
len = data.remove.length;
for (num = 0; num < len; num++) {
// Quick and dirty: only support values
if (typeof(tmp[num]) !== 'object') {
inp.find('option[' + this._findvalue(tmp[num]) + ']').remove();
}
// Default behaviour
else {
if (typeof(tmp[num]['selected']) !== u) {
if (tmp[num]['selected']) {
inp.find('option:selected').remove();
} else {
inp.find('option:not(:selected)').remove();
}
} else if (typeof(tmp[num]['value']) !== u) {
if (tmp[num]['value']) {
inp.find('option[' + this._findvalue(tmp[num]['value']) + ']').remove();
}
}
}
}
}
// Insert new options to the multiselect
if (typeof(data.insert) !== u && data.insert.length > 0) {
tmp = data.insert;
len = data.insert.length;
for (num = 0; num < len; num++) {
// Very quick and dirty: only support values
if (typeof(tmp[num]) !== 'object') {
$('<option value="' + tmp[num] + '">' + tmp[num] + '</option>').appendTo(inp);
}
// Default behaviour
else {
var txt = '', val = '', sel = '';
if (typeof(tmp[num]['value']) !== u) {
val = tmp[num]['value'];
} else if (typeof(tmp[num][0]) !== u) {
val = tmp[num][0];
txt = tmp[num][0];
}
if (typeof(tmp[num]['option']) !== u) {
text = tmp[num]['option'];
} else if (typeof(tmp[num][1]) !== u) {
if (tmp[num][1]) {
txt = tmp[num][1];
}
}
if (typeof(tmp[num]['selected']) !== u) {
if (tmp[num]['selected']) {
sel = ' selected="selected"';
}
} else if (typeof(tmp[num][2]) !== u) {
if (tmp[num][2]) {
sel = ' selected="selected"';
}
}
if (val !== '') {
$('<option value="' + val + '"' + sel + '>' + ((txt !== '') ? txt : val) + '</option>').appendTo(inp);
}
}
}
}
// Change the selected state from options in multiselect
if (typeof(data.change) !== u && data.change.length > 0) {
tmp = data.change;
len = data.change.length;
for (num = 0; num < len; num++) {
sel = false; val = '';
// Quick and dirty: only support values
if (typeof(tmp[num]) !== 'object') {
val = this._findvalue(tmp[num]);
sel = inp.find('option[' + val + ']').attr('selected');
if (sel) {
inp.find('option[' + val + ']').removeAttr('selected');
} else {
inp.find('option[' + val + ']').attr('selected', 'selected');
}
}
// Default behaviour
else {
if (typeof(tmp[num]['selected']) !== u) {
sel = tmp[num]['selected'];
}
if (typeof(tmp[num]['value']) !== u) {
val = this._findvalue(tmp[num]['value']);
}
if (val !== '') {
if (sel) {
inp.find('option[' + val + ']').attr('selected', 'selected');
} else {
inp.find('option[' + val + ']').removeAttr('selected');
}
}
}
}
}
},
// Gets all options elements from a multiselect list
// @param object options DOMElement(s)
// @return object item DOMElement
_makelists: function(options) {
this._busy(true);
this.availItems.children('.ui-element').remove();
this.selectItems.children('.ui-element').remove();
this.count = 0;
var self = this;
var items = $(options.map(function(i) {
var item = self._getnode(this);
item.appendTo(this.selected ? self.selectItems : self.availItems).show();
if (this.selected) {
self.count += 1;
}
self._setstate(item, this.selected);
item.data('idx', i);
return item[0];
}));
this._busy(false);
},
// Register onHover Events
// @param DOMElement
_reghover: function(el) {
el.mouseover(function() {
$(this).removeClass('ui-state-default').addClass('ui-state-hover');
});
el.mouseout(function() {
$(this).removeClass('ui-state-hover').addClass('ui-state-default');
});
},
// Register onRemove Events
// @param DOMElement
_regremove: function(el) {
var self = this;
// Single click on Icon
el.click(function() {
self._updoption($(this).parent(), false);
self.count -= 1;
self._updcount();
return false;
});
// Double click the parent DOMElement
el.parent().dblclick(function() {
self._updoption($(this), false);
self.count -= 1;
self._updcount();
return false;
});
},
// Register onSearch Events
// @param DOMElement
// @param string type ('input' | 'select')
_regsearch: function(input, type) {
var self = this;
input.focus(function() {
$(this).addClass('ui-state-active');
}).blur(function() {
$(this).removeClass('ui-state-active');
});
if (type !== 'select') {
input.keypress(function(e) {
if (e.keyCode == 13) {
return false;
}
}).keyup(function() {
self._filter.apply(this, [self.availItems]);
});
}
else {
input.change(function() {
self._filter.apply(this, [self.availItems]);
return false;
});
}
},
// Register onSelect Events
// @param DOMElement
_regselect: function(el) {
var self = this;
// Single click on Icon
el.click(function() {
var item = self._updoption($(this).parent(), true);
self.count += 1;
self._updcount();
return false;
});
// Double click the parent DOMElement
el.parent().dblclick(function() {
self._updoption($(this), true);
self.count -= 1;
self._updcount();
return false;
});
},
// Resizes the Multiselect Widget
_resize: function() {
var d = 0, s = this.sizes, p = this.options, v = 0;
// Calculate the Heights
if (s.bodyHeight > 0) {
this.container.height(s.bodyHeight);
d = this.container.height();
if (d > 0) {
v = d - this.availHead.outerHeight(true);
this.availBody.height(d); this.availList.height(v);
this.availItems.height(v - 2);
this.selectBody.height(d); this.selectList.height(v);
this.selectItems.height(v - 2);
}
}
// Caclulate the Widths
if (s.bodyWidth > 0) {
this.container.width(s.bodyWidth);
v = Math.floor(this.container.width() * 0.5);
if (v > 0) {
this.availBody.width(v); this.selectBody.width(v);
if (p.search.enabled) {
d = ((this.availText.outerWidth(true) - this.availText.width()) * 2) + this.availText.find('.ui-icon').outerWidth(true) + (p.icons.selectAll ? this.selectAllIcon.outerWidth(true) : 0) + 5;
this.searchInput.width(v - d);
}
d = ((this.selectText.outerWidth(true) - this.selectText.width()) * 2) + (p.icons.removeAll ? this.removeAllIcon.outerWidth(true) : 0);
this.selectText.width(v - d).css({ 'overflow' : 'hidden' });
this.selectText.find('panel-text').width(v - (d + this.selectText.find('.ui-icon').outerWidth(true)));
}
}
},
// Sets the state of an element
// @param DOMElement
// @param bool state (true | false) set selected status
_setstate: function(item, state) {
// SELECTED
if (state) {
item.find('a.action').addClass(this.options.icons.removeItem).removeClass(this.options.icons.selectItem).attr('title', this.lang.removeItem).text(this.lang.removeItem);
// Register Remove Event
this._regremove(item.find('a.action'));
}
// NOT SELECTED
else {
item.find('a.action').addClass(this.options.icons.selectItem).removeClass(this.options.icons.removeItem).attr('title', this.lang.selectItem).text(this.lang.selectItem);
// Register Select Event
this._regselect(item.find('a.action'));
}
// Register Hover Event
this._reghover(item);
},
// Sets the state of an element
// @param DOMElement
// @param bool state (true | false) set selected status
// @param bool noeffect (true | false) optional and only needed by
// drag and drop
_updoption: function(item, state, noeffect) {
var anim = this.options.animate;
item.data('optionLink').attr('selected', state);
// SELECTED
if (state) {
// look for successor based on initial option index
var items = this.selectItems.find('li'), comparator = this.options.nodeComparator;
var succ = null, i = item.data('idx'), d = comparator(item, $(items[i]));
// TODO: test needed for dynamic list populating
if (d) {
var l = items.length;
while (i > -1 && i < l) {
d > 0 ? i++ : i--;
if (d != comparator(item, $(items[i]))) {
// going up, go back one item down, otherwise leave as is
succ = items[d > 0 ? i : i+1];
break;
}
}
} else {
succ = items[i];
}
var other = this._copynode(item);
succ ? other.insertBefore($(succ)) : other.appendTo(this.selectItems);
// Effect?
if (!noeffect) {
if (anim.hide !== 'hide') {
$(item).hide(anim.hide, null, anim.speed, function() { $(this).remove(); });
} else {
$(item).hide(anim.speed, function() { $(this).remove(); });
}
} else {
$(item).hide().remove();
}
other.appendTo(this.selectItems).hide();
// Effect?
if (!noeffect) {
if (anim.show !== 'show') {
$(other).show(anim.show, null, anim.speed);
} else {
$(other).show(anim.speed);
}
} else {
$(other).show();
}
this._setstate(other, true);
return other;
}
// NOT SELECTED
else {
// look for successor based on initial option index
var items = this.availItems.find('li'), comparator = this.options.nodeComparator;
var succ = null, i = item.data('idx'), d = comparator(item, $(items[i]));
// TODO: test needed for dynamic list populating
if (d) {
var l = items.length;
while (i > -1 && i < l) {
d > 0 ? i++ : i--;
if (d != comparator(item, $(items[i]))) {
// going up, go back one item down, otherwise leave as is
succ = items[d > 0 ? i : i+1];
break;
}
}
} else {
succ = items[i];
}
var other = this._copynode(item);
succ ? other.insertBefore($(succ)) : other.appendTo(this.availItems);
// Effect?
if (!noeffect) {
if (anim.hide !== 'hide') {
$(item).hide(anim.hide, null, anim.speed, function() { $(this).remove(); });
} else {
$(item).hide(anim.speed, function() { $(this).remove(); });
}
} else {
$(item).hide().remove();
}
other.hide();
// Effect?
if (!noeffect) {
if (anim.show !== 'show') {
$(other).show(anim.show, null, anim.speed);
} else {
$(other).show(anim.speed);
}
} else {
$(other).show();
}
this._setstate(other, false);
return other;
}
},
// -------------------------------------------------------------------
// PUBLIC FUNCTIONS
// -------------------------------------------------------------------
// UI Function
// Creates the Multiselect Widget
_create: function() {
var p = this.options, l = (this.lang = $.ui.multiselect.locale), u = 'undefined', evopts = {};
// Check Animation Options
if ( !(typeof(p.animate) !== u && typeof(p.animate.speed) !== u && p.animate.speed) ) {
p.animate.speed = (this.options.animate.speed = 0);
p.animate.show = (this.options.animate.show = 'show');
p.animate.hide = (this.options.animate.hide = 'hide');
}
// Check Icons Options
if ( !(typeof(p.icons) !== u && typeof(p.icons.removeItem) !== u && p.icons.removeItem) ) {
p.icons.removeItem = (this.options.icons.removeItem = 'ui-icon-minus');
}
if ( !(typeof(p.icons) !== u && typeof(p.icons.selectItem) !== u && p.icons.selectItem) ) {
p.icons.selectItem = (this.options.icons.selectItem = 'ui-icon-plus');
}
// Busy state
this.busy = false;
// Overwrite Sortable and Droppable Options (deprecated)
this.options.sort = true;
this.options.drop = true;
// Populate Lists if given
if (this.options.data) {
var d = this.options.data;
if ( d.empty || (d.change && d.change.length > 0) || (d.insert && d.insert.length > 0) || (d.remove && d.remove.length > 0) ) {
this._initlists(this.options.data);
}
}
// Hide original object
this.id = this.element.attr('id');
this.element.hide();
// Main-Body Object
this.container = $('<div class="ui-multiselect ui-helper-clearfix ui-widget ui-corner-all' + (p.cssclass ? ' ' + p.cssclass : '') + '"></div>').insertAfter(this.element);
// Available Objects
this.availBody = $('<div class="ui-multiselect-left"></div>').appendTo(this.container);
this.availHead = $('<div class="ui-widget-header"></div>').appendTo(this.availBody);
this.availText = $('<div class="panel"></div>').appendTo(this.availHead);
this.availList = $('<div class="ui-widget-content"></div>').appendTo(this.availBody);
this.availItems = $('<ul class="available connected-list"><li class="ui-helper-hidden-accessible">&#160;</li></ul>').css({ 'overflow' : 'auto','overflowX' : 'hidden' }).bind('selectstart', function() { return false; }).appendTo(this.availList);
// Selected Objects
this.selectBody = $('<div class="ui-multiselect-right"></div>').appendTo(this.container);
this.selectHead = $('<div class="ui-widget-header"></div>').appendTo(this.selectBody);
this.selectText = $('<div class="panel"></div>').css({ 'overflow' : 'hidden' }).appendTo(this.selectHead);
this.selectList = $('<div class="ui-widget-content"></div>').appendTo(this.selectBody);
this.selectItems = $('<ul class="selected connected-list"><li class="ui-helper-hidden-accessible">&#160;</li></ul>').css({ 'overflow': 'auto', 'overflowX': 'hidden' }).bind('selectstart', function(){ return false; }).appendTo(this.selectList);
// Button 'Remove All'
this.removeAllIcon = $('<a href="#" class="ui-icon" title="' + l.removeAll + '">' + l.removeAll + '</a>').appendTo(this.selectHead).hide();
// Button 'Select All'
this.selectAllIcon = $('<a href="#" class="ui-icon" title="' + l.selectAll + '">' + l.selectAll + '</a>').appendTo(this.availHead).hide();
// Add Search Input for Live Search
this.searchType = false;
if (typeof(p.search) !== u && typeof(p.search.input) !== u) {
if (('' + p.search.input).substring(0, 6) == '<input' || ('' + p.search.input).substring(0, 7) == '<select') {
if (('' + p.search.input).substring(0, 7) == '<select') {
this.searchType = 'select';
} else {
this.searchType = 'input';
}
this.searchInput = $(p.search.input).appendTo(this.availText).hide();
}
}
if (!this.searchType) {
this.searchInput = $('<input type="text" size="20" value="" />').appendTo(this.availText).hide();
this.searchType = 'input';
}
// Busy DOMElement
this.busyInfo = $('<div class="busy-info"><span class="ui-icon ui-icon-loading"></span><span class="panel-text">' + l.busy + '</span></div>').appendTo(this.selectText).show();
// Count DOMElement
this.countInfo = $('<div class="count-info"><span class="panel-text"></span></div>').appendTo(this.selectText).hide();
// init lists
var self = this;
this._busy(true);
this._makelists(this.element.find('option'));
// Add Event to 'Remove All'
if (p.icons.removeAll) {
this.removeAllIcon.addClass(p.icons.removeAll).show().click(function() {
self._makelists(self.element.find('option').removeAttr('selected'));
return false;
});
}
// Add Event to 'Select All'
if (p.icons.selectAll) {
this.selectAllIcon.addClass(p.icons.selectAll).show().click(function() {
self._makelists(self.element.find('option').attr('selected', 'selected'));
return false;
});
}
// Add Event to Search
if (p.search.enabled) {
if (p.search.value) {
this.searchInput.val(p.search.value);
} else if (p.filter) {
this.searchInput.val(p.filter);
}
if (this.searchInput.val() !== '') {
this._filter.apply(this.searchInput, [this.availItems]);
}
this._regsearch(this.searchInput, this.searchType);
this.searchInput.show();
} else {
if (p.filter) {
this._filter.apply(p.filter, [this.availItems]);
}
}
// Save Sizes
this.sizes = {
'bodyWidth': ( (p.width == 'auto') ? (this.options.width = this.element.width()) : (p.width ? p.width : 0) ),
'bodyHeight': ( (p.height == 'auto') ? (this.options.height = this.element.height()) : (p.height ? p.height : 0) ),
'minWidth': p.minWidth || Math.floor(this.element.width() * 0.5)
}
// Resizable
this._resize();
if (p.resizable) {
this.container.resizable({
grid: [10, 10],
handles: p.resizable,
maxWidth: (p.maxWidth || false),
minWidth: self.sizes.minWidth,
maxHeight: (p.maxHeight || false),
minHeight: (p.minHeight || 80),
resize: function() {
self.sizes.bodyWidth = self.container.width();
self.sizes.bodyHeight = self.container.height();
self._resize();
}
});
}
// Sortable
if (this.options.sort) {
var sortopts = {
appendTo: self.container,
containment: self.container,
connectWith: '.connected-list',
forceHelperSize: true,
forcePlaceholderSize: true,
placeholder: 'ui-state-highlight',
revert: false
};
this.availItems.bind('sortreceive', function(event, ui) {
ui.item.data('optionLink').attr('selected', false);
self.count -= 1;
self._updcount();
self._updoption(ui.item, false, true);
}).bind('sortbeforestop', function(event, ui) {
ui.helper.removeClass('ui-multiselect-cloned');
}).bind('sortstop', function(event, ui) {
self.availItems.find('li').each(function() {
if ($(this).data('optionLink')) {
$(this).data('optionLink').remove().appendTo(self.element);
}
});
}).bind('sortstart', function(event, ui) {
ui.helper.addClass('ui-multiselect-cloned');
}).sortable(sortopts);
this.selectItems.bind('sortreceive', function(event, ui) {
ui.item.data('optionLink').attr('selected', true);
self.count += 1;
self._updcount();
self._updoption(ui.item, true, true);
}).bind('sortbeforestop', function(event, ui) {
ui.helper.removeClass('ui-multiselect-cloned');
}).bind('sortstop', function(event, ui) {
self.selectItems.find('li').each(function() {
if ($(this).data('optionLink')) {
$(this).data('optionLink').remove().appendTo(self.element);
}
});
}).bind('sortstart', function(event, ui) {
ui.helper.addClass('ui-multiselect-cloned');
}).sortable(sortopts);
}
this._busy(false);
},
// UI FUNCTION _setOption
// @param string key
// @param mixed value
_setOption: function(key, value) {
var self = this, u = 'undefined', p = this.options;
switch (key) {
// Set the busy state
case 'busy':
if (value) {
this._busy(true);
} else {
this._busy(false);
}
break;
// Manipulate the multiselect options
// Changes the selected status
case 'change':
this.change(value);
break;
// Update all datas, if it is an object
case 'data':
this._initlists(data);
this.refresh();
break;
// Empty multiselect
case 'empty':
this.empty();
break;
// Insert new options to the multiselect
case 'insert':
this.change(value);
break;
// Remove some options from the multiselect
case 'remove':
this.remove(value);
break;
// Update the list
case 'update':
case 'refresh':
this.refresh();
break;
// Set a new filter or remove the filter
case 'filter':
if (value) {
this.searchInput.val(value);
this._filter.apply(this.searchInput, [self.availItems]);
}
break;
// Update the 'removeAll' and/or 'selectAll' buttons
case 'icons':
if (typeof(value['removeAll']) !== u) {
var v = value['removeAll'];
if (v) {
if (typeof(v) == 'boolean') {
v = p.icons.removeAll;
}
this.removeAll.removeClass(p.icons.removeAll).addClass(v).show().click(function() {
self._makelists(self.element.find('option').removeAttr('selected'));
return false;
});
} else {
this.removeAllIcon.hide();
}
}
if (typeof(value['selectAll']) !== u) {
var v = value['selectAll'];
if (v) {
if (typeof(v) == 'boolean') {
v = p.icons.selectAll;
}
this.selectAllIcon.removeClass(p.icons.selectAll).addClass(v).show().click(function() {
self._makelists(self.element.find('option').attr('selected', 'selected'));
return false;
});
} else {
this.selectAllIcon.hide();
}
}
break;
// Enable or disable the resizable
case 'resizable':
this.container.resizable('destroy');
if (value) {
this.body.resizable({
grid: [10, 10],
handles: (typeof(value) !== 'boolean' && typeof(value) == 'string') ? value : p.resizable,
maxWidth: (p.maxWidth || false), minWidth: self.sizes.minWidth,
maxHeight: (p.maxHeight || false), minHeight: (p.minHeight || 80),
resize: function() {
self.sizes.bodyWidth = self.container.width();
self.sizes.bodyHeight = self.container.height();
self._resize();
}
});
}
break;
// Set new search input
case 'search':
if (typeof(value['input']) !== u && value['input']) {
this.searchType = false;
if (('' + value['input']).substring(0, 6) == '<input' || ('' + value['input']).substring(0, 7) == '<select') {
if (('' + value['input']).substring(0, 7) == '<select') {
this.searchType = 'select';
} else {
this.searchType = 'input';
}
this.searchInput = $(value['input']).appendTo(this.availText).hide();
}
if (!this.searchType) {
this.searchInput = $('<input type="text" size="20" value="" />').appendTo(this.availText).hide();
this.searchType = 'input';
}
}
if (typeof(value['enabled']) !== u) {
if (value['enabled']) {
this._regsearch(this.searchInput, this.searchType);
this.searchInput.show();
} else {
this.searchInput.hide();
}
}
if (typeof(value['value']) !== u) {
if (value['value']) {
this.searchInput.val(value['value']);
this._filter.apply(this.searchInput, [self.availItems]);
}
}
break;
// Set new maxWidth
case 'maxWidth':
this.sizes.maxWidth = (this.options.maxWidth = (value ? Max.abs(parseInt(value, 10)) : p.maxWidth) );
break;
// Set new maxHeight
case 'maxHeight':
this.sizes.maxWidth = (this.options.maxHeight = (value ? Max.abs(parseInt(value, 10)) : p.maxHeight) );
break;
// Set new width
case 'width':
this.sizes.bodyWidth = ( (value == 'auto') ? (this.options.width = this.element.width()) : (value ? (this.options.width = value) : p.width) );
this._resize();
break;
// Set new height
case 'height':
this.sizes.bodyHeight = ( (value == 'auto') ? (this.options.height = this.element.height()) : (value ? (this.options.height = value) : p.height) );
this._resize();
break;
}
},
// UI FUNCTION
// Destroy (remove) the Multiselect Widget
destroy: function() {
this.element.show();
this.container.remove();
$.Widget.prototype.destroy.apply(this, arguments);
},
// UI FUNCTION
// Enable or disable
enabled: function(state) {
if (typeof(state) !== 'undefined') {
if (state) {
this.container.removeClass('ui-state-disabled');
this.container.find('li').removeClass('ui-state-disabled');
this.element.removeAttr('disabled');
}
else {
this.container.addClass('ui-state-disabled');
this.container.find('li').addClass('ui-state-disabled');
this.element.attr('disabled', true);
}
}
return !this.element.attr('disabled');
},
// UI FUNCTION
// Update after html append or insert
refresh: function() {
this._makelists(this.element.find('option'));
},
// UI FUNCTION
// Changing selected status
change: function(value) {
var data = { change: value };
this._initlists(data);
this.refresh();
},
// UI FUNCTION
// Removing all options
empty: function() {
var data = { empty: true };
this._initlists(data);
this.refresh();
},
// UI FUNCTION
// insert new options
insert: function(value) {
var data = { insert: value };
this._initlists(data);
this.refresh();
},
// UI FUNCTION
// remove options
remove: function(value) {
var data = { remove: value };
this._initlists(data);
this.refresh();
},
// UI FUNCTION
// get values
values: function() {
var value = 'option'
if (typeof(arguments[0]) !== 'undefined') {
if (typeof(arguments[0]) == 'string') {
var key = ('' + arguments[0]).toLowerCase();
switch (key) {
case 'selected':
case 'true':
case '1':
value = 'option:selected';
break;
case 'notselected':
case '!selected':
case 'false':
case '0':
value = 'option:not(:selected)';
break;
default:
value = 'option[' + this._findvalue(arguments[0]) + ']';
break;
}
} else if (typeof(arguments[0]) == 'boolean') {
if (arguments[0]) {
value = 'option:selected'
} else {
value = 'option:not(:selected)'
}
}
}
return $.map(
this.element.find(value),
function (item, i) {
return $(item).val();
}
);
},
// UI FUNCTION
// get selected
selected: function(value) {
value = 'option[' + this._findvalue(value) + ']';
return $.map(
this.element.find(value),
function (item, i) {
return $(item).attr('selected') ? true : false;
}
);
}
});
$.extend($.ui.multiselect, {
locale: {
selectAll : 'Select all',
removeAll : 'Remove all',
selectItem : 'Select',
removeItem : 'Remove',
countItems : '{count} items selected',
search : 'Search',
busy : 'Loading'
}
});
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment