Skip to content

Commit 20d5b99

Browse files
committed
CRUD Buttons in grid Header (#194)
1 parent 1bbe345 commit 20d5b99

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1007
-69
lines changed

GridBlazor/CGrid.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ public virtual void AutoGenerateColumns()
631631
/// </summary>
632632
public string DeleteLabel { get; set; }
633633

634+
public bool HeaderCrudButtons { get; set; }
635+
634636
#region Custom row css classes
635637
public void SetRowCssClassesContraint(Func<T, string> contraint)
636638
{

GridBlazor/Client/GridClient.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,12 @@ public IGridClient<T> SetCrudButtonLabels(string createLabel, string readLabel,
285285
return this;
286286
}
287287

288+
public IGridClient<T> SetHeaderCrudButtons(bool enabled)
289+
{
290+
_source.HeaderCrudButtons = enabled;
291+
return this;
292+
}
293+
288294
public IGridClient<T> SetCreateComponent<TComponent>()
289295
{
290296
return SetCreateComponent<TComponent>(null, null, null);

GridBlazor/Client/IGridClient.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ IGridClient<T> ODataCrud(bool createEnabled, Func<T, bool> readEnabled,
177177
/// </summary>
178178
IGridClient<T> SetCrudButtonLabels(string createLabel, string readLabel, string updateLabel, string deleteLabel);
179179

180+
/// <summary>
181+
/// Configure CRUD buttons on the header
182+
/// </summary>
183+
IGridClient<T> SetHeaderCrudButtons(bool enabled);
184+
180185
/// <summary>
181186
/// Setup the Create Component
182187
/// </summary>

GridBlazor/ICGrid.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,5 +219,10 @@ public interface ICGrid : IGrid, IGridOptions
219219
/// Delete button label
220220
/// </summary>
221221
string DeleteLabel { get; set; }
222+
223+
/// <summary>
224+
/// Header CRUD buttons
225+
/// </summary>
226+
bool HeaderCrudButtons { get; set; }
222227
}
223228
}

GridBlazor/Pages/GridComponent.razor

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121
{
2222
<td class="@GridCellCssClass" data-name="" style="width:36.5px;"></td>
2323
}
24-
@if (Grid.ReadEnabled || ((CGrid<T>)Grid).FuncReadEnabled != null)
24+
@if ((Grid.ReadEnabled || ((CGrid<T>)Grid).FuncReadEnabled != null) && !HeaderCrudButtons)
2525
{
2626
<td class="@GridButtonCellCssClass" data-name="" style="width:35px;"></td>
2727
}
28-
@if (Grid.UpdateEnabled || ((CGrid<T>)Grid).FuncUpdateEnabled != null)
28+
@if ((Grid.UpdateEnabled || ((CGrid<T>)Grid).FuncUpdateEnabled != null) && !HeaderCrudButtons)
2929
{
3030
<td class="@GridButtonCellCssClass" data-name="" style="width:35px;"></td>
3131
}
32-
@if (Grid.DeleteEnabled || ((CGrid<T>)Grid).FuncDeleteEnabled != null)
32+
@if ((Grid.DeleteEnabled || ((CGrid<T>)Grid).FuncDeleteEnabled != null) && !HeaderCrudButtons)
3333
{
3434
<td class="@GridButtonCellCssClass" data-name="" style="width:35px;"></td>
3535
}
@@ -65,7 +65,9 @@
6565
}
6666
if (_hasTotals)
6767
{
68-
<GridTotalsComponent T="@T" Grid="@Grid"></GridTotalsComponent>
68+
<CascadingValue Value=@this Name="GridComponent">
69+
<GridTotalsComponent T="@T" Grid="@Grid"></GridTotalsComponent>
70+
</CascadingValue>
6971
}
7072
}
7173
else
@@ -82,6 +84,7 @@
8284
@ref="gridmvc"
8385
@onkeyup="GridComponentKeyup">
8486
<div class="@GridWrapCssClass">
87+
<p id="error" style="color:red;">@Error</p>
8588
<div class="row">
8689
<div class="col-md-6 grid-header-buttons">
8790
@if (Grid.ClearFiltersButtonEnabled)
@@ -103,6 +106,45 @@
103106
}
104107
</div>
105108
}
109+
@if ((Grid.ReadEnabled || ((CGrid<T>)Grid).FuncReadEnabled != null) && HeaderCrudButtons)
110+
{
111+
<div class="grid-crud">
112+
@if (string.IsNullOrWhiteSpace(Grid.ReadLabel))
113+
{
114+
<button class='grid-button grid-button-header-view btn btn-sm btn-outline-secondary' title="@Strings.ReadItem" @onclick="@(e => ReadSelectedHandler())" type="button" @onclick:stopPropagation></button>
115+
}
116+
else
117+
{
118+
<button class='grid-button-header-label-view btn btn-sm btn-primary' title="@Strings.ReadItem" @onclick="@(e => ReadSelectedHandler())" type="button" @onclick:stopPropagation>@Grid.ReadLabel</button>
119+
}
120+
</div>
121+
}
122+
@if ((Grid.UpdateEnabled || ((CGrid<T>)Grid).FuncUpdateEnabled != null) && HeaderCrudButtons)
123+
{
124+
<div class="grid-crud">
125+
@if (string.IsNullOrWhiteSpace(Grid.UpdateLabel))
126+
{
127+
<button class='grid-button grid-button-header-edit btn btn-sm btn-outline-secondary' title="@Strings.UpdateItem" @onclick="@(e => UpdateSelectedHandler())" type="button" @onclick:stopPropagation></button>
128+
}
129+
else
130+
{
131+
<button class='grid-button-header-label-edit btn btn-sm btn-primary' title="@Strings.UpdateItem" @onclick="@(e => UpdateSelectedHandler())" type="button" @onclick:stopPropagation>@Grid.UpdateLabel</button>
132+
}
133+
</div>
134+
}
135+
@if ((Grid.DeleteEnabled || ((CGrid<T>)Grid).FuncDeleteEnabled != null) && HeaderCrudButtons)
136+
{
137+
<div class="grid-crud">
138+
@if (string.IsNullOrWhiteSpace(Grid.DeleteLabel))
139+
{
140+
<button class='grid-button grid-button-header-delete btn btn-sm btn-outline-secondary' title="@Strings.DeleteItem" @onclick="@(e => DeleteSelectedHandler())" type="button" @onclick:stopPropagation></button>
141+
}
142+
else
143+
{
144+
<button class='grid-button-header-label-delete btn btn-sm btn-primary' title="@Strings.DeleteItem" @onclick="@(e => DeleteSelectedHandler())" type="button" @onclick:stopPropagation>@Grid.DeleteLabel</button>
145+
}
146+
</div>
147+
}
106148
@if (Grid.ExcelExport)
107149
{
108150
<div class="grid-excel">
@@ -150,15 +192,15 @@
150192
{
151193
<th class="@GridHeaderCssClass" style="width:36.5px;"></th>
152194
}
153-
@if (Grid.ReadEnabled || ((CGrid<T>)Grid).FuncReadEnabled != null)
195+
@if ((Grid.ReadEnabled || ((CGrid<T>)Grid).FuncReadEnabled != null) && !HeaderCrudButtons)
154196
{
155197
<th class="@GridHeaderCssClass" style="width:35px;"></th>
156198
}
157-
@if (Grid.UpdateEnabled || ((CGrid<T>)Grid).FuncUpdateEnabled != null)
199+
@if ((Grid.UpdateEnabled || ((CGrid<T>)Grid).FuncUpdateEnabled != null) && !HeaderCrudButtons)
158200
{
159201
<th class="@GridHeaderCssClass" style="width:35px;"></th>
160202
}
161-
@if (Grid.DeleteEnabled || ((CGrid<T>)Grid).FuncDeleteEnabled != null)
203+
@if ((Grid.DeleteEnabled || ((CGrid<T>)Grid).FuncDeleteEnabled != null) && !HeaderCrudButtons)
162204
{
163205
<th class="@GridHeaderCssClass" style="width:35px;"></th>
164206
}
@@ -182,15 +224,15 @@
182224
{
183225
<td class="@GridCellCssClass" data-name="" style="width:36.5px;"></td>
184226
}
185-
@if (Grid.ReadEnabled || ((CGrid<T>)Grid).FuncReadEnabled != null)
227+
@if ((Grid.ReadEnabled || ((CGrid<T>)Grid).FuncReadEnabled != null) && !HeaderCrudButtons)
186228
{
187229
<td class="@GridButtonCellCssClass" data-name="" style="width:35px;"></td>
188230
}
189-
@if (Grid.UpdateEnabled || ((CGrid<T>)Grid).FuncUpdateEnabled != null)
231+
@if ((Grid.UpdateEnabled || ((CGrid<T>)Grid).FuncUpdateEnabled != null) && !HeaderCrudButtons)
190232
{
191233
<td class="@GridButtonCellCssClass" data-name="" style="width:35px;"></td>
192234
}
193-
@if (Grid.DeleteEnabled || ((CGrid<T>)Grid).FuncDeleteEnabled != null)
235+
@if ((Grid.DeleteEnabled || ((CGrid<T>)Grid).FuncDeleteEnabled != null) && !HeaderCrudButtons)
194236
{
195237
<td class="@GridButtonCellCssClass" data-name="" style="width:35px;"></td>
196238
}
@@ -226,7 +268,9 @@
226268
}
227269
@if (_hasTotals)
228270
{
229-
<GridTotalsComponent T="@T" Grid="@Grid"></GridTotalsComponent>
271+
<CascadingValue Value=@this Name="GridComponent">
272+
<GridTotalsComponent T="@T" Grid="@Grid"></GridTotalsComponent>
273+
</CascadingValue>
230274
}
231275
</tbody>
232276
</table>

GridBlazor/Pages/GridComponent.razor.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using GridBlazor.Pagination;
2+
using GridBlazor.Resources;
23
using GridBlazor.Searching;
34
using GridShared;
45
using GridShared.Columns;
@@ -14,6 +15,7 @@
1415
using System.Collections.Generic;
1516
using System.Linq;
1617
using System.Net.Http.Json;
18+
using System.Threading;
1719
using System.Threading.Tasks;
1820

1921
namespace GridBlazor.Pages
@@ -38,6 +40,9 @@ public partial class GridComponent<T>
3840
internal bool _isWeekSupported = false;
3941
internal bool _isMonthSupported = false;
4042

43+
// CRUD buttons on the header
44+
internal bool HeaderCrudButtons = false;
45+
4146
protected ElementReference gridmvc;
4247

4348
public event Func<object, SortEventArgs, Task> SortChanged;
@@ -97,6 +102,8 @@ public partial class GridComponent<T>
97102

98103
protected RenderFragment CrudRender { get; set; }
99104

105+
public string Error { get; set; } = "";
106+
100107
[Parameter]
101108
public ICGrid Grid { get; set; }
102109

@@ -202,6 +209,10 @@ protected override void OnParametersSet()
202209
&& (FirstColumn.IsSumEnabled || FirstColumn.IsAverageEnabled
203210
|| FirstColumn.IsMaxEnabled || FirstColumn.IsMinEnabled);
204211

