Commit 7ef5d2f7 authored by jheyming's avatar jheyming

Added better knockout documentation.

Added tests to clarify that selectedOptions is what
 to use when you want to update the checked state of
 multiple options.
parent 03582561
......@@ -5375,6 +5375,42 @@ optionLabel: function(element){
<dt>How to bind object values using Knockout JS?</dt>
<dd>
This issue was discussed in <a href="https://github.com/davidstutz/bootstrap-multiselect/issues/532">#532</a>.
<br>
<br>
<p>
bootstrap-multiselect depends upon the following standard knockout bindings:
<br>
<code>options, value, selectedOptions, enable, disable</code>
<br><br>
When these options change, they will update the internal <code>&lt;select&gt;</code> box and then the jQuery multiselect plugin triggers a refresh.
</p>
<ul>
<li><h4>options</h4></li>
<ul>
<li>When options is an observable and changes, your <code>&lt;select&gt;</code> options will be recalculated by knockout, then bootstrap-multiselect will refresh.</li>
</ul>
<li><h4>value</h4></li>
<ul>
<li>Only use this when you are using the radio button feature of bootstrap-multiselect. Knockout doesn't support using the value binding handler to update <code>&ltselect multiple="multiple"&gt;</code></li>
</ul>
<li><h4>selectedOptions</h4></li>
<ul>
<li>This is a standard knockout binding that updates the checked options inside a select element. Use this when trying to update a multiple type select box.</li>
</ul>
<li><h4>enable</h4></li>
<ul>
<li>Use it to enable the bootstrap dropdown.</li>
</ul>
<li><h4>disable</h4></li>
<ul>
<li>Use it to enable the bootstrap dropdown.</li>
</ul>
</ul>
<br>
<p>
Any other options inside the multiselect data bind are passed to the jQuery multiselect plugin.
</p>
<br>
</dd>
<dt>Options do net get updated when using Angular JS?</dt>
......
......@@ -13,9 +13,11 @@
<script type="text/javascript" src="lib/jasmine-2.0.2/boot.js"></script>
<script type="text/javascript" src="../docs/js/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-3.4.0.debug.js"></script>
<script type="text/javascript" src="../docs/js/bootstrap-3.3.2.min.js"></script>
<script type="text/javascript" src="../dist/js/bootstrap-multiselect.js"></script>
<script type="text/javascript" src="spec/bootstrap-multiselect.js"></script>
</head>
......
......@@ -705,3 +705,73 @@ describe('Bootstrap Multiselect Specific Issues', function() {
$selection.remove();
});
});
describe('Test knockout binding', function() {
var $testArea;
afterEach(function() {
if ($testArea) {
$testArea.multiselect('destroy').remove();
}
});
it('should update values and options with an observable array', function() {
jasmine.clock().install();
$testArea = $('<select multiple="multiple" data-bind="selectedOptions: myValues, options: myOptions, multiselect: {numberDisplayed: 1}"></select>').appendTo(document.body);
var viewModel = {
myValues: ko.observableArray(),
myOptions: ko.observableArray([])
};
expect(ko.bindingHandlers.multiselect.init !== undefined).toEqual(true);
var optionSpy = spyOn(ko.bindingHandlers.selectedOptions, 'init').and.callThrough(),
multiSpy = spyOn(ko.bindingHandlers.multiselect, 'init').and.callThrough();
ko.applyBindings(viewModel, $testArea[0]);
// knockout bindings were called
expect(optionSpy.calls.count()).toEqual(1);
expect(multiSpy.calls.count()).toEqual(1);
// no options are present since myOptions was empty
expect($testArea.find('option').length).toEqual(0);
expect($testArea.val()).toEqual(null);
expect($testArea.next().find('button.multiselect').text().trim()).toEqual('None selected');
expect($testArea.next().find('ul li').length).toEqual(0);
// Add more options
viewModel.myOptions(['option1', 'option2']);
jasmine.clock().tick(1000);
expect($testArea.next().find('ul li').length).toEqual(2);
expect($testArea.find('option').length).toEqual(2);
expect($testArea.find('option:checked').length).toEqual(0);
// select one
viewModel.myValues(['option2']);
jasmine.clock().tick(1000);
expect($testArea.find('option:checked').length).toEqual(1);
expect($testArea.find('option:checked').text().trim()).toEqual('option2');
// select all
viewModel.myValues(['option1', 'option2']);
jasmine.clock().tick(1000);
expect($testArea.find('option:checked').length).toEqual(2);
expect($testArea.find('option:checked').map(function() { return $(this).text().trim() }).toArray()).toEqual(['option1', 'option2']);
expect($testArea.next().find('button.multiselect').text().trim()).toEqual('All selected (2)');
// add another option
viewModel.myOptions.push('wacky option');
jasmine.clock().tick(1000);
expect($testArea.find('option:checked').length).toEqual(2);
expect($testArea.find('option:checked').map(function() { return $(this).text().trim() }).toArray()).toEqual(['option1', 'option2']);
expect($testArea.find('option').map(function() { return $(this).text().trim() }).toArray()).toEqual(['option1', 'option2', 'wacky option']);
expect($testArea.next().find('button.multiselect').text().trim()).toEqual('2 selected');
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment