Add, Edit, Delete Data Using Knockout in MVC 4

In my last article we saw how to display data using Knockout using MVC 4 here. Now in this article you will see how to add a new record, delete and edit data using Knockout in MVC 4.
 
Read my first article about how to start and how to display data. In this article we will learn only how to add a new record, delete a record, and edit a record.
 
Do this in my model class.
  1. public class Employee  
  2. {  
  3.     public int EmployeeID { get; set; }  
  4.     public string LastName { get; set; }  
  5.     public string FirstName { get; set; }  
  6.     public string City { get; set; }  
  7.     public string Region { get; set; }  
  8.     public string PostalCode { get; set; }  
  9.     public string Country { get; set; }  
This is the repository class; as you can see this class is inherited by the interface so the interface code is below this.
  1. public class EmployeeRepository: KnockoutSample.Models.IEmployeeRepository {  
  2.     private List < Employee > employeeList = new List < Employee > ();  
  3.     private int _nextId = 1;  
  4.   
  5.     public EmployeeRepository() {  
  6.         // Add employees records to display  
  7.         Add(new Employee { EmployeeID = 1, FirstName = "Nancy", LastName = "Davolio", City = "Seattle", Region = "WA", PostalCode = "98122", Country = "USA" });  
  8.         Add(new Employee { EmployeeID = 2, FirstName = "Andrew", LastName = "Fuller", City = "Tacoma", Region = "WA", PostalCode = "98401", Country = "USA" });  
  9.         Add(new Employee { EmployeeID = 3, FirstName = "Janet", LastName = "Leverling", City = "Kirkland", Region = "WA", PostalCode = "98033", Country = "USA" });  
  10.         Add(new Employee { EmployeeID = 4, FirstName = "Margaret", LastName = "Peacock", City = "Redmond", Region = "WA", PostalCode = "98052", Country = "USA" });  
  11.         Add(new Employee { EmployeeID = 5, FirstName = "Steven", LastName = "Buchanan", City = "London", Region = "WA", PostalCode = "SW1 8JR", Country = "UK" });  
  12.         Add(new Employee { EmployeeID = 6, FirstName = "Michael", LastName = "Suyama", City = "London", Region = "WA", PostalCode = "EC2 7JR", Country = "UK" });  
  13.         Add(new Employee { EmployeeID = 7, FirstName = "Robert", LastName = "King", City = "London", Region = "WA", PostalCode = "RG1 9SP", Country = "UK" });  
  14.         Add(new Employee { EmployeeID = 8, FirstName = "Laura", LastName = "Callahan", City = "Seattle", Region = "WA", PostalCode = "98105", Country = "USA" });  
  15.         Add(new Employee { EmployeeID = 9, FirstName = "Anne", LastName = "Dodsworth", City = "London", Region = "WA", PostalCode = "WG2 7LT", Country = "UK" });  
  16.   
  17.     }  
  18.   
  19.     public IEnumerable < Employee > GetAll() {  
  20.         // Code to get the list of all the records in database  
  21.         return employeeList;  
  22.     }  
  23.   
  24.     public Employee Get(int id) {  
  25.         // Code to find a record in database  
  26.         return employeeList.Find(p => p.EmployeeID == id);  
  27.     }  
  28.   
  29.     public Employee Add(Employee item) {  
  30.         if (item == null) {  
  31.             throw new ArgumentNullException("item");  
  32.         }  
  33.   
  34.         // Code to save record into database  
  35.         item.EmployeeID = _nextId++;  
  36.         employeeList.Add(item);  
  37.   
  38.         return item;  
  39.     }  
  40.   
  41.     public bool Update(Employee item) {  
  42.         if (item == null) {  
  43.             throw new ArgumentNullException("item");  
  44.         }  
  45.   
  46.         // Code to update record into database  
  47.         int index = employeeList.FindIndex(p => p.EmployeeID == item.EmployeeID);  
  48.         if (index == -1) {  
  49.             return false;  
  50.         }  
  51.         employeeList.RemoveAt(index);  
  52.         employeeList.Insert(index, item);  
  53.   
  54.         return true;  
  55.     }  
  56.   
  57.     public bool Delete(int id) {  
  58.         // Code to remove the records from database  
  59.         employeeList.RemoveAll(p => p.EmployeeID == id);  
  60.   
  61.         return true;  
  62.     }  
  63.   
  64. }  
And this is the repository interface.
  1. interface IEmployeeRepository {  
  2.     Employee Add(Employee item);  
  3.     bool Delete(int id);  
  4.     Employee Get(int id);  
  5.     System.Collections.Generic.IEnumerable < Employee > GetAll();  
  6.     bool Update(Employee item);  
  7. }  
And this is the repository interface.
  1. static readonly IEmployeeRepository repository = new EmployeeRepository();  
  2. //  
  3. // GET: /Employee/  
  4. public ActionResult Employee() {  
  5.     return View();  
  6. }  
  7. //  
  8. // GET: /Employees/  
  9. public JsonResult GetAllEmployees() {  
  10.     return Json(repository.GetAll(), JsonRequestBehavior.AllowGet);  
  11. }  
  12. //  
  13. // GET: /Employee/Create  
  14. public JsonResult CreateEmployee(Employee item) {  
  15.     item = repository.Add(item);  
  16.     return Json(item, JsonRequestBehavior.AllowGet);  
  17. //  
  18. // GET: /Employee/Edit/5  
  19. public JsonResult EditEmployee(int EmployeeID, Employee employee) {  
  20.     employee.EmployeeID = EmployeeID;  
  21.     if (repository.Update(employee)) {  
  22.         return Json(repository.GetAll(), JsonRequestBehavior.AllowGet);  
  23.     }  
  24.     return Json(null);  
  25. }  
  26. //  
  27. // GET: /Employee/Delete/5  
  28. public JsonResult Delete(int id) {  
  29.     if (repository.Delete(id)) {  
  30.         return Json(new { Status = true }, JsonRequestBehavior.AllowGet);  
  31.     }  
  32.     return Json(new { Status = false }, JsonRequestBehavior.AllowGet);  
  33. }  
Now let's work on views.
  1. <script src="~/Scripts/jquery-2.0.3.js"></script>  
  2. <script src="~/Scripts/knockout-2.3.0.js"></script>  
  3. <script src='@Url.Content("~/Scripts/knockout-2.3.0.debug.js")' type="text/javascript"></script>  
  4. <script type="text/javascript">  
  5. function EmployeeViewModel() {  
  6.     var self = this;  
  7.     self.EmployeeID = ko.observable("");  
  8.     self.FirstName = ko.observable("");  
  9.     self.LastName = ko.observable("");  
  10.     self.City = ko.observable("");  
  11.     self.Region = ko.observable("");  
  12.     self.PostalCode = ko.observable("");  
  13.     self.Country = ko.observable("");  
  14.   
  15.     var Employee = {  
  16.         EmployeeID: self.EmployeeID,  
  17.         FirstName: self.FirstName,  
  18.         LastName: self.LastName,  
  19.         City: self.City,  
  20.         Region: self.Region,  
  21.         PostalCode: self.PostalCode,  
  22.         Country: self.Country  
  23.     };  
  24.   
  25.     self.Employee = ko.observable();  
  26.     self.Employees = ko.observableArray();  
  27.   
  28.     $.ajax({  
  29.         url: '@Url.Action("GetAllEmployees", "Employee")',  
  30.         cache: false,  
  31.         type: 'GET',  
  32.         contentType: 'application/json; charset=utf-8',  
  33.         data: {},  
  34.         success: function(data) {  
  35.             self.Employees(data);  
  36.         }  
  37.     });  
  38.   
  39.     //Add New Employee  
  40.     self.create = function() {  
  41.         if (Employee.FirstName() != "" && Employee.LastName() != "" && Employee.City() != "" && Employee.Region() != "" && Employee.PostalCode() != "" && Employee.Country() != "") {  
  42.             $.ajax({  
  43.                 url: '@Url.Action("CreateEmployee", "Employee")',  
  44.                 cache: false,  
  45.                 type: 'POST',  
  46.                 contentType: 'application/json; charset=utf-8',  
  47.                 data: ko.toJSON(Employee),  
  48.                 success: function(data) {  
  49.                     self.Employees.push(data);  
  50.                     self.FirstName("");  
  51.                     self.LastName("");  
  52.                     self.City("");  
  53.                     self.Region("");  
  54.                     self.PostalCode("");  
  55.                     self.Country("");  
  56.   
  57.                 }  
  58.             }).fail(  
  59.                 function(xhr, textStatus, err) {  
  60.                     alert(err);  
  61.                 });  
  62.   
  63.         } else {  
  64.             alert('Please Enter All the Values !!');  
  65.         }  
  66.   
  67.     }  
  68.   
  69.     // Delete employee  
  70.     self.delete = function(Employee) {  
  71.         if (confirm('Are you sure to Delete "' + Employee.FirstName + '" employee ??')) {  
  72.             var id = Employee.EmployeeID;  
  73.   
  74.             $.ajax({  
  75.                 url: '@Url.Action("DeleteEmployee", "Employee")',  
  76.                 cache: false,  
  77.                 type: 'POST',  
  78.                 contentType: 'application/json; charset=utf-8',  
  79.                 data: ko.toJSON(id),  
  80.                 success: function(data) {  
  81.                     self.Employees.remove(Employee);  
  82.                     //   alert("Record Deleted Successfully");  
  83.                 }  
  84.             }).fail(  
  85.                 function(xhr, textStatus, err) {  
  86.                     alert(err);  
  87.                 });  
  88.         }  
  89.     }  
  90.   
  91.     // Edit employee  
  92.     self.edit = function(Employee) {  
  93.         self.Employee(Employee);  
  94.   
  95.     }  
  96.   
  97.     //// Update employee  
  98.     self.update = function() {  
  99.         var Employee = self.Employee();  
  100.         alert(Employee.EmployeeID);  
  101.   
  102.         debugger;  
  103.         $.ajax({  
  104.                 url: '@Url.Action("EditEmployee", "Employee")',  
  105.                 cache: false,  
  106.                 type: 'PUT',  
  107.                 contentType: 'application/json; charset=utf-8',  
  108.                 data: ko.toJSON(Employee),  
  109.                 success: function(data) {  
  110.                     alert(data);  
  111.                     self.Employees.removeAll();  
  112.                     self.Employees(data); //Put the response in ObservableArray  
  113.                     self.Employee(null);  
  114.                     alert("Record Updated Successfully");  
  115.   
  116.                 }  
  117.             })  
  118.             .fail(  
  119.                 function(xhr, textStatus, err) {  
  120.                     alert(err);  
  121.                 });  
  122.     }  
  123.   
  124.   
  125.     // Reset employee  
  126.     self.reset = function() {  
  127.         self.FirstName("");  
  128.         self.LastName("");  
  129.         self.City("");  
  130.         self.Region("");  
  131.         self.PostalCode("");  
  132.         self.Country("");  
  133.     }  
  134.   
  135.     // Cancel employee  
  136.   
  137.     self.cancel = function() {  
  138.         self.Employee(null);  
  139.   
  140.     }  
  141. }  
  142.   
  143. // Binding knockout  
  144.   
  145. $(document).ready(function() {  
  146.     var viewModel = new EmployeeViewModel();  
  147.     ko.applyBindings(viewModel);  
  148. });  
  149. </script>  
  150. <h3>Employees</h3>  
  151. <table id="empl" data-bind="visible: Employees().length > 0">  
  152.     <thead>  
  153.         <tr>  
  154.             <th>Employee ID</th>  
  155.             <th>First Name</th>  
  156.             <th>Last Name</th>  
  157.             <th>City</th>  
  158.             <th>Region</th>  
  159.             <th>Postal Code</th>  
  160.             <th>Country</th>  
  161.         </tr>  
  162.     </thead>  
  163.     <tbody data-bind="foreach: Employees">  
  164.         <tr>  
  165.             <td data-bind="text: EmployeeID"></td>  
  166.             <td data-bind="text: FirstName"></td>  
  167.             <td data-bind="text: LastName"></td>  
  168.             <td data-bind="text: City"></td>  
  169.             <td data-bind="text: Region"></td>  
  170.             <td data-bind="text: PostalCode"></td>  
  171.             <td data-bind="text: Country"></td>  
  172.             <td>  
  173.                 <button data-bind="click: $root.edit">Edit</button>  
  174.                 <button data-bind="click: $root.delete">Delete</button>  
  175.             </td>  
  176.         </tr>  
  177.     </tbody>  
  178. </table>  
  179. <br />  
  180. <div style="border-top: solid 2px  #282828; width: 430px; height: 10px"> </div>  
  181. <div data-bind="if: Employee">  
  182.     <div>  
  183.         <h2>Update Employee</h2>  
  184.     </div>  
  185.     <div>  
  186.         <label for="EmployeeID" data-bind="visible: false">Employee ID</label>  
  187.         <label data-bind="text: Employee().EmployeeID, visible: false"></label>  
  188.     </div>  
  189.     <div>  
  190.         <label for="firstname">First Name</label>  
  191.         <input data-bind="value: Employee().FirstName" type="text" title="First Name" />  
  192.     </div>  
  193.     <div>  
  194.         <label for="lastname">Last Name</label>  
  195.         <input data-bind="value: Employee().LastName" type="text" title="Last Name" />  
  196.     </div>  
  197.     <div>  
  198.         <label for="city">City</label>  
  199.         <input data-bind="value: Employee().City" type="text" title="City" />  
  200.     </div>  
  201.     <div>  
  202.         <label for="region">Region</label>  
  203.         <input data-bind="value: Employee().Region" type="text" title="Price" />  
  204.     </div>  
  205.     <div>  
  206.         <label for="postalcode">Postal Code</label>  
  207.         <input data-bind="value: Employee().PostalCode" type="text" title="PostalCode" />  
  208.     </div>  
  209.     <div>  
  210.         <label for="country">Country</label>  
  211.         <input data-bind="value: Employee().Country" type="text" title="Country" />  
  212.     </div>  
  213.     <br />  
  214.     <div>  
  215.         <button data-bind="click: $root.update">Update</button>  
  216.         <button data-bind="click: $root.cancel">Cancel</button>  
  217.     </div>  
  218. </div>  
  219. <div data-bind="ifnot: Employee()">  
  220.     <div>  
  221.         <h2>Add New Employee</h2>  
  222.     </div>  
  223.     <div>  
  224.         <label for="firstname">First Name</label>  
  225.         <input data-bind="value: $root.FirstName" type="text" title="FirstName" />  
  226.     </div>  
  227.     <div>  
  228.         <label for="lastname">Last Name</label>  
  229.         <input data-bind="value: $root.LastName" type="text" title="LastName" />  
  230.     </div>  
  231.     <div>  
  232.         <label for="city">City</label>  
  233.         <input data-bind="value: $root.City" type="text" title="City" />  
  234.     </div>  
  235.     <div>  
  236.         <label for="region">Region</label>  
  237.         <input data-bind="value: $root.Region" type="text" title="Region" />  
  238.     </div>  
  239.     <div>  
  240.         <label for="postalcode">Postal Code</label>  
  241.         <input data-bind="value: $root.PostalCode" type="text" title="PostalCode" />  
  242.     </div>  
  243.     <div>  
  244.         <label for="country">Country</label>  
  245.         <input data-bind="value: $root.Country" type="text" title="Country" />  
  246.     </div>  
  247.     <br />  
  248.     <div>  
  249.         <button data-bind="click: $root.create">Save</button>  
  250.         <button data-bind="click: $root.reset">Reset</button>  
  251.     </div>  
  252. </div>  
Hit F5 to run the application.
 
Knockout in MVC 4
 
Image 1.