I'm having a little trouble with the following. I'm using knockout to edit a list containing nested lists, a little like the Contacts Editor on the knockout website:
http://knockoutjs.com/examples/contactsEditor.html
In my example as follows the "designs" relate to the "Contacts" from the above example and the "designDeliveries" relate to the "Phone Numbers".
So I have a value within each "design" called MaxQuantity and a value within each "designDelivery" called Quantity. Effectively, what I'm trying to achieve is have another value in each "design" called lets say "Remaining" which basically will be the "MaxQuantity" minus the sum of "Quantity" in all "designDeliveries" relating to a particular "design". As I add new "designDeliveries" and populate the "Quantity" field this should of course be deducted from the new "Remaining" value for that particular design
so far I have the code below:
var DesignsModel = function (designs) {
var self = this;
self.designs = ko.observableArray(ko.utils.arrayMap(designs, function (design) {
return { BookingDesignId: design.BookingDesignId,
DesignName: design.DesignName,
MaxQuantity: design.Quantity,
DesignDeliveries: ko.observableArray(design.DesignDeliveries) };
}));
self.addDesignDelivery = function (design) {
design.DesignDeliveries.push({
Quantity: "",
DepotId: ""
});
};
self.removeDesignDelivery = function (designDelivery) {
$.each(self.designs(), function () { this.DesignDeliveries.remove(designDelivery) })
};
self.save = function () {
self.lastSavedJson(JSON.stringify(ko.toJS(self.designs), null, 2));
};
self.lastSavedJson = ko.observable("");
};
ko.applyBindings(new DesignsModel(initialData));
initialData looks like this:
[{"DesignId":"1","DesignName":"Design1","Quantity":50,"DesignDeliveries":[]},{"DesignId":"2","DesignName":"Design2","Quantity":50,"DesignDeliveries":[]},{"DesignId":"3","DesignName":"Design3","Quantity":500,"DesignDeliveries":[]}]
and the html like this:
<div data-bind="foreach: designs">
<div>
<span data-bind="text: DesignName"></span>
<a href="#" data-bind="click: $root.addDesignDelivery">Add</a>
</div>
<div>
<span data-bind="text: MaxQuantity"></span>
</div>
<div>
<span data-bind="text: Remaining"></span>
</div>
<div data-bind="foreach: DesignDeliveries">
<div>
<input data-bind="value: Quantity" />
</div>
<div>
<a href="#" data-bind="click: $root.removeDesignDelivery">
Delete
</a>
</div>
</div>
</div>
I hope this is clear enough. Does anybody have an idea how I would go about achieving this?
Thanks in advance
I would recomend you to split up your complex view model to several small view models. Then to achive desired functionality you just need to add computed that calculates remaining quantity:
And small updates to html to change context of calling add and remove functions:
Here is working fiddle: http://jsfiddle.net/vyshniakov/7JUGE/