Skip to content

Commit 7322966

Browse files
authored
Grid summary (#1071)
* Grid summary - Average, Count, Max, Min, Sum
1 parent b647d53 commit 7322966

File tree

11 files changed

+419
-37
lines changed

11 files changed

+419
-37
lines changed

BlazorBootstrap.Demo.RCL/Components/Layout/MainLayout.razor.cs

+19-18
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,24 @@ internal override IEnumerable<NavItem> GetNavItems()
4848

4949
#region Grid
5050

51-
new (){ Id = "513", Text = "Grid", IconName = IconName.Grid, ParentId = "5" },
52-
new (){ Id = "51101", Text = "Overview", Href = RouteConstants.Demos_Grid_Overview_Documentation, IconName = IconName.Grid, ParentId = "513" }, // first item - do not change
53-
new (){ Id = "51102", Text = "Alignment", Href = RouteConstants.Demos_Grid_Alignment_Documentation, IconName = IconName.Justify, ParentId = "513" },
54-
new (){ Id = "51103", Text = "Custom CSS Class", Href = RouteConstants.Demos_Grid_CustomCSSClass_Documentation, IconName = IconName.FileTypeCss, ParentId = "513" },
55-
new (){ Id = "51104", Text = "Data Binding", Href = RouteConstants.Demos_Grid_DataBinding_Documentation, IconName = IconName.GridFill, ParentId = "513" },
56-
new (){ Id = "51106", Text = "Detail View", Href = RouteConstants.Demos_Grid_DetailView_Documentation, IconName = IconName.ListNested, ParentId = "513" },
57-
new (){ Id = "51107", Text = "Events", Href = RouteConstants.Demos_Grid_Events_Documentation, IconName = IconName.LightningChargeFill, ParentId = "513" },
58-
new (){ Id = "51107", Text = "Filters", Href = RouteConstants.Demos_Grid_Filters_Documentation, IconName = IconName.FunnelFill, ParentId = "513" },
59-
new (){ Id = "51108", Text = "Fixed Header", Href = RouteConstants.Demos_Grid_FixedHeader_Documentation, IconName = IconName.Table, ParentId = "513" },
60-
new (){ Id = "51109", Text = "Freeze Columns", Href = RouteConstants.Demos_Grid_FreezeColumns_Documentation, IconName = IconName.LayoutThreeColumns, ParentId = "513" },
61-
new (){ Id = "51110", Text = "Grid Settings", Href = RouteConstants.Demos_Grid_Settings_Documentation, IconName = IconName.GearFill, ParentId = "513" },
62-
new (){ Id = "51111", Text = "Nested Grid", Href = RouteConstants.Demos_Grid_NestedGrid_Documentation, IconName = IconName.Pip, ParentId = "513" },
63-
new (){ Id = "51112", Text = "Paging", Href = RouteConstants.Demos_Grid_Paging_Documentation, IconName = IconName.ChevronBarRight, ParentId = "513" },
64-
new (){ Id = "51113", Text = "Selection", Href = RouteConstants.Demos_Grid_Selection_Documentation, IconName = IconName.CheckSquareFill, ParentId = "513" },
65-
new (){ Id = "51114", Text = "Sorting", Href = RouteConstants.Demos_Grid_Sorting_Documentation, IconName = IconName.ArrowDownUp, ParentId = "513" },
66-
new (){ Id = "51115", Text = "Translations", Href = RouteConstants.Demos_Grid_Translations_Documentation, IconName = IconName.Translate, ParentId = "513" },
67-
new (){ Id = "51199", Text = "Other", Href = RouteConstants.Demos_Grid_OtherExamples_Documentation, IconName = IconName.PlusSquareFill, ParentId = "513" }, // last item - do not change
51+
new (){ Id = "513", Text = "Grid", IconName = IconName.Grid, ParentId = "5" },
52+
new (){ Id = "51301", Text = "Overview", Href = RouteConstants.Demos_Grid_Overview_Documentation, IconName = IconName.Grid, ParentId = "513" }, // first item - do not change
53+
new (){ Id = "51302", Text = "Alignment", Href = RouteConstants.Demos_Grid_Alignment_Documentation, IconName = IconName.Justify, ParentId = "513" },
54+
new (){ Id = "51303", Text = "Custom CSS Class", Href = RouteConstants.Demos_Grid_CustomCSSClass_Documentation, IconName = IconName.FileTypeCss, ParentId = "513" },
55+
new (){ Id = "51304", Text = "Data Binding", Href = RouteConstants.Demos_Grid_DataBinding_Documentation, IconName = IconName.GridFill, ParentId = "513" },
56+
new (){ Id = "51306", Text = "Detail View", Href = RouteConstants.Demos_Grid_DetailView_Documentation, IconName = IconName.ListNested, ParentId = "513" },
57+
new (){ Id = "51307", Text = "Events", Href = RouteConstants.Demos_Grid_Events_Documentation, IconName = IconName.LightningChargeFill, ParentId = "513" },
58+
new (){ Id = "51307", Text = "Filters", Href = RouteConstants.Demos_Grid_Filters_Documentation, IconName = IconName.FunnelFill, ParentId = "513" },
59+
new (){ Id = "51308", Text = "Fixed Header", Href = RouteConstants.Demos_Grid_FixedHeader_Documentation, IconName = IconName.Table, ParentId = "513" },
60+
new (){ Id = "51309", Text = "Freeze Columns", Href = RouteConstants.Demos_Grid_FreezeColumns_Documentation, IconName = IconName.LayoutThreeColumns, ParentId = "513" },
61+
new (){ Id = "51310", Text = "Grid Settings", Href = RouteConstants.Demos_Grid_Settings_Documentation, IconName = IconName.GearFill, ParentId = "513" },
62+
new (){ Id = "51311", Text = "Nested Grid", Href = RouteConstants.Demos_Grid_NestedGrid_Documentation, IconName = IconName.Pip, ParentId = "513" },
63+
new (){ Id = "51312", Text = "Paging", Href = RouteConstants.Demos_Grid_Paging_Documentation, IconName = IconName.ChevronBarRight, ParentId = "513" },
64+
new (){ Id = "51313", Text = "Selection", Href = RouteConstants.Demos_Grid_Selection_Documentation, IconName = IconName.CheckSquareFill, ParentId = "513" },
65+
new (){ Id = "51314", Text = "Sorting", Href = RouteConstants.Demos_Grid_Sorting_Documentation, IconName = IconName.ArrowDownUp, ParentId = "513" },
66+
new (){ Id = "51315", Text = "Summary", Href = RouteConstants.Demos_Grid_Summary_Documentation, IconName = IconName.Calculator, ParentId = "513" },
67+
new (){ Id = "51316", Text = "Translations", Href = RouteConstants.Demos_Grid_Translations_Documentation, IconName = IconName.Translate, ParentId = "513" },
68+
new (){ Id = "51399", Text = "Other", Href = RouteConstants.Demos_Grid_OtherExamples_Documentation, IconName = IconName.PlusSquareFill, ParentId = "513" }, // last item - do not change
6869

6970
#endregion Grid
7071

@@ -106,6 +107,6 @@ internal override IEnumerable<NavItem> GetNavItems()
106107
return navItems;
107108
}
108109

