This is a migrated thread and some comments may be shown as answers.

Does TreeList support Drag and Drop?

1 Answer 71 Views
TreeList
This is a migrated thread and some comments may be shown as answers.
Steve
Top achievements
Rank 1
Steve asked on 04 Sep 2012, 03:05 PM
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

1 Answer, 1 is accepted

Sort by
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:
<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.
Tags
TreeList
Asked by
Steve
Top achievements
Rank 1
Answers by
Princy
Top achievements
Rank 2
Share this question
or