Grid nesting, hierarchy
The Awesome grid can have multiple nests which can open under a grid row, this feature can be used to achive Hierarchical Grid, Master-Detail Grid, and more.
An url or javascript function can be specified for loading the nest content.
When using url the Key of the grid is sent as
The class of the html element that will act as a toggle button for the nest needs to be specified, that element will get
The nest can also be open using the grid api
An url or javascript function can be specified for loading the nest content.
When using url the Key of the grid is sent as
Key parameter to the url.The class of the html element that will act as a toggle button for the nest needs to be specified, that element will get
classname+"-on" class while its nest is open.The nest can also be open using the grid api
nestOpen(row, class) as shown in the demos below.
Opening a nest will close other nests that are open for the same row.
Master detail grid
Using one nest with url to achieve a master detail grid viewusing grid api to open, close and toggle open nest for the first row:
GridNestingDemo/Index.cshtml
@(Html.Awex().Grid<Lunch>()
.Main()
.Columns(b =>{
b.Add(new Column { ClientFormat = MyAweIcons.DetailNstBtn("Id"), Width = 100, Header = "Id" });
b.Add(o => o.Person);
b.Add(o => o.Dish.Name);
b.Add(o => o.Location);
})
.Url(Url.Action("GetItems", "LunchGrid"))
.PageSize(5)
.Height(300)
.Nests(new Nest { Name = "detailnst", Url = Url.Action("LunchDetail"), LoadOnce = true }))
<br />
<p>
using grid api to open, close and toggle open nest for the first row:
</p>
<button type="button" class="awe-btn" id="btnOpenNest">Open nest</button>
<button type="button" class="awe-btn" id="btnCloseNest">Close nest </button>
<button type="button" class="awe-btn" id="btnToggleNest">Toggle nest</button>
<script>
$(function () {
var grid = $('#MasterDetailGrid');
var api = grid.data('api');
$('#btnToggleNest').click(function () {
api.nestToggle(grid.find('.awe-row:first'), 'detailnst');
});
$('#btnOpenNest').click(function () {
api.nestOpen(grid.find('.awe-row:first'), 'detailnst');
});
$('#btnCloseNest').click(function () {
api.nestClose(grid.find('.awe-row:first'), 'detailnst');
});
});
</script>
Awesome/Grid/LunchGridController.cs
public class LunchGridController : Controller
{
public IActionResult GetItems(GridParams g, int? country, string person, string dish)
{
var query = Db.Lunches.AsQueryable();
var gmb = new GridModelBuilder<Lunch>(query.AsQueryable(), g);
gmb.KeyProp = o => o.Id;
// for when using parent controls filters
gmb.FilterContainsStr(o => o.Person, person)
.FilterContainsStr(o => o.Dish.Name, dish)
.FilterEq(o => o.Country.Id, country);
// props used in site.imgDish js function
gmb.Prop(o => o.Dish.Pic, "DishPic");
gmb.Prop(o => o.Dish.Name, "DishName");
// used by some demos (GridFrozenColumns)`
gmb.Prop(o => o.Organic, render: o => o ? "Yes" : "No");
return this.AweJson(gmb.Build());
}
}
Demos/Grid/GridNestingDemoController.cs
public IActionResult LunchDetail(int? key)
{
Check.NotNull(key, nameof(key));
var lunch = Db.Lunches.Where(o => o.Id == key).FirstOrDefault();
return PartialView(lunch);
}
GridNestingDemo/LunchDetail.cshtml
@model AweCoreDemo.Models.Lunch
<div style="padding:0.2em 2em;" class="o-fzcon">
@Model.Person had @Model.Dish.Name at @Model.Location in @Model.Country.Name<br/>
View loaded from server at: @DateTime.UtcNow UTC
</div>
Nested grids / Hierarchical grid
Hierarchical grid done using the grid nest feature.
The url of the grid nest is set to an action that returns a partial view (created by the user) which contains a grid, the action also receives the key of the row (Id) as a parameter.
The url of the grid nest is set to an action that returns a partial view (created by the user) which contains a grid, the action also receives the key of the row (Id) as a parameter.
GridNestingDemo/Index.cshtml
@(Html.Awex().Grid<Category>()
.Main()
.Groupable(false)
.Url(Url.Action("CategoriesGrid", "Data"))
.Columns(b => {
b.Add(o => o.Name, new Column { ClientFormat = MyAweIcons.DetailNstBtn("Name")});
})
.Nests(new Nest { Name = "detailnst", Url = Url.Action("MealGrid"), LoadOnce = true }))
Demos/Grid/GridNestingDemoController.cs
public IActionResult MealGrid(int? key)
{
Check.NotNull(key, nameof(key));
ViewData["Id"] = key;
return PartialView();
}
GridNestingDemo/MealGrid.cshtml
@using AweCoreDemo.Models
<div style="margin: 5px;">
@* adding Id to grid name to have unique html ids across all nests*@
@(Html.Awex().Grid<Meal>("MealsGrid" + ViewData["Id"])
.Url(Url.Action("ChildMealsGrid", "Data"))
.Columns(b =>
{
b.Add(o => o.Id, new Column { Width = 50});
b.Add(o => o.Name, new Column { Width = 150});
b.Add(o => o.Description);
})
.Resizable()
.Groupable(false)
.Parameter("categories", ViewData["Id"]))
</div>
Awesome/DataController.cs
public IActionResult CategoriesGrid(GridParams g)
{
var gmb = new GridModelBuilder<Category>(Db.Categories.AsQueryable(), g)
{
KeyProp = o => o.Id
};
var model = gmb.Build();
return this.AweJson(model);
}
public IActionResult ChildMealsGrid(GridParams g, int[] categories)
{
categories ??= new int[] { };
var query = Db.Meals.Where(o => categories.Contains(o.Category.Id)).AsQueryable();
var gmb = new GridModelBuilder<Meal>(query, g);
var model = gmb.Build();
return this.AweJson(model);
}
Grid nest editing
Combining the PopupForm, inline popup, and grid nesting to achieve in nest editing. We have 2 nests, both with js functions specified for loading the content,
the js func uses the popup api to load the content inside the nest and binds to the popups aweclose event so that the nest will close when the popup closes.
All the popups are in the same group so opening a create popup will close other edit/delete popups etc.
Shared/Demos/GridNestEdit.cshtml
@{
var grid3 = "NestDinnersGrid";
}
@Html.InitCrudForGridNest(grid3, "DinnersGridCrud")
<div class="bar">
<button type="button" onclick="aweUtils.nestCreate('@grid3', 'create@(grid3)')" class="awe-btn">Create</button>
</div>
@(Html.Awex().Grid<Dinner>(grid3)
.Main()
.Url(Url.Action("GridGetItems", "DinnersGridCrud"))
.Attr("data-syncg", "dinner")
.Nests(
new Nest { Name = "editnst", GetFunc = $"aweUtils.loadNestPopup('edit{grid3}')" },
new Nest { Name = "delnst", GetFunc = $"aweUtils.loadNestPopup('delete{grid3}')" })
.Columns(b => {
b.Add(o => o.Id).Width(75);
b.Add(Html.EditDelNestColumn());
b.Add(o => o.Name);
b.Add(o => o.Date);
b.Add(o => new { o.Chef.FirstName, o.Chef.LastName });
b.Add(o => o.Meals.Select(m => m.Name));
})
)
<style>
#NestDinnersGrid .earea {
max-width: 20em;
}
.editnst-on .editnst, .delnst-on .delnst {
outline: gray auto 5px;
}
</style>
Comments