109-
private async ValueTask OnThemeChanged(string themeName)
110+
private async ValueTask OnThemeChanged(string themeName)
110111
=> await JS.InvokeVoidAsync("updateDemoCodeThemeCss", themeName);
111112
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<Grid TItem="Employee"
2+
Class="table table-hover table-bordered table-striped"
3+
DataProvider="EmployeesDataProvider"
4+
AllowSummary="true"
5+
Responsive="true">
6+
7+
<GridColumns>
8+
<GridColumn TItem="Employee" HeaderText="Id" PropertyName="Id">
9+
@context.Id
10+
</GridColumn>
11+
<GridColumn TItem="Employee" HeaderText="Employee Name" PropertyName="Name" SummaryType="GridSummaryColumnType.Count">
12+
@context.Name
13+
</GridColumn>
14+
<GridColumn TItem="Employee" HeaderText="Designation" PropertyName="Designation">
15+
@context.Designation
16+
</GridColumn>
17+
<GridColumn TItem="Employee" HeaderText="DOJ" PropertyName="DOJ">
18+
@context.DOJ
19+
</GridColumn>
20+
<GridColumn TItem="Employee" HeaderText="Salary" PropertyName="Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C">
21+
@context.Salary.ToString("C")
22+
</GridColumn>
23+
<GridColumn TItem="Employee" HeaderText="Active" PropertyName="IsActive">
24+
@context.IsActive
25+
</GridColumn>
26+
</GridColumns>
27+
</Grid>
28+
29+
@code {
30+
private IEnumerable<Employee> employees = default!;
31+
32+
private async Task<GridDataProviderResult<Employee>> EmployeesDataProvider(GridDataProviderRequest<Employee> request)
33+
{
34+
if (employees is null) // pull employees only one time for client-side filtering, sorting, and paging
35+
employees = GetEmployees(); // call a service or an API to pull the employees
36+
37+
return await Task.FromResult(request.ApplyTo(employees));
38+
}
39+
40+
private IEnumerable<Employee> GetEmployees()
41+
{
42+
return new List<Employee>
43+
{
44+
new Employee { Id = 107, Name = "Alice", Designation = "AI Engineer", DOJ = new DateOnly(1998, 11, 17), Salary = 7700, IsActive = true },
45+
new Employee { Id = 103, Name = "Bob", Designation = "Senior DevOps Engineer", DOJ = new DateOnly(1985, 1, 5), Salary = 19000, IsActive = true },
46+
new Employee { Id = 106, Name = "John", Designation = "Data Engineer", DOJ = new DateOnly(1995, 4, 17), Salary = 12000, IsActive = true },
47+
new Employee { Id = 104, Name = "Pop", Designation = "Associate Architect", DOJ = new DateOnly(1985, 6, 8), Salary = 19000, IsActive = false },
48+
new Employee { Id = 105, Name = "Ronald", Designation = "Senior Data Engineer", DOJ = new DateOnly(1991, 8, 23), Salary = 16500.50f, IsActive = true },
49+
new Employee { Id = 102, Name = "Line", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 24000, IsActive = true },
50+
new Employee { Id = 101, Name = "Daniel", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 21000, IsActive = true },
51+
new Employee { Id = 113, Name = "Merlin", Designation = "Senior Consultant", DOJ = new DateOnly(1989, 10, 2), Salary = 13500, IsActive = true },
52+
new Employee { Id = 117, Name = "Sharna", Designation = "Data Analyst", DOJ = new DateOnly(1994, 5, 12), Salary = 15800.10f, IsActive = true },
53+
new Employee { Id = 108, Name = "Zayne", Designation = "Data Analyst", DOJ = new DateOnly(1991, 1, 1), Salary = 14000, IsActive = true },
54+
new Employee { Id = 109, Name = "Isha", Designation = "App Maker", DOJ = new DateOnly(1996, 7, 1), Salary = 8000, IsActive = true },
55+
new Employee { Id = 111, Name = "Glenda", Designation = "Data Engineer", DOJ = new DateOnly(1994, 1, 12), Salary = 17850, IsActive = true },
56+
};
57+
}
58+
59+
public record class Employee
60+
{
61+
public int Id { get; set; }
62+
public string? Name { get; set; }
63+
public string? Designation { get; set; }
64+
public DateOnly DOJ { get; set; }
65+
public float Salary { get; set; }
66+
public bool IsActive { get; set; }
67+
}
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<Grid TItem="Employee"
2+
Class="table table-hover table-bordered table-striped"
3+
DataProvider="EmployeesDataProvider"
4+
AllowFiltering="true"
5+
AllowPaging="true"
6+
PageSize="5"
7+
AllowSorting="true"
8+
AllowSelection="true"
9+
SelectionMode="GridSelectionMode.Multiple"
10+
SelectedItemsChanged="OnSelectedItemsChanged"
11+
AllowSummary="true"
12+
Responsive="true">
13+
14+
<GridColumns>
15+
<GridColumn TItem="Employee" HeaderText="Id" PropertyName="Id" SortKeySelector="item => item.Id">
16+
@context.Id
17+
</GridColumn>
18+
<GridColumn TItem="Employee" HeaderText="Employee Name" PropertyName="Name" FilterTextboxWidth="50" FilterTextboxWidthUnit="Unit.Percentage" SortKeySelector="item => item.Name" SummaryType="GridSummaryColumnType.Count">
19+
@context.Name
20+
</GridColumn>
21+
<GridColumn TItem="Employee" HeaderText="Designation" PropertyName="Designation" SortKeySelector="item => item.Designation">
22+
@context.Designation
23+
</GridColumn>
24+
<GridColumn TItem="Employee" HeaderText="DOJ" PropertyName="DOJ" SortKeySelector="item => item.DOJ">
25+
@context.DOJ
26+
</GridColumn>
27+
<GridColumn TItem="Employee" HeaderText="Salary" PropertyName="Salary" SortKeySelector="item => item.Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C">
28+
@context.Salary.ToString("C")
29+
</GridColumn>
30+
<GridColumn TItem="Employee" HeaderText="Active" PropertyName="IsActive" SortKeySelector="item => item.IsActive">
31+
@context.IsActive
32+
</GridColumn>
33+
</GridColumns>
34+
</Grid>
35+
36+
@code {
37+
private IEnumerable<Employee> employees = default!;
38+
39+
private HashSet<Employee> selectedEmployees = new();
40+
41+
private async Task<GridDataProviderResult<Employee>> EmployeesDataProvider(GridDataProviderRequest<Employee> request)
42+
{
43+
if (employees is null) // pull employees only one time for client-side filtering, sorting, and paging
44+
employees = GetEmployees(); // call a service or an API to pull the employees
45+
46+
return await Task.FromResult(request.ApplyTo(employees));
47+
}
48+
49+
private IEnumerable<Employee> GetEmployees()
50+
{
51+
return new List<Employee>
52+
{
53+
new Employee { Id = 107, Name = "Alice", Designation = "AI Engineer", DOJ = new DateOnly(1998, 11, 17), Salary = 7700, IsActive = true },
54+
new Employee { Id = 103, Name = "Bob", Designation = "Senior DevOps Engineer", DOJ = new DateOnly(1985, 1, 5), Salary = 19000, IsActive = true },
55+
new Employee { Id = 106, Name = "John", Designation = "Data Engineer", DOJ = new DateOnly(1995, 4, 17), Salary = 12000, IsActive = true },
56+
new Employee { Id = 104, Name = "Pop", Designation = "Associate Architect", DOJ = new DateOnly(1985, 6, 8), Salary = 19000, IsActive = false },
57+
new Employee { Id = 105, Name = "Ronald", Designation = "Senior Data Engineer", DOJ = new DateOnly(1991, 8, 23), Salary = 16500.50f, IsActive = true },
58+
new Employee { Id = 102, Name = "Line", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 24000, IsActive = true },
59+
new Employee { Id = 101, Name = "Daniel", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 21000, IsActive = true },
60+
new Employee { Id = 113, Name = "Merlin", Designation = "Senior Consultant", DOJ = new DateOnly(1989, 10, 2), Salary = 13500, IsActive = true },
61+
new Employee { Id = 117, Name = "Sharna", Designation = "Data Analyst", DOJ = new DateOnly(1994, 5, 12), Salary = 15800.10f, IsActive = true },
62+
new Employee { Id = 108, Name = "Zayne", Designation = "Data Analyst", DOJ = new DateOnly(1991, 1, 1), Salary = 14000, IsActive = true },
63+
new Employee { Id = 109, Name = "Isha", Designation = "App Maker", DOJ = new DateOnly(1996, 7, 1), Salary = 8000, IsActive = true },
64+
new Employee { Id = 111, Name = "Glenda", Designation = "Data Engineer", DOJ = new DateOnly(1994, 1, 12), Salary = 17850, IsActive = true },
65+
};
66+
}
67+
68+
private Task OnSelectedItemsChanged(HashSet<Employee> employees)
69+
{
70+
selectedEmployees = employees is not null && employees.Any() ? employees : new();
71+
return Task.CompletedTask;
72+
}
73+
74+
public record class Employee
75+
{
76+
public int Id { get; set; }
77+
public string? Name { get; set; }
78+
public string? Designation { get; set; }
79+
public DateOnly DOJ { get; set; }
80+
public float Salary { get; set; }
81+
public bool IsActive { get; set; }
82+
}
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
@attribute [Route(pageUrl)]
2+
3+
<PageMetaTags PageUrl="@pageUrl"
4+
Title="@metaTitle"
5+
Description="@metaDescription"
6+
ImageUrl="@imageUrl" />
7+
8+
<PageHero Heading="@pageTitle">
9+
<LeadSection>@pageDescription</LeadSection>
10+
</PageHero>
11+
12+
<CarbonAds />
13+
14+
<Section Size="HeadingSize.H2" Name="Example" PageUrl="@pageUrl" Link="example">
15+
<div class="mb-3">
16+
To enable summaries on columns, set the <code>AllowSummary</code> parameter to <b>true</b> at the Grid level. Additionally, set the <code>SummaryType</code> parameter on each GridColumn.
17+
<br />
18+
In the following example, the Employee Name column has <code>SummaryType</code> set to <b>GridSummaryColumnType.Count</b>, and the <b>Salary</b> column has <code>SummaryType</code> set to <b>GridSummaryColumnType.Sum</b> and <code>SummaryValueDisplayFormat</code> set to <b>C</b> to display the sum of salaries in currency format.
19+
</div>
20+
<Callout Color="CalloutColor.Info">
21+
<div>
22+
<code>GridSummaryColumnType</code>: Average, Count, Max, Min, Sum. Default value is <code>GridSummaryColumnType.None</code>.
23+
</div>
24+
</Callout>
25+
<Demo Type="typeof(Grid_Demo_01_Summary_Example)" Tabs="true" />
26+
</Section>
27+
28+
<Section Size="HeadingSize.H2" Name="Summary with Filters and Paging" PageUrl="@pageUrl" Link="summary-with-filters-paging">
29+
<Callout Color="CalloutColor.Danger">
30+
<b>NOTE: </b>Summaries will be calculated based on the current page data.
31+
</Callout>
32+
<Demo Type="typeof(Grid_Demo_02_Summary_with_Filters_Paging)" Tabs="true" />
33+
</Section>
34+
35+
@code {
36+
private const string pageUrl = RouteConstants.Demos_Grid_Summary_Documentation;
37+
private const string pageTitle = "Blazor Grid - Summary";
38+
private const string pageDescription = "Use Blazor Bootstrap grid component to display tabular data from the data source. And it supports client-side and server-side filtering, paging, and sorting.";
39+
private const string metaTitle = "Blazor Grid Component - Summary";
40+
private const string metaDescription = "Use Blazor Bootstrap grid component to display tabular data from the data source. And it supports client-side and server-side filtering, paging, and sorting.";
41+
private const string imageUrl = "https://i.imgur.com/eetvhBB.png";
42+
}

BlazorBootstrap.Demo.RCL/Constants/RouteConstants.cs

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public static class RouteConstants
6666
public const string Demos_Grid_Paging_Documentation = Demos_Grid_Prefix + "/paging";
6767
public const string Demos_Grid_Selection_Documentation = Demos_Grid_Prefix + "/selection";
6868
public const string Demos_Grid_Sorting_Documentation = Demos_Grid_Prefix + "/sorting";
69+
public const string Demos_Grid_Summary_Documentation = Demos_Grid_Prefix + "/summary";
6970
public const string Demos_Grid_Translations_Documentation = Demos_Grid_Prefix + "/translations";
7071
public const string Demos_Grid_OtherExamples_Documentation = Demos_Grid_Prefix + "/other";
7172
#endregion Grid

0 commit comments

Comments
 (0)