SamovarGrid 8.0.0-beta.3
This is a prerelease version of SamovarGrid.
dotnet add package SamovarGrid --version 8.0.0-beta.3
NuGet\Install-Package SamovarGrid -Version 8.0.0-beta.3
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SamovarGrid" Version="8.0.0-beta.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add SamovarGrid --version 8.0.0-beta.3
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: SamovarGrid, 8.0.0-beta.3"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install SamovarGrid as a Cake Addin #addin nuget:?package=SamovarGrid&version=8.0.0-beta.3&prerelease // Install SamovarGrid as a Cake Tool #tool nuget:?package=SamovarGrid&version=8.0.0-beta.3&prerelease
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Basic sample
Add the following code to your _Layout.cshtml or App.razor file
<head>
...
<link href="_content/SamovarGrid/samovar.grid.css" rel="stylesheet" />
...
</head>
_Imports.razor
@using static Microsoft.AspNetCore.Components.Web.RenderMode
Index.razor
add @rendermode InteractiveServer to your page
@page "/"
@rendermode InteractiveServer
@using Samovar.Grid.Server.Test.Data
@using System.ComponentModel.DataAnnotations
@using System
@using System.Diagnostics;
@inject WeatherForecastService ForecastService
<h1>Common tests</h1>
<div class="mb-3">
<button class="btn btn-primary" @onclick="loadData">load data</button>
</div>
<div class="row">
<div class="col-10">
<SmGrid @ref=@grid
Data=@forecasts
Height=@gridHeight
Width=@gridWidth
ShowDetailRow=@showDetailRow
PageSize=@pageSize
EditMode=@gridEditMode
SelectionMode=@selectionMode
ColumnResizeMode=@columnResizeMode
CssClass=@cssClass
@bind-SingleSelectedDataRow=@selectedRow
@bind-MultipleSelectedDataRows=@selectedRows
RowEditBegin="@((WeatherForecast data) => RowEditBeginHandler(data))"
RowInserting="@((WeatherForecast data) => RowInsertingHandler(data))"
RowRemoving="@((WeatherForecast data) => RowRemovingHandler(data))">
<Columns>
<Column Title="Date" Field="@nameof(WeatherForecast.Date)" Width="100px" />
<Column Title="TemperatureC" Field="@nameof(WeatherForecast.TemperatureC)" Width="1*" />
<Column Title="TemperatureF" Field="@nameof(WeatherForecast.TemperatureF)" Width=@columnWidth />
<Column Field="@nameof(WeatherForecast.Summary)" Width="1*" />
<CommandColumn EditButtonVisible=true DeleteButtonVisible=true NewButtonVisible=true Width="150px" />
</Columns>
<EditPopupTitleTemplate Context="context">
@{
WeatherForecast data = context as WeatherForecast;
<div>@($"Temperature on {data!.Date:yyyy-MM-dd}")</div>
}
</EditPopupTitleTemplate>
<DetailRowTemplate Context="mydata">
@{
WeatherForecast data = mydata as WeatherForecast;
<div class="form-group row mb-2">
<label class="col-2 col-form-label">Date</label>
<div class="col-10">
@($"{data.Date:yyyy-MM-dd}")
</div>
</div>
<div class="form-group row mb-2">
<label class="col-2 col-form-label">Temp.C</label>
<div class="col-10">
@data.TemperatureC
</div>
</div>
<div class="form-group row mb-2">
<label class="col-2 col-form-label">Temp.F</label>
<div class="col-10">
@data.TemperatureF
</div>
</div>
<div class="form-group row mb-2">
<label class="col-2 col-form-label">Summary</label>
<div class="col-10">
@data.Summary
</div>
</div>
}
</DetailRowTemplate>
</SmGrid>
</div>
<div class="col-2">
<div class="mb-3">
<label for="pageSize" class="form-label">Page size</label>
<input type="text" class="form-control" id="pageSize" @bind=pageSize />
</div>
<div class="mb-3">
<label for="columnWidth">Column width</label>
<input type="text" class="form-control" id="columnWidth" @bind=columnWidth />
</div>
<div class="mb-3">
<label for="gridHeight">Grid height</label>
<input type="text" class="form-control" id="gridHeight" @bind=gridHeight />
</div>
<div class="mb-3">
<label for="gridWidth">Grid width</label>
<input type="text" class="form-control" id="gridWidth" @bind=gridWidth />
</div>
<div class="mb-3">
<label for="gridEditMode" class="form-label">Grid edit mode</label>
<select id="gridEditMode" class="form-select form-select-lg" @bind=gridEditMode>
<option value=@GridEditMode.None>None</option>
<option value=@GridEditMode.Form>Form</option>
<option value=@GridEditMode.Popup>Popup</option>
</select>
</div>
<div class="mb-3">
<label for="columnResizeMode" class="form-label">Column resize mode</label>
<select id="columnResizeMode" class="form-select form-select-lg" @bind=columnResizeMode>
<option value=@GridColumnResizeMode.None>None</option>
<option value=@GridColumnResizeMode.Sliding>Sliding</option>
<option value=@GridColumnResizeMode.Block>Block</option>
</select>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" @bind=showDetailRow id="showDetailRow">
<label class="form-check-label" for="showDetailRow">
Show detail row
</label>
</div>
</div>
<div class="mb-3">
<button class="btn btn-primary" @onclick="collapseAllDetailRows">Collapse all detail rows</button>
</div>
<div class="mb-3">
<button class="btn btn-primary" @onclick="changeStyle">Change table style</button>
</div>
<div class="mb-3">
<label for="rowSelectionMode" class="form-label">Row selection mode</label>
<select id="rowSelectionMode" class="form-select form-select-lg" @bind=selectionMode>
<option value=@RowSelectionMode.None>None</option>
<option value=@RowSelectionMode.Single>Single</option>
<option value=@RowSelectionMode.Multiple>Multiple</option>
</select>
</div>
@if (selectedRow is not null)
{
<div class="mb-3 row">
<div class="col-8">@($"{selectedRow.Summary} Temp. {selectedRow.TemperatureC} C")</div>
<div class="col-4">
<button class="btn btn-danger mb-3" @onclick="deselectSingleSelectedItem">deselect</button>
</div>
</div>
}
@if (selectedRows != null)
{
@foreach (var item in selectedRows)
{
<div class="mb-3 row">
<div class="col-8">@($"{item.Summary} Temp. {item.TemperatureC} C")</div>
<div class="col-4">
<button class="btn btn-danger mb-3" @onclick=@(()=>{selectedRows = selectedRows.Except([item]);})>deselect</button>
</div>
</div>
}
}
</div>
</div>
@code {
private List<WeatherForecast>? forecasts;
SmGrid<WeatherForecast>? grid;
WeatherForecast? selectedRow = null;
uint pageSize = 10;
string gridWidth = "1200px";
string gridHeight = "600px";
string columnWidth = "150px";
string? cssClass;
RowSelectionMode selectionMode = RowSelectionMode.Single;
GridEditMode gridEditMode = GridEditMode.Form;
GridColumnResizeMode columnResizeMode = GridColumnResizeMode.Sliding;
IEnumerable<WeatherForecast> selectedRows = [];
bool showDetailRow = true;
async Task loadData()
{
forecasts = (await ForecastService.GetForecastAsync(DateTime.Now)).ToList();
}
Task changeStyle()
{
cssClass = "blueTable";
return Task.CompletedTask;
}
Task RowEditBeginHandler(WeatherForecast item)
{
return Task.CompletedTask;
}
Task RowInsertingHandler(WeatherForecast item)
{
forecasts ??= new List<WeatherForecast>();
forecasts = ((new WeatherForecast[] { item }).Concat(forecasts)).ToList();
return Task.CompletedTask;
}
Task RowRemovingHandler(WeatherForecast item)
{
forecasts = forecasts?.Except([item]).ToList();
return Task.CompletedTask;
}
Task deselectSingleSelectedItem()
{
selectedRow = null;
return Task.CompletedTask;
}
protected override Task OnInitializedAsync()
{
return base.OnInitializedAsync();
}
async Task collapseAllDetailRows() => await grid!.CollapseAllDetailRows();
}
EditTemplate.razor
add @rendermode InteractiveServer to your page
@page "/edit-template"
@rendermode InteractiveServer
@using Samovar.Grid.Server.Test.Data
@using System.ComponentModel.DataAnnotations
@using System
@inject WeatherForecastService ForecastService
<h1>Insert / Edit Templates</h1>
<div class="form-group row align-items-center mb-3">
<label for="gridEditMode" class="form-label col-1">Grid edit mode</label>
<div class="col-1">
<select id="gridEditMode" class="col-10 form-select form-select-lg" @bind=gridEditMode>
<option value=@GridEditMode.None>None</option>
<option value=@GridEditMode.Form>Form</option>
<option value=@GridEditMode.Popup>Popup</option>
</select>
</div>
</div>
<SmGrid @ref=grid
Data="forecasts"
FilterMode=GridFilterMode.FilterRow
Height="600px"
RowEditBegin="@((WeatherForecast data) => RowEditBeginHandler(data))"
RowInsertBegin=@RowInsertBeginHandler
EditMode=@gridEditMode
DataNavigationMode=NavigationMode.Paging
SelectionMode=RowSelectionMode.Multiple>
<Columns>
<CommandColumn EditButtonVisible=true NewButtonVisible=true DeleteButtonVisible=false Width="150px" />
<Column Title="Summary" Field="@nameof(WeatherForecast.Summary)">
<CellShowTemplate>
@{
WeatherForecast data = context as WeatherForecast;
<div style="white-space:break-spaces">@($"Summary: {data!.Summary}")</div>
}
</CellShowTemplate>
</Column>
<Column Title="Date" Field="@nameof(WeatherForecast.Date)" />
<Column Title="TemperatureC" Field="@nameof(WeatherForecast.TemperatureC)" />
<Column Title="TemperatureF" Field="@nameof(WeatherForecast.TemperatureF)" />
</Columns>
<EditFormTemplate>
<EditForm Model="@EditContext" Context="EditFormContext" OnValidSubmit=HandleValidCustomEditSubmit>
<DataAnnotationsValidator />
<div class="form-group row mb-2">
<label class="col-2 col-form-label" for="temperatureC">Temp.C</label>
<div class="col-10">
<InputNumber class="form-control" id="temperatureC" TValue="int?" @bind-Value="EditContext.TemperatureC" />
</div>
</div>
<div class="form-group row mb-2">
<label class="col-2 col-form-label" for="summary">Summary</label>
<div class="col-10">
<InputText class="form-control" id="summary" @bind-Value="EditContext.Summary" />
</div>
</div>
<div class="row mb-2">
<ValidationSummary />
</div>
<div class="row">
<div class="col s-flex justify-content-end">
<button type="submit" class="btn btn-outline-primary mx-1">update</button>
<button type="button" class="btn btn-outline-secondary mx-1" @onclick="HandleCancelCustomEdit">cancel</button>
</div>
</div>
</EditForm>
</EditFormTemplate>
<InsertFormTemplate>
<EditForm Model="@InsertContext" Context="EditFormContext" OnValidSubmit=HandleValidInsertingSubmit>
<DataAnnotationsValidator />
<div class="form-group row mb-2">
<label class="col-2 col-form-label" for="temperatureC">Temp.C</label>
<div class="col-10">
<InputNumber class="form-control" id="temperatureC" TValue="int?" @bind-Value="InsertContext.TemperatureC" />
</div>
</div>
<div class="form-group row mb-2">
<label class="col-2 col-form-label" for="summary">Summary</label>
<div class="col-10">
<InputText class="form-control" id="summary" @bind-Value="InsertContext.Summary" />
</div>
</div>
<div class="form-row">
<ValidationSummary />
</div>
<div class="row">
<div class="col s-flex justify-content-end">
<button type="submit" class="btn btn-outline-primary mx-1">add</button>
<button type="button" class="btn btn-outline-secondary mx-1" @onclick="OnCancelInsertingButtonClick">cancel</button>
</div>
</div>
</EditForm>
</InsertFormTemplate>
</SmGrid>
@code {
private List<WeatherForecast> forecasts;
FormEditContext EditContext = null;
FormInsertContext InsertContext = null;
SmGrid<WeatherForecast> grid;
GridEditMode gridEditMode = GridEditMode.Form;
protected override async Task OnInitializedAsync()
{
forecasts = (await ForecastService.GetForecastAsync(DateTime.Now)).ToList();
}
void RowEditBeginHandler(WeatherForecast item)
{
EditContext = new FormEditContext(item);
// var context = new Microsoft.AspNetCore.Components.Forms.EditContext(item);
// context.
}
void RowInsertBeginHandler()
{
InsertContext = new FormInsertContext();
}
async Task HandleValidCustomEditSubmit()
{
EditContext.DataItem.TemperatureC = EditContext.TemperatureC;
EditContext.DataItem.Summary = EditContext.Summary;
await grid.CommitCustomRowEdit(EditContext.DataItem);
}
async Task HandleValidInsertingSubmit()
{
var newItem = new WeatherForecast
{
Summary = InsertContext.Summary,
Date = DateTime.Now,
TemperatureC = InsertContext.TemperatureC
};
forecasts = ((new WeatherForecast[] { newItem }).Concat(forecasts)).ToList();
await grid.CancelRowInsert();
StateHasChanged();
}
async Task HandleCancelCustomEdit()
{
await grid.CancelCustomRowEdit(EditContext.DataItem);
EditContext = null;
}
async Task OnCancelInsertingButtonClick()
{
await grid.CancelRowInsert();
EditContext = null;
}
class FormEditContext
{
public FormEditContext(WeatherForecast dataItem)
{
DataItem = dataItem;
TemperatureC = dataItem.TemperatureC;
Summary = dataItem.Summary;
}
public WeatherForecast DataItem { get; set; }
[Required]
[StringLength(maximumLength: 32, MinimumLength = 4, ErrorMessage = "The description should be 4 to 32 characters.")]
public string Summary { get; set; }
public int? TemperatureC { get; set; }
}
internal class FormInsertContext
{
internal FormInsertContext()
{
Summary = "[init summary value}";
}
[Required]
public int? TemperatureC { get; set; }
[Required]
[StringLength(maximumLength: 32, MinimumLength = 4, ErrorMessage = "The description should be 4 to 32 characters.")]
public string Summary { get; set; }
}
}
CellTemplate.razor
add @rendermode InteractiveServer to your page
@page "/cell-template"
@rendermode InteractiveServer
@using Samovar.Grid.Server.Test.Data
@using System.ComponentModel.DataAnnotations
@using System
@inject WeatherForecastService ForecastService
<h1>Cell Templates</h1>
<style>
.above-degree-style {
color: red;
font-weight: bold;
}
.below-degree-style {
color: blue;
font-weight: bold;
}
</style>
<SmGrid @ref=grid
Data="forecasts"
FilterMode=GridFilterMode.FilterRow
Height="600px"
DataNavigationMode=NavigationMode.Paging
SelectionMode=RowSelectionMode.Multiple>
<Columns>
<Column Field="@nameof(WeatherForecast.Summary)">
<CellShowTemplate>
@{
<div>@($"Summary: {(context as WeatherForecast)!.Summary}")</div>
}
</CellShowTemplate>
</Column>
<Column Field="@nameof(WeatherForecast.Date)">
<CellShowTemplate>
@{
<div>@($"{(context as WeatherForecast)!.Date:yyyy-MM-dd}")</div>
}
</CellShowTemplate>
</Column>
<Column Field="@nameof(WeatherForecast.TemperatureC)">
<CellShowTemplate>
@{
var temperature = (context as WeatherForecast)!.TemperatureC;
if (temperature > 0)
{
<div class="above-degree-style">@($"{temperature} C")</div>
}
else
{
<div class="below-degree-style">@($"{temperature} C")</div>
}
}
</CellShowTemplate>
</Column>
</Columns>
</SmGrid>
@code {
private List<WeatherForecast> forecasts;
SmGrid<WeatherForecast> grid;
GridEditMode gridEditMode = GridEditMode.Form;
protected override async Task OnInitializedAsync()
{
forecasts = (await ForecastService.GetForecastAsync(DateTime.Now)).ToList();
}
}
Filter.razor
add @rendermode InteractiveServer to your page
@page "/filter"
@rendermode InteractiveServer
@using Samovar.Grid.Server.Test.Data
@using System.ComponentModel.DataAnnotations
@using System
@inject WeatherForecastService ForecastService
<h1>Filter</h1>
<div class="form-group row">
<label for="filterMode" class="col-1 col-form-label m-2">Filter mode</label>
<div class="col-1 m-2">
<select id="filterMode" class="form-select form-select-lg" @bind=filterMode>
<option value=@GridFilterMode.None>None</option>
<option value=@GridFilterMode.Custom>Custom</option>
<option value=@GridFilterMode.FilterRow>FilterRow</option>
</select>
</div>
<button class="col-2 btn btn-primary m-3" @onclick="ApplyCustomFilter">Apply custom filter</button>
<button class="col-2 btn btn-primary m-3" @onclick="ResetCustomFilter">reset custom filter</button>
</div>
<SmGrid @ref=grid
Data=forecasts
FilterMode=filterMode
Height="600px">
<Columns>
<Column Field="@nameof(WeatherForecast.Summary)" />
<Column Field="@nameof(WeatherForecast.Date)" />
<Column Field="@nameof(WeatherForecast.TemperatureC)" />
</Columns>
</SmGrid>
@code {
private List<WeatherForecast> forecasts;
SmGrid<WeatherForecast> grid;
GridFilterMode filterMode = GridFilterMode.Custom;
protected override async Task OnInitializedAsync()
{
forecasts = (await ForecastService.GetForecastAsync(DateTime.Now)).ToList();
}
async Task ApplyCustomFilter()
{
Func<WeatherForecast, bool> filter = w => w.Summary.ToLower() == "cool";
await grid.ApplyCustomFilter(filter);
}
async Task ResetCustomFilter()
{
await grid.ResetCustomFilter();
}
}
Virtual.razor
add @rendermode InteractiveServer to your page
@page "/virtual"
@rendermode InteractiveServer
@using Samovar.Grid.Server.Test.Data
@using System.ComponentModel.DataAnnotations
@using System
@inject WeatherForecastService ForecastService
<h1>Virtual</h1>
<SmGrid Data=forecasts DataNavigationMode=NavigationMode.Virtual>
<Columns>
<Column Field="@nameof(WeatherForecast.Date)" />
<Column Field="@nameof(WeatherForecast.Summary)" />
<Column Field="@nameof(WeatherForecast.TemperatureC)" />
</Columns>
</SmGrid>
@code {
private List<WeatherForecast> forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = (await ForecastService.GetForecastAsync(DateTime.Now)).ToList();
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Microsoft.AspNetCore.Components.Web (>= 8.0.6)
- System.Reactive (>= 6.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated | |
---|---|---|---|
8.0.0-beta.3 | 63 | 7/10/2024 | |
2.3.1 | 2,438 | 7/26/2020 | |
2.1.0 | 663 | 2/22/2020 | |
2.0.1 | 499 | 12/18/2019 | |
1.0.1 | 555 | 10/30/2019 |