For Part I, click here>>
Introduction
In online marketing, a shopping cart is a piece of e-commerce software running on a web server, that allows visitors to an Internet shop to select items for eventual purchase, analogous to the American English term "shopping cart." In British English, it is generally known as a shopping basket, almost exclusively shortened on websites to "basket".
The software allows online shopping customers to accumulate a list of items for purchase, described metaphorically as “placing items in the shopping cart” or “add to cart.” Upon checkout, the software typically calculates a total for the order, including shipping and handling (i.e., postage and packing) charges and the associated taxes, as applicable.
This article describes the implementation of a shopping cart using MVC and jQuery.
Prerequisites
- General knowledge of web applications.
- HTML, CSS, Bootstrap, JavaScript.
- Database Configuration and Connection.
Agenda
- Displaying product details from the database.
- Showing particular product details from the database.
- Implementing Zoom effect for products.
- Adding selected items to the shopping cart.
- Showing all recently added cart items.
- Removing items from a cart.
In our previous section, we have learned how to start creating the shopping cart application. There we learned about creating a project with different layers, basic flow, creating basic Layouts, etc. You can find the link here.
In this section, we will learn to add a full description to each product from the database. Here is the code to show the full description of the product in the View.
@model IEnumerable<DapperProject.Models.ProductDetails>
@{
ViewBag.Title = "EachProductDetails";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<h3>Product Specification</h3>
<div ng-controller="MainCtrl">
@foreach(var x in Model) {
<div class="panel panel-default">
<div class="panel-heading">@x.MobileName</div>
<div class="panel-body">
<div class="col-sm-3 col-md-6" style="color:blue">
<img src="~/Images/@x.Url" width="400" height="400"/>
</div>
<div class="col-sm-9 col-md-6">
<h3><span id="mobilename" style="color:black"><b>MobileName:</b></span></h3>
<h6><span id="mobilename" style="color:black">@x.MobileName</span></h6>
<h3><span id="mobilename" style="color:black"><b>Features:</b></span></h3>
<h6><span id="mobilename" style="color:black">@x.Features</span></h6>
<h3><span id="mobilename" style="color:black"><b>Color:</b></span></h3>
<h4><span id="mobilename" style="color:black">@x.color</span></h4>
<h3><span id="mobilename" style="color:black"><b>Sim Type</b></span></h3>
<h4><span id="mobilename" style="color:black">@x.SimType</span></h4>
<h3><span id="mobilename" style="color:black"><b>Model:</b></span></h3>
<h6><span id="mobilename" style="color:black">@x.model</span></h6>
<h3><span id="mobilename" style="color:black"><b>Price:</b></span></h3>
<h6><span id="mobilename" style="color:black">@x.Price</span></h6>
</div>
</div>
<div>
<a id="btn_add" href="@Url.Action("Add", "AddToCart", x)" class="btn btn-info btn-lg" style="margin-left:60px"><span class="glyphicon glyphicon-shopping-cart"></span> Add To Cart</a>
<a id="btn_add" href="@Url.Action("Index", "Home")" class="btn btn-info btn-lg" style="margin-left:60px"><span class="glyphicon glyphicon-eye-open"></span> Continue shopping</a><br/>
</div>
</div>
}
</div>
So, here is our ProductDetails model.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DapperProject.Models {
public class ProductDetails {
public int? slno {
get;
set;
}
public string MobileName {
get;
set;
}
public double Price {
get;
set;
}
public string Url {
get;
set;
}
public string Features {
get;
set;
}
public string model {
get;
set;
}
public string color {
get;
set;
}
public string SimType {
get;
set;
}
}
}
Here is the model for mobile.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DapperProject.Models
{
public class Mobiles
{
public int? slno { get; set; }
public string MobileName { get; set; }
public double Price { get; set; }
public string Url { get; set; }
public string ZoomUrl { get; set; }
public string Description { get; set; }
}
}
This is the script of the table.
USE [Demo]
GO
/****** Object: Table [dbo].[MobileDetails] Script Date: 03-12-2016 10:33:24 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MobileDetails](
[SLNO] [int] IDENTITY(1, 1) NOT NULL,
[MobileId] [int] NULL,
NULL,
NULL,
NULL,
NULL,
CONSTRAINT [PK_MobileDetails] PRIMARY KEY CLUSTERED
(
[SLNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[MobileDetails] WITH CHECK ADD CONSTRAINT [FK_MobileDetails_Mobiles] FOREIGN KEY([MobileId])
REFERENCES [dbo].[Mobiles] ([slNo])
GO
ALTER TABLE [dbo].[MobileDetails] CHECK CONSTRAINT [FK_MobileDetails_Mobiles]
GO
And, this is my table data for showing in the details page.
Now, given below is the Controller logic to get the data.
public ActionResult EachProductDetails(Mobiles m)
{
string mycmd = "select m.slNo,m.MobileName,m.price,m.url,md.Features,md.model,md.color,md.SimType from mobiles m inner join MobileDetails md on m.slNo=md.MobileId where m.slNo="+m.slno+"";
dt = new DataTable();
dt = _mdal.SelactAll(mycmd);
List<ProductDetails> list = new List<ProductDetails>();
for (int i = 0; i < dt.Rows.Count; i++)
{
ProductDetails mob = new ProductDetails();
mob.slno = Convert.ToInt32(dt.Rows[i]["slNo"]);
mob.MobileName = dt.Rows[i]["MobileName"].ToString();
mob.Price = Convert.ToDouble(dt.Rows[i]["Price"]);
mob.Url = dt.Rows[i]["Url"].ToString();
mob.Features= dt.Rows[i]["Features"].ToString();
mob.color = dt.Rows[i]["color"].ToString();
mob.SimType = dt.Rows[i]["SimType"].ToString();
list.Add(mob);
}
return View(list);
}
Here is our MobileDAL.cs class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
namespace MobileDAL.cs {
public class MobiledetailDAL {
SqlCommand cmd;
SqlDataAdapter da;
DataSet ds;
public static SqlConnection connect() {
string connection = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;
SqlConnection con = new SqlConnection(connection);
if (con.State == ConnectionState.Open) {
con.Close();
} else {
con.Open();
}
return con;
}
public bool DMLOpperation(string query) {
cmd = new SqlCommand(query, MobiledetailDAL.connect());
int x = cmd.ExecuteNonQuery();
if (x == 1) {
return true;
} else {
return false;
}
}
public DataTable SelactAll(string query) {
da = new SqlDataAdapter(query, MobiledetailDAL.connect());
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
}
Now, just run the project. It will show the following output.
Now, we will check the zoom functionality of the selected image in the detail View. For working with the zoom functionality, we need to use some jQuery plugins. In this case, I have tried AngularJS for zoom functionality.
So, just change the image div as follows.
<div class="col-sm-3 col-md-6" style="color: blue">
<a href="http://localhost:56829/ZoomImages/@x.Url" class="cloud-zoom" rel="adjustX: 10, adjustY:-4">
<img src="~/Images/@x.Url" width="400" height="400"/>
</a>
</div>
Use the following scripts in the head section.
<link rel="stylesheet" href="style.css">
<link href="http://www.professorcloud.com/styles/cloud-zoom.css" rel="stylesheet" type="text/css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js"></script>
<script type="text/JavaScript" src="http://www.professorcloud.com/js/cloud-zoom.1.0.2.js"></script>
<script src="~/Scripts/app.js"></script>
To learn more about this Zoom functionality, please visit the site here.
Now, save the project and run it. You will find the following zoom effect.
Let's start to work with the product in the shopping cart. Here is my design for the Product Specification page.
<div>
<a id="btn_add" href="@Url.Action("Add", "AddToCart", x)" class="btn btn-info btn-lg" style="margin-left:60px">
<span class="glyphicon glyphicon-shopping-cart"></span> Add To Cart
</a>
<a id="btn_add" href="@Url.Action("Index", "Home")" class="btn btn-info btn-lg" style="margin-left:60px">
<span class="glyphicon glyphicon-eye-open"></span> Continue shopping
</a>
<br />
<br />
</div>
For adding items to the cart, we have created a Controller as AddToCart, where we have an action method as Add. On the button click of Addtocart, we are sending all the information of that particular Controller to the action method. Please check the full View HTML code which is shown above. This is only one portion of the View.
Finally, we are sending all the details of the clicked product to the Controller. Here is my Controller Add method.
public class AddToCartController : Controller
{
DataTable dt;
MobiledetailDAL _mdal = new MobiledetailDAL();
// GET: AddToCart
public ActionResult Add(Mobiles mo)
{
if (Session["cart"] == null)
{
List<Mobiles> li = new List<Mobiles>();
li.Add(mo);
Session["cart"] = li;
ViewBag.cart = li.Count();
Session["count"] = 1;
}
else
{
List<Mobiles> li = (List<Mobiles>)Session["cart"];
li.Add(mo);
Session["cart"] = li;
ViewBag.cart = li.Count();
Session["count"] = Convert.ToInt32(Session["count"]) + 1;
}
return RedirectToAction("Index", "Home");
}
}
So, to add the product to the cart, we are basically following 4 important steps.
- Creating a session "Session["cart"]" which is null for the first time, for all users.
- If the cart is null, create a list of mobile types, save the mobile details coming through the parameter of a view, and assigning them to the session.
- Creating another session Session["count"] for counting the product added to the cart.
- Similarly, if the "Session["cart"] is not null, then adding one more list item to the session and increasing the counter as per the number of products added.
So, after adding the product to the cart, I am redirecting the user to the shopping page.
Here is the code which will update the product count in the layout.
<ul class="nav navbar-nav">
<li class="active">
<a href="@Url.Action("Myorder", "AddToCart")" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-shopping-cart" style="color:green"></span>
Cart <span class="badge">@Session["count"]</span>
</a>
</li>
</ul>
Now it will appear like this.
To check all the items in the cart, we have the following Myorder method.
public ActionResult Myorder()
{
return View((List<Mobiles>)Session["cart"]);
}
Here, we just return the data of the session to the View. The code of the view is given below.
@model IEnumerable<DapperProject.Models.Mobiles>
@{
ViewBag.Title = "Myorder";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
int sum = 0;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div id="dvContents">
<table class="table table-hover" width="100%">
<thead>
<img src="~/Templates/Header.jpg" width="100%" height="70px"/>
<tr>
<th>SlNO</th>
<th>Mobile Name</th>
<th>Image</th>
<th>Price</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
@foreach(var x in Model)
{
<tr>
<td>@x.slno</td>
<td>@x.MobileName</td>
<td><img id="img1" src="~/Images/@x.Url" height="100" width="75"/></td>
<td>₹@x.Price</td>
<td>
<button id="btn_delete" class="label label-primary" data-slno="@x.slno" onclick="location.href='@Url.Action("Remove", "AddToCart", x)'">
<img src="~/Icons/delete.png" height="30" width="30"/>
</button>
</td>
</tr>
}
</tbody>
@foreach(var x in Model)
{
sum = Convert.ToInt32(x.Price) + sum;
}
<tfoot>
<tr>
<td></td>
<td></td>
<td><b>Total</b></td>
<td>₹@sum</td>
</tr>
</tfoot>
</table>
<div id="footer">
<img src="~/Templates/Footer.jpg" width="100%" height="60px"/>
</div>
<button type="button" id="btnPrint" class="btn btn-primary">Print</button>
<button type="button" class="btn btn-success">Continue Shopping</button>
<button type="button" class="btn btn-warning">Place Order</button>
</div>
Now, if we want to remove any item from the cart, here is the code.
<td>
<button id="btn_delete" class="label label-primary" data-slno="@x.slno" onclick="location.href='@Url.Action("Remove","AddToCart",x)'">
<img src="~/Icons/delete.png" height="30" width="30" />
</button>
</td>
Method for removing items from the cart.
public ActionResult Remove(Mobiles mob)
{
List<Mobiles> li = (List<Mobiles>)Session["cart"];
li.RemoveAll(x => x.slno == mob.slno);
Session["cart"] = li;
Session["count"] = Convert.ToInt32(Session["count"]) - 1;
return RedirectToAction("Myorder", "AddToCart");
}
If you want to print the order sheet, here is the JavaScript code that will print the invoice.
<style type="text/css">
.label {
font-size: 10pt;
font-weight: bold;
font-family: Arial;
}
.contents {
border: 1px dotted black;
padding: 5px;
width: 300px;
}
.name {
color: #18B5F0;
}
.left {
float: left;
width: 50px;
height: 50px;
}
.right {
margin-left: 60px;
line-height: 50px;
}
.clear {
clear: both;
}
#footer {
position: fixed;
bottom: 0px;
height: 3px;
background-color: #666;
color: #eee;
width: 100%;
}
</style>
<script type="text/javascript">
$(function() {
$("#btnPrint").click(function() {
var contents = $("#dvContents").html();
var frame1 = $('<iframe />');
frame1[0].name = "frame1";
frame1.css({
"position": "absolute",
"top": "-1000000px"
});
$("body").append(frame1);
var frameDoc = frame1[0].contentWindow ? frame1[0].contentWindow : frame1[0].contentDocument.document ? frame1[0].contentDocument.document : frame1[0].contentDocument;
frameDoc.document.open();
// Create a new HTML document.
frameDoc.document.write('<html><head><title>DIV Contents</title>');
frameDoc.document.write('</head><body>');
// Append the external CSS file.
frameDoc.document.write('<link href="style.css" rel="stylesheet" type="text/css" />');
// Append the DIV contents.
frameDoc.document.write(contents);
frameDoc.document.write('</body></html>');
frameDoc.document.close();
setTimeout(function() {
window.frames["frame1"].focus();
window.frames["frame1"].print();
frame1.remove();
}, 500);
});
});
</script>
This will print the complete report structure inside the "dvcontents" div.
So, in this way, we can create a simple shopping cart application. If you have any doubts regarding this, please let me know.
Download Source Code