Reputation: 2167
I'm trying to use the value of a select list for a calculation but I can't get it to retrieve the number when it's selected.
When I return the selected quantity it returns some javascript instead of the number
selectedQuantity is the value I'm trying to retrieve.
<table border="1">
<thead><tr>
<th>ID</th><th>Inventory</th><th>Quantity</th><th>Price</th><th>Total</th><th></th>
</tr></thead>
<tbody data-bind="foreach: itemNumbers">
<tr>
<td data-bind="text: ID"></td>
<td data-bind="text: inventory"></td>
<td><select data-bind="quantityDropdown: inventory, value: selectedQuantity"></select></td>
<td data-bind="text: formattedPrice"></td>
<td data-bind="text: itemTotal"></td>
<td><a href="#" data-bind="click: $root.removeItem">Remove</a></td>
</tr>
</tbody>
</table>
Here's the javascript
function ItemEntry(ID, inventory, price) {
var self = this;
self.ID = ID;
self.inventory = inventory;
self.price = price;
self.selectedQuantity = ko.observable(); //returned value (trying to get it at least!)
self.itemTotal = ko.computed(function() {
var price = self.price;
var quantity = self.selectedQuantity;
return quantity; //just returning quantity for now to verify correct value is selected
});
self.formattedPrice = ko.computed(function() {
var price = self.price;
return price ? "$" + price.toFixed(2) : "None";
});
}
function EntryViewModel(newItem) {
var self = this;
self.newItem = newItem;
//start the array with some items
self.itemNumbers = ko.observableArray([
new ItemEntry("1", 20, 22.50) //ID, inventory, price
]);
// Computed data
self.totalCost = ko.computed(function() {
var total = 0;
for (var i = 0; i < self.itemNumbers().length; i++) {
total += Number(self.itemNumbers()[i].price);
}
return total;
});
self.removeItem = function(item) { self.itemNumbers.remove(item) }
}
//populate the select list with values up to the number in inventory (ex, if inventory is 3, it will fill with 0-7)
ko.bindingHandlers.quantityDropdown = {
update: function(quantityDropdown, inventory, EntryViewModel) {
var quantity = ko.utils.unwrapObservable(inventory());
for(var i = 0; i <= inventory(); i++){
$(quantityDropdown).append('<option value="' + i + '">' + i + '</option>');
}
}
};
ko.applyBindings(new EntryViewModel());
Upvotes: 0
Views: 346
Reputation: 8510
Looks like self.selectedQuantity is defined as (set to) a ko.observable. Observables are functions, so in order to retrieve the value, you should call it like a function:
self.itemTotal = ko.computed(function() {
var price = self.price;
//notice the parentheses here to execute the selectedQuantity observable and extract the variable.
var quantity = self.selectedQuantity();
return quantity; //just returning quantity for now to verify correct value is selected
});
Also, it's good to understand how ko.computed functions work. A ko.computed value will automatically update to reflect changes to any ko.observables that are referenced therein. However, the dependency tracking mechanism uses the retrieval of observable values to detect that an observable is being used and should be tracked.
In other words, if you want a ko.computed to update whenever a value changes, you need to reference that value by executing the observable variable as in the code sample above.
The KnockOut documentation says it a lot better than I can: http://knockoutjs.com/documentation/observables.html http://knockoutjs.com/documentation/computedObservables.html.
Upvotes: 2