Grid Infinite scrolling
Loading data when the content is scrolled
Grid with infinite/endless scroll. Scrolling down or up from a certain page will automatically load the next/previous page.
If you scroll faster you can skip several pages.
For group aggregates GridModelBuilder.MakeHeader needs to ignore the group items (GroupInfo.Items) and call the data source directly to calculate aggregate values, otherwise the values will be calculated only on the items present in the current page.
For group aggregates GridModelBuilder.MakeHeader needs to ignore the group items (GroupInfo.Items) and call the data source directly to calculate aggregate values, otherwise the values will be calculated only on the items present in the current page.
GridInfiniteScrollingDemo/Index.cshtml
@(Html.Awe().Grid("InfiniteScrollingGrid")
.Mod(o => o.Main().InfiniteScroll())
.Columns(
new Column {ClientFormat = ".(Nr)", Header = "Nr", Width = 75},
new Column {Bind = "Id", Width = 75, Groupable = false, Resizable = false},
new Column {Bind = "Person"},
new Column {Bind = "Food.Name"},
new Column {Bind = "Location"},
new Column {Bind = "Date", Width = 120},
new Column {Bind = "Country.Name", Header = "Country"},
new Column {Bind = "Chef.FirstName,Chef.LastName", Prop = "ChefName", Header = "Chef"})
.Url(Url.Action("GetItems"))
.Resizable()
.Reorderable()
.Height(400))
Demos/Grid/GridInfiniteScrollingDemoController.cs
public class GridInfiniteScrollingDemoController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult GetItems(GridParams g)
{
var query = Db.Lunches.AsQueryable();
var nr = 1;
var gmb = new GridModelBuilder<Lunch>(query, g)
{
KeyProp = o => o.Id,
MakeHeader = MakeHeader,
Map = o => new
{
Nr = nr++ + (g.Spage - 1) * g.PageSize,
o.Id,
o.Person,
FoodName = o.Food.Name,
FoodPic = o.Food.Pic,
o.Location,
o.Price,
Date = o.Date.ToShortDateString(),
CountryName = o.Country.Name,
ChefName = o.Chef.FullName
}
};
return Json(gmb.Build());
// only needed if you have group aggregate values
GroupHeader MakeHeader(GroupInfo<Lunch> info)
{
// get first item in the group
var first = info.Items.First();
// get the grouped column value(s) for the first item
var val = string.Join(" ", AweUtil.GetColumnValue(info.Column, first).Select(ToStr));
// info.Items has only the items on the current page, so the aggregate value (Count, Sum, etc) may be incorrect
// here we're manually selecting the items for the current group without considering page
var qitems = Db.Lunches.AsQueryable();
foreach (var groupName in g.Groups)
{
var names = groupName.Split(','); // call Split for groups like Chef column "Chef.FirstName,Chef.LastName"
var gvals = AweUtil.GetColumnValue(groupName, first).ToArray();
for (var i = 0; i < names.Length; i++)
{
qitems = qitems.Where(names[i] + "==@0", gvals[i]); // using Dynamic Linq
}
if (groupName == info.Column) break; // reached current group level
}
return new GroupHeader { Content = $" {info.Header} : {val} ( Count = {qitems.Count()} )" };
}
}
private static string ToStr(object o)
{
return o is DateTime ? ((DateTime)o).ToShortDateString() : o.ToString();
}
}
Grid with load more button
Instead of loading the next page on scroll a Load more data button is provided.
GridInfiniteScrollingDemo/Index.cshtml
@(Html.Awe().Grid("GridLoadMore")
.Mod(o => o.Main().InfiniteScroll(true))
.Columns(
new Column {ClientFormat = ".(Nr)", Header = "Nr", Width = 75},
new Column {Bind = "Id", Width = 75, Groupable = false, Resizable = false},
new Column {Bind = "Person"},
new Column {Bind = "Food.Name"},
new Column {Bind = "Location"},
new Column {Bind = "Date", Width = 120},
new Column {Bind = "Country.Name", Header = "Country"},
new Column {Bind = "Chef.FirstName,Chef.LastName", Prop = "ChefName", Header = "Chef"})
.Url(Url.Action("GetItems"))
.Resizable()
.Reorderable()
.Height(400)
.PageSize(10))
Comments