KnockoutJS ObservableArray data grouping
https://stackoverflow.com/questions/47681651/how-to-sort-in-a-group-with-knockout-js/47682052#47682052
by jlspake
HTML
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<div class="displayTable" data-bind="foreach: choices">
<div class="displayRow">
<div class="displayCell" data-bind="text: $data"></div>
<div class="displayCell">Age</div>
<div class="displayCell">Phone</div>
</div>
<div class="displayRow" data-bind="foreach: $root.people.index.type()[$data]">
<div class="displayTable">
<div class="displayRow">
<div class="displayCell" data-bind="text: name"></div>
<div class="displayCell" data-bind="text: age"></div>
</div>
</div>
</div>
</div>
CSS
.displayTable {
display: table;
border: 1px solid black;
border-collapse: collapse;
width: 100px;
}
.displayRow {
display: table-row;
}
.displayCell {
display: table-cell;
border: 1px solid black;
}
.displayCell.age,
.displayCell.section {
width: 50px;
}
JavaScript
ko.observableArray.fn.distinct = function(prop, sort) {
var target = this;
target.index = {};
target.index[prop] = ko.observable({});
ko.computed(function() {
//rebuild index
var propIndex = {};
ko.utils.arrayForEach(target(), function(item) {
var key = ko.utils.unwrapObservable(item[prop]);
propIndex[key] = propIndex[key] || [];
propIndex[key].push(item);
});
// Sort within groups
for(var i in propIndex){
if(propIndex.hasOwnProperty(i)){
propIndex[i].sort(function(l, r) {
return ko.unwrap(l[sort]) == ko.unwrap(r[sort]) ? 0 : (ko.unwrap(l[sort]) < ko.unwrap(r[sort]) ? -1 : 1);
});
}
}
target.index[prop](propIndex);
});
return target;
};
var Person = function(name, type, age) {
this.name = ko.observable(name);
this.type = ko.observable(type);
this.age = ko.observable(age);
}
var ViewModel = function() {
var self = this;
this.choices = ["Friend", "Enemy", "Other"];
this.people = ko.observableArray([
new Person("Jimmy", "Friend", 35),
new Person("George", "Friend", 40),
new Person("Mike", "Friend", 30),
new Person("Zippy", "Enemy", 20)
]).distinct('type', 'age');
this.addPerson = function() {
self.people.push(new Person("new", "Other", 0));
};
this.removePerson = function(person) {
self.people.remove(person);
};
};
ko.applyBindings(new ViewModel());