Introduction
This article explains how to create a Shopping Cart editor for your project using Knockoutjs in an ASP.NET Apllication.
In this article you will see how multiple Observables can be chained together in an application.
Here we will use two two js files, one is the Knockoutjs File and the other one is the jQuerymin.js file, both of these are necessary to make your application run.
Now let's see the procedure required to create such an application.
Step 1
First of all add Knockoutjs and Jquerymin.js to your application, you can either download them from the internet or can download my Zip File that is provided at the start of this article and then fetch them through it.
You need to add them in the head section of your application.
Step 2
After this you need to work on the View Model of your application and add this code to your application.
<script type="text/javascript">
$(function () {
function Option(name) {
var self = this;
self.name = name;
}
function Product(name, price, quantity, options) {
var self = this;
self.name = ko.observable(name);
self.price = price;
self.quantity = ko.observable(quantity);
self.options = ko.observableArray(ko.utils.arrayMap(options, function (option) {
return new Option(option.name, option.quantity);
}));
self.addOption = function (name, quantity) {
self.options.push(new Option(name, quantity));
};
}
function Category(name, products) {
var self = this;
self.name = name;
self.products = ko.observableArray(ko.utils.arrayMap(products, function (product) {
return new Product(product.name, product.price, product.quantity, product.options);
}));
}
function Menu(categories) {
var self = this;
self.categories = ko.observableArray(ko.utils.arrayMap(categories, function (category) {
return new Category(category.name, category.products);
}));
self.addCategory = function (name) {
self.categories.push(new Category(name));
};
}
function CartLine() {
var self = this;
self.category = ko.observable();
self.product = ko.observable();
self.quantity = ko.observable(1);
self.subtotal = ko.computed(function () {
return self.product() ? self.product().price * parseInt("0" + self.quantity(), 10) : 0;
});
self.category.subscribe(function () {
self.product(undefined);
});
}
function ViewModel(menus) {
var self = this;
self.lines = ko.observableArray([new CartLine()]);
self.menus = ko.utils.arrayMap(menus, function (menu) {
return new Menu(menu.categories);
});
self.addLine = function () {
self.lines.push(new CartLine())
};
self.removeLine = function (line) {
self.lines.remove(line)
};
self.grandTotal = ko.computed(function () {
var total = 0;
$.each(self.lines(), function () {
total += this.subtotal()
})
return total;
});
}
ko.applyBindings(new ViewModel(data));
});
Here in the first function named Option I provided the options related to each product type, then in the second function I passed the name of the product, it's quantity, it's price and a function named addOption that will help to add a new Product to the Cart.
After that I created another function named Category to show the Product and it's attributes according to it's selected name. In the next function a menu of Categories is created, so until now we had passed categories that have some products and those products have some attributes that are related to the name of these products.
In the next functions I had provided the facilities to remove or add a Product. Also a grand total of your selections will be shown to you by the grandTotal function that does the calculation.
At the end, binding is applied to the function ViewModel so that it can be bound to the View of our application.
Our ViewModel is now completed. We will now move towards the View Part of our application.
Step 3
Write this code in your View part:
<form id="form1" runat="server">
<div>
<!-- ko foreach:lines -->
<!-- ko foreach:$parent.menus -->
<select data-bind='options: categories, optionsText: "name", value: $parent.category' ></select>
<!-- /ko -->
<!-- ko with: category -->
<select data-bind='options: products, optionsText: "name", value: $parent.product'></select>
<!-- /ko -->
<!-- ko with: product -->
<span data-bind="text: price"></span>
<select data-bind='options: options, optionsText: "name"'></select>
<input data-bind="value: $parent.quantity, valueUpdate: 'keyup'" />
<!-- /ko -->
<span data-bind="text: subtotal"></span>
<a href='#' data-bind='click: $parent.removeLine'>Remove</a><br/>
<!-- /ko -->
</div>
Total value: <span data-bind='text: grandTotal()'> </span>
<button data-bind="click: addLine">Add Product</button>
</form>
Here first Categories are bound to the Drop Down list, then after the categories 'Products' are bound that will be shown according to the category selected.
Through the name of the product all the attributes are filled in the required Drop Down List and in the labels.
Subtotal is Shawn at the end of each row that will show the total of that specific row and at the end of the Grid a grand total is shown that will show the total of all the rows.
Output
Now you can debug your application. On debugging the application you will get output like this:
Now you can select the different car by clicking on the Drop Down list.
Also I can add a new product by clicking on "Add New product". Here I chose a bike as the new product. Also you will see that at the end of each row a total is shown and at the end of the grid a total of all the rows is shown.