I have a situation where I need to allow things to be dragged from one TreeList to another. Additionally, in the 2nd TreeList I need to be able to reorder the items by dragging and dropping. I haven't been able to find anything yet on drag and drop capability for the Treelist so I was wondering if anyone has done drag and drop of this sort or whether it's supported, etc.
Thanks in advance for any info.
Steve
Thanks in advance for any info.
Steve
1 Answer, 1 is accepted
0
Princy
Top achievements
Rank 2
answered on 05 Sep 2012, 04:41 AM
Hi Steve,
Try the following code snippet to achieve your scenario.
ASPX:
JS:
C#:
Please take a look into this demo and documentation for more information.
Hope this helps.
Regards,
Princy.
Try the following code snippet to achieve your scenario.
ASPX:
<telerik:RadTreeList ID="RadTreeList1" runat="server" AllowPaging="True" DataSourceID="SqlDataSource1" DataKeyNames="EmployeeID" ParentDataKeyNames="ParentEmployeeID" AutoGenerateColumns="false" AllowRecursiveDelete="true" Width="410px" PageSize="6" OnItemCommand="RadTreeList1_ItemCommand"> <PagerStyle Mode="NumericPages" /> <Columns> <telerik:TreeListTemplateColumn HeaderText="Source" DataField="FirstName"> <ItemTemplate> <table class="templateTable"> <tr> <td class="templateHeader"> <asp:Label ID="lblFirstName" runat="server" Text='<%# Bind("FirstName") %>' /> <asp:Label ID="lblMiddleName" runat="server" Text='<%# Bind("MiddleName") %>' /> <asp:Label ID="lblLastName" runat="server" Text='<%# Bind("LastName") %>' /> </td> </tr> <tr> <td> <asp:Label ID="lblPhone" runat="Server" Text='<%# Bind("Phone") %>' /> </td> </tr> <tr> <td> <asp:Label ID="lblCity" runat="server" Text='<%# Bind("City") %>' /> <asp:Label ID="lblAddress" runat="server" Text='<%# Bind("Address") %>' /> </td> </tr> </table> </ItemTemplate> </telerik:TreeListTemplateColumn> </Columns> <ClientSettings AllowItemsDragDrop="true"> <Selecting AllowItemSelection="True" /> <ClientEvents OnItemDropping="itemDropping" OnItemDragging="itemDragging" OnTreeListCreated="function(sender) { treeList1 = sender; }" /> </ClientSettings></telerik:RadTreeList><telerik:RadTreeList ID="RadTreeList2" runat="server" AllowPaging="True" DataSourceID="SqlDataSource2" DataKeyNames="EmployeeID" ParentDataKeyNames="ManagerID" AutoGenerateColumns="false" ClientDataKeyNames="EmployeeID" PageSize="6" Width="410px"> <PagerStyle Mode="NumericPages" /> <Columns> <telerik:TreeListTemplateColumn HeaderText="Target"> <ItemTemplate> <table id="Table1" class="templateTable" runat="server"> <tr> <td class="templateHeader"> <asp:Label ID="lblFirstName" runat="server" Text='<%# Bind("FirstName") %>' /> <asp:Label ID="lblMiddleName" runat="server" Text='<%# Bind("MiddleName") %>' /> <asp:Label ID="lblLastName" runat="server" Text='<%# Bind("LastName") %>' /> </td> </tr> <tr> <td> <asp:Label ID="lblPhone" runat="Server" Text='<%# Bind("Phone") %>' /> </td> </tr> <tr> <td> <asp:Label ID="lblCity" runat="server" Text='<%# Bind("City") %>' /> <asp:Label ID="lblAddress" runat="server" Text='<%# Bind("Address") %>' /> </td> </tr> </table> </ItemTemplate> </telerik:TreeListTemplateColumn> </Columns> <ClientSettings AllowItemsDragDrop="true"> <Selecting AllowItemSelection="True" /> <ClientEvents OnItemDropping="itemDropping" OnItemDragging="itemDragging" OnTreeListCreated="function(sender) { treeList2 = sender; }" /> </ClientSettings></telerik:RadTreeList><asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:SelfReferencingDbConnectionString %>" SelectCommand="SELECT [EmployeeID], [ParentEmployeeID], [FirstName], [MiddleName], [LastName], [Phone], [Address], [City] FROM [TelerikEmployees]" DeleteCommand="DELETE FROM [TelerikEmployees] WHERE [EmployeeID] = @EmployeeID" InsertCommand="INSERT INTO [TelerikEmployees] ([ParentEmployeeID]) VALUES (@ParentEmployeeID)" UpdateCommand="UPDATE [TelerikEmployees] SET [ParentEmployeeID] = @ParentEmployeeID WHERE [EmployeeID] = @EmployeeID"> <DeleteParameters> <asp:Parameter Name="EmployeeID" Type="Int32" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="ParentEmployeeID" Type="Int32" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="ParentEmployeeID" Type="Int32" /> <asp:Parameter Name="EmployeeID" Type="Int32" /> </UpdateParameters></asp:SqlDataSource><asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:SelfReferencingDbConnectionString %>" SelectCommand="SELECT [EmployeeID], [FirstName], [MiddleName], [LastName], [ManagerID], [Address], [City], [Phone] FROM [EmployeesNew]" DeleteCommand="DELETE FROM [EmployeesNew] WHERE [EmployeeID] = @EmployeeID" InsertCommand="INSERT INTO [EmployeesNew] ([ManagerID]) VALUES (@ManagerID)" UpdateCommand="UPDATE [EmployeesNew] SET [ManagerID] = @ManagerID WHERE [EmployeeID] = @EmployeeID"> <DeleteParameters> <asp:Parameter Name="EmployeeID" Type="Int32" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="ManagerID" Type="Int32" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="ManagerID" Type="Int32" /> <asp:Parameter Name="EmployeeID" Type="Int32" /> </UpdateParameters></asp:SqlDataSource>JS:
<script type="text/javascript"> var treeList1; var treeList2; function findParentItem(element) { if (element.tagName.toLowerCase() == "html") return null; while (!(element.id != "" && typeof element.tagName != "undefined" && element.tagName.toLowerCase() == "tr")) { if (element.parentNode == null) return null; element = element.parentNode; } return element; } function get_isTreeListChild(elem) { var isInTreeList1 = $telerik.isDescendant(treeList1.get_element(), elem); var isInTreeList2 = $telerik.isDescendant(treeList2.get_element(), elem); return isInTreeList1 || isInTreeList2; } function get_dropTarget(domEvent) { return domEvent.srcElement || domEvent.target; } function itemDragging(sender, args) { var isChild; var dropClue = $telerik.findElement(args.get_draggedContainer(), "DropClue"); args.set_dropClueVisible(true); //drop clue is always visible if (!args.get_canDrop()) //trying to drag a parent item onto its own child { dropClue.className = "dropClue dropDisabled"; return; } if (sender == treeList2) //In this demo, RadTreeList2 supports item reordering only { isChild = $telerik.isDescendant(treeList2.get_element(), get_dropTarget(args.get_domEvent())); } else //RadTreeList1 supports both reordering and drop over RadTreeList2 { isChild = get_isTreeListChild(get_dropTarget(args.get_domEvent())); //is child of RadTreeList1 or RadTreeList2 } var className = isChild ? "dropEnabled" : "dropDisabled"; //Change drop clue icon depending on the drop target args.set_canDrop(isChild); dropClue.className = "dropClue " + className; } function itemDropping(sender, args) { var targetRow = findParentItem(args.get_destinationHtmlElement()); //Target row is null or not a child of RadTreeList -> Cancel if (targetRow == null || !get_isTreeListChild(targetRow)) { args.set_cancel(true); return; } //Target row is descendant of the sender -> Reorder operation if ($telerik.isDescendant(sender.get_element(), targetRow)) return; //Target row is descendant of RadTreeList2 -> Copy/Move item args.set_cancel(true); treeList2.get_dataItems(); var itm = args.get_draggedItems()[0]; var employeeID = $find(targetRow.id).get_dataKeyValue("EmployeeID"); itm.fireCommand("CustomItemsDropped", employeeID); //Fire custom command }</script>C#:
private readonly string connString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;private readonly string[] sqlParams = new string[] {"EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath","Score","Time","IsValid" };protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { RadTreeList1.ExpandToLevel(2); RadTreeList2.ExpandToLevel(2); } }private Hashtable ExtractControlValuesFromItem(TreeListItem item) { Hashtable table = new Hashtable(); foreach (string par in sqlParams) { string id = String.Format("lbl{0}", par); Label lbl = item.FindControl(id) as Label; if (lbl != null) table.Add(par, lbl.Text); } return table; }protected void RadTreeList1_ItemCommand(object sender, TreeListCommandEventArgs e) { if (e.CommandName == "CustomItemsDropped") { TreeListDataItem item = e.Item as TreeListDataItem; string EmployeeID = e.CommandArgument.ToString(); SqlConnection connection = new SqlConnection(connString); SqlCommand cmd = new SqlCommand("INSERT INTO Employees ( EmployeeID,LastName,FirstName,Title,TitleOfCourtesy,BirthDate,HireDate,Address,City,Region,PostalCode,Country,HomePhone,Extension,Photo,Notes,ReportsTo,PhotoPath,Score,Time,IsValid )" + "VALUES (@EmployeeID,@LastName,@FirstName,@Title,@TitleOfCourtesy,@BirthDate,@HireDate,@Address,@City,@Region,@PostalCode,@Country,@HomePhone,@Extension,@Photo,@Notes,@ReportsTo,@PhotoPath,@Score,@Time,@IsValid );" + "SELECT @ScopeID=SCOPE_IDENTITY()", connection); connection.Open(); using (connection) { InsertItemsRecursively(item, EmployeeID, connection, cmd); } RadTreeList1.PerformDelete(item); RadTreeList2.Rebind(); } }private void InsertItemsRecursively(TreeListDataItem dataItem, string EmployeeID, SqlConnection connection, SqlCommand cmd) { Hashtable values = ExtractControlValuesFromItem(dataItem); foreach (string param in sqlParams) { if (param == "EmployeeID") cmd.Parameters.AddWithValue("EmployeeID", EmployeeID); else cmd.Parameters.AddWithValue(param, values[param]); } SqlParameter scopeIdentity = new SqlParameter("ScopeID", SqlDbType.Int); scopeIdentity.Direction = ParameterDirection.Output; cmd.Parameters.Add(scopeIdentity); cmd.ExecuteNonQuery(); string id = cmd.Parameters["ScopeID"].Value.ToString(); cmd.Parameters.Clear(); foreach (TreeListDataItem item in dataItem.ChildItems) InsertItemsRecursively(item, id, connection, cmd); }Please take a look into this demo and documentation for more information.
Hope this helps.
Regards,
Princy.