Skip to content

Commit 612918e

Browse files
ntachevadimodi
andauthored
Update Gantt Command Column article (#535)
* chore(gantt):fix command column article draft * chore(gantt)improve update command column article * chore(gantt):updated command column article * Update components/gantt/gantt-tree/columns/command.md Co-authored-by: Dimo Dimov <[email protected]> * Update components/gantt/gantt-tree/columns/command.md Co-authored-by: Dimo Dimov <[email protected]> * Update components/gantt/gantt-tree/columns/command.md Co-authored-by: Dimo Dimov <[email protected]> * chore(gantt):command column article improvements Co-authored-by: Dimo Dimov <[email protected]>
1 parent 5d8c911 commit 612918e

File tree

3 files changed

+281
-6
lines changed

3 files changed

+281
-6
lines changed

components/gantt/gantt-tree/columns/command.md

Lines changed: 279 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ In this article:
2222
* [GanttCommandButton](#the-ganttcommandbutton-tag)
2323
* [Built-in Commands](#built-in-commands)
2424
* [OnClick Handler](#onclick-handler)
25+
* [Context](#context)
2526
* [Code Example](#example)
2627

2728

@@ -40,12 +41,286 @@ The `GanttCommandButton` tag offers the following features:
4041

4142
### Built-in Commands
4243

43-
There are four built-in commands:
44+
There are two built-in commands:
4445

4546
* `Add` - initiates the creation of a new item. Can apply to rows as well, to create a child element for the current row.
46-
* `Edit` - initiates the editing in the Gantt Tree.
47-
* `Save` - performs the actual update operation after the data has been changed. Triggers the `OnUpdate` or `OnCreate` event so you can perform the data source operation. Which event is triggered depends on whether the item was created or edited.
48-
* `Cancel` - aborts the current operation (edit or insert).
47+
* `Delete` - initiates the deletion of an existing item.
48+
49+
### OnClick handler
50+
51+
The `OnClick` handler of the commands receives an argument of type `GanttTaskCommandEventArgs` that exposes the following properties:
52+
53+
* `IsCancelled` - set this to `true` to prevent the operation if the business logic requires it.
54+
* `Item` - the model item of the Gantt row. You can use it to access the model fields and perform the actual data source operations. This property is applicable only for command buttons that are inside a Gantt row, not the toolbar.
55+
* `IsNew` - a boolean field indicating whether the item was just added through the Gantt interface.
56+
57+
>tip For handling CRUD operations we recommend that you use the Gantt events (`OnEdit`, `OnUpdate`, `OnCancel`, `OnCreate`). The `OnClick` handler is available for the built-in commands to provide consistency of the API.
58+
59+
### Context
60+
61+
The command column provides access to the data item via `context`. This may be useful for conditional statements or passing parameters to custom business logic.
62+
63+
Use a **named** context variable to avoid errors when nesting components or `RenderFragment`s in general. In such cases, the exception will be similar to ["Child content element ... uses the same parameter name ('context') as enclosing child content element ..."]({%slug nest-renderfragment%}).
64+
65+
````CSHTML
66+
<GanttCommandColumn Context="currTask">
67+
@{
68+
var task = currTask as FlatModel;
69+
70+
if (task.ParentId != null)
71+
{
72+
<GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
73+
}
74+
else
75+
{
76+
<span>Cannot delete main tasks</span>
77+
}
78+
}
79+
</GanttCommandColumn>
80+
````
81+
82+
## Example
83+
84+
The following code example demonstrates declarations and handling of the built-in and custom commands.
85+
86+
>tip The event handlers use `EventCallback` and can be synchronous or async. This example shows async versions, and the signature for the synchronous handlers is `void MyHandlerName(GanttTaskCommandEventArgs args)`.
87+
88+
>caption Example of handling built-in and custom commands in the Gantt component
89+
90+
````CSHTML
91+
@* This sample showcases:
92+
- using the built-in Add and Delete commands
93+
- a custom command for a row
94+
*@
95+
96+
<TelerikGantt Data="@Data"
97+
@bind-View="@SelectedView"
98+
Width="1000px"
99+
Height="600px"
100+
IdField="Id"
101+
ParentIdField="ParentId"
102+
OnCreate="@CreateItem"
103+
OnUpdate="@UpdateItem"
104+
OnDelete="@DeleteItem">
105+
<GanttColumns>
106+
<GanttColumn Field="Title"
107+
Expandable="true"
108+
Width="160px"
109+
Title="Task Title">
110+
</GanttColumn>
111+
<GanttColumn Field="Start"
112+
Width="100px"
113+
DisplayFormat="{0:d}">
114+
</GanttColumn>
115+
<GanttColumn Field="End"
116+
Width="100px"
117+
DisplayFormat="{0:d}">
118+
</GanttColumn>
119+
<GanttCommandColumn>
120+
<GanttCommandButton OnClick="@((args) => GetTaskDetails(args))" Icon="info-circle
121+
"></GanttCommandButton>
122+
<GanttCommandButton Command="Add" Icon="add"></GanttCommandButton>
123+
<GanttCommandButton Command="Delete" Icon="delete"></GanttCommandButton>
124+
</GanttCommandColumn>
125+
</GanttColumns>
126+
<GanttViews>
127+
<GanttDayView></GanttDayView>
128+
<GanttWeekView></GanttWeekView>
129+
<GanttMonthView></GanttMonthView>
130+
</GanttViews>
131+
</TelerikGantt>
132+
133+
@code {
134+
public GanttView SelectedView { get; set; } = GanttView.Week;
135+
136+
[CascadingParameter]
137+
public DialogFactory Dialogs { get; set; }
138+
139+
public async Task GetTaskDetails(GanttTaskCommandEventArgs args)
140+
{
141+
var currTask = args.Item as FlatModel;
142+
143+
await Dialogs.AlertAsync(
144+
$"Completed: {currTask.PercentComplete}%",
145+
$"Summary for {currTask.Title}"
146+
);
147+
}
148+
private async Task CreateItem(GanttCreateEventArgs args)
149+
{
150+
var argsItem = args.Item as FlatModel;
151+
152+
argsItem.Id = LastId++;
153+
154+
if (args.ParentItem != null)
155+
{
156+
var parent = (FlatModel)args.ParentItem;
157+
158+
argsItem.ParentId = parent.Id;
159+
}
160+
161+
Data.Insert(0, argsItem);
162+
163+
CalculateParentPercentRecursive(argsItem);
164+
CalculateParentRangeRecursive(argsItem);
165+
}
166+
167+
private async Task UpdateItem(GanttUpdateEventArgs args)
168+
{
169+
var item = args.Item as FlatModel;
170+
171+
var foundItem = Data.FirstOrDefault(i => i.Id.Equals(item.Id));
172+
173+
if (foundItem != null)
174+
{
175+
var startOffset = item.Start - foundItem.Start;
176+
if (startOffset != TimeSpan.Zero)
177+
{
178+
MoveChildrenRecursive(foundItem, startOffset);
179+
}
180+
181+
foundItem.Title = item.Title;
182+
foundItem.Start = item.Start;
183+
foundItem.End = item.End;
184+
foundItem.PercentComplete = item.PercentComplete;
185+
}
186+
187+
CalculateParentPercentRecursive(foundItem);
188+
CalculateParentRangeRecursive(foundItem);
189+
}
190+
191+
private async Task DeleteItem(GanttDeleteEventArgs args)
192+
{
193+
var item = Data.FirstOrDefault(i => i.Id.Equals((args.Item as FlatModel).Id));
194+
195+
RemoveChildRecursive(item);
196+
197+
CalculateParentPercentRecursive(item);
198+
CalculateParentRangeRecursive(item);
199+
}
200+
201+
private void RemoveChildRecursive(FlatModel item)
202+
{
203+
var children = GetChildren(item).ToList();
204+
205+
foreach (var child in children)
206+
{
207+
RemoveChildRecursive(child);
208+
}
209+
210+
Data.Remove(item);
211+
}
212+
213+
private void CalculateParentPercentRecursive(FlatModel item)
214+
{
215+
if (item.ParentId != null)
216+
{
217+
var parent = GetParent(item);
218+
219+
var children = GetChildren(parent);
220+
221+
if (children.Any())
222+
{
223+
parent.PercentComplete = children.Average(i => i.PercentComplete);
224+
225+
CalculateParentPercentRecursive(parent);
226+
}
227+
}
228+
}
229+
230+
private void CalculateParentRangeRecursive(FlatModel item)
231+
{
232+
if (item.ParentId != null)
233+
{
234+
var parent = GetParent(item);
235+
236+
var children = GetChildren(parent);
237+
238+
if (children.Any())
239+
{
240+
parent.Start = children.Min(i => i.Start);
241+
parent.End = children.Max(i => i.End);
242+
243+
CalculateParentRangeRecursive(parent);
244+
}
245+
}
246+
}
247+
248+
private void MoveChildrenRecursive(FlatModel item, TimeSpan offset)
249+
{
250+
var children = GetChildren(item);
251+
252+
foreach (var child in children)
253+
{
254+
child.Start = child.Start.Add(offset);
255+
child.End = child.End.Add(offset);
256+
257+
MoveChildrenRecursive(child, offset);
258+
}
259+
}
260+
261+
private FlatModel GetParent(FlatModel item)
262+
{
263+
return Data.FirstOrDefault(i => i.Id.Equals(item.ParentId));
264+
}
265+
266+
private IEnumerable<FlatModel> GetChildren(FlatModel item)
267+
{
268+
return Data.Where(i => item.Id.Equals(i.ParentId));
269+
}
270+
271+
class FlatModel
272+
{
273+
public int Id { get; set; }
274+
public int? ParentId { get; set; }
275+
public string Title { get; set; }
276+
public double PercentComplete { get; set; }
277+
public DateTime Start { get; set; }
278+
public DateTime End { get; set; }
279+
}
280+
281+
public int LastId { get; set; } = 1;
282+
List<FlatModel> Data { get; set; }
283+
284+
protected override void OnInitialized()
285+
{
286+
Data = new List<FlatModel>();
287+
var random = new Random();
288+
289+
for (int i = 1; i < 6; i++)
290+
{
291+
var newItem = new FlatModel()
292+
{
293+
Id = LastId,
294+
Title = "Task " + i.ToString(),
295+
Start = new DateTime(2020, 12, 6 + i),
296+
End = new DateTime(2020, 12, 11 + i),
297+
PercentComplete = Math.Round(random.NextDouble(), 2)
298+
};
299+
300+
Data.Add(newItem);
301+
var parentId = LastId;
302+
LastId++;
303+
304+
for (int j = 0; j < 5; j++)
305+
{
306+
Data.Add(new FlatModel()
307+
{
308+
Id = LastId,
309+
ParentId = parentId,
310+
Title = " Task " + i + " : " + j.ToString(),
311+
Start = new DateTime(2020, 12, 6 + i + j),
312+
End = new DateTime(2020, 12, 7 + i + j),
313+
PercentComplete = Math.Round(random.NextDouble(), 2)
314+
});
315+
316+
LastId++;
317+
}
318+
}
319+
320+
base.OnInitialized();
321+
}
322+
}
323+
````
49324

50325
## See Also
51326

components/grid/columns/command.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ There are four built-in commands:
5252
The `OnClick` handler of the commands receives an argument of type `GridCommandEventArgs` that exposes the following properties:
5353

5454
* `IsCancelled` - set this to true to prevent the operation if the business logic requires it.
55-
* `Item` - the model item the grid row is bound to. You can use it to access the model fields and methods in order to preform the actual data source operations. Applicable for buttons in a row, not in a toolbar.
55+
* `Item` - the model item of the Grid row. You can use it to access the model fields and preform the actual data source operations. This property is applicable only for command buttons that are inside a Grid row, not the toolbar.
5656
* `IsNew` - a boolean field indicating whether the item was just added through the grid interface.
5757

5858
>tip For handling CRUD operations we recommend that you use the grid events (`OnEdit`, `OnUpdate`, `OnCancel`, `OnCreate`). The `OnClick` handler is available for the built-in commands to provide consistency of the API.

components/treelist/columns/command.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ The command column provides access to the data item via `context`. This may be u
7575
The `OnClick` handler of the commands receives an argument of type `TreeListCommandEventArgs` that exposes the following properties:
7676

7777
* `IsCancelled` - set this to true to prevent the operation if the business logic requires it.
78-
* `Item` - the model item the treelist row is bound to. You can use it to access the model fields and methods in order to preform the actual data source operations. Applicable for buttons in a row, not in a toolbar.
78+
* `Item` - the model item of the treelist row. You can use it to access the model fields and preform the actual data source operations. This property is applicable only for command buttons that are inside a treelist row, not the toolbar.
7979
* `ParentItem` - the parent item of the current item, if any, otherwise `null`.
8080
* `IsNew` - a boolean field indicating whether the item was just added through the treelist interface.
8181

0 commit comments

Comments
 (0)