212+
HeaderCrudButtons = Grid.HeaderCrudButtons
213+
&& Grid.ComponentOptions.Selectable
214+
&& !Grid.ComponentOptions.MultiSelectable;
215+
205216
HeaderComponents = new QueryDictionary<GridHeaderComponent<T>>();
206217

207218
InitCheckboxAndSubGridVars();
@@ -602,6 +613,33 @@ public void ReadHandler(object item)
602613
StateHasChanged();
603614
}
604615

616+
public void ReadSelectedHandler()
617+
{
618+
if (SelectedRow != -1)
619+
{
620+
var item = Grid.ItemsToDisplay.ElementAt(SelectedRow);
621+
ReadHandler(item);
622+
}
623+
else
624+
ShowError(Strings.SelectionReadError);
625+
}
626+
627+
public void ShowError(string error)
628+
{
629+
Error = error;
630+
var timer = new Timer((_) => {
631+
InvokeAsync(OnTimerEvent);
632+
}, null, 3000, -1);
633+
_shouldRender = true;
634+
}
635+
636+
private void OnTimerEvent()
637+
{
638+
Error = "";
639+
_shouldRender = true;
640+
StateHasChanged();
641+
}
642+
605643
public async Task UpdateHandler(object item)
606644
{
607645
var keys = Grid.GetPrimaryKeyValues(item);
@@ -630,6 +668,18 @@ public async Task UpdateHandler(object[] keys)
630668
throw;
631669
}
632670
}
671+
672+
public async Task UpdateSelectedHandler()
673+
{
674+
if (SelectedRow != -1)
675+
{
676+
var item = Grid.ItemsToDisplay.ElementAt(SelectedRow);
677+
await UpdateHandler(item);
678+
}
679+
else
680+
ShowError(Strings.SelectionUpdateError);
681+
}
682+
633683
public void DeleteHandler(object item)
634684
{
635685
_item = (T)item;
@@ -643,6 +693,17 @@ public void DeleteHandler(object item)
643693
StateHasChanged();
644694
}
645695

696+
public void DeleteSelectedHandler()
697+
{
698+
if (SelectedRow != -1)
699+
{
700+
var item = Grid.ItemsToDisplay.ElementAt(SelectedRow);
701+
DeleteHandler(item);
702+
}
703+
else
704+
ShowError(Strings.SelectionDeleteError);
705+
}
706+
646707
public async Task ExcelHandler()
647708
{
648709
await Grid.DownloadExcel(jSRuntime, Grid.ComponentOptions.GridName + ".xlsx");

GridBlazor/Pages/GridDeleteComponent.razor.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,28 @@ protected override async Task OnParametersSetAsync()
4242
var grid = await ((ICGridColumn)column).SubGrids(values, false, true, false, true) as ICGrid;
4343
grid.Direction = GridComponent.Grid.Direction;
4444
VariableReference reference = new VariableReference();
45-
Children.Add(column.Name, reference);
46-
_renderFragments.Add(column.Name, CreateSubGridComponent(grid, reference));
45+
if (Children.ContainsKey(column.Name))
46+
Children[column.Name] = reference;
47+
else
48+
Children.Add(column.Name, reference);
49+
if (_renderFragments.ContainsKey(column.Name))
50+
_renderFragments[column.Name] = CreateSubGridComponent(grid, reference);
51+
else
52+
_renderFragments.Add(column.Name, CreateSubGridComponent(grid, reference));
4753
}
4854
else if (column.DeleteComponentType != null)
4955
{
5056
VariableReference reference = new VariableReference();
51-
Children.Add(column.Name, reference);
52-
_renderFragments.Add(column.Name, GridCellComponent<T>.CreateComponent(_sequence,
53-
GridComponent, column.DeleteComponentType, column, Item, null, true, reference));
57+
if (Children.ContainsKey(column.Name))
58+
Children[column.Name] = reference;
59+
else
60+
Children.Add(column.Name, reference);
61+
if (_renderFragments.ContainsKey(column.Name))
62+
_renderFragments[column.Name] = GridCellComponent<T>.CreateComponent(_sequence,
63+
GridComponent, column.DeleteComponentType, column, Item, null, true, reference);
64+
else
65+
_renderFragments.Add(column.Name, GridCellComponent<T>.CreateComponent(_sequence,
66+
GridComponent, column.DeleteComponentType, column, Item, null, true, reference));
5467
}
5568
}
5669
_tabGroups = GridComponent.Grid.Columns

GridBlazor/Pages/GridReadComponent.razor.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,28 @@ protected override async Task OnParametersSetAsync()
3939
var grid = await ((ICGridColumn)column).SubGrids(values, false, true, false, false) as ICGrid;
4040
grid.Direction = GridComponent.Grid.Direction;
4141
VariableReference reference = new VariableReference();
42-
Children.Add(column.Name, reference);
43-
_renderFragments.Add(column.Name, CreateSubGridComponent(grid, reference));
42+
if (Children.ContainsKey(column.Name))
43+
Children[column.Name] = reference;
44+
else
45+
Children.Add(column.Name, reference);
46+
if (_renderFragments.ContainsKey(column.Name))
47+
_renderFragments[column.Name] = CreateSubGridComponent(grid, reference);
48+
else
49+
_renderFragments.Add(column.Name, CreateSubGridComponent(grid, reference));
4450
}
4551
else if (column.ReadComponentType != null)
4652
{
4753
VariableReference reference = new VariableReference();
48-
Children.Add(column.Name, reference);
49-
_renderFragments.Add(column.Name, GridCellComponent<T>.CreateComponent(_sequence,
50-
GridComponent, column.ReadComponentType, column, Item, null, true, reference));
54+
if (Children.ContainsKey(column.Name))
55+
Children[column.Name] = reference;
56+
else
57+
Children.Add(column.Name, reference);
58+
if (_renderFragments.ContainsKey(column.Name))
59+
_renderFragments[column.Name] = GridCellComponent<T>.CreateComponent(_sequence,
60+
GridComponent, column.ReadComponentType, column, Item, null, true, reference);
61+
else
62+
_renderFragments.Add(column.Name, GridCellComponent<T>.CreateComponent(_sequence,
63+
GridComponent, column.ReadComponentType, column, Item, null, true, reference));
5164
}
5265
}
5366
_tabGroups = GridComponent.Grid.Columns

0 commit comments

Comments
 (0)