Introduction
In this sample, I'm going to show how to develop an application for editing master-detail entities in a single page. In this sample, I have utilized JQuery Ajax feature as well as JQuery.UI
dialog extension.
Using the Code
Home Page
Home Index view has been made of three DIVs: logo
, navigation
and contentFrame
like this:
<table>
<tr>
<td colspan="2">
<div id="logo"> </div>
</td>
</tr>
<tr style="height:600px">
<td id="navigation" style="width:200px; ">
<div>
@{Html.RenderAction("Index", "Orders");}
</div>
</td>
<td>
<div id="contentFrame">
</div>
</td>
</tr>
</table>
I have selected Orders
as master entity and have implemented it as a PartialView
. This entity is loaded inside navigation DIV
by using this code:
@{Html.RenderAction("Index", "Orders");}
On controller side, we need to change Index
controller action to return PartialView
instead of View
. Also, I have added an integer parameter to get page number from view:
public ActionResult Index(int? page)
{
var orders = db.Orders.Include(o => o.Customer).OrderByDescending(o => o.OrderDate);
int pageNumber = page ?? 1;
int pageSize = 3;
return PartialView(orders.ToPagedList(pageNumber,pageSize));
Master Entity
As I mentioned, I have selected Order
as master entity. To make this entity loaded as a PartialView
inside contentFrame DIV
, we need to change Create
, Edit
and Delete
buttons. For Create
button, first we set its id attribute to btnCreateNew
to find this object through JavaScript:
@Html.ActionLink("Create New", "Create",new {}, new {id="btnCreateNew" })
Then, we wire up its click event to load Create View inside contentFrame
:
$('#btnCreateNew').click(function (e) {
e.preventDefault();
$('#contentFrame').mask("waiting ...");
$('#contentFrame').load(this.href, function (response, status, xhr) {
$('#contentFrame').unmask("waiting ...");
});
});
Because it might take time to load PartialView
, it’s recommended to show a loadmask inside contentFrame
when it is loading data:
$('#contentFrame').mask("waiting ...");
After loading PartailView
was finished, loadmask
should disappear with this function call:
$('#contentFrame').unmask("waiting ...");
We need to include these JS and CSS files in web application:
~/Scripts/jquery.mask.js
~/Content/jquery.loadmask.css
You may put these two files inside BundleConfig.cs as I did. Also, we should put this image file in application:
~/images/loading.gif
For more information about JQuery loadmask
, please refer to this web address:
Because there is more than one Edit button, we set its btnName
attribute to btnEdit
to find these objects through JavaScript:
@Html.ActionLink("Edit", "Edit",
new { id = item.OrderID }, new { btnName = "btnEdit" })
Then, we wire up its click event to load Edit View inside contentFrame
:
$('a[btnName=btnEdit]').click(function (e) {
e.preventDefault();
$('#contentFrame').mask("waiting ...");
$('#contentFrame').load(this.href, function (response, status, xhr) {
$('#contentFrame').unmask("waiting ...");
});
});
Delete button is the same as Edit button.
Detail Entity
I have selected Order
Items as detail entity. We show detail entity only in master entity's Edit View. So we need to load OrderItems Index
view as a PartialView
inside Order
's Edit View and pass OrderID
as a parameter to its action:
<div id="detailFrame">
@{Html.RenderAction("Index", "OrderItems",new {OrderID = Model.OrderID});}
</div>
We need to get OrderID
as a parameter in Index
action of the OrderItems
and filter Order
Items to return only order items for this order:
public ActionResult Index(int OrderID,int? page)
{
ViewBag.OrderID = OrderID;
var orderItems = db.OrderItems.Include(oi => oi.Order).Include
(oi => oi.Product).OrderByDescending(oi => oi.OrderItemID);
int pageSize = 3;
int pageNumber = page ?? 1;
return PartialView(orderItems.Where(oi => oi.OrderID == OrderID).ToPagedList(pageNumber,pageSize));
}
Create and Edit Detail Entity
For creating and editing detail entity, we need to open modal dialog that I already have developed an example about. For more information about creating and editing entity through modal dialog and adding other functionalities such as filtering and sorting, please take a look at my previous article titled: "MVC pagination, filtering and sorting inside partial view with edit in modal dialog" at this URL: