Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<GridColumn TItem="Employee" HeaderText="DOJ" PropertyName="DOJ">
@context.DOJ
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Salary" PropertyName="Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C">
<GridColumn TItem="Employee" HeaderText="Salary" HeaderTextAlignment="Alignment.End" TextAlignment="Alignment.End" PropertyName="Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C">
@context.Salary.ToString("C")
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Active" PropertyName="IsActive">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<GridColumn TItem="Employee" HeaderText="DOJ" PropertyName="DOJ" SortKeySelector="item => item.DOJ">
@context.DOJ
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Salary" PropertyName="Salary" SortKeySelector="item => item.Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C">
<GridColumn TItem="Employee" HeaderText="Salary" HeaderTextAlignment="Alignment.End" TextAlignment="Alignment.End" PropertyName="Salary" SortKeySelector="item => item.Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C">
@context.Salary.ToString("C")
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Active" PropertyName="IsActive" SortKeySelector="item => item.IsActive">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<Grid TItem="Employee"
Class="table table-hover table-bordered table-striped"
DataProvider="EmployeesDataProvider"
AllowSummary="true"
Responsive="true">

<GridColumns>
<GridColumn TItem="Employee" HeaderText="Id" PropertyName="Id">
@context.Id
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Employee Name" PropertyName="Name" SummaryType="GridSummaryColumnType.Count" SummaryValuePrefix="Records count: ">
@context.Name
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Designation" PropertyName="Designation">
@context.Designation
</GridColumn>
<GridColumn TItem="Employee" HeaderText="DOJ" PropertyName="DOJ">
@context.DOJ
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Salary" HeaderTextAlignment="Alignment.End" TextAlignment="Alignment.End" PropertyName="Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C" SummaryValuePrefix="Sum: ">
@context.Salary.ToString("C")
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Active" PropertyName="IsActive">
@context.IsActive
</GridColumn>
</GridColumns>
</Grid>

@code {
private IEnumerable<Employee> employees = default!;

private async Task<GridDataProviderResult<Employee>> EmployeesDataProvider(GridDataProviderRequest<Employee> request)
{
if (employees is null) // pull employees only one time for client-side filtering, sorting, and paging
employees = GetEmployees(); // call a service or an API to pull the employees

return await Task.FromResult(request.ApplyTo(employees));
}

private IEnumerable<Employee> GetEmployees()
{
return new List<Employee>
{
new Employee { Id = 107, Name = "Alice", Designation = "AI Engineer", DOJ = new DateOnly(1998, 11, 17), Salary = 7700, IsActive = true },
new Employee { Id = 103, Name = "Bob", Designation = "Senior DevOps Engineer", DOJ = new DateOnly(1985, 1, 5), Salary = 19000, IsActive = true },
new Employee { Id = 106, Name = "John", Designation = "Data Engineer", DOJ = new DateOnly(1995, 4, 17), Salary = 12000, IsActive = true },
new Employee { Id = 104, Name = "Pop", Designation = "Associate Architect", DOJ = new DateOnly(1985, 6, 8), Salary = 19000, IsActive = false },
new Employee { Id = 105, Name = "Ronald", Designation = "Senior Data Engineer", DOJ = new DateOnly(1991, 8, 23), Salary = 16500.50f, IsActive = true },
new Employee { Id = 102, Name = "Line", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 24000, IsActive = true },
new Employee { Id = 101, Name = "Daniel", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 21000, IsActive = true },
new Employee { Id = 113, Name = "Merlin", Designation = "Senior Consultant", DOJ = new DateOnly(1989, 10, 2), Salary = 13500, IsActive = true },
new Employee { Id = 117, Name = "Sharna", Designation = "Data Analyst", DOJ = new DateOnly(1994, 5, 12), Salary = 15800.10f, IsActive = true },
new Employee { Id = 108, Name = "Zayne", Designation = "Data Analyst", DOJ = new DateOnly(1991, 1, 1), Salary = 14000, IsActive = true },
new Employee { Id = 109, Name = "Isha", Designation = "App Maker", DOJ = new DateOnly(1996, 7, 1), Salary = 8000, IsActive = true },
new Employee { Id = 111, Name = "Glenda", Designation = "Data Engineer", DOJ = new DateOnly(1994, 1, 12), Salary = 17850, IsActive = true },
};
}

public record class Employee
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Designation { get; set; }
public DateOnly DOJ { get; set; }
public float Salary { get; set; }
public bool IsActive { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<Grid TItem="Employee"
Class="table table-hover table-bordered table-striped"
DataProvider="EmployeesDataProvider"
AllowSummary="true"
Responsive="true">

<GridColumns>
<GridColumn TItem="Employee" HeaderText="Id" PropertyName="Id">
@context.Id
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Employee Name" PropertyName="Name" SummaryType="GridSummaryColumnType.Count" SummaryValuePrefix="">
@context.Name
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Designation" PropertyName="Designation">
@context.Designation
</GridColumn>
<GridColumn TItem="Employee" HeaderText="DOJ" PropertyName="DOJ">
@context.DOJ
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Salary" HeaderTextAlignment="Alignment.End" TextAlignment="Alignment.End" PropertyName="Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C" SummaryValuePrefix="">
@context.Salary.ToString("C")
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Active" PropertyName="IsActive">
@context.IsActive
</GridColumn>
</GridColumns>
</Grid>

@code {
private IEnumerable<Employee> employees = default!;

private async Task<GridDataProviderResult<Employee>> EmployeesDataProvider(GridDataProviderRequest<Employee> request)
{
if (employees is null) // pull employees only one time for client-side filtering, sorting, and paging
employees = GetEmployees(); // call a service or an API to pull the employees

return await Task.FromResult(request.ApplyTo(employees));
}

private IEnumerable<Employee> GetEmployees()
{
return new List<Employee>
{
new Employee { Id = 107, Name = "Alice", Designation = "AI Engineer", DOJ = new DateOnly(1998, 11, 17), Salary = 7700, IsActive = true },
new Employee { Id = 103, Name = "Bob", Designation = "Senior DevOps Engineer", DOJ = new DateOnly(1985, 1, 5), Salary = 19000, IsActive = true },
new Employee { Id = 106, Name = "John", Designation = "Data Engineer", DOJ = new DateOnly(1995, 4, 17), Salary = 12000, IsActive = true },
new Employee { Id = 104, Name = "Pop", Designation = "Associate Architect", DOJ = new DateOnly(1985, 6, 8), Salary = 19000, IsActive = false },
new Employee { Id = 105, Name = "Ronald", Designation = "Senior Data Engineer", DOJ = new DateOnly(1991, 8, 23), Salary = 16500.50f, IsActive = true },
new Employee { Id = 102, Name = "Line", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 24000, IsActive = true },
new Employee { Id = 101, Name = "Daniel", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 21000, IsActive = true },
new Employee { Id = 113, Name = "Merlin", Designation = "Senior Consultant", DOJ = new DateOnly(1989, 10, 2), Salary = 13500, IsActive = true },
new Employee { Id = 117, Name = "Sharna", Designation = "Data Analyst", DOJ = new DateOnly(1994, 5, 12), Salary = 15800.10f, IsActive = true },
new Employee { Id = 108, Name = "Zayne", Designation = "Data Analyst", DOJ = new DateOnly(1991, 1, 1), Salary = 14000, IsActive = true },
new Employee { Id = 109, Name = "Isha", Designation = "App Maker", DOJ = new DateOnly(1996, 7, 1), Salary = 8000, IsActive = true },
new Employee { Id = 111, Name = "Glenda", Designation = "Data Engineer", DOJ = new DateOnly(1994, 1, 12), Salary = 17850, IsActive = true },
};
}

public record class Employee
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Designation { get; set; }
public DateOnly DOJ { get; set; }
public float Salary { get; set; }
public bool IsActive { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<Grid TItem="Employee"
Class="table table-hover table-bordered table-striped"
DataProvider="EmployeesDataProvider"
AllowSummary="true"
Locale="en-IN"
Responsive="true">

<GridColumns>
<GridColumn TItem="Employee" HeaderText="Id" PropertyName="Id">
@context.Id
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Employee Name" PropertyName="Name" SummaryType="GridSummaryColumnType.Count">
@context.Name
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Designation" PropertyName="Designation">
@context.Designation
</GridColumn>
<GridColumn TItem="Employee" HeaderText="DOJ" PropertyName="DOJ">
@context.DOJ
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Salary" HeaderTextAlignment="Alignment.End" TextAlignment="Alignment.End" PropertyName="Salary" SummaryType="GridSummaryColumnType.Sum" SummaryValueDisplayFormat="C">
@context.Salary.ToString("C", System.Globalization.CultureInfo.GetCultureInfo("en-IN"))
</GridColumn>
<GridColumn TItem="Employee" HeaderText="Active" PropertyName="IsActive">
@context.IsActive
</GridColumn>
</GridColumns>
</Grid>

@code {
private IEnumerable<Employee> employees = default!;

private async Task<GridDataProviderResult<Employee>> EmployeesDataProvider(GridDataProviderRequest<Employee> request)
{
if (employees is null) // pull employees only one time for client-side filtering, sorting, and paging
employees = GetEmployees(); // call a service or an API to pull the employees

return await Task.FromResult(request.ApplyTo(employees));
}

private IEnumerable<Employee> GetEmployees()
{
return new List<Employee>
{
new Employee { Id = 107, Name = "Alice", Designation = "AI Engineer", DOJ = new DateOnly(1998, 11, 17), Salary = 7700, IsActive = true },
new Employee { Id = 103, Name = "Bob", Designation = "Senior DevOps Engineer", DOJ = new DateOnly(1985, 1, 5), Salary = 19000, IsActive = true },
new Employee { Id = 106, Name = "John", Designation = "Data Engineer", DOJ = new DateOnly(1995, 4, 17), Salary = 12000, IsActive = true },
new Employee { Id = 104, Name = "Pop", Designation = "Associate Architect", DOJ = new DateOnly(1985, 6, 8), Salary = 19000, IsActive = false },
new Employee { Id = 105, Name = "Ronald", Designation = "Senior Data Engineer", DOJ = new DateOnly(1991, 8, 23), Salary = 16500.50f, IsActive = true },
new Employee { Id = 102, Name = "Line", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 24000, IsActive = true },
new Employee { Id = 101, Name = "Daniel", Designation = "Architect", DOJ = new DateOnly(1977, 1, 12), Salary = 21000, IsActive = true },
new Employee { Id = 113, Name = "Merlin", Designation = "Senior Consultant", DOJ = new DateOnly(1989, 10, 2), Salary = 13500, IsActive = true },
new Employee { Id = 117, Name = "Sharna", Designation = "Data Analyst", DOJ = new DateOnly(1994, 5, 12), Salary = 15800.10f, IsActive = true },
new Employee { Id = 108, Name = "Zayne", Designation = "Data Analyst", DOJ = new DateOnly(1991, 1, 1), Salary = 14000, IsActive = true },
new Employee { Id = 109, Name = "Isha", Designation = "App Maker", DOJ = new DateOnly(1996, 7, 1), Salary = 8000, IsActive = true },
new Employee { Id = 111, Name = "Glenda", Designation = "Data Engineer", DOJ = new DateOnly(1994, 1, 12), Salary = 17850, IsActive = true },
};
}

public record class Employee
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Designation { get; set; }
public DateOnly DOJ { get; set; }
public float Salary { get; set; }
public bool IsActive { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,33 @@
</Section>

<Section Size="HeadingSize.H2" Name="Summary with Filters and Paging" PageUrl="@pageUrl" Link="summary-with-filters-paging">
<Callout Color="CalloutColor.Danger">
<b>NOTE: </b>Summaries will be calculated based on the current page data.
</Callout>
<div class="mb-3">
Summaries will be calculated based on the current page data.
</div>
<Demo Type="typeof(Grid_Demo_02_Summary_with_Filters_Paging)" Tabs="true" />
</Section>

<Section Size="HeadingSize.H2" Name="Change prefix" PageUrl="@pageUrl" Link="change-prefix">
<div class="mb-3">
Set the <code>SummaryValuePrefix</code> parameter to custom string to change the prefix from the summary value.
</div>
<Demo Type="typeof(Grid_Demo_03_Change_Prefix)" Tabs="true" />
</Section>

<Section Size="HeadingSize.H2" Name="Remove prefix" PageUrl="@pageUrl" Link="remove-prefix">
<div class="mb-3">
Set the <code>SummaryValuePrefix</code> parameter to empty string to remove the prefix from the summary value.
</div>
<Demo Type="typeof(Grid_Demo_04_Remove_Prefix)" Tabs="true" />
</Section>

<Section Size="HeadingSize.H2" Name="Locale" PageUrl="@pageUrl" Link="locale">
<div class="mb-3">
Set the <code>Locale</code> parameter on the Grid to change the <code>CultureInfo</code> of the summary.
</div>
<Demo Type="typeof(Grid_Demo_05_Locale)" Tabs="true" />
</Section>

@code {
private const string pageUrl = RouteConstants.Demos_Grid_Summary_Documentation;
private const string pageTitle = "Blazor Grid - Summary";
Expand Down
2 changes: 1 addition & 1 deletion blazorbootstrap/Components/Grid/Grid.razor
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
}
else if (column.SummaryType != GridSummaryColumnType.None)
{
<td>@GetColumnSummaryValue(column.SummaryType, column.PropertyName, column.SummaryValueDisplayFormat)</td>
<td class="@column.TextAlignment.ToTextAlignmentClass()">@GetColumnSummaryValue(column.SummaryType, column.PropertyName, column.SummaryValueDisplayFormat, column.SummaryValuePrefix)</td>
}
}
}
Expand Down
41 changes: 32 additions & 9 deletions blazorbootstrap/Components/Grid/Grid.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,41 +123,40 @@ protected override Task OnParametersSetAsync()
.Where(column => column.Filterable && column.GetFilterOperator() != FilterOperator.None && !string.IsNullOrWhiteSpace(column.GetFilterValue()))
?.Select(column => new FilterItem(column.PropertyName, column.GetFilterValue(), column.GetFilterOperator(), column.StringComparison));

private string GetColumnSummaryValue(GridSummaryColumnType type, string propertyName, string format)
private string GetColumnSummaryValue(GridSummaryColumnType type, string propertyName, string format, string prefix)
{
string? prefix = null;
double value = 0;

if (type == GridSummaryColumnType.Average)
{
prefix = "Avg";
prefix ??= "Avg: ";
value = items?.Average(x => Convert.ToDouble(x.GetType().GetProperty(propertyName)?.GetValue(x))) ?? 0;
}
else if (type == GridSummaryColumnType.Count)
{
prefix = "Count";
prefix ??= "Count: ";
value = items?.Where(x => x.GetType().GetProperty(propertyName)?.GetValue(x) is not null).Count() ?? 0;
}
else if (type == GridSummaryColumnType.Max)
{
prefix = "Max";
prefix ??= "Max: ";
value = items?.Max(x => Convert.ToDouble(x.GetType().GetProperty(propertyName)?.GetValue(x))) ?? 0;
}
else if (type == GridSummaryColumnType.Min)
{
prefix = "Min";
prefix ??= "Min: ";
value = items?.Min(x => Convert.ToDouble(x.GetType().GetProperty(propertyName)?.GetValue(x))) ?? 0;
}
else if (type == GridSummaryColumnType.Sum)
{
prefix = "Total";
prefix ??= "Total: ";
value = items?.Sum(x => Convert.ToDouble(x.GetType().GetProperty(propertyName)?.GetValue(x))) ?? 0;
}

if (string.IsNullOrWhiteSpace(format))
return $"{prefix}: {value}";
return $"{prefix}{value}";
else
return $"{prefix}: {value.ToString(format)}";
return $"{prefix}{value.ToString(format, GetCultureInfo())}";
}

/// <summary>
Expand Down Expand Up @@ -353,6 +352,21 @@ private RenderFragment ChildSelectionTemplate(int rowIndex, TItem rowData) =>
builder.CloseElement(); // close: th
};

private CultureInfo GetCultureInfo()
{
if (string.IsNullOrWhiteSpace(Locale))
return CultureInfo.InvariantCulture;

try
{
return CultureInfo.GetCultureInfo(Locale);
}
catch (CultureNotFoundException)
{
return CultureInfo.InvariantCulture;
}
}

private IEnumerable<SortingItem<TItem>>? GetDefaultSorting() =>
!AllowSorting || columns == null || !columns.Any()
? null
Expand Down Expand Up @@ -893,6 +907,15 @@ private void SetFilters(IEnumerable<FilterItem> filterItems)
//[EditorRequired]
public string ItemsPerPageText { get; set; } = "Items per page"!;

/// <summary>
/// Gets or sets the locale.
/// <para>
/// Default value is 'en-US'.
/// </para>
/// </summary>
[Parameter]
public string? Locale { get; set; } = "en-US";

/// <summary>
/// This event is triggered when the user clicks on the row.
/// Set AllowRowClick to true to enable row clicking.
Expand Down
11 changes: 11 additions & 0 deletions blazorbootstrap/Components/Grid/GridColumn.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,17 @@ private async Task OnSortClickAsync()
[Parameter]
public string? SummaryValueDisplayFormat { get; set; }

/// <summary>
/// Gets or sets the summary value prefix. If set, it will be displayed before the summary value.
/// Otherwise, based on the <see cref="SummaryType"/>, default prefix will be displayed.
/// To remove the default prefix, set this property to an empty string.
/// <para>
/// Example: "Total: ", "Average: ", etc.
/// </para>
/// </summary>
[Parameter]
public string? SummaryValuePrefix { get; set; }

/// <summary>
/// Gets or sets the text alignment.
/// </summary>
Expand Down
Loading
Loading