Skip to content

Commit 93df8a6

Browse files
xristianstefanovdimodi
authored andcommitted
chore(Grid): address comments
1 parent 5462723 commit 93df8a6

File tree

2 files changed

+237
-95
lines changed

2 files changed

+237
-95
lines changed

knowledge-base/grid-kb-loader-during-contextmenu-actions.md

Lines changed: 0 additions & 95 deletions
This file was deleted.
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
---
2+
title: Display Loader During Actions in TelerikGrid with ContextMenu
3+
description: Learn how to show a loading indicator while performing actions from a ContextMenu in a TelerikGrid for Blazor.
4+
type: how-to
5+
page_title: How to Display a Loader in TelerikGrid for Blazor During ContextMenu Actions
6+
slug: grid-kb-loader-during-contextmenu-actions
7+
tags: contextmenu,grid,loader,loading, loadercontainer,actions
8+
res_type: kb
9+
ticketid: 1675767
10+
---
11+
12+
## Environment
13+
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>Grid for Blazor</td>
19+
<td>Context Menu for Blazor</td>
20+
</tr>
21+
</tbody>
22+
</table>
23+
24+
## Description
25+
26+
When the TelerikGrid is used with ContextMenu for various row actions, there is a noticeable delay between selecting an action and its execution. This delay could be due to data retrieval or data manipulation. The goal is to display a loading notice to the user while the data loads and the result is not yet visible.
27+
28+
This knowledge base article also answers the following questions:
29+
- How to use the TelerikLoaderContainer during data fetch operations in Blazor?
30+
- How to show a loading indicator while waiting for an action?
31+
- How to improve user experience during delayed operations in TelerikGrid with ContextMenu in Blazor?
32+
33+
## Solution
34+
35+
To display a spinner during delayed operations initiated from a ContextMenu in a TelerikGrid, utilize the [TelerikLoaderContainer](slug://loadercontainer-overview) component. Display the TelerikLoaderContainer while the data is being loaded or an action is being performed, and hide it once the operation is complete.
36+
37+
````RAZOR
38+
@using System.Collections.ObjectModel
39+
40+
<TelerikContextMenu @ref="@ContextMenuRef" Data="@MenuItems"
41+
OnClick="@((MenuItem item) => ContextMenuClickHandler(item))">
42+
</TelerikContextMenu>
43+
44+
<TelerikLoaderContainer Visible="@LoaderVisible" Text="Please wait..." />
45+
46+
<TelerikGrid Data="@GridData" @ref="@GridRef"
47+
EditMode="@GridEditMode.Inline"
48+
Height="500px"
49+
Pageable="true"
50+
OnCreate="@CreateItem" OnUpdate="@UpdateHandler"
51+
OnRowContextMenu="@OnContextMenu"
52+
SelectionMode="@GridSelectionMode.Multiple"
53+
@bind-SelectedItems="@SelectedItems">
54+
<GridToolBarTemplate>
55+
<GridCommandButton Command="Add" Icon="@SvgIcon.Plus">Add Employee</GridCommandButton>
56+
</GridToolBarTemplate>
57+
<GridColumns>
58+
<GridColumn Field=@nameof(SampleData.ID) Editable="false" />
59+
<GridColumn Field=@nameof(SampleData.Name) />
60+
<GridCommandColumn>
61+
<GridCommandButton Command="Save" Icon="@SvgIcon.Save" ShowInEdit="true">Save</GridCommandButton>
62+
<GridCommandButton Command="Cancel" Icon="@SvgIcon.Cancel" ShowInEdit="true">Cancel</GridCommandButton>
63+
</GridCommandColumn>
64+
</GridColumns>
65+
</TelerikGrid>
66+
67+
@if (SelectedItems.Any())
68+
{
69+
<ul>
70+
@foreach (var item in SelectedItems)
71+
{
72+
<li>@item.Name</li>
73+
}
74+
</ul>
75+
}
76+
77+
@code {
78+
private ObservableCollection<SampleData> GridData { get; set; }
79+
private List<MenuItem> MenuItems { get; set; }
80+
private IEnumerable<SampleData> SelectedItems { get; set; } = Enumerable.Empty<SampleData>();
81+
private SampleData SelectedPerson { get; set; }
82+
private TelerikContextMenu<MenuItem> ContextMenuRef { get; set; }
83+
private TelerikGrid<SampleData> GridRef { get; set; }
84+
private bool LoaderVisible { get; set; }
85+
86+
public class MenuItem
87+
{
88+
public string Text { get; set; }
89+
public ISvgIcon Icon { get; set; }
90+
public Action Action { get; set; }
91+
public string CommandName { get; set; }
92+
}
93+
94+
private async Task OnContextMenu(GridRowClickEventArgs args)
95+
{
96+
var argsItem = args.Item as SampleData;
97+
98+
SelectedPerson = argsItem;
99+
100+
if (args.EventArgs is MouseEventArgs mouseEventArgs)
101+
{
102+
await ContextMenuRef.ShowAsync(mouseEventArgs.ClientX, mouseEventArgs.ClientY);
103+
}
104+
}
105+
106+
private async Task ContextMenuClickHandler(MenuItem item)
107+
{
108+
if (item.Action != null)
109+
{
110+
item.Action.Invoke();
111+
}
112+
else
113+
{
114+
switch (item.CommandName)
115+
{
116+
case "BeginEdit":
117+
LoaderVisible = true;
118+
await Task.Delay(3000); //initiates delay
119+
LoaderVisible = false;
120+
121+
var currState = GridRef.GetState();
122+
currState.InsertedItem = null;
123+
SampleData itemToEdit = SampleData.GetClonedInstance(GridData.Where(itm => itm.ID == SelectedPerson.ID).FirstOrDefault());
124+
currState.OriginalEditItem = itemToEdit;
125+
await GridRef.SetStateAsync(currState);
126+
break;
127+
case "ToggleSelect":
128+
LoaderVisible = true;
129+
await Task.Delay(3000); //initiates delay
130+
LoaderVisible = false;
131+
132+
var selItems = SelectedItems.ToList();
133+
if (SelectedItems.Contains(SelectedPerson))
134+
{
135+
selItems.Remove(SelectedPerson);
136+
}
137+
else
138+
{
139+
selItems.Add(SelectedPerson);
140+
}
141+
SelectedItems = selItems;
142+
break;
143+
default:
144+
break;
145+
}
146+
}
147+
SelectedPerson = null; // clean up
148+
}
149+
150+
protected override void OnInitialized()
151+
{
152+
MenuItems = new List<MenuItem>()
153+
{
154+
new MenuItem(){ Text = "Select", Icon = SvgIcon.CheckboxChecked, CommandName="ToggleSelect" },
155+
new MenuItem(){ Text = "Edit", Icon = SvgIcon.Pencil, CommandName="BeginEdit" },
156+
new MenuItem(){ Text = "Delete", Icon = SvgIcon.Trash, Action = DeleteItem }
157+
};
158+
159+
GridData = new ObservableCollection<SampleData>();
160+
var rand = new Random();
161+
162+
for (int i = 0; i < 100; i++)
163+
{
164+
GridData.Add(new SampleData()
165+
{
166+
ID = i,
167+
Name = "Employee " + i.ToString(),
168+
});
169+
}
170+
}
171+
172+
private async Task CreateItem(GridCommandEventArgs args)
173+
{
174+
var argsItem = args.Item as SampleData;
175+
176+
argsItem.ID = GridData.Count + 1;
177+
178+
GridData.Insert(0, argsItem);
179+
}
180+
181+
private void DeleteItem()
182+
{
183+
var argsItem = SelectedPerson;
184+
185+
GridData.Remove(argsItem);
186+
}
187+
188+
private async Task UpdateHandler(GridCommandEventArgs args)
189+
{
190+
var argsItem = args.Item as SampleData;
191+
192+
var index = GridData.ToList().FindIndex(i => i.ID == argsItem.ID);
193+
if (index != -1)
194+
{
195+
GridData[index] = argsItem;
196+
}
197+
}
198+
199+
public class SampleData
200+
{
201+
public int ID { get; set; }
202+
public string Name { get; set; }
203+
204+
205+
public override bool Equals(object obj)
206+
{
207+
if (obj is SampleData)
208+
{
209+
return this.ID == (obj as SampleData).ID;
210+
}
211+
return false;
212+
}
213+
214+
public SampleData()
215+
{
216+
217+
}
218+
219+
public SampleData(SampleData itmToClone)
220+
{
221+
this.ID = itmToClone.ID;
222+
this.Name = itmToClone.Name;
223+
}
224+
225+
public static SampleData GetClonedInstance(SampleData itmToClone)
226+
{
227+
return new SampleData(itmToClone);
228+
}
229+
}
230+
}
231+
````
232+
233+
## See Also
234+
235+
- [LoaderContainer Overview](slug://loadercontainer-overview)
236+
- [Grid Documentation](slug://grid-overview)
237+
- [ContextMenu Documentation](slug://contextmenu-overview)

0 commit comments

Comments
 (0)