Does TreeList support Drag and Drop?

2 posts, 0 answers
  1. Steve
    Steve avatar
    5 posts
    Member since:
    Aug 2012

    Posted 04 Sep 2012 Link to this post

    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
  2. Princy
    Princy avatar
    17421 posts
    Member since:
    Mar 2007

    Posted 04 Sep 2012 Link to this post

    Hi Steve,

    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.
  3. UI for ASP.NET Ajax is Ready for VS 2017
Back to Top