Skip to content
Closed
23 changes: 22 additions & 1 deletion src/jquery.multiselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
noneSelectedText: 'Select options', // (str) The text to show in the button where nothing is selected.
selectedText: '# of # selected', // (str) A "template" that indicates how to show the count of selections in the button. The "#'s" are replaced by the selection count & option count.
selectedList: 0, // (int) The actual list selections will be shown in the button when the count of selections is <= than this number.
selectedMax: null, // (int | function) If selected count > selectedMax or if function returns 1, then message is displayed, and new selection is undone.
show: null, // (array) An array containing menu opening effects.
hide: null, // (array) An array containing menu closing effects.
autoOpen: false, // (true | false) If true, then the menu will be opening immediately after initialization.
Expand Down Expand Up @@ -453,13 +454,32 @@
var checked = this.checked;
var $tags = self.element.find('option'); // "element" is a jQuery object representing the underlying select
var isMultiple = !!self.element[0].multiple;

var inputCount = self.$inputs.length;
var numChecked = self.$inputs.filter(":checked").length;
var selectedMax = self.options.selectedMax;

// bail if this input is disabled or the event is cancelled
if(this.disabled || self._trigger('click', e, { value: val, text: optionText, checked: checked }) === false) {
e.preventDefault();
return;
}

if ( selectedMax && checked && ( $.isFunction(selectedMax) ? !!selectedMax.call(this, self.$inputs) : numChecked > selectedMax ) ) {
var o = self.options;
var saveText = o.selectedText;

// The following warning is shown in the button and then cleared after a second.
o.selectedText = "<center><b>LIMIT OF " + (numChecked - 1) + " REACHED!</b></center>";
self.update();
setTimeout( function() {
o.selectedText = saveText;
self.update();
}, 1000 );

e.preventDefault(); // Kill the event.
return false;
}

// make sure the input has focus. otherwise, the esc key
// won't close the menu after clicking an item.
$this.focus();
Expand Down Expand Up @@ -993,6 +1013,7 @@
break;
case 'selectedText':
case 'selectedList':
case 'selectedMax':
case 'noneSelectedText':
this.options[key] = value; // these all needs to update immediately for the update() call
this.update();
Expand Down
35 changes: 27 additions & 8 deletions tests/unit/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,33 @@
selectedList: 2
});

el.multiselect("checkAll");
equals( button().text(), '3 of 3 selected', 'after checkAll with a limited selectedList value, button value displays number of checked');
el.multiselect("destroy").remove();
});

function asyncSelectedList( useTrigger, message ){
expect(1);
stop();
el.multiselect("checkAll");
equals( button().text(), '3 of 3 selected', 'after checkAll with a limited selectedList value, button value displays number of checked');
el.multiselect("destroy").remove();
});

test("selectedMax", function(){
expect(1);

var html = '<select multiple><option value="foo">foo &quot;with quotes&quot;</option><option value="bar">bar</option><option value="baz">baz</option></select>';

el = $(html).appendTo("body").multiselect({
selectedMax: 2
});

checkboxes = el.multiselect("widget").find(":checkbox");
checkboxes.eq(0).trigger('click');
checkboxes.eq(1).trigger('click');
checkboxes.eq(2).trigger('click');

equals( menu().find("input").filter(":checked").length, 2 , 'after clicking each checkbox, count of checked restored to selectedMax of 2');
el.multiselect("destroy").remove();

});

function asyncSelectedList( useTrigger, message ){
expect(1);
stop();

var html = '<select multiple><option value="foo">foo</option><option value="bar">bar</option><option value="baz">baz</option></select>',
checkboxes;
Expand Down