Skip to content

Commit 35023ef

Browse files
github-actions[bot]ntachevaTsvetomir-Hr
authored
Merge treeview-validate-drop-target-2588 into production (#2616)
* chore(TreeView): validate drop target * Update knowledge-base/treeview-validate-drop-target.md Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com> * Update knowledge-base/treeview-validate-drop-target.md Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com> * Update knowledge-base/treeview-validate-drop-target.md Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com> * Update knowledge-base/treeview-validate-drop-target.md Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com> * Update knowledge-base/treeview-validate-drop-target.md Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com> --------- Co-authored-by: Nadezhda Tacheva <Nadezhda.Tacheva@progress.com> Co-authored-by: Nadezhda Tacheva <73842592+ntacheva@users.noreply.github.com> Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com>
1 parent 7a3c569 commit 35023ef

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
title: Validate Drop Target in TreeView
3+
description: How to validate drop target in Telerik TreeView for Blazor and prevent drop for invalid target.
4+
type: how-to
5+
page_title: How to Validate Drop Target in TreeView
6+
slug: treeview-kb-validate-drop-target
7+
tags: treeview, item, node, drop target, draggable, validate, invalid, prevent drop
8+
ticketid: 1592132
9+
res_type: kb
10+
---
11+
12+
## Environment
13+
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>TreeView for Blazor</td>
19+
</tr>
20+
</tbody>
21+
</table>
22+
23+
## Description
24+
25+
I have a draggable TreeView and I want to prevent the user from dropping items in specific locations or folders. How can I achieve this?
26+
27+
How to validate the drop target, so I don't allow the user to drop the file if the target is invalid?
28+
29+
## Solution
30+
31+
To validate the drop target and prevent the user from dropping on an invalid target, follow these steps:
32+
33+
1. Handle the [`OnDrag`]({%slug treeview-events%}#drag-events) event of the TreeView to validate the target based on your requirements. In the example below, we are checking it the user tries to drop an item from the **Documents** folder into the **Pictures** folder - the **Pictures** folder is not a valid target in this case.
34+
1. Raise a flag if the target is not valid.
35+
1. Change the icon in the drag clue to indicate the target is not valid. Once the [Drag Clue Template](https://feedback.telerik.com/blazor/1501043-drag-clue-template) is available, you may use it to change the rendering as needed. At the time of writing, changing the icon is only possible with CSS as per the example below.
36+
1. Include a conditional logic in your [`OnDrop`]({%slug treeview-events%}#drag-events) handler to not perform any action if the target is invalid.
37+
1. Use CSS to hide the build-in drop hint for the invalid target.
38+
39+
40+
>caption Validate TreeView drop target and prevent drop for invalid target
41+
42+
````CSHTML
43+
This TreeView does not allow the user to drop items from the Documents folder into the Pictures folder.
44+
45+
<TelerikTreeView Data="@Data"
46+
@bind-ExpandedItems="@ExpandedItems"
47+
Draggable="true"
48+
DragThrottleInterval="150"
49+
OnDrag="@OnDrag"
50+
OnDrop="@OnItemDrop">
51+
</TelerikTreeView>
52+
53+
@if (IsPointerOverInvalidTarget)
54+
{
55+
<style>
56+
.k-drag-clue .k-svg-icon svg path {
57+
d: path("M256 32c-50.3 0-96.8 16.6-134.1 44.6-17.2 12.8-32.4 28.1-45.3 45.3C48.6 159.2 32 205.7 32 256c0 123.7 100.3 224 224 224 50.3 0 96.8-16.6 134.1-44.6 17.2-12.8 32.4-28.1 45.3-45.3 28-37.4 44.6-83.8 44.6-134.1 0-123.7-100.3-224-224-224m0 384c-88.2 0-160-71.8-160-160 0-32.6 9.8-62.9 26.6-88.2l221.6 221.6C318.9 406.2 288.6 416 256 416m133.4-71.8L167.8 122.6C193.1 105.8 223.4 96 256 96c88.2 0 160 71.8 160 160 0 32.6-9.8 62.9-26.6 88.2");
58+
}
59+
60+
.k-drop-hint {
61+
display: none;
62+
}
63+
</style>
64+
}
65+
66+
@code {
67+
private TreeItem DestinationItem { get; set; }
68+
private List<TreeItem> Data { get; set; } = new List<TreeItem>();
69+
private IEnumerable<object> ExpandedItems { get; set; } = Enumerable.Empty<object>();
70+
private bool IsPointerOverInvalidTarget { get; set; }
71+
72+
private void OnDrag(TreeViewDragEventArgs args)
73+
{
74+
if (args.DestinationItem != null)
75+
{
76+
var draggedItem = args.Item as TreeItem;
77+
var destinationItem = args.DestinationItem as TreeItem;
78+
79+
if (draggedItem.ParentId == 1 && (destinationItem.ParentId == 7 || destinationItem.Id == 6 || destinationItem.Id == 7))
80+
{
81+
IsPointerOverInvalidTarget = true;
82+
}
83+
else
84+
{
85+
IsPointerOverInvalidTarget = false;
86+
}
87+
}
88+
}
89+
90+
private void OnItemDrop(TreeViewDropEventArgs args)
91+
{
92+
if (IsPointerOverInvalidTarget)
93+
{
94+
return;
95+
}
96+
else
97+
{
98+
var item = args.Item as TreeItem;
99+
var destinationItem = args.DestinationItem as TreeItem;
100+
101+
if (destinationItem != null && IsChild(item, destinationItem))
102+
{
103+
return;
104+
}
105+
106+
Data.Remove(item);
107+
108+
if (item.ParentId != null && !Data.Any(x => item.ParentId == x.ParentId))
109+
{
110+
Data.FirstOrDefault(x => x.Id == item.ParentId).HasChildren = false;
111+
}
112+
113+
if (args.DropPosition == TreeViewDropPosition.Over)
114+
{
115+
item.ParentId = destinationItem.Id;
116+
destinationItem.HasChildren = true;
117+
118+
Data.Add(item);
119+
}
120+
else
121+
{
122+
var index = Data.IndexOf(destinationItem);
123+
124+
item.ParentId = destinationItem.ParentId;
125+
126+
if (args.DropPosition == TreeViewDropPosition.After)
127+
{
128+
index++;
129+
}
130+
131+
Data.Insert(index, item);
132+
}
133+
134+
// Refresh data
135+
Data = new List<TreeItem>(Data);
136+
}
137+
}
138+
139+
private bool IsChild(TreeItem item, TreeItem destinationItem)
140+
{
141+
if (destinationItem?.ParentId == null || item == null)
142+
{
143+
return false;
144+
}
145+
else if (destinationItem.ParentId?.Equals(item.Id) == true)
146+
{
147+
return true;
148+
}
149+
150+
var parentDestinationItem = Data.FirstOrDefault(e => e.Id.Equals(destinationItem.ParentId));
151+
return IsChild(item, parentDestinationItem);
152+
}
153+
154+
protected override void OnInitialized()
155+
{
156+
LoadData();
157+
base.OnInitialized();
158+
}
159+
160+
private void LoadData()
161+
{
162+
Data = new List<TreeItem>()
163+
{
164+
new TreeItem(1, null, "Documents", SvgIcon.Folder, true),
165+
new TreeItem(2, 1, "report.xlsx", SvgIcon.FileExcel, false),
166+
new TreeItem(3, 1, "status.docx", SvgIcon.FileWord, false),
167+
new TreeItem(4, 1, "conferences.xlsx", SvgIcon.FileExcel, false),
168+
new TreeItem(5, 1, "performance.pdf", SvgIcon.FilePdf, false),
169+
new TreeItem(6, null, "Pictures", SvgIcon.Folder, true),
170+
new TreeItem(7, 6, "Camera Roll", SvgIcon.Folder, true),
171+
new TreeItem(8, 7, "team.png", SvgIcon.FileImage, false),
172+
new TreeItem(9, 7, "team-building.png", SvgIcon.FileImage, false),
173+
new TreeItem(10, 7, "friends.png", SvgIcon.FileImage, false),
174+
};
175+
ExpandedItems = Data.ToList();
176+
}
177+
178+
public class TreeItem
179+
{
180+
public int Id { get; set; }
181+
public int? ParentId { get; set; }
182+
public string Text { get; set; }
183+
public ISvgIcon Icon { get; set; }
184+
public bool HasChildren { get; set; }
185+
186+
public TreeItem(int id, int? parent, string text, ISvgIcon icon, bool hasChildren)
187+
{
188+
Id = id;
189+
ParentId = parent;
190+
Text = text;
191+
Icon = icon;
192+
HasChildren = hasChildren;
193+
}
194+
}
195+
}
196+
````

0 commit comments

Comments
 (0)