igniteui-cli 15.1.0 → 15.2.1-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/PromptSession.d.ts +1 -1
- package/lib/PromptSession.js +2 -2
- package/lib/commands/ai-config.d.ts +3 -5
- package/lib/commands/ai-config.js +68 -23
- package/lib/commands/new.js +1 -1
- package/package.json +4 -4
- package/templates/blazor/igb/index.d.ts +1 -0
- package/templates/blazor/igb/index.js +12 -0
- package/templates/blazor/igb/projects/ai-config/files/AGENTS.md +65 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/AGENTS.md +65 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/README.md +61 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/SKILL.md +118 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/charts.md +302 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/data-display.md +350 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/feedback.md +178 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/form-controls.md +365 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/layout-manager.md +180 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/layout.md +322 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/mcp-setup.md +78 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-components/references/setup.md +214 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-generate-from-image-design/SKILL.md +284 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-generate-from-image-design/references/component-mapping.md +281 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-generate-from-image-design/references/gotchas.md +503 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/SKILL.md +188 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/data-operations.md +264 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/editing.md +297 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/features.md +447 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/mcp-setup.md +78 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/paging-remote.md +299 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/sizing.md +284 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/state.md +160 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/structure.md +497 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/types.md +553 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-theming/SKILL.md +259 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-theming/references/common-patterns.md +276 -0
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-theming/references/mcp-setup.md +81 -0
- package/templates/blazor/igb/projects/ai-config/index.d.ts +22 -0
- package/templates/blazor/igb/projects/ai-config/index.js +62 -0
- package/templates/blazor/index.d.ts +3 -0
- package/templates/blazor/index.js +11 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# State Persistence
|
|
2
|
+
|
|
3
|
+
> **Part of the [`igniteui-blazor-grids`](../SKILL.md) skill hub.**
|
|
4
|
+
> For grid setup and column configuration — see [`structure.md`](./structure.md).
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- [State Persistence](#state-persistence)
|
|
9
|
+
- [Key Rules](#key-rules)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## State Persistence
|
|
14
|
+
|
|
15
|
+
Save and restore the full grid state (sorting, filtering, grouping, paging, selection, column order, column widths, column visibility, pinning) to survive page reloads, navigation, or user sessions.
|
|
16
|
+
|
|
17
|
+
### Save state
|
|
18
|
+
|
|
19
|
+
```razor
|
|
20
|
+
@inject IJSRuntime JS
|
|
21
|
+
|
|
22
|
+
<IgbGrid @ref="grid" Data="data" PrimaryKey="Id" AutoGenerate="false"
|
|
23
|
+
Width="100%" Height="500px">
|
|
24
|
+
<IgbColumn Field="Name" Sortable="true" Filterable="true" />
|
|
25
|
+
<IgbColumn Field="Department" Sortable="true" Groupable="true" />
|
|
26
|
+
<IgbColumn Field="Salary" DataType="GridColumnDataType.Currency" HasSummary="true" />
|
|
27
|
+
<IgbPaginator PerPage="10" />
|
|
28
|
+
</IgbGrid>
|
|
29
|
+
|
|
30
|
+
<IgbButton @onclick="SaveState">Save State</IgbButton>
|
|
31
|
+
<IgbButton @onclick="RestoreState">Restore State</IgbButton>
|
|
32
|
+
|
|
33
|
+
@code {
|
|
34
|
+
private IgbGrid grid = default!;
|
|
35
|
+
|
|
36
|
+
private async Task SaveState()
|
|
37
|
+
{
|
|
38
|
+
var state = await grid.GetStateAsync();
|
|
39
|
+
var json = state.ToJson();
|
|
40
|
+
await JS.InvokeVoidAsync("localStorage.setItem", "gridState", json);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private async Task RestoreState()
|
|
44
|
+
{
|
|
45
|
+
var json = await JS.InvokeAsync<string>("localStorage.getItem", "gridState");
|
|
46
|
+
if (!string.IsNullOrEmpty(json))
|
|
47
|
+
{
|
|
48
|
+
var state = IgbGridState.FromJson(json);
|
|
49
|
+
await grid.SetStateAsync(state);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### What state includes
|
|
56
|
+
|
|
57
|
+
| State Category | Properties Saved |
|
|
58
|
+
|---|---|
|
|
59
|
+
| Columns | Order, width, visibility, pinned, data type |
|
|
60
|
+
| Sorting | Active sort expressions and directions |
|
|
61
|
+
| Filtering | Active filter expressions |
|
|
62
|
+
| Grouping | Active group-by expressions (IgbGrid only) |
|
|
63
|
+
| Paging | Current page, page size |
|
|
64
|
+
| Selection | Selected rows, selected cells, selected columns |
|
|
65
|
+
| Advanced Filtering | Advanced filtering expressions tree |
|
|
66
|
+
| Row expansion | Expanded row IDs (Tree Grid, Hierarchical Grid) |
|
|
67
|
+
| Column moving | Column positions after user reordering |
|
|
68
|
+
|
|
69
|
+
### Auto-save on navigation
|
|
70
|
+
|
|
71
|
+
```razor
|
|
72
|
+
@implements IAsyncDisposable
|
|
73
|
+
|
|
74
|
+
<IgbGrid @ref="grid" Data="data" PrimaryKey="Id">
|
|
75
|
+
...
|
|
76
|
+
</IgbGrid>
|
|
77
|
+
|
|
78
|
+
@code {
|
|
79
|
+
private IgbGrid grid = default!;
|
|
80
|
+
|
|
81
|
+
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
82
|
+
{
|
|
83
|
+
if (firstRender)
|
|
84
|
+
{
|
|
85
|
+
await RestoreState();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public async ValueTask DisposeAsync()
|
|
90
|
+
{
|
|
91
|
+
await SaveState();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private async Task SaveState()
|
|
95
|
+
{
|
|
96
|
+
var state = await grid.GetStateAsync();
|
|
97
|
+
await JS.InvokeVoidAsync("localStorage.setItem", "gridState", state.ToJson());
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private async Task RestoreState()
|
|
101
|
+
{
|
|
102
|
+
var json = await JS.InvokeAsync<string>("localStorage.getItem", "gridState");
|
|
103
|
+
if (!string.IsNullOrEmpty(json))
|
|
104
|
+
{
|
|
105
|
+
await grid.SetStateAsync(IgbGridState.FromJson(json));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Selective state save/restore
|
|
112
|
+
|
|
113
|
+
Save only specific parts of the state:
|
|
114
|
+
|
|
115
|
+
```razor
|
|
116
|
+
@code {
|
|
117
|
+
private async Task SaveSortingOnly()
|
|
118
|
+
{
|
|
119
|
+
var state = await grid.GetStateAsync(new IgbGridStateOptions
|
|
120
|
+
{
|
|
121
|
+
Sorting = true,
|
|
122
|
+
Filtering = false,
|
|
123
|
+
Paging = false,
|
|
124
|
+
Selection = false,
|
|
125
|
+
Columns = false
|
|
126
|
+
});
|
|
127
|
+
await JS.InvokeVoidAsync("localStorage.setItem", "gridSorting", state.ToJson());
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### State with server storage
|
|
133
|
+
|
|
134
|
+
```razor
|
|
135
|
+
@code {
|
|
136
|
+
private async Task SaveToServer()
|
|
137
|
+
{
|
|
138
|
+
var state = await grid.GetStateAsync();
|
|
139
|
+
var json = state.ToJson();
|
|
140
|
+
await UserPreferencesApi.SaveGridStateAsync(userId, "employeesGrid", json);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private async Task LoadFromServer()
|
|
144
|
+
{
|
|
145
|
+
var json = await UserPreferencesApi.GetGridStateAsync(userId, "employeesGrid");
|
|
146
|
+
if (!string.IsNullOrEmpty(json))
|
|
147
|
+
{
|
|
148
|
+
await grid.SetStateAsync(IgbGridState.FromJson(json));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Key Rules
|
|
157
|
+
|
|
158
|
+
1. **`PrimaryKey` must be set on the grid** for state persistence to work reliably (especially for selection and row pinning).
|
|
159
|
+
2. **State serialization is JSON** - `GetStateAsync()` returns an object that can be serialized with `ToJson()`.
|
|
160
|
+
3. **Restore state in `OnAfterRenderAsync`** - the grid must be rendered before you can call `SetStateAsync`.
|
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
# Structure - Grid Setup, Columns, Sorting, Filtering & Selection
|
|
2
|
+
|
|
3
|
+
> **Part of the [`igniteui-blazor-grids`](../SKILL.md) skill hub.**
|
|
4
|
+
> For specialized grid types (Tree Grid, Hierarchical Grid, Pivot Grid, Grid Lite) — see [`types.md`](./types.md).
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- [Quick Start](#quick-start)
|
|
9
|
+
- [Column Configuration](#column-configuration)
|
|
10
|
+
- [Column Templates](#column-templates)
|
|
11
|
+
- [Column Groups (Multi-Column Headers)](#column-groups-multi-column-headers)
|
|
12
|
+
- [Multi-Row Layout (MRL)](#multi-row-layout-mrl)
|
|
13
|
+
- [Column Pinning](#column-pinning)
|
|
14
|
+
- [Sorting](#sorting)
|
|
15
|
+
- [Filtering](#filtering)
|
|
16
|
+
- [Selection](#selection)
|
|
17
|
+
- [Key Rules](#key-rules)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Register the module in Program.cs
|
|
24
|
+
|
|
25
|
+
```csharp
|
|
26
|
+
using IgniteUI.Blazor.Controls;
|
|
27
|
+
|
|
28
|
+
builder.Services.AddIgniteUIBlazor(typeof(IgbGridModule));
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Add `@using` in _Imports.razor
|
|
32
|
+
|
|
33
|
+
```razor
|
|
34
|
+
@using IgniteUI.Blazor.Controls
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 3. Basic grid markup
|
|
38
|
+
|
|
39
|
+
```razor
|
|
40
|
+
<IgbGrid Data="employees" PrimaryKey="Id" AutoGenerate="false"
|
|
41
|
+
Width="100%" Height="500px">
|
|
42
|
+
<IgbColumn Field="Id" Header="ID" DataType="GridColumnDataType.Number" />
|
|
43
|
+
<IgbColumn Field="Name" Header="Full Name" DataType="GridColumnDataType.String" Sortable="true" />
|
|
44
|
+
<IgbColumn Field="HireDate" Header="Hire Date" DataType="GridColumnDataType.Date" Filterable="true" />
|
|
45
|
+
<IgbColumn Field="Salary" Header="Salary" DataType="GridColumnDataType.Currency" />
|
|
46
|
+
<IgbColumn Field="IsActive" Header="Active" DataType="GridColumnDataType.Boolean" />
|
|
47
|
+
</IgbGrid>
|
|
48
|
+
|
|
49
|
+
@code {
|
|
50
|
+
private List<Employee> employees = new();
|
|
51
|
+
|
|
52
|
+
protected override void OnInitialized()
|
|
53
|
+
{
|
|
54
|
+
employees = EmployeeService.GetAll();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 4. Auto-generated columns
|
|
60
|
+
|
|
61
|
+
```razor
|
|
62
|
+
<IgbGrid Data="employees" PrimaryKey="Id" AutoGenerate="true"
|
|
63
|
+
Width="100%" Height="500px" />
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
When `AutoGenerate="true"`, the grid creates a column for each public property of the data type. You can hook `AutoGenerating` to customize or skip columns:
|
|
67
|
+
|
|
68
|
+
```razor
|
|
69
|
+
<IgbGrid Data="employees" PrimaryKey="Id" AutoGenerate="true"
|
|
70
|
+
AutoGenerating="OnAutoGenerating" />
|
|
71
|
+
|
|
72
|
+
@code {
|
|
73
|
+
private void OnAutoGenerating(IgbColumnAutoGenerateEventArgs args)
|
|
74
|
+
{
|
|
75
|
+
if (args.Column.Field == "InternalCode")
|
|
76
|
+
{
|
|
77
|
+
args.Cancel = true; // skip this column
|
|
78
|
+
}
|
|
79
|
+
else if (args.Column.Field == "Salary")
|
|
80
|
+
{
|
|
81
|
+
args.Column.DataType = GridColumnDataType.Currency;
|
|
82
|
+
args.Column.Editable = false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Column Configuration
|
|
91
|
+
|
|
92
|
+
### Column data types
|
|
93
|
+
|
|
94
|
+
Use `GridColumnDataType` to set the type. This controls sorting, filtering, editing, and display:
|
|
95
|
+
|
|
96
|
+
| Data Type | Enum Value | Behavior |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| String | `GridColumnDataType.String` | Text display and filtering |
|
|
99
|
+
| Number | `GridColumnDataType.Number` | Numeric sorting and filtering |
|
|
100
|
+
| Boolean | `GridColumnDataType.Boolean` | Checkbox display |
|
|
101
|
+
| Date | `GridColumnDataType.Date` | Date picker in edit mode |
|
|
102
|
+
| DateTime | `GridColumnDataType.DateTime` | Date-time picker in edit mode |
|
|
103
|
+
| Currency | `GridColumnDataType.Currency` | Formatted currency display |
|
|
104
|
+
| Percent | `GridColumnDataType.Percent` | Formatted percentage display |
|
|
105
|
+
| Image | `GridColumnDataType.Image` | Renders image from URL |
|
|
106
|
+
|
|
107
|
+
### Key column parameters
|
|
108
|
+
|
|
109
|
+
| Parameter | Type | Default | Description |
|
|
110
|
+
|---|---|---|---|
|
|
111
|
+
| `Field` | `string` | - | Property name on the data object |
|
|
112
|
+
| `Header` | `string` | Field name | Column header text |
|
|
113
|
+
| `DataType` | `GridColumnDataType` | `String` | Data type for display, sort, filter, edit |
|
|
114
|
+
| `Width` | `string` | - | Column width (e.g., `"200px"`, `"20%"`) |
|
|
115
|
+
| `MinWidth` | `string` | - | Minimum column width |
|
|
116
|
+
| `MaxWidth` | `string` | - | Maximum column width |
|
|
117
|
+
| `Sortable` | `bool` | `false` | Enables sorting on this column |
|
|
118
|
+
| `Filterable` | `bool` | `true` | Enables filtering on this column |
|
|
119
|
+
| `Filterable` | `bool` | `false` | Disable filtering on this column |
|
|
120
|
+
| `Editable` | `bool` | `false` | Enables editing on this column |
|
|
121
|
+
| `Resizable` | `bool` | `false` | Enables column resizing |
|
|
122
|
+
| `Movable` | `bool` | `false` | Enables column moving |
|
|
123
|
+
| `Hidden` | `bool` | `false` | Hides the column |
|
|
124
|
+
| `Pinned` | `bool` | `false` | Pins the column |
|
|
125
|
+
| `Groupable` | `bool` | `false` | Enables grouping for this column (IgbGrid only) |
|
|
126
|
+
| `HasSummary` | `bool` | `false` | Enables summaries for this column |
|
|
127
|
+
| `DisablePinning` | `bool` | `false` | Disables pinning for this column |
|
|
128
|
+
| `DisableHiding` | `bool` | `false` | Prevents hiding this column |
|
|
129
|
+
| `CellClasses` | `string` | - | CSS class(es) to apply to cells |
|
|
130
|
+
| `HeaderClasses` | `string` | - | CSS class(es) to apply to the header |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Column Templates
|
|
135
|
+
|
|
136
|
+
### Cell template
|
|
137
|
+
|
|
138
|
+
Use the `BodyTemplate` render fragment to customize the cell display:
|
|
139
|
+
|
|
140
|
+
```razor
|
|
141
|
+
<IgbColumn Field="Salary" Header="Salary" DataType="GridColumnDataType.Currency">
|
|
142
|
+
<BodyTemplate>
|
|
143
|
+
@{
|
|
144
|
+
var cell = (IgbCellTemplateContext)context;
|
|
145
|
+
var salary = (decimal)cell.Cell.Value;
|
|
146
|
+
}
|
|
147
|
+
<span class="@(salary > 50000 ? "high-salary" : "")">
|
|
148
|
+
@salary.ToString("C")
|
|
149
|
+
</span>
|
|
150
|
+
</BodyTemplate>
|
|
151
|
+
</IgbColumn>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Header template
|
|
155
|
+
|
|
156
|
+
```razor
|
|
157
|
+
<IgbColumn Field="Name" Header="Name">
|
|
158
|
+
<HeaderTemplate>
|
|
159
|
+
<div style="display: flex; align-items: center; gap: 4px;">
|
|
160
|
+
<IgbIcon Name="person" Collection="material" />
|
|
161
|
+
<span>Employee Name</span>
|
|
162
|
+
</div>
|
|
163
|
+
</HeaderTemplate>
|
|
164
|
+
</IgbColumn>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Edit template
|
|
168
|
+
|
|
169
|
+
Provide a custom editor for edit mode:
|
|
170
|
+
|
|
171
|
+
```razor
|
|
172
|
+
<IgbColumn Field="Status" Header="Status" Editable="true">
|
|
173
|
+
<InlineEditorTemplate>
|
|
174
|
+
@{
|
|
175
|
+
var cell = (IgbCellTemplateContext)context;
|
|
176
|
+
}
|
|
177
|
+
<IgbSelect @bind-Value="cell.Cell.EditValue">
|
|
178
|
+
<IgbSelectItem Value="Active">Active</IgbSelectItem>
|
|
179
|
+
<IgbSelectItem Value="Inactive">Inactive</IgbSelectItem>
|
|
180
|
+
<IgbSelectItem Value="Pending">Pending</IgbSelectItem>
|
|
181
|
+
</IgbSelect>
|
|
182
|
+
</InlineEditorTemplate>
|
|
183
|
+
</IgbColumn>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Column Groups (Multi-Column Headers)
|
|
189
|
+
|
|
190
|
+
Group columns under a shared header:
|
|
191
|
+
|
|
192
|
+
```razor
|
|
193
|
+
<IgbGrid Data="employees" PrimaryKey="Id" AutoGenerate="false">
|
|
194
|
+
<IgbColumn Field="Id" Header="ID" />
|
|
195
|
+
<IgbColumnGroup Header="Personal Info">
|
|
196
|
+
<IgbColumn Field="FirstName" Header="First Name" />
|
|
197
|
+
<IgbColumn Field="LastName" Header="Last Name" />
|
|
198
|
+
<IgbColumn Field="BirthDate" Header="Birth Date" DataType="GridColumnDataType.Date" />
|
|
199
|
+
</IgbColumnGroup>
|
|
200
|
+
<IgbColumnGroup Header="Employment">
|
|
201
|
+
<IgbColumn Field="Department" Header="Department" />
|
|
202
|
+
<IgbColumn Field="HireDate" Header="Hire Date" DataType="GridColumnDataType.Date" />
|
|
203
|
+
<IgbColumn Field="Salary" Header="Salary" DataType="GridColumnDataType.Currency" />
|
|
204
|
+
</IgbColumnGroup>
|
|
205
|
+
</IgbGrid>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Column groups can be nested for multi-level headers.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Multi-Row Layout (MRL)
|
|
213
|
+
|
|
214
|
+
Display multiple fields in a single visual row:
|
|
215
|
+
|
|
216
|
+
```razor
|
|
217
|
+
<IgbGrid Data="data" PrimaryKey="Id" AutoGenerate="false">
|
|
218
|
+
<IgbColumnLayout>
|
|
219
|
+
<IgbColumn Field="Name" Header="Name" RowStart="1" ColStart="1" ColEnd="3" />
|
|
220
|
+
<IgbColumn Field="Phone" Header="Phone" RowStart="2" ColStart="1" />
|
|
221
|
+
<IgbColumn Field="Email" Header="Email" RowStart="2" ColStart="2" />
|
|
222
|
+
</IgbColumnLayout>
|
|
223
|
+
<IgbColumnLayout>
|
|
224
|
+
<IgbColumn Field="City" Header="City" RowStart="1" ColStart="1" />
|
|
225
|
+
<IgbColumn Field="Country" Header="Country" RowStart="1" ColStart="2" />
|
|
226
|
+
<IgbColumn Field="PostalCode" Header="ZIP" RowStart="2" ColStart="1" ColEnd="3" />
|
|
227
|
+
</IgbColumnLayout>
|
|
228
|
+
</IgbGrid>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Each `IgbColumnLayout` defines a group. Within it, `RowStart`, `ColStart`, `RowEnd`, `ColEnd` position columns on a layout grid.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Column Pinning
|
|
236
|
+
|
|
237
|
+
### Declarative pinning
|
|
238
|
+
|
|
239
|
+
```razor
|
|
240
|
+
<IgbColumn Field="Name" Header="Name" Pinned="true" />
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Programmatic pinning
|
|
244
|
+
|
|
245
|
+
```razor
|
|
246
|
+
<IgbGrid @ref="grid" Data="data" PrimaryKey="Id" AutoGenerate="false">
|
|
247
|
+
<IgbColumn Field="Id" Header="ID" />
|
|
248
|
+
<IgbColumn Field="Name" Header="Name" />
|
|
249
|
+
</IgbGrid>
|
|
250
|
+
|
|
251
|
+
<IgbButton @onclick="PinNameColumn">Pin Name</IgbButton>
|
|
252
|
+
|
|
253
|
+
@code {
|
|
254
|
+
private IgbGrid grid = default!;
|
|
255
|
+
|
|
256
|
+
private async Task PinNameColumn()
|
|
257
|
+
{
|
|
258
|
+
var col = grid.GetColumnByName("Name");
|
|
259
|
+
col.Pinned = true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Pin position
|
|
265
|
+
|
|
266
|
+
Control whether pinned columns appear at the start or end:
|
|
267
|
+
|
|
268
|
+
```razor
|
|
269
|
+
<IgbGrid Data="data" PrimaryKey="Id" Pinning="pinningConfig">
|
|
270
|
+
...
|
|
271
|
+
</IgbGrid>
|
|
272
|
+
|
|
273
|
+
@code {
|
|
274
|
+
private IgbPinningConfig pinningConfig = new IgbPinningConfig
|
|
275
|
+
{
|
|
276
|
+
Columns = ColumnPinningPosition.End
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Sorting
|
|
284
|
+
|
|
285
|
+
### Enable sorting on columns
|
|
286
|
+
|
|
287
|
+
```razor
|
|
288
|
+
<IgbColumn Field="Name" Header="Name" Sortable="true" />
|
|
289
|
+
<IgbColumn Field="HireDate" Header="Hire Date" Sortable="true" DataType="GridColumnDataType.Date" />
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Grid-level sorting mode
|
|
293
|
+
|
|
294
|
+
| Parameter | Type | Default | Description |
|
|
295
|
+
|---|---|---|---|
|
|
296
|
+
| `SortingMode` | `SortingMode` | `Single` | `Single` - one column at a time; `Multiple` - multi-column sort |
|
|
297
|
+
|
|
298
|
+
```razor
|
|
299
|
+
<IgbGrid Data="data" PrimaryKey="Id" SortingMode="SortingMode.Multiple">
|
|
300
|
+
<IgbColumn Field="Department" Sortable="true" />
|
|
301
|
+
<IgbColumn Field="Name" Sortable="true" />
|
|
302
|
+
</IgbGrid>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Sorting events
|
|
306
|
+
|
|
307
|
+
| Event | Type | Description |
|
|
308
|
+
|---|---|---|
|
|
309
|
+
| `SortingDone` | `EventCallback<IgbSortingEventArgs>` | Fires after sorting is applied |
|
|
310
|
+
|
|
311
|
+
```razor
|
|
312
|
+
<IgbGrid Data="data" PrimaryKey="Id" SortingDone="OnSortingDone">
|
|
313
|
+
...
|
|
314
|
+
</IgbGrid>
|
|
315
|
+
|
|
316
|
+
@code {
|
|
317
|
+
private void OnSortingDone(IgbSortingEventArgs args)
|
|
318
|
+
{
|
|
319
|
+
// React to sorting changes
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Pre-set sorting expressions
|
|
325
|
+
|
|
326
|
+
```razor
|
|
327
|
+
<IgbGrid Data="data" PrimaryKey="Id" SortingExpressions="sortExpressions">
|
|
328
|
+
...
|
|
329
|
+
</IgbGrid>
|
|
330
|
+
|
|
331
|
+
@code {
|
|
332
|
+
private IgbSortingExpression[] sortExpressions = new[]
|
|
333
|
+
{
|
|
334
|
+
new IgbSortingExpression
|
|
335
|
+
{
|
|
336
|
+
FieldName = "Name",
|
|
337
|
+
Dir = SortingDirection.Asc
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Filtering
|
|
346
|
+
|
|
347
|
+
### Quick Filter Row
|
|
348
|
+
|
|
349
|
+
The default filter row appears below the header:
|
|
350
|
+
|
|
351
|
+
```razor
|
|
352
|
+
<IgbGrid Data="data" PrimaryKey="Id" AllowFiltering="true">
|
|
353
|
+
<IgbColumn Field="Name" Filterable="true" DataType="GridColumnDataType.String" />
|
|
354
|
+
<IgbColumn Field="HireDate" Filterable="true" DataType="GridColumnDataType.Date" />
|
|
355
|
+
<IgbColumn Field="Salary" Filterable="true" DataType="GridColumnDataType.Number" />
|
|
356
|
+
</IgbGrid>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Excel-Style Filtering
|
|
360
|
+
|
|
361
|
+
```razor
|
|
362
|
+
<IgbGrid Data="data" PrimaryKey="Id"
|
|
363
|
+
AllowFiltering="true"
|
|
364
|
+
FilterMode="FilterMode.ExcelStyleFilter">
|
|
365
|
+
<IgbColumn Field="Department" Filterable="true" />
|
|
366
|
+
<IgbColumn Field="Name" Filterable="true" />
|
|
367
|
+
</IgbGrid>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Advanced Filtering
|
|
371
|
+
|
|
372
|
+
The advanced filter dialog provides a query-builder experience with AND/OR grouping:
|
|
373
|
+
|
|
374
|
+
```razor
|
|
375
|
+
<IgbGrid Data="data" PrimaryKey="Id"
|
|
376
|
+
AllowAdvancedFiltering="true">
|
|
377
|
+
...
|
|
378
|
+
</IgbGrid>
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
> `AllowAdvancedFiltering` and column-level `AllowFiltering` with `FilterMode` can coexist. The toolbar button opens the advanced dialog, while the column-level filter row remains available.
|
|
382
|
+
|
|
383
|
+
### Filtering Conditions
|
|
384
|
+
|
|
385
|
+
The filter condition depends on the column's `DataType`:
|
|
386
|
+
|
|
387
|
+
| Data Type | Available Conditions |
|
|
388
|
+
|---|---|
|
|
389
|
+
| String | Contains, StartsWith, EndsWith, Equals, DoesNotEqual, Empty, NotEmpty |
|
|
390
|
+
| Number | Equals, DoesNotEqual, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, Empty, NotEmpty |
|
|
391
|
+
| Boolean | All, True, False, Empty, NotEmpty |
|
|
392
|
+
| Date | Equals, DoesNotEqual, Before, After, Today, Yesterday, ThisMonth, LastMonth, NextMonth, ThisYear, LastYear, NextYear, Empty, NotEmpty |
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Selection
|
|
397
|
+
|
|
398
|
+
### Row Selection
|
|
399
|
+
|
|
400
|
+
```razor
|
|
401
|
+
<IgbGrid Data="data" PrimaryKey="Id"
|
|
402
|
+
RowSelection="GridSelectionMode.Multiple"
|
|
403
|
+
RowSelectionChanged="OnRowSelection">
|
|
404
|
+
...
|
|
405
|
+
</IgbGrid>
|
|
406
|
+
|
|
407
|
+
@code {
|
|
408
|
+
private void OnRowSelection(IgbRowSelectionEventArgs args)
|
|
409
|
+
{
|
|
410
|
+
var newSelection = args.NewSelection; // selected row data
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
| `RowSelection` Value | Behavior |
|
|
416
|
+
|---|---|
|
|
417
|
+
| `GridSelectionMode.None` | No row selection |
|
|
418
|
+
| `GridSelectionMode.Single` | Select one row at a time |
|
|
419
|
+
| `GridSelectionMode.Multiple` | Multi-select with checkboxes |
|
|
420
|
+
| `GridSelectionMode.MultipleCascade` | Multi-select with cascade (Tree Grid: selects children when parent is selected) |
|
|
421
|
+
|
|
422
|
+
### Cell Selection
|
|
423
|
+
|
|
424
|
+
```razor
|
|
425
|
+
<IgbGrid Data="data" PrimaryKey="Id"
|
|
426
|
+
CellSelection="GridSelectionMode.Multiple"
|
|
427
|
+
RangeSelected="OnRangeSelected">
|
|
428
|
+
...
|
|
429
|
+
</IgbGrid>
|
|
430
|
+
|
|
431
|
+
@code {
|
|
432
|
+
private void OnRangeSelected(IgbGridForOfState<IgbCellType> args)
|
|
433
|
+
{
|
|
434
|
+
// Handle range selection
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Column Selection
|
|
440
|
+
|
|
441
|
+
Enable per-column:
|
|
442
|
+
|
|
443
|
+
```razor
|
|
444
|
+
<IgbColumn Field="Name" Selectable="true" />
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Or grid-wide:
|
|
448
|
+
|
|
449
|
+
```razor
|
|
450
|
+
<IgbGrid Data="data" PrimaryKey="Id"
|
|
451
|
+
ColumnSelection="GridSelectionMode.Multiple">
|
|
452
|
+
...
|
|
453
|
+
</IgbGrid>
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Getting selected rows
|
|
457
|
+
|
|
458
|
+
```razor
|
|
459
|
+
@code {
|
|
460
|
+
private IgbGrid grid = default!;
|
|
461
|
+
|
|
462
|
+
private void GetSelectedRows()
|
|
463
|
+
{
|
|
464
|
+
var selectedRows = grid.SelectedRows; // object[] of primary key values
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Programmatic selection
|
|
470
|
+
|
|
471
|
+
```razor
|
|
472
|
+
@code {
|
|
473
|
+
private IgbGrid grid = default!;
|
|
474
|
+
|
|
475
|
+
private async Task SelectRows()
|
|
476
|
+
{
|
|
477
|
+
await grid.SelectRowsAsync(new object[] { 1, 3, 5 }); // select by primary keys
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
private async Task DeselectAll()
|
|
481
|
+
{
|
|
482
|
+
await grid.DeselectAllRowsAsync();
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Key Rules
|
|
490
|
+
|
|
491
|
+
1. **Always set `PrimaryKey`** - it is required for selection, editing, and row identity.
|
|
492
|
+
2. **`AutoGenerate="false"` is recommended** - it gives you full control over column order, types, and templates.
|
|
493
|
+
3. **Column `DataType` matters** - it determines the filter conditions, sort behavior, and edit experience. Always set it explicitly.
|
|
494
|
+
4. **Registration is mandatory** - every grid module must be registered in `Program.cs` or the component silently fails to render.
|
|
495
|
+
5. **Use PascalCase for all parameters** - Blazor parameters use PascalCase (`Sortable`, `Filterable`), not kebab-case.
|
|
496
|
+
6. **Data must be a C# collection** - `List<T>`, `T[]`, or `IEnumerable<T>`. Not a JSON string or JavaScript object.
|
|
497
|
+
7. **Use `@ref` for programmatic access** - declare `private IgbGrid grid = default!;` and use `@ref="grid"` on the component.
|