HI WELCOME TO SIRIS

How to create Master Detail entry form in asp.net MVC4

Leave a Comment

Introduction

In one of the previous article, I have explained how to show master-details data in asp.net MVC application with collapse / expand option and also I have explained how we can show master-details data in report viewer control in asp.net webform application. But Sometimes we need to create master details entry form in the single page, like Order and order details. Here we will see, how we can create master details entry form in a single page in asp.net MVC application.

Steps :

Step - 1 : Create New Project.

Go to File > New > Project > Select asp.net MVC4 web application > Entry Application Name > Click OK > Select Basic > Select view engine Razor > OK

Step-2: Add a Database.

Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.


Step-3: Create table for Save data.

Here I will create 2 table (as below). 1 for save master record (Order) and another for save details record (order items).
Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok.
In this example, I have used 2 tables as below

Order

OrderDetails


Here in this OrderDetails table, I have added a Foreign Key on OrderID field which is References to OrderID filed of Order table.

See relation in image : 


Step-4: Add Entity Data Model.

Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add.
A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.

Step-5: Create a view model.

Here we will create a ViewModel. First we will add a new folder named "ViewModel" and inside this folder we will create a class as below

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5.  
  6. namespace MvcMasterDetails.Models
  7. {
  8. public class OrderVM
  9. {
  10. public string OrderNo { get; set; }
  11. public DateTime OrderDate { get; set; }
  12. public string Description { get; set; }
  13. public List<OrderDetail> OrderDetails {get;set;}
  14. }
  15. }

Step-6: Create a Controller.

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete "empty MVC Controller"> Add.

Here I have created a controller "HomeController"

Step-7: Add new action into your controller for Get Method

Here I have added "Index" Action into "Home" Controller. Please write this following code

  1. public ActionResult Index()
  2. {
  3. return View();
  4. }

Step-8: Add view for your Action & design.

Right Click on Action Method (here right click on Index action) > Add View... > Enter View Name > Select View Engine (Razor) > Add.
HTML Code 
  1. @{
  2. ViewBag.Title = "Index";
  3. }
  4.  
  5. <h2>Master Details entry form</h2>
  6. <div class="container" style="max-width:640px">
  7. <div class="master">
  8. <h4>Order details</h4>
  9. <table>
  10. <tr>
  11. <td>Order No</td>
  12. <td>
  13. <input type="text" id="orderNo" />
  14. <span class="error">Order no required</span>
  15. </td>
  16. <td>Order Date</td>
  17. <td>
  18. <input type="text" id="orderDate" />
  19. <span class="error">Valid order date required (ex. MM-dd-yyyy)</span>
  20. </td>
  21. </tr>
  22. <tr>
  23. <td>Description</td>
  24. <td colspan="3">
  25. <textarea id="description" style="width:100%"></textarea>
  26. </td>
  27. </tr>
  28. </table>
  29. </div>
  30. <div class="details">
  31. <h4>Order Items</h4>
  32. <table width="100%">
  33. <tr>
  34. <td>Item Name</td>
  35. <td>Quantity</td>
  36. <td>Rate</td>
  37. <td>&nbsp;</td>
  38. </tr>
  39. <tr>
  40. <td>
  41. <input type="text" id="itemName" />
  42. <span class="error">Item name required</span>
  43. </td>
  44. <td>
  45. <input type="text" id="quantity" />
  46. <span class="error">Valid quantity required</span>
  47. </td>
  48. <td>
  49. <input type="text" id="rate" />
  50. <span class="error">Valid rate required</span>
  51. </td>
  52. <td>
  53. <input type="button" id="add" value="add" />
  54. </td>
  55. </tr>
  56. </table>
  57. <div id="orderItems" class="tablecontainer">
  58.  
  59. </div>
  60. <div style="padding:10px 0px; text-align:right">
  61. <input id="submit" type="button" value="Save" style="padding:10px 20px" />
  62. </div>
  63. </div>
  64. </div>

Updated on 18 may 2016 : Added yellow mark code for support remove functionality.

Step-9: Add jquery code

Jquery Code 
  1. <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
  2. <script>
  3. //Date Picker
  4. $(function () {
  5. $('#orderDate').datepicker({
  6. dateFormat : 'mm-dd-yy'
  7. });
  8. });
  9.  
  10. $(document).ready(function () {
  11. var orderItems = [];
  12. //Add button click function
  13. $('#add').click(function () {
  14. //Check validation of order item
  15. var isValidItem = true;
  16. if ($('#itemName').val().trim() == '') {
  17. isValidItem = false;
  18. $('#itemName').siblings('span.error').css('visibility', 'visible');
  19. }
  20. else {
  21. $('#itemName').siblings('span.error').css('visibility', 'hidden');
  22. }
  23.  
  24. if (!($('#quantity').val().trim() != '' && !isNaN($('#quantity').val().trim()))) {
  25. isValidItem = false;
  26. $('#quantity').siblings('span.error').css('visibility', 'visible');
  27. }
  28. else {
  29. $('#quantity').siblings('span.error').css('visibility', 'hidden');
  30. }
  31.  
  32. if (!($('#rate').val().trim() != '' && !isNaN($('#rate').val().trim()))) {
  33. isValidItem = false;
  34. $('#rate').siblings('span.error').css('visibility', 'visible');
  35. }
  36. else {
  37. $('#rate').siblings('span.error').css('visibility', 'hidden');
  38. }
  39.  
  40. //Add item to list if valid
  41. if (isValidItem) {
  42. orderItems.push({
  43. ItemName: $('#itemName').val().trim(),
  44. Quantity: parseInt($('#quantity').val().trim()),
  45. Rate: parseFloat($('#rate').val().trim()),
  46. TotalAmount: parseInt($('#quantity').val().trim()) * parseFloat($('#rate').val().trim())
  47. });
  48.  
  49. //Clear fields
  50. $('#itemName').val('').focus();
  51. $('#quantity,#rate').val('');
  52.  
  53. }
  54. //populate order items
  55. GeneratedItemsTable();
  56.  
  57. });
  58. //Save button click function
  59. $('#submit').click(function () {
  60. //validation of order
  61. var isAllValid = true;
  62. if (orderItems.length == 0) {
  63. $('#orderItems').html('<span style="color:red;">Please add order items</span>');
  64. isAllValid = false;
  65. }
  66.  
  67. if ($('#orderNo').val().trim() == '') {
  68. $('#orderNo').siblings('span.error').css('visibility', 'visible');
  69. isAllValid = false;
  70. }
  71. else {
  72. $('#orderNo').siblings('span.error').css('visibility', 'hidden');
  73. }
  74.  
  75. if ($('#orderDate').val().trim() == '') {
  76. $('#orderDate').siblings('span.error').css('visibility', 'visible');
  77. isAllValid = false;
  78. }
  79. else {
  80. $('#orderDate').siblings('span.error').css('visibility', 'hidden');
  81. }
  82.  
  83. //Save if valid
  84. if (isAllValid) {
  85. var data = {
  86. OrderNo: $('#orderNo').val().trim(),
  87. OrderDate: $('#orderDate').val().trim(),
  88. //Sorry forgot to add Description Field
  89. Description : $('#description').val().trim(),
  90. OrderDetails : orderItems
  91. }
  92.  
  93. $(this).val('Please wait...');
  94.  
  95. $.ajax({
  96. url: '/Home/SaveOrder',
  97. type: "POST",
  98. data: JSON.stringify(data),
  99. dataType: "JSON",
  100. contentType: "application/json",
  101. success: function (d) {
  102. //check is successfully save to database
  103. if (d.status == true) {
  104. //will send status from server side
  105. alert('Successfully done.');
  106. //clear form
  107. orderItems = [];
  108. $('#orderNo').val('');
  109. $('#orderDate').val('');
  110. $('#orderItems').empty();
  111. }
  112. else {
  113. alert('Failed');
  114. }
  115. $('#submit').val('Save');
  116. },
  117. error: function () {
  118. alert('Error. Please try again.');
  119. $('#submit').val('Save');
  120. }
  121. });
  122. }
  123.  
  124. });
  125. //function for show added items in table
  126. function GeneratedItemsTable() {
  127. if (orderItems.length > 0)
  128. {
  129. var $table = $('<table/>');
  130. $table.append('<thead><tr><th>Item</th><th>Quantity</th><th>Rate</th><th>Total</th><th></th></tr></thead>');
  131. var $tbody = $('<tbody/>');
  132. $.each(orderItems, function (i, val) {
  133. var $row = $('<tr/>');
  134. $row.append($('<td/>').html(val.ItemName));
  135. $row.append($('<td/>').html(val.Quantity));
  136. $row.append($('<td/>').html(val.Rate));
  137. $row.append($('<td/>').html(val.TotalAmount));
  138. var $remove = $('<a href="#">Remove</a>');
  139. $remove.click(function (e) {
  140. e.preventDefault();
  141. orderItems.splice(i, 1);
  142. GeneratedItemsTable();
  143. });
  144. $row.append($('<td/>').html($remove));
  145. $tbody.append($row);
  146. });
  147. console.log("current", orderItems);
  148. $table.append($tbody);
  149. $('#orderItems').html($table);
  150. }
  151. else {
  152. $('#orderItems').html('');
  153. }
  154. }
  155. });
  156.  
  157. </script>
Complete HTML Code 
  1. @{
  2. ViewBag.Title = "Index";
  3. }
  4.  
  5. <h2>Master Details entry form</h2>
  6. <div class="container" style="max-width:640px">
  7. <div class="master">
  8. <h4>Order details</h4>
  9. <table>
  10. <tr>
  11. <td>Order No</td>
  12. <td>
  13. <input type="text" id="orderNo" />
  14. <span class="error">Order no required</span>
  15. </td>
  16. <td>Order Date</td>
  17. <td>
  18. <input type="text" id="orderDate" />
  19. <span class="error">Valid order date required (ex. MM-dd-yyyy)</span>
  20. </td>
  21. </tr>
  22. <tr>
  23. <td>Description</td>
  24. <td colspan="3">
  25. <textarea id="description" style="width:100%"></textarea>
  26. </td>
  27. </tr>
  28. </table>
  29. </div>
  30. <div class="details">
  31. <h4>Order Items</h4>
  32. <table width="100%">
  33. <tr>
  34. <td>Item Name</td>
  35. <td>Quantity</td>
  36. <td>Rate</td>
  37. <td>&nbsp;</td>
  38. </tr>
  39. <tr>
  40. <td>
  41. <input type="text" id="itemName" />
  42. <span class="error">Item name required</span>
  43. </td>
  44. <td>
  45. <input type="text" id="quantity" />
  46. <span class="error">Valid quantity required</span>
  47. </td>
  48. <td>
  49. <input type="text" id="rate" />
  50. <span class="error">Valid rate required</span>
  51. </td>
  52. <td>
  53. <input type="button" id="add" value="add" />
  54. </td>
  55. </tr>
  56. </table>
  57. <div id="orderItems" class="tablecontainer">
  58.  
  59. </div>
  60. <div style="padding:10px 0px; text-align:right">
  61. <input id="submit" type="button" value="Save" style="padding:10px 20px" />
  62. </div>
  63. </div>
  64. </div>
  65.  
  66. <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  67. @section Scripts{
  68. <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
  69. <script>
  70. //Date Picker
  71. $(function () {
  72. $('#orderDate').datepicker({
  73. dateFormat : 'mm-dd-yy'
  74. });
  75. });
  76.  
  77. $(document).ready(function () {
  78. var orderItems = [];
  79. //Add button click function
  80. $('#add').click(function () {
  81. //Check validation of order item
  82. var isValidItem = true;
  83. if ($('#itemName').val().trim() == '') {
  84. isValidItem = false;
  85. $('#itemName').siblings('span.error').css('visibility', 'visible');
  86. }
  87. else {
  88. $('#itemName').siblings('span.error').css('visibility', 'hidden');
  89. }
  90.  
  91. if (!($('#quantity').val().trim() != '' && !isNaN($('#quantity').val().trim()))) {
  92. isValidItem = false;
  93. $('#quantity').siblings('span.error').css('visibility', 'visible');
  94. }
  95. else {
  96. $('#quantity').siblings('span.error').css('visibility', 'hidden');
  97. }
  98.  
  99. if (!($('#rate').val().trim() != '' && !isNaN($('#rate').val().trim()))) {
  100. isValidItem = false;
  101. $('#rate').siblings('span.error').css('visibility', 'visible');
  102. }
  103. else {
  104. $('#rate').siblings('span.error').css('visibility', 'hidden');
  105. }
  106.  
  107. //Add item to list if valid
  108. if (isValidItem) {
  109. orderItems.push({
  110. ItemName: $('#itemName').val().trim(),
  111. Quantity: parseInt($('#quantity').val().trim()),
  112. Rate: parseFloat($('#rate').val().trim()),
  113. TotalAmount: parseInt($('#quantity').val().trim()) * parseFloat($('#rate').val().trim())
  114. });
  115.  
  116. //Clear fields
  117. $('#itemName').val('').focus();
  118. $('#quantity,#rate').val('');
  119.  
  120. }
  121. //populate order items
  122. GeneratedItemsTable();
  123.  
  124. });
  125. //Save button click function
  126. $('#submit').click(function () {
  127. //validation of order
  128. var isAllValid = true;
  129. if (orderItems.length == 0) {
  130. $('#orderItems').html('<span style="color:red;">Please add order items</span>');
  131. isAllValid = false;
  132. }
  133.  
  134. if ($('#orderNo').val().trim() == '') {
  135. $('#orderNo').siblings('span.error').css('visibility', 'visible');
  136. isAllValid = false;
  137. }
  138. else {
  139. $('#orderNo').siblings('span.error').css('visibility', 'hidden');
  140. }
  141.  
  142. if ($('#orderDate').val().trim() == '') {
  143. $('#orderDate').siblings('span.error').css('visibility', 'visible');
  144. isAllValid = false;
  145. }
  146. else {
  147. $('#orderDate').siblings('span.error').css('visibility', 'hidden');
  148. }
  149.  
  150. //Save if valid
  151. if (isAllValid) {
  152. var data = {
  153. OrderNo: $('#orderNo').val().trim(),
  154. OrderDate: $('#orderDate').val().trim(),
  155. //Sorry forgot to add Description Field
  156. Description : $('#description').val().trim(),
  157. OrderDetails : orderItems
  158. }
  159.  
  160. $(this).val('Please wait...');
  161.  
  162. $.ajax({
  163. url: '/Home/SaveOrder',
  164. type: "POST",
  165. data: JSON.stringify(data),
  166. dataType: "JSON",
  167. contentType: "application/json",
  168. success: function (d) {
  169. //check is successfully save to database
  170. if (d.status == true) {
  171. //will send status from server side
  172. alert('Successfully done.');
  173. //clear form
  174. orderItems = [];
  175. $('#orderNo').val('');
  176. $('#orderDate').val('');
  177. $('#orderItems').empty();
  178. }
  179. else {
  180. alert('Failed');
  181. }
  182. $('#submit').val('Save');
  183. },
  184. error: function () {
  185. alert('Error. Please try again.');
  186. $('#submit').val('Save');
  187. }
  188. });
  189. }
  190.  
  191. });
  192. //function for show added items in table
  193. function GeneratedItemsTable() {
  194. if (orderItems.length > 0)
  195. {
  196. var $table = $('<table/>');
  197. $table.append('<thead><tr><th>Item</th><th>Quantity</th><th>Rate</th><th>Total</th><th></th></tr></thead>');
  198. var $tbody = $('<tbody/>');
  199. $.each(orderItems, function (i, val) {
  200. var $row = $('<tr/>');
  201. $row.append($('<td/>').html(val.ItemName));
  202. $row.append($('<td/>').html(val.Quantity));
  203. $row.append($('<td/>').html(val.Rate));
  204. $row.append($('<td/>').html(val.TotalAmount));
  205. var $remove = $('<a href="#">Remove</a>');
  206. $remove.click(function (e) {
  207. e.preventDefault();
  208. orderItems.splice(i, 1);
  209. GeneratedItemsTable();
  210. });
  211. $row.append($('<td/>').html($remove));
  212. $tbody.append($row);
  213. });
  214. console.log("current", orderItems);
  215. $table.append($tbody);
  216. $('#orderItems').html($table);
  217. }
  218. else {
  219. $('#orderItems').html('');
  220. }
  221. }
  222. });
  223.  
  224. </script>
  225. }
  226.  
  227. <style>
  228. /*Adding some css for looks good*/
  229. span.error {
  230. display:block;
  231. visibility:hidden;
  232. color:red;
  233. font-size:90%;
  234. }
  235.  
  236.  
  237. /*css for table*/
  238. .container td {
  239. vertical-align: top;
  240. }
  241. .tablecontainer table {
  242. width: 100%;
  243. border-collapse: collapse;
  244. border-top: 1px solid #BFAEAE;
  245. border-right: 1px solid #BFAEAE;
  246. }
  247. .tablecontainer th {
  248. border-bottom: 2px solid #BFAEAE !important;
  249. }
  250. .tablecontainer th, .tablecontainer td {
  251. text-align: left;
  252. border-left: 1px solid #BFAEAE;
  253. padding: 5px;
  254. border-bottom: 1px solid #BFAEAE;
  255. }
  256. .ui-widget {
  257. font-size:12px !important;
  258. }
  259. </style>

Step-10: Add new action into your controller for save order and order details (POST Method)

Here I have added "SaveOrder" Action into "Home" Controller. Please write this following code

  1. //Post action for Save data to database
  2. [HttpPost]
  3. public JsonResult SaveOrder(OrderVM O)
  4. {
  5. bool status = false;
  6. if (ModelState.IsValid)
  7. {
  8. using (MyDatabaseEntities dc = new MyDatabaseEntities())
  9. {
  10. Order order = new Order { OrderNo = O.OrderNo, OrderDate = O.OrderDate, Description = O.Description };
  11. foreach (var i in O.OrderDetails)
  12. {
  13. //
  14. // i.TotalAmount =
  15. order.OrderDetails.Add(i);
  16. }
  17. dc.Orders.Add(order);
  18. dc.SaveChanges();
  19. status = true;
  20. }
  21. }
  22. else
  23. {
  24. status = false;
  25. }
  26. return new JsonResult { Data = new { status = status} };
  27. }

Step-11: Run Application.

0 comments:

Post a Comment

Note: only a member of this blog may post a comment.