Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 33 additions & 32 deletions src/jquery.multiselect.filter.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, boss:true, undef:true, curly:true, browser:true, jquery:true */
/*
* jQuery MultiSelect UI Widget Filtering Plugin 2.0.0
* jQuery MultiSelect UI Widget Filtering Plugin 3.0.0
* Copyright (c) 2012 Eric Hynds
*
* http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/
*
* Depends:
* - jQuery 1.7+
* - jQuery UI MultiSelect widget
*
* Dual licensed under the MIT and GPL licenses:
Expand Down Expand Up @@ -48,30 +49,30 @@

_create: function() {
var opts = this.options;
var elem = $(this.element);
var $elem = this.element;

// get the multiselect instance
this.instance = elem.multiselect('instance');
this.instance = $elem.multiselect('instance');

// store header; add filter class so the close/check all/uncheck all links can be positioned correctly
this.header = this.instance.menu.find('.ui-multiselect-header').addClass('ui-multiselect-hasfilter');
this.$header = this.instance.$menu.find('.ui-multiselect-header').addClass('ui-multiselect-hasfilter');

// wrapper elem
this.input = $("<input/>").attr({
// wrapper $elem
this.$input = $("<input/>").attr({
placeholder: opts.placeholder,
type: "search"
}).css({
width: (/\d/.test(opts.width) ? opts.width + 'px' : null)
}).bind({
}).on({
keydown: function(e) {
// prevent the enter key from submitting the form / closing the widget
if(e.which === 13) {
e.preventDefault();
} else if(e.which === 27) {
elem.multiselect('close');
$elem.multiselect('close');
e.preventDefault();
} else if(e.which === 9 && e.shiftKey) {
elem.multiselect('close');
$elem.multiselect('close');
e.preventDefault();
} else if(e.altKey) {
switch(e.which) {
Expand All @@ -80,13 +81,13 @@
$(this).val('').trigger('input', '');
break;
case 65:
elem.multiselect('checkAll');
$elem.multiselect('checkAll');
break;
case 85:
elem.multiselect('uncheckAll');
$elem.multiselect('uncheckAll');
break;
case 76:
elem.multiselect('instance').labels.first().trigger("mouseenter");
$elem.multiselect('instance').$labels.first().trigger("mouseenter");
break;
}
}
Expand All @@ -96,25 +97,25 @@
});
// automatically reset the widget on close?
if(this.options.autoReset) {
elem.bind('multiselectclose', $.proxy(this._reset, this));
$elem.on('multiselectclose', $.proxy(this._reset, this));
}
// rebuild cache when multiselect is updated
elem.bind('multiselectrefresh', $.proxy(function() {
$elem.on('multiselectrefresh', $.proxy(function() {
this.updateCache();
this._handler();
}, this));
this.wrapper = $("<div/>").addClass("ui-multiselect-filter").text(opts.label).append(this.input).prependTo(this.header);
this.$wrapper = $("<div/>").addClass("ui-multiselect-filter").text(opts.label).append(this.$input).prependTo(this.$header);

// reference to the actual inputs
this.inputs = this.instance.menu.find('input[type="checkbox"], input[type="radio"]');
this.$inputs = this.instance.$menu.find('input[type="checkbox"], input[type="radio"]');

// cache input values for searching
this.updateCache();

// rewrite internal _toggleChecked fn so that when checkAll/uncheckAll is fired,
// only the currently filtered elements are checked
// only the currently filtered $elements are checked
this.instance._toggleChecked = function(flag, group) {
var $inputs = (group && group.length) ? group : this.labels.find('input');
var $inputs = (group && group.length) ? group : this.$labels.find('input');
var _self = this;

// do not include hidden elems if the menu isn't open.
Expand Down Expand Up @@ -149,11 +150,11 @@

// thx for the logic here ben alman
_handler: function(e) {
var term = $.trim(this.input[0].value.toLowerCase()),
var term = $.trim(this.$input[0].value.toLowerCase()),

// speed up lookups
rows = this.rows, inputs = this.inputs, cache = this.cache;
var $groups = this.instance.menu.find(".ui-multiselect-optgroup");
rows = this.rows, $inputs = this.$inputs, $cache = this.$cache;
var $groups = this.instance.$menu.find(".ui-multiselect-optgroup");
$groups.show();
if(!term) {
rows.show();
Expand All @@ -162,10 +163,10 @@

var regex = new RegExp(term.replace(rEscape, "\\$&"), 'gi');

this._trigger("filter", e, $.map(cache, function(v, i) {
this._trigger("filter", e, $.map($cache, function(v, i) {
if(v.search(regex) !== -1) {
rows.eq(i).show();
return inputs.get(i);
return $inputs.get(i);
}

return null;
Expand All @@ -183,36 +184,36 @@
},

_reset: function() {
this.input.val('').trigger('input', '');
this.$input.val('').trigger('input', '');
},

updateCache: function() {
// each list item
this.rows = this.instance.labels.parent();
this.rows = this.instance.$labels.parent();

// cache
this.cache = this.element.children().map(function() {
var elem = $(this);
this.$cache = this.element.children().map(function() {
var $elem = $(this);

// account for optgroups
if(this.tagName.toLowerCase() === "optgroup") {
elem = elem.children();
$elem = $elem.children();
}

return elem.map(function() {
return $elem.map(function() {
return this.innerHTML.toLowerCase();
}).get();
}).get();
},

widget: function() {
return this.wrapper;
return this.$wrapper;
},

destroy: function() {
$.Widget.prototype.destroy.call(this);
this.input.val('').trigger("keyup");
this.wrapper.remove();
this.$input.val('').trigger("keyup");
this.$wrapper.remove();
}
});

Expand Down
Loading