
Download Project (Full Project)
Step-1
In this tutorial we make Edit option in master detail page. First open visual studio then open our project where we working. Open OrdersController and under OrdersController create a method name is EditOrder then write the edit code. This method receive a parameter, this parameter name is id. This id parameter responsible to find the data from database. If data are not found then it should be null or data are found this value are not null. When data are null then we insert into database and when data are not null we Edit the database by id parameter. When we click edit button then the list redirect to another page to edit view. Then we can change like product name, quantity, price, amount, customer gender etc, we have to check ado.net edmx file. Under OrderController create a method name is EditOrder this method receive an id parameter which is allow nullabal. Then check this id is null or not null by the if else condition. If id is not null then find the order from order tables. Then check order, if order is null then return http not found method or order is not null then initialize the viewBag for customer information and return the the order object in edit order view. This edit order view is rezor syntax use. Then under order view add a link to pass order id. In this order view add some script. Now editeOrdar httpPost receive the order details. Then check ithe model state is velid or not. Then call the db entity and save the database of the object. Then redirect index view. Then assign viewbag customer id. Return order object the index view. We also add edit customer details by the same method copy and paste some change the method. Like edit order to edit customer. Then find the value customer table and pass the customer object. In this method no need viewbag and every order object change to customer table object. Then the pass value of customer object. Then add view for edit customer like order view. Then pass the customer object. In this view add a action for edit customer and change the object name order to customer. Now we edit order and also customer. Given bellow the OrdersController code :
using MasterDetailsDemo.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
namespace MasterDetailsDemo.Controllers
{
public class OrdersController : Controller
{
OnlineShopEntities db = new OnlineShopEntities();
public ActionResult Index()
{
//if (Session["AdminLogin"].ToString() != "")
//{
List<Customer> OrderAndCustomerList = db.Customers.OrderByDescending(s=>s.OrderDate).ToList();
return View(OrderAndCustomerList);
//}
//return RedirectToAction("Login", "AdminPanel");
}
public ActionResult SaveOrder(string name, String address, Order[] order)
{
if (Session["AdminLogin"].ToString() != "")
{
string result = "Error! Order Is Not Complete!";
if (name != null && address != null && order != null)
{
var cutomerId = Guid.NewGuid();
Customer model = new Customer();
model.CustomerId = cutomerId;
model.Name = name;
model.Address = address;
model.OrderDate = DateTime.Now;
db.Customers.Add(model);
foreach (var item in order)
{
var orderId = Guid.NewGuid();
Order O = new Order();
O.OrderId = orderId;
O.ProductName = item.ProductName;
O.Quantity = item.Quantity;
O.Price = item.Price;
O.Amount = item.Amount;
O.CustomerId = cutomerId;
db.Orders.Add(O);
}
db.SaveChanges();
result = "Success! Order Is Complete!";
}
return Json(result, JsonRequestBehavior.AllowGet);
}
return RedirectToAction("Login", "AdminPanel");
}
public ActionResult EditOrder( Guid? id)
{
if(id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Order order = db.Orders.Find(id);
if (order == null)
{
return HttpNotFound();
}
ViewBag.CustomerId=new SelectList(db.Customers, "CustomerId", "Name", order.CustomerId);
return View(order);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditOrder([Bind(Include = "OrderId,ProductName,Quantity,Price,Amount,CustomerId")] Order order)
{
if (ModelState.IsValid)
{
db.Entry(order).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CustomerId = new SelectList(db.Customers, "CustomerId", "Name", order.CustomerId);
return View(order);
}
public ActionResult EditCustomer(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Customer cus = db.Customers.Find(id);
if (cus == null)
{
return HttpNotFound();
}
return View(cus);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditCustomer([Bind(Include = "CustomerId,Name,Address,OrderDate")] Customer customer)
{
if (ModelState.IsValid)
{
db.Entry(customer).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
}
}
Step-2
Now this method represent the edit view. This view actually pass the edit id and this passing value receive the EditOrder controller and process the edit act. This view name is EditOrder.cshtml. This view also calculate the product quantity and price by multiply to display total price.
Now given bellow the EditOrder.cshtm or view code:
@model MasterDetailsDemo.Models.Order
@{
ViewBag.Title = "EditOrder";
}
<h2>Edit Order details</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Order</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.OrderId)
<div class="form-group">
@Html.LabelFor(model => model.ProductName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ProductName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ProductName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Quantity, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Quantity, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Amount, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Amount, new { htmlAttributes = new { @class = "form-control", @readonly="readonly" } })
@Html.ValidationMessageFor(model => model.Amount, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CustomerId, "CustomerId", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("CustomerId", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.CustomerId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#Quantity,#Price").keyup(function (e) {
var q = $("#Quantity").val();
var p = $("#Price").val();
var result = "";
if (q !== "" && p !== "" && $.isNumeric(q) && $.isNumeric(p)) {
result = parseFloat(q) * parseFloat(p);
}
$("#Amount").val(result);
});
});
</script>
Step-3
Now some modify the index.cshtml file. In this file we include the edit button. when we click the button then the view are redirect to the editOrder view and also pass the id of the controller.
Given below the index.cshtml code :
@model IEnumerable<MasterDetailsDemo.Models.Customer>
@{
ViewBag.Title = "Index";
}
<br /><br />
<div class="panel panel-default">
<div class="panel-heading">
<div class="row">
<h2 class="panel-title pull-left" style="margin-left:10px;">
<strong>Order Details</strong>
</h2>
<button style="margin-right:10px" class="btn btn-primary pull-right" onclick="addNewOrder()">New Order</button>
</div>
</div>
@*Receive All Database Data From Controller And Display Those Data In Client Side*@
@if (Model.Count() != 0)
{
foreach (var item in Model)
{
<div class="card">
<div class="card-header">
Invoice
<strong> @item.OrderDate</strong>
@*<span class="float-right"> <strong>Status:</strong> Pending</span>*@
</div>
<div class="card-body">
<div class="row">
<div class="col-lg-4 col-sm-5">
</div>
<div class="row mb-4">
<div class="col-sm-6">
<h6 class="mb-3">Customer Details:</h6>
<div>
<strong>Customer Name : @item.Name </strong>
</div>
<div >Address: <span style="text-decoration: underline;">@item.Address</span> </div>
<div>@Html.ActionLink(" ", "EditCustomer", new { id = @item.CustomerId }, new { @class = "btn btn-warning btn-sm glyphicon glyphicon-edit" })</div>
</div>
</div>
</div>
<div class="panel-body">
<table class="table table-striped table-responsive">
<tbody>
<tr>
<td colspan="3">
<div class="table-responsive-sm">
<table class="table table-striped css-serial">
<thead>
<tr>
<th>#</th>
<th>Item</th>
<th>Quantity</th>
<th>Unit Cost</th>
<th>Total</th>
<th></th>
</tr>
</thead>
@{
var totalBill = 0;
}
@foreach (var order in item.Orders)
{
<tbody>
<tr>
<td></td>
<td>@order.ProductName</td>
<td>@order.Quantity</td>
<td>@order.Price</td>
<td>@order.Amount</td>
<td>@Html.ActionLink(" ", "EditOrder", new {id= @order.OrderId}, new { @class = "btn btn-warning pull-right btn-sm glyphicon glyphicon-edit" })</td>
</tr>
</tbody>
totalBill = totalBill + @Convert.ToInt32(order.Amount);
}
</table>
<div class="row">
<div class="col-lg-4 col-sm-5">
</div>
<div class="col-lg-4 col-sm-5 ml-auto">
<table class="table table-clear">
<tbody>
<tr>
<td class="left">
<strong>Total Bill:</strong>
</td>
<td class="right">
<strong>$@totalBill</strong>
</td>
@*<td class="left">
<span class="pull-right" style="margin-right:200px;"><strong>Total Bill : </strong> @totalBill</span>
</td>*@
</tr>
</tbody>
</table>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
}
}
else
{
<div class="panel-body">
<h3 style="color:red;">Empty!</h3>
</div>
}
</div>
<div class="modal fade" id="newOrderModal">
<div class="modal-dialog modal-lg" style=" width 900px !important;">
<div class="modal-content">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal">×</a>
<h4>Add New Order</h4>
</div>
<form id="NewOrderForm">
<div class="modal-body">
@*Customer Details*@
<h5 style="color:#ff6347">Customer Details</h5>
<hr />
<div class="form-horizontal">
<input type="hidden" id="CustomerId" />
<div class="form-group">
<label class="control-label col-md-2">
Customer Name
</label>
<div class="col-md-4">
<input type="text" id="name" name="name" placeholder="Customer Name" class="form-control" />
</div>
<label class="control-label col-md-2">
Address
</label>
<div class="col-md-4">
<input type="text" id="address" name="address" placeholder="Customer Address" class="form-control" />
</div>
</div>
</div>
@*Order Details*@
<h5 style="margin-top:10px;color:#ff6347">Order Details</h5>
<hr />
<div class="form-horizontal">
<input type="hidden" id="OrderId" />
<div class="form-group">
<label class="control-label col-md-2">
Product Name
</label>
<div class="col-md-4">
<input type="text" id="productName" name="productName" placeholder="Product Name" class="form-control" />
</div>
<label class="control-label col-md-2">
Price
</label>
<div class="col-md-4">
<input type="number" id="price" name="price" placeholder="Product Price" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">
Quantity
</label>
<div class="col-md-4">
<input type="number" id="quantity" name="quantity" placeholder="Quantity" class="form-control" />
</div>
<div class="col-md-2">
<a id="addToList" class="btn btn-primary">Add To List</a>
</div>
</div>
<table id="detailsTable" class="table">
<thead>
<tr>
<th style="width:30%">Product</th>
<th style="width:10%">Qty</th>
<th style="width:25%">Unit Cost</th>
<th style="width:25%">Amount</th>
<th style="width:10%"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="reset" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="saveOrder" type="submit" class="btn btn-danger">Save Order</button>
</div>
</form>
</div>
</div>
</div>
@section scripts{
<script>
//Show Modal.
function addNewOrder() {
$("#newOrderModal").modal();
}
//Add Multiple Order.
$("#addToList").click(function (e) {
e.preventDefault();
if ($.trim($("#productName").val()) == "" || $.trim($("#price").val()) == "" || $.trim($("#quantity").val()) == "") return;
var productName = $("#productName").val(),
price = $("#price").val(),
quantity = $("#quantity").val(),
detailsTableBody = $("#detailsTable tbody");
var productItem = '<tr><td>' + productName + '</td><td>' + quantity + '</td><td>' + price + '</td><td>' + (parseFloat(price) * parseInt(quantity)) + '</td><td><a data-itemId="0" href="#" class="deleteItem">Remove</a></td></tr>';
detailsTableBody.append(productItem);
clearItem();
});
//After Add A New Order In The List, Clear Clean The Form For Add More Order.
function clearItem() {
$("#productName").val('');
$("#price").val('');
$("#quantity").val('');
}
// After Add A New Order In The List, If You Want, You Can Remove It.
$(document).on('click', 'a.deleteItem', function (e) {
e.preventDefault();
var $self = $(this);
if ($(this).attr('data-itemId') == "0") {
$(this).parents('tr').css("background-color", "#ff6347").fadeOut(800, function () {
$(this).remove();
});
}
});
//After Click Save Button Pass All Data View To Controller For Save Database
function saveOrder(data) {
return $.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: "/Orders/SaveOrder",
data: data,
success: function (result) {
alert(result);
location.reload();
},
error: function () {
alert("Error!")
}
});
}
//Collect Multiple Order List For Pass To Controller
$("#saveOrder").click(function (e) {
e.preventDefault();
var orderArr = [];
orderArr.length = 0;
$.each($("#detailsTable tbody tr"), function () {
orderArr.push({
productName: $(this).find('td:eq(0)').html(),
quantity: $(this).find('td:eq(1)').html(),
price: $(this).find('td:eq(2)').html(),
amount: $(this).find('td:eq(3)').html()
});
});
var data = JSON.stringify({
name: $("#name").val(),
address: $("#address").val(),
order: orderArr
});
$.when(saveOrder(data)).then(function (response) {
console.log(response);
}).fail(function (err) {
console.log(err);
});
});
</script>
}
<style>
.css-serial {
counter-reset: serial-number; /* Set the serial number counter to 0 */
}
.css-serial td:first-child:before {
counter-increment: serial-number; /* Increment the serial number counter */
content: counter(serial-number); /* Display the counter */
}
.card {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0, 0, 0, 0.125);
border-radius: 0.25rem;
}
.card > hr {
margin-right: 0;
margin-left: 0;
}
.card > .list-group:first-child .list-group-item:first-child {
border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem;
}
.card > .list-group:last-child .list-group-item:last-child {
border-bottom-right-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
}
.card-body {
-webkit-box-flex: 1;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
padding: 1.25rem;
}
.card-title {
margin-bottom: 0.75rem;
}
.card-subtitle {
margin-top: -0.375rem;
margin-bottom: 0;
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link:hover {
text-decoration: none;
}
.card-link + .card-link {
margin-left: 1.25rem;
}
.card-header {
padding: 0.75rem 1.25rem;
margin-bottom: 0;
background-color: rgba(0, 0, 0, 0.03);
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
}
.card-header:first-child {
border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;
}
.card-header + .list-group .list-group-item:first-child {
border-top: 0;
}
</style>
Step-4
We need to create model for represent the view and help to pass or find the value from database. The controller also use the model to pass and find data from database. This model file name is ‘Order.cs”.
Given bellow the model code:
namespace MasterDetailsDemo.Models
{
using System;
using System.Collections.Generic;
public partial class Order
{
public System.Guid OrderId { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public Nullable<decimal> Amount { get; set; }
public System.Guid CustomerId { get; set; }
public virtual Customer Customer { get; set; }
}
}
Step-5
Now run the project.