Skip to content

Instantly share code, notes, and snippets.

@bb
Last active December 11, 2015 22:09
Show Gist options
  • Save bb/4667871 to your computer and use it in GitHub Desktop.
Save bb/4667871 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<body>
<form id="select_multiple_values">
<fieldset>
<label>Example one: Select many from many:</label><br>
<select multiple="multiple" data-bind="options: list2, optionsText: 'name', selectedOptions: selected2"></select>
<ul data-bind="foreach: selected2">
<li><span data-bind="text: name"></span> is on <span data-bind="text: host"></span></li>
</ul>
<p style="color: green">Works as expected</p>
</fieldset>
<br>
<fieldset>
<label>Example two: Select one from many (but store in collection)</label><br>
<select data-bind="options: list, optionsText: 'name', selectedOptions: selected"></select>
first from selected list: <span data-bind="text: selected()[0] !== undefined && selected()[0].name"></span> is on <span data-bind="text: selected()[0] !== undefined && selected()[0].host" ></span>
<p style="color: orange">Works as expected. TODO: what's the best way to set the first option as default? If model is null, and the UI shows the first, I'd like the model to be updated to have the first as well. Also, the data binding on the "first" item and reading it's property does not look nice.</p>
</fieldset>
</form>
<br>
<form id="select_one_value">
<fieldset>
<label>Example three: Select one from many (and store it in a single value)</label><br>
<select data-bind="options: list, optionsText: 'name', value: single"></select>
One selected: <span data-bind="text: single().name()"></span>
<p style="color: red">FIXME: This does not work with kb.observable as of 2013-01-31. See JS console for the error: "Uncaught TypeError: Object #&lt;ViewModel&gt; has no method 'bind' ". It looks like KB want's to call bind on the view model instead of the model. <span style="color: green">However, there is a workaround using computed properties.</span>
</fieldset>
</form>
<script src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<script src="https://raw.github.com/kmalakoff/knockback/master/knockback-full-stack.js"></script>
<script>
var bblist = new Backbone.Collection([
{ name: "dev", host: "host1"},
{ name: "qa", host: "host2"},
{ name: "sta", host: "host3"},
]);
var bbcontainer = new Backbone.Model();
var bbselected = new Backbone.Collection();
var bbselected2 = new Backbone.Collection();
var select_multiple_values_vm = {
list: kb.collectionObservable(bblist),
list2: kb.collectionObservable(bblist),
selected: kb.collectionObservable(bbselected),
selected2: kb.collectionObservable(bbselected2)
}
ko.applyBindings(select_multiple_values_vm, $("#select_multiple_values")[0]);
// I want the property bbsingle in the BackBone model bbcontainer to be updated.
// The first short version is not working, please see below for a work around
// var select_one_value_vm = {
// list: kb.collectionObservable(bblist),
// single: kb.observable(bbcontainer, "bbsingle"),
// }
// Work around
var SelectOneValueVM = function(model) {
var self = this;
self.list = kb.collectionObservable(bblist);
// instead of
self.single = kb.observable(model, "bbsingle"),
// we have to use
self.single = ko.observable();
self.single_for_updating_model = ko.computed( function () {
return model.set("bbsingle", self.single() != null && self.single().model());
});
}
var select_one_value_vm = new SelectOneValueVM(bbcontainer);
ko.applyBindings(select_one_value_vm, $("#select_one_value")[0]);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment