JSFiddle - React, Tailwind, and code Playground
by lamarant
HTML
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
<script src="//cdn.iamwebdeveloper.in/js/knockout.mapping/2.3.2/knockout.mapping.js"></script>
Solution #1 to: <a href="http://stackoverflow.com/questions/16137887" target="_blank">http://stackoverflow.com/questions/16137887</a>
<hr />
<h1>All Foo's</h1>
<div data-bind="template: { name: 'MyTemplate', data: {arr: Foo} }"></div>
<hr />
<h1>All Poo's</h1>
<div data-bind="template: { name: 'MyTemplate', data: {arr: Poo} }"></div>
<hr />
<script type="text/html" id="MyTemplate">
<div class="addnew">
Add Member »
<select data-bind="options: $data.arr.listMembers, optionsText: 'ID', optionsValue: 'ID'"></select>
<button data-bind="click: function() { $root.addMember($data.arr, $element); }">+</button>
</div>
<div data-bind="{ foreach: $data.arr }">
<div>
Member #<span data-bind="text: ID"></span> »
<input type="text" data-bind="value: Title, valueUpdate:'afterkeydown'" />
<button data-bind="click: function() { $root.removeMember($parent.arr, $data) }">x</button>
</div>
</div>
</script>
<h1 class="Debug">Debug</h1>
<strong>viewModel._AllObjects</strong>
<pre data-bind="text: ko.toJSON($data._AllObjects, null, 2)"></pre>
<strong>model.Foo</strong>
<pre data-bind="text: ko.toJSON($data.Foo, null, 2)"></pre>
<strong>model.Poo</strong>
<pre data-bind="text: ko.toJSON($data.Poo, null, 2)"></pre>
CSS
body{color: #444; font-family: Arial; font-size: 14px;}
input{width: 50%; padding: 5px;}
button{cursor: pointer;}
select{padding: 5px;}
h1{font-size: 16px;}
h1.Debug{font-size: 14px; background: red; color: #fff;padding: 5px;}
pre, strong{font-size: 12px;}
.addnew{background: #eee;padding: 5px;margin-bottom: 10px;}
JavaScript
var Members = ko.mapping.fromJS([
{ ID: 100, Title: 'This is item number 100' },
{ ID: 776, Title: 'This is item number 776' },
{ ID: 456, Title: 'This is item number 456' },
{ ID: 999, Title: 'This is item number 999' }
]);
var model = ko.mapping.fromJS({
AllMembers : Members, //make Members accessible via $root in data-bind
Foo : [
Members()[1]
],
Poo : [
Members()[1],
Members()[2]
],
addMember: function(arrCtx, elem) {
var selID = $(elem).parent().find('select').val();
if (selID) {
$.each(model.AllMembers(), function (k, item) {
if (item.ID() == selID) {
// add the item to ArrCtx by reference
arrCtx.push(item);
}
});
}
},
removeMember: function(arrCtx, item) {
arrCtx.remove(item);
}
});
arrayInverseIntersect = function(a, b)
{
return $.grep(a, function(i)
{
return $.inArray(i, b) === -1;
});
};
//methods used for building select boxes
model.Foo.listMembers = ko.computed(function(){
return arrayInverseIntersect(model.AllMembers(), model.Foo());
});
model.Poo.listMembers = ko.computed(function(){
return arrayInverseIntersect(model.AllMembers(), model.Poo());
});
ko.applyBindings(model);