I have daily data for multiple employees and depending on the start time and end time that could mean a lot of data.
So with the mapping plugin i mapped them into one big list, but i will need them grouped by employee into smaller lists so i can make a tables per employee (like smaller view models) that has filtering and sorting for that subset of data.
Here is a basic example i created with static data.
$(function () {
var data = {
Employees: [{
Id: 1,
Name: "Employee1",
Day: new Date(),
Price: 12.54
}, {
Id: 2,
Name: "Employee2",
Day: new Date(),
Price: 112.54
}, {
Id: 1,
Name: "Employee1",
Day: new Date(),
Price: 12.54
}, {
Id: 3,
Name: "Employee3",
Day: new Date(),
Price: 12.54
}]
};
// simulate the model to json conversion. from now on i work with the json
var jsonModel = JSON.stringify(data);
function employeeModel(data) {
var employeeMapping = {
'copy': ["Id", "Name", "Day", "Price"]
};
ko.mapping.fromJS(data, employeeMapping, this);
}
function employeeViewModel(data) {
var self = this;
var employeesMapping = {
'Employees': {
create: function (options) {
return new employeeModel(options.data);
}
}
};
ko.mapping.fromJSON(data, employeesMapping, self);
}
var productsModel = new employeeViewModel(jsonModel);
ko.applyBindings(productsModel);
});
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
tr:nth-child(even) {
background-color: white;
}
tr:nth-child(odd) {
background-color: #C1C0C0;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<table>
<tbody data-bind="foreach: Employees">
<tr>
<td><span data-bind="text:Id"></span>
</td>
<td><span data-bind="text:Name"></span>
</td>
<td><span data-bind="text:Day"></span>
</td>
<td><span data-bind="text:Price"></span>
</td>
</tr>
</tbody>
</table>
One possibility would be to use a computed value to group your data.
self.EmployeeGroups = ko.pureComputed(function () {
var employees = self.Employees(),
index = {},
group = [];
ko.utils.arrayForEach(employees, function(empl) {
var id = ko.unwrap(empl.Id);
if ( !index.hasOwnProperty(id) ) {
index[id] = {
grouping: {
Id: empl.Id,
Name: empl.Name
},
items: []
};
group.push(index[id]);
}
index[id].items.push(empl);
});
return group;
});
would turn your data from a flat array to this:
[{ grouping: { Id: /* ... */, Name: /* ... */ } items: [/* references to all employee objects in this group */] }, { /* same */ }]
Expand the code snippet below to see it at work.
$(function () {
var data = {
Employees: [{
Id: 1,
Name: "Employee1",
Day: new Date(),
Price: 12.54
}, {
Id: 2,
Name: "Employee2",
Day: new Date(),
Price: 112.54
}, {
Id: 1,
Name: "Employee1",
Day: new Date(),
Price: 12.54
}, {
Id: 3,
Name: "Employee3",
Day: new Date(),
Price: 12.54
}]
};
var jsonModel = JSON.stringify(data);
function employeeModel(data) {
var employeeMapping = {
'copy': ["Id", "Name", "Day", "Price"]
};
ko.mapping.fromJS(data, employeeMapping, this);
}
function employeeViewModel(data) {
var self = this;
self.Employees = ko.observableArray();
self.EmployeeGroups = ko.pureComputed(function () {
var employees = self.Employees(),
index = {},
group = [];
ko.utils.arrayForEach(employees, function(empl) {
var id = ko.unwrap(empl.Id);
if ( !index.hasOwnProperty(id) ) {
index[id] = {
grouping: {
Id: empl.Id,
Name: empl.Name
},
items: []
};
group.push(index[id]);
}
index[id].items.push(empl);
});
return group;
});
// init
var employeesMapping = {
'Employees': {
create: function (options) {
return new employeeModel(options.data);
}
}
};
ko.mapping.fromJSON(data, employeesMapping, self);
}
var productsModel = new employeeViewModel(jsonModel);
ko.applyBindings(productsModel);
});
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
tr:nth-child(even) {
background-color: #efefef;
}
tr:nth-child(odd) {
background-color: #CCCCCC;
}
tr.subhead {
background-color: #D6E3FF;
font-weight: bold;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<table>
<!-- ko foreach: EmployeeGroups -->
<tbody>
<!-- ko with: grouping -->
<tr class="subhead">
<td colspan="2">
<span data-bind="text: Id"></span>
<span data-bind="text: Name"></span>
</td>
</tr>
<!-- /ko -->
<!-- ko foreach: items -->
<tr>
<td><span data-bind="text: Day"></span></td>
<td><span data-bind="text: Price"></span></td>
</tr>
<!-- /ko -->
</tbody>
<!-- /ko -->
</table>
<pre data-bind="text: ko.toJSON($root, null, 2)" style="font-size: smallest;"></pre>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With