As you know Knockout is a javascript library that
allow you to bind html elements to any data model. You can also use
Knockout for Insert, Update, Delete and Retrieve operations. This
article will demonstrate, how to use Knockout with MVC4 for CRUD
(Create, Read, Update, Delete) Operations.
Step 1: Define Model
Product.csIProductRepository.cs
- public class Product
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public string Category { get; set; }
- public decimal Price { get; set; }
- }
ProductRepository.cs
- interface IProductRepository
- {
- IEnumerable<Product> GetAll();
- Product Get(int id);
- Product Add(Product item);
- bool Update(Product item);
- bool Delete(int id);
- }
- public class ProductRepository : IProductRepository
- {
- private List<Product> products = new List<Product>();
- private int _nextId = 1;
- public ProductRepository()
- {
- // Add products for the Demonstration
- Add(new Product { Name = "Computer", Category = "Electronics", Price = 23.54M });
- Add(new Product { Name = "Laptop", Category = "Electronics", Price = 33.75M });
- Add(new Product { Name = "iPhone4", Category = "Phone", Price = 16.99M });
- }
- public IEnumerable<Product> GetAll()
- {
- // TO DO : Code to get the list of all the records in database
- return products;
- }
- public Product Get(int id)
- {
- // TO DO : Code to find a record in database
- return products.Find(p => p.Id == id);
- }
- public Product Add(Product item)
- {
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
- // TO DO : Code to save record into database
- item.Id = _nextId++;
- products.Add(item);
- return item;
- }
- public bool Update(Product item)
- {
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
- // TO DO : Code to update record into database
- int index = products.FindIndex(p => p.Id == item.Id);
- if (index == -1)
- {
- return false;
- }
- products.RemoveAt(index);
- products.Insert(index,item);
- return true;
- }
- public bool Delete(int id)
- {
- // TO DO : Code to remove the records from database
- products.RemoveAll(p => p.Id == id);
- return true;
- }
- }
Step 2: Define Controller
ProductController.cs
- public class ProductController : Controller
- {
- static readonly IProductRepository repository = new ProductRepository();
- public ActionResult Product()
- {
- return View();
- }
- public JsonResult GetAllProducts()
- {
- return Json(repository.GetAll(), JsonRequestBehavior.AllowGet);
- }
- public JsonResult AddProduct(Product item)
- {
- item = repository.Add(item);
- return Json(item, JsonRequestBehavior.AllowGet);
- }
- public JsonResult EditProduct(int id, Product product)
- {
- product.Id = id;
- if (repository.Update(product))
- {
- return Json(repository.GetAll(), JsonRequestBehavior.AllowGet);
- }
- return Json(null);
- }
- public JsonResult DeleteProduct(int id)
- {
- if (repository.Delete(id))
- {
- return Json(new { Status = true }, JsonRequestBehavior.AllowGet);
- }
- return Json(new { Status = false }, JsonRequestBehavior.AllowGet);
- }
- }
Step 3: Define View
Product.cshtml
- @{
- ViewBag.Title = "Products' List";
- }
- @section scripts {
- <style type="text/css">
- body {
- margin: 20px;
- font-family: "Arial", "Helventica", sans-serif;
- }
- label {
- width: 80px;
- display: inline-block;
- }
- button {
- display: inline-block;
- outline: none;
- cursor: pointer;
- text-align: center;
- text-decoration: none;
- padding: .4em 1.1em .4em;
- color: #fef4e9;
- border: solid 1px #006fb9;
- background: #1276bb;
- }
- button:hover {
- text-decoration: none;
- background: #282828;
- border: solid 1px #000;
- }
- table {
- padding-top: 1em;
- }
- thead, tfoot {
- font-weight: 600;
- }
- th, td {
- padding: .1em .5em;
- text-align: left;
- }
- td li, td ul {
- margin: 0;
- padding: 0;
- }
- td li {
- display: inline;
- }
- td li::after {
- content: ',';
- }
- td li:last-child::after {
- content: '';
- }
- </style>
- <script src="~/Scripts/jquery-1.8.2.min.js"></script>
- <script src="~/Scripts/knockout-2.2.0.js"></script>
- <script src="~/Scripts/knockout-2.2.0.debug.js"></script>
- <script type="text/javascript">
- function formatCurrency(value) {
- return "$" + value.toFixed(2);
- }
- function ProductViewModel() {
- //Make the self as 'this' reference
- var self = this;
- //Declare observable which will be bind with UI
- self.Id = ko.observable("");
- self.Name = ko.observable("");
- self.Price = ko.observable("");
- self.Category = ko.observable("");
- var Product = {
- Id: self.Id,
- Name: self.Name,
- Price: self.Price,
- Category: self.Category
- };
- self.Product = ko.observable();
- self.Products = ko.observableArray(); // Contains the list of products
- // Initialize the view-model
- $.ajax({
- url: '@Url.Action("GetAllProducts", "Product")',
- cache: false,
- type: 'GET',
- contentType: 'application/json; charset=utf-8',
- data: {},
- success: function (data) {
- self.Products(data); //Put the response in ObservableArray
- }
- });
- // Calculate Total of Price After Initialization
- self.Total = ko.computed(function () {
- var sum = 0;
- var arr = self.Products();
- for (var i = 0; i < arr.length; i++) {
- sum += arr[i].Price;
- }
- return sum;
- });
- //Add New Item
- self.create = function () {
- if (Product.Name() != "" && Product.Price() != "" && Product.Category() != "") {
- $.ajax({
- url: '@Url.Action("AddProduct", "Product")',
- cache: false,
- type: 'POST',
- contentType: 'application/json; charset=utf-8',
- data: ko.toJSON(Product),
- success: function (data) {
- self.Products.push(data);
- self.Name("");
- self.Price("");
- self.Category("");
- }
- }).fail(
- function (xhr, textStatus, err) {
- alert(err);
- });
- }
- else {
- alert('Please Enter All the Values !!');
- }
- }
- // Delete product details
- self.delete = function (Product) {
- if (confirm('Are you sure to Delete "' + Product.Name + '" product ??')) {
- var id = Product.Id;
- $.ajax({
- url: '@Url.Action("AddProduct", "Product")',
- cache: false,
- type: 'POST',
- contentType: 'application/json; charset=utf-8',
- data: ko.toJSON(id),
- success: function (data) {
- self.Products.remove(Product);
- }
- }).fail(
- function (xhr, textStatus, err) {
- self.status(err);
- });
- }
- }
- // Edit product details
- self.edit = function (Product) {
- self.Product(Product);
- }
- // Update product details
- self.update = function () {
- var Product = self.Product();
- $.ajax({
- url: '@Url.Action("EditProduct", "Product")',
- cache: false,
- type: 'PUT',
- contentType: 'application/json; charset=utf-8',
- data: ko.toJSON(Product),
- success: function (data) {
- self.Products.removeAll();
- self.Products(data); //Put the response in ObservableArray
- self.Product(null);
- alert("Record Updated Successfully");
- }
- })
- .fail(
- function (xhr, textStatus, err) {
- alert(err);
- });
- }
- // Reset product details
- self.reset = function () {
- self.Name("");
- self.Price("");
- self.Category("");
- }
- // Cancel product details
- self.cancel = function () {
- self.Product(null);
- }
- }
- var viewModel = new ProductViewModel();
- ko.applyBindings(viewModel);
- </script>
- }
- <div id="body">
- <h2>Knockout CRUD Operations with MVC4</h2>
- <h3>List of Products</h3>
- <table id="products1" data-bind="visible: Products().length > 0">
- <thead>
- <tr>
- <th>ID</th>
- <th>Name</th>
- <th>Category</th>
- <th>Price</th>
- <th>Actions</th>
- </tr>
- </thead>
- <tbody data-bind="foreach: Products">
- <tr>
- <td data-bind="text: Id"></td>
- <td data-bind="text: Name"></td>
- <td data-bind="text: Category"></td>
- <td data-bind="text: formatCurrency(Price)"></td>
- <td>
- <button data-bind="click: $root.edit">Edit</button>
- <button data-bind="click: $root.delete">Delete</button>
- </td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td></td>
- <td></td>
- <td>Total :</td>
- <td data-bind="text: formatCurrency($root.Total())"></td>
- <td></td>
- </tr>
- </tfoot>
- </table>
- <br />
- <div style="border-top: solid 2px #282828; width: 430px; height: 10px"> </div>
- <div data-bind="if: Product">
- <div>
- <h2>Update Product</h2>
- </div>
- <div>
- <label for="productId" data-bind="visible: false">ID</label>
- <label data-bind="text: Product().Id, visible: false"></label>
- </div>
- <div>
- <label for="name">Name</label>
- <input data-bind="value: Product().Name" type="text" title="Name" />
- </div>
- <div>
- <label for="category">Category</label>
- <input data-bind="value: Product().Category" type="text" title="Category" />
- </div>
- <div>
- <label for="price">Price</label>
- <input data-bind="value: Product().Price" type="text" title="Price" />
- </div>
- <br />
- <div>
- <button data-bind="click: $root.update">Update</button>
- <button data-bind="click: $root.cancel">Cancel</button>
- </div>
- </div>
- <div data-bind="ifnot: Product()">
- <div>
- <h2>Add New Product</h2>
- </div>
- <div>
- <label for="name">Name</label>
- <input data-bind="value: $root.Name" type="text" title="Name" />
- </div>
- <div>
- <label for="category">Category</label>
- <input data-bind="value: $root.Category" type="text" title="Category" />
- </div>
- <div>
- <label for="price">Price</label>
- <input data-bind="value: $root.Price" type="text" title="Price" />
- </div>
- <br />
- <div>
- <button data-bind="click: $root.create">Save</button>
- <button data-bind="click: $root.reset">Reset</button>
- </div>
- </div>
- </div>
Leave your comment
Post a Comment