Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF

Sometimes we have a requirement in which we need to manage information without touching the database, and save all of that information only when the user clicks the SUBMIT button, i.e. in one store one client wants to buy some products, the cashier has to scan every product and the system will be listing the items on screen, but the information will be submitted only when the cashier clicks the "MAKE TRANSACTION"  button.
 
So here is a small tutorial of how to add items to a temportal/virtual table (html table in front end), and remove items from that table just using jquery, and saving all items of the table into database only when the submit button is clicked:
 
So, let's begin with the tutorial.
 
The tools we need for this tutorial:
  1. EntityFramework.
  2. Jquery.
  3. Bootstrap (Optional) 
  4. Visual Studio
  5. Sql Server Management Studio
First of all let's create a new database and a new table, open sql server management studio, and execute the following scripts,
 
Create database MoviesDB
  1. create database MoviesDB -- Create a new database with the name MoviesDB  
  2.   
  3. use MoviesDB -- use this database  
  4.   
  5. --Create new Movie table  
  6. Create Table Movie (  
  7. Id int Identity primary key,  
  8. Title varchar(500),  
  9. Summary varchar(max),  
  10. Year int  
  11. )  
Now let's create a new MVC Project:
 
Open Visual Studio, then go to File - New - Project, and under Web section select .Net web application, give it any name you want and click OK button:
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF
 
Now in the project, right click on references and then Manage nuget packages, click on browse tab and then type Entity Framework :
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF 
 
Install the package (select the most recent version).
 
Now lets create the database model for Movie Table using code first method (manually):
 
Add a new class with the name "Movie" inside the Models folder:
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF
 
Here is the definition of the class, 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel.DataAnnotations.Schema;  
  4. using System.Linq;  
  5. using System.Web;  
  6.   
  7. namespace CrudJQuery.Models  
  8. {  
  9.     [Table("Movie")] //Attribute required to prevent pluralization(Movies)  
  10.     public class Movie  
  11.     {  
  12.         public int Id { getset; }  
  13.         public string Title { getset; }  
  14.         public string Summary { getset; }  
  15.         public int Year { getset; }  
  16.     }  
  17. }   
Now we need to create our dbcontext class to use this model. To do this let's create a new folder in the project and name it "DBModels", once created add a new class named "MoviesContext" to it,
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF
 
Here is the definition of the class,
  1. using CrudJQuery.Models;  
  2. using Microsoft.EntityFrameworkCore;  
  3. using System;  
  4. using System.Collections.Generic;  
  5. using System.Data.Entity;  
  6. using System.Linq;  
  7. using System.Web;  
  8.   
  9.   
  10. namespace CrudJQuery.DBModels  
  11. {  
  12.   
  13.     public class MoviesContext : DbContext  
  14.     {  
  15.         public MoviesContext() : base("DbConnection"//Connection string name located in web.config file  
  16.         {  
  17.         }  
  18.   
  19.         public DbSet<Movie> Movies { getset; }  //Movie model as property
  20.       
  21.     }  
  22.   
  23. }  
The last step  to configure entity framework is to add the connection string in our web.config file.
 
Open your web.config file located on the root path of the project and then add the following content inside configuration node.
  1. <connectionStrings>  
  2. <add name="DbConnection" connectionString="Data Source=JASBALANCE; Initial Catalog=MoviesDB; Trusted_Connection=True;" providerName="System.Data.SqlClient"/>  
  3. </connectionStrings>  
  4.    
Here we are doing connection to sql server through Windows authentication: 
 
The name of the connection string must match the one specified in our context class.
 
Now let's create a new function to receive the list of movies from the frontend and to save the informaiton into our database, open HomeController,
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF 
 
And replace all content for the following content, 
  1. using CrudJQuery.DBModels;  
  2. using CrudJQuery.Models;  
  3. using System.Collections.Generic;  
  4. using System.Web.Mvc;  
  5.   
  6. namespace CrudJQuery.Controllers //namespace will depend of your project name  
  7. {  
  8.     public class HomeController : Controller  
  9.     {  
  10.         public ActionResult Index()  
  11.         {  
  12.             return View();  
  13.         }  
  14.   
  15.         [HttpPost]  
  16.         public JsonResult SaveMovies(List<Movie> Movies)  //function to save information into database
  17.         {  
  18.   
  19.             using (MoviesContext db = new MoviesContext())  
  20.             {  
  21.                 foreach (Movie mov in Movies)  
  22.                 {  
  23.                     db.Movies.Add(mov);  
  24.                 }  
  25.                 db.SaveChanges();  
  26.             }  
  27.               
  28.             bool Result = true;  
  29.             return Json(Result);  
  30.         }  
  31.     }  
  32. }  
Now we are done with the backend side.
 
Let's continue with the front end stuff.
 
Open Layout file located on Views/Shared folder and replace all content by the following content , here we are including reference to jquery and bootstrap.
  1. <!DOCTYPE html>    
  2. <html>    
  3. <head>    
  4.     <title>JQUERY Crud</title>    
  5.     @*Bootstrap reference*@    
  6.     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"    
  7.           integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">    
  8.     @*Jquery Reference*@    
  9.     <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>    
  10. </head>    
  11. <body>    
  12.     <div class="container body-content">    
  13.         @RenderBody()    
  14.         <hr />    
  15.     </div>    
  16.     @RenderSection("scripts", required: false)    
  17. </body>    
  18. </html>    
Now open Index.cshtml file located inside views folder and replace all of its content with the following content,
  1. @*Page scripts references*@    
  2. <script src="~/JsJquery/MoviesScript.js" type="text/javascript"></script>    
  3.     
  4. <section class="m-3">    
  5.     <section class="card">    
  6.         <section class="card-header text-center">    
  7.             <label class="h3">Create Movies</label>    
  8.         </section>    
  9.         <section class="card-body">    
  10.             <section id="form-container">    
  11.                 <section class="form-group">    
  12.                     <label>Title:</label>    
  13.                     <input type="text" placeholder="Title" id="TitleTxt" class="form-control" />    
  14.                 </section>    
  15.                 <section class="form-group">    
  16.                     <label>Summary:</label>    
  17.                     <input type="text" placeholder="Summary" id="SummaryTxt" class="form-control" />    
  18.                 </section>    
  19.                 <section class="form-group">    
  20.                     <label>Year:</label>    
  21.                     <input type="text" placeholder="Year" id="YearTxt" class="form-control" />    
  22.                 </section>    
  23.                 <section class="text-center">    
  24.                     <a href="javascript:void(0)" class="text-info" id="AddTempMovieBtn">ADD MOVIE</a>    
  25.                 </section>    
  26.             </section>    
  27.             <section id="MsnContainer">    
  28.                 <section class="text-center">    
  29.                     <label class="font-weight-bold text-danger" id="Msn"></label>    
  30.                 </section>    
  31.             </section>    
  32.             <br><br>    
  33.             <section id="table-container">    
  34.                 <table class="table table-bordered table-striped" id="table-information">    
  35.                     <thead>    
  36.                         <tr class="bg-info text-light font-weight-bold text-center">    
  37.                             <td>Title</td>    
  38.                             <td>Summary</td>    
  39.                             <td>Year</td>    
  40.                             <td>Actions</td>    
  41.                         </tr>    
  42.                     </thead>    
  43.                     <tbody id="table-body"></tbody>    
  44.                 </table>    
  45.                 <section class="text-center">    
  46.                     <button id="SubmitMoviesBtn" disabled="disabled" class="btn btn-success w-50">SAVE ALL MOVIES</button>    
  47.                 </section>    
  48.             </section>    
  49.         </section>    
  50.     </section>    
  51. </section>    
And to finish let's create a new folder in our project and name it "JsJquery", then add a new javascript file inside this folder and name it "MoviesScript" (this is the file referenced in Index view file and this file contains all js operations to control that view):
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF 
 
Now paste all the following content on it (please read comments to see what each method/function does), 
  1. $(document).ready(function () {  
  2.     //set onclick events for buttons  
  3.     $('#AddTempMovieBtn').click(function () { AddTempMoview(); });  
  4.     $('#SubmitMoviesBtn').click(function () { PostMovies(); });  
  5. });  
  6.   
  7. //Send List of Movies to controller  
  8. function PostMovies() {  
  9.     //Build List object that has to be sent to controller  
  10.     var MoviesList = []; // list object  
  11.     $('#table-information > tbody  > tr').each(function () { //loop in table list  
  12.   
  13.         var Movie = {}; // create new Movie object and set its properties  
  14.         Movie.Title = this.cells[0].innerHTML;  
  15.         Movie.Summary = this.cells[1].innerHTML;  
  16.         Movie.Year = this.cells[2].innerHTML;  
  17.   
  18.         MoviesList.push(Movie); // add Movie object to list object  
  19.     });  
  20.   
  21.     //Send list of movies to controller via ajax  
  22.     $.ajax({  
  23.         url: '/home/SaveMovies',  
  24.         type: "POST",  
  25.         data: JSON.stringify(MoviesList),  
  26.         contentType: "application/json",  
  27.         dataType: "json",  
  28.         success: function (response) {  
  29.             // Process response from controller  
  30.             if (response === true) {  
  31.                 ShowMsn("Movies have been saved successfully."); // show success notification  
  32.                 ClearForm(); //clear form fields  
  33.                 $('#table-body').empty(); // clear table items  
  34.                 CheckSubmitBtn(); // disable submit button  
  35.             } else {  
  36.                 ShowMsn("Ooops, an error has ocurrer while processing the transaction.");  
  37.             }  
  38.         }  
  39.     });  
  40.   
  41. }  
  42.   
  43. //Add item to temp table   
  44. function AddTempMoview() {  
  45.   
  46.     //Create Movie Object  
  47.     var Movie = {};  
  48.     Movie.Title = $('#TitleTxt').val();  
  49.     Movie.Summary = $('#SummaryTxt').val();  
  50.     Movie.Year = $('#YearTxt').val();  
  51.   
  52.   
  53.     //Validate required fields  
  54.     var Errors = ""// Main Error Messages Variable  
  55.   
  56.     //validate Title  
  57.     if (Movie.Title.trim().length == 0) {  
  58.         Errors += "Title is required.<br>";  
  59.         $('#TitleTxt').addClass("border-danger");  
  60.     } else {  
  61.         $('#TitleTxt').removeClass("border-danger");  
  62.     }  
  63.   
  64.     //validate Summary  
  65.     if (Movie.Summary.trim().length == 0) {  
  66.         Errors += "Please provide a summary.<br>";  
  67.         $('#SummaryTxt').addClass("border-danger");  
  68.     } else {  
  69.         $('#SummaryTxt').removeClass("border-danger");  
  70.     }  
  71.   
  72.     //validate Year  
  73.     if (Movie.Year.trim().length < 4) {  
  74.         Errors += "A valid Year is required.<br>";  
  75.         $('#YearTxt').addClass("border-danger");  
  76.     } else {  
  77.         $('#YearTxt').removeClass("border-danger");  
  78.     }  
  79.   
  80.     if (Errors.length > 0) {//if errors detected then notify user and cancel transaction  
  81.         ShowMsn(Errors);  
  82.         return false//exit function  
  83.     }  
  84.     //end validation required  
  85.   
  86.     //Validate no duplicated Titles  
  87.     var ExistTitle = false// < -- Main indicator  
  88.     $('#table-information > tbody  > tr').each(function () {  
  89.         var Title = $(this).find('.TitleCol').text(); // get text of current row by class selector  
  90.         if (Movie.Title.toLowerCase() == Title.toLowerCase()) { //Compare provided and existing title  
  91.             ExistTitle = true;  
  92.             return false; 
  93.         }  
  94.     });  
  95.   
  96.     //Add movie if title is not duplicated otherwise show error  
  97.     if (ExistTitle === false) {  
  98.         ClearMsn();  
  99.         //Create Row element with provided data  
  100.         var Row = $('<tr>');  
  101.         $('<td>').html(Movie.Title).addClass("TitleCol").appendTo(Row);  
  102.         $('<td>').html(Movie.Summary).appendTo(Row);  
  103.         $('<td>').html(Movie.Year).appendTo(Row);  
  104.         $('<td>').html("<div class='text-center'><button class='btn btn-danger btn-sm' onclick='Delete($(this))'>Remove</button></div>").appendTo(Row);  
  105.   
  106.         //Append row to table's body  
  107.         $('#table-body').append(Row);  
  108.         CheckSubmitBtn(); // Enable submit button  
  109.     }  
  110.     else {  
  111.         ShowMsn("Title can not be duplicated.");  
  112.     }  
  113. }  
  114.   
  115. // clear all textboxes inside form  
  116. function ClearForm() {  
  117.     $('#form-container input[type="text"]').val('');  
  118. }  
  119.   
  120. //Msn label for notifications  
  121. function ShowMsn(message) {  
  122.     $('#Msn').html(message);  
  123. }  
  124. //Clear text of Msn label  
  125. function ClearMsn() {  
  126.     $('#Msn').html("");  
  127. }  
  128.   
  129. //Delete selected row  
  130. function Delete(row) { // remove row from table  
  131.     row.closest('tr').remove();  
  132.     CheckSubmitBtn();  
  133. }  
  134.   
  135. //Enable or disabled submit button  
  136. function CheckSubmitBtn() {  
  137.     if ($('#table-information > tbody  > tr').length > 0) { // count items in table if at least 1 item is found then enable button  
  138.         $('#SubmitMoviesBtn').removeAttr("disabled");  
  139.     } else {  
  140.         $('#SubmitMoviesBtn').attr("disabled""disabled");  
  141.     }  
  142. }  
And we are done, now let's see the project in action. Run your project and you will see the following page,
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF
 
SAVE ALL MOVIES button will be enable only if one or more items are added in the table, so let's add 3 or more items,
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF
 
To remove a movie from the table just click the remove button of the movie you want to remove.
 
Finally, to save those movies into the db just click SAVE ALL MOVIES button and jquery will execute our function to send the list of movies to the controller,
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF
 
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF
and let's check our database,
Manage Temp HTML Table With jQuery, And Post List Of Items To Database Using MVC And EF
 
And that's it my friends, I hope this post helps someone. Thanks.