RadGrid Grouping with Checkboxes

16 posts, 0 answers
  1. Chris Trina
    Chris Trina avatar
    86 posts
    Member since:
    Mar 2006

    Posted 13 Dec 2012 Link to this post

    I have a grid with grouping by state.  At each level I have check boxes (Header, Group, Detail).  If the header is checked, all check boxes are checked.  If a group check box is checked, all detail check boxes in that group are checked.  If a detail check box is unchecked, the group needs to be unchecked and the header needs to be unchecked.  I had to write custom code for this because I could find no imbedded controls to do this for me.  I used the code example Select All option in Grid Header along with individual group selection as a starting point.  My problem is that this is all done server side.  I would like it to be client side.  I found client side examples that let me select all, but none that did the unselecting when a lower item was unchecked.  I have made several attempts at writing the client side code, but have failed.

    I am using telerik version 2012.3.1016.4, Visual Basic .Net Framework 4.  This needs to work in all (most common) browsers.

    My aspx page
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <div>
            <br />
            <telerik:RadGrid ID="RadGrid1" runat="server" AllowMultiRowSelection="true"  DataSourceID="SqlDataSource1" GridLines="None" AutoGenerateColumns="False" OnItemCreated="RadGrid1_ItemCreated" Skin="Hay">
                <MasterTableView DataSourceID="SqlDataSource1">
                    <RowIndicatorColumn Visible="False">
                        <HeaderStyle Width="20px" />
                    </RowIndicatorColumn>
                    <ExpandCollapseColumn Resizable="False" Visible="False">
                        <HeaderStyle Width="40px" />
                    </ExpandCollapseColumn>
                    <GroupByExpressions>
                      <telerik:GridGroupByExpression>
                       <GroupByFields>
                         <telerik:GridGroupByField FieldName="State" FieldAlias="State" />
                       </GroupByFields>
                       <SelectFields>
                         <telerik:GridGroupByField FieldName="State" FieldAlias="State" />
                       </SelectFields>
                      </telerik:GridGroupByExpression>
                    </GroupByExpressions>
                    <Columns>
                    <telerik:GridBoundColumn SortExpression="LastName" HeaderText="Last Name" HeaderButtonType="TextButton"
                        DataField="LastName" UniqueName="LastName" ItemStyle-Width="40px" >
                    </telerik:GridBoundColumn>
                    <telerik:GridBoundColumn SortExpression="FirstName" HeaderText="First Name" HeaderButtonType="TextButton"
                        DataField="FirstName" UniqueName="FirstName">
                    </telerik:GridBoundColumn>
                    </Columns>
                    <EditFormSettings>
                        <PopUpSettings ScrollBars="None" />
                    </EditFormSettings>
                </MasterTableView>
            </telerik:RadGrid><br />
            <br />
        <asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:ConnString %>"
            ProviderName="System.Data.SqlClient" SelectCommand="select * from TAZTestData order by State, LastName"
            runat="server">
        </asp:SqlDataSource>
             </div>
    </form>

    My vb.net code
    Protected Sub RadGrid1_ItemCreated(sender As Object, e As Telerik.Web.UI.GridItemEventArgs)
        If TypeOf e.Item Is GridHeaderItem Then
            Dim header As GridHeaderItem = DirectCast(e.Item, GridHeaderItem)
            Dim headerchkbx As New CheckBox()
            headerchkbx.ID = "CheckBox1"
            headerchkbx.AutoPostBack = True
            AddHandler headerchkbx.CheckedChanged, AddressOf headerchkbx_CheckedChanged
            header("column").Controls.Add(headerchkbx)
        End If
        If TypeOf e.Item Is GridGroupHeaderItem Then
            Dim header As GridGroupHeaderItem = DirectCast(e.Item, GridGroupHeaderItem)
            Dim groupchkbx As New CheckBox()
            groupchkbx.ID = "CheckBox2"
            groupchkbx.AutoPostBack = True
            AddHandler groupchkbx.CheckedChanged, AddressOf groupchkbx_CheckedChanged
            header.Controls(0).Controls.Add(groupchkbx)
        End If
        If TypeOf e.Item Is GridDataItem Then
            Dim header As GridDataItem = DirectCast(e.Item, GridDataItem)
            Dim detailchkbx As New CheckBox()
            detailchkbx.ID = "CheckBox3"
            detailchkbx.AutoPostBack = True
            AddHandler detailchkbx.CheckedChanged, AddressOf detailchkbx_CheckedChanged
            header.Controls(0).Controls.Add(detailchkbx)
        End If
     
    End Sub
     
    Private Sub headerchkbx_CheckedChanged(sender As Object, e As EventArgs)
     
        Dim headerchkbx As CheckBox = DirectCast(sender, CheckBox)
        For Each groupHeader As GridGroupHeaderItem In RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader)
            Dim children As GridItem() = groupHeader.GetChildItems()
            Dim groupchkbx As CheckBox = DirectCast(groupHeader.Controls(0).FindControl("CheckBox2"), CheckBox)
            For Each child As GridItem In children
                Dim detailchkbx As CheckBox = DirectCast(child.Controls(0).FindControl("CheckBox3"), CheckBox)
                detailchkbx.Checked = headerchkbx.Checked
            Next
     
            ' If headerchkbx.Checked Then
            groupchkbx.Checked = headerchkbx.Checked
            'Else
            'item.Selected = False
            'groupchkbx.Checked = False
     
            'End If
        Next
        For Each item As GridHeaderItem In RadGrid1.MasterTableView.GetItems(GridItemType.Header)
            item.Selected = headerchkbx.Checked
        Next
    End Sub
     
    Private Sub groupchkbx_CheckedChanged(sender As Object, e As EventArgs)
        Dim chkCount As Integer = 0
        For Each groupHeader As GridGroupHeaderItem In RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader)
            Dim children As GridItem() = groupHeader.GetChildItems()
     
            Dim groupchkbx As CheckBox = DirectCast(groupHeader.Controls(0).FindControl("CheckBox2"), CheckBox)
            If (groupchkbx.Checked) Then
                chkCount += 1
            End If
            For Each child As GridItem In children
                Dim detailchkbx As CheckBox = DirectCast(child.Controls(0).FindControl("CheckBox3"), CheckBox)
                detailchkbx.Checked = groupchkbx.Checked
                'Dim dataItem As GridDataItem = TryCast(child, GridDataItem)
                'dataItem.Selected = groupchkbx.Checked
     
                For Each item As GridHeaderItem In RadGrid1.MasterTableView.GetItems(GridItemType.Header)
                    Dim headerchkbx As CheckBox = DirectCast(item("column").FindControl("CheckBox1"), CheckBox)
     
                    If (Not groupchkbx.Checked) Then
                        headerchkbx.Checked = False
                    End If
                    If RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader).Length = chkCount Then
                        headerchkbx.Checked = True
     
                    End If
                Next
            Next
        Next
    End Sub
     
    Private Sub detailchkbx_CheckedChanged(sender As Object, e As EventArgs)
        Dim totalCount As Integer = 0
        Dim groupCount As Integer = 0
        Dim totalChkCount As Integer = 0
        Dim groupChkCount As Integer = 0
        'Loop through all groups
        For Each groupHeader As GridGroupHeaderItem In RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader)
            Dim groupchkbx As CheckBox = DirectCast(groupHeader.Controls(0).FindControl("CheckBox2"), CheckBox)
            Dim grpChildren As GridItem() = groupHeader.GetChildItems()
     
            For Each child As GridItem In grpChildren
                'Count total number of checkboxes in whole grid and in each group
                totalCount += 1
                groupCount += 1
                Dim detailchkbx As CheckBox = DirectCast(child.Controls(0).FindControl("CheckBox3"), CheckBox)
                'Count number of checkboxes that are checked in whole grid and in each group
                If (detailchkbx.Checked) Then
                    totalChkCount += 1
                    groupChkCount += 1
                End If
            Next
            'Check the group check box if all the children are checked
            If groupCount = groupChkCount Then
                groupchkbx.Checked = True
            Else
                groupchkbx.Checked = False
            End If
            groupCount = 0
            groupChkCount = 0
        Next
        For Each hdr As GridHeaderItem In RadGrid1.MasterTableView.GetItems(GridItemType.Header)
            Dim headerchkbx As CheckBox = DirectCast(hdr("column").FindControl("CheckBox1"), CheckBox)
            If totalCount = totalChkCount Then
                headerchkbx.Checked = True
            Else
                headerchkbx.Checked = False
            End If
        Next
    End Sub

    Thank you for any help!
  2. Radoslav
    Admin
    Radoslav avatar
    1564 posts

    Posted 18 Dec 2012 Link to this post

    Hi Chris,

    I am sending you a simple example which demonstrates how to add a checkbox into the group headers and check/uncheck all items from the current group on the client. You can use it as a start point. In your case you need to add logic which find if all items from the groups are checked and then to check the header checkbox.

    Please give it try and let me know if you experience any problems. Looking forward for your reply.

    Kind regards,
    Radoslav
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Chris Trina
    Chris Trina avatar
    86 posts
    Member since:
    Mar 2006

    Posted 19 Dec 2012 Link to this post

    If I am looping through all the nodes, how do I start at the top of the grid?  And how do I know when I get to the last node?
  5. Radoslav
    Admin
    Radoslav avatar
    1564 posts

    Posted 21 Dec 2012 Link to this post

    Hi Chris,

    You do not need to iterate over all rows you need to check if all checkbox from the current group are checked or someone of them is unchecked. I am sending you the modified version of the example please check it out and let me know if it helps you.

    Looking forward for your reply.

    All the best,
    Radoslav
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  6. Chris Trina
    Chris Trina avatar
    86 posts
    Member since:
    Mar 2006

    Posted 21 Dec 2012 Link to this post

    Thanks for the new code.  However, I do not see the call to "checkUncheckParent".  I know how to send the current checkbox as a parameter, but how do I send the parent?

    Thanks again for your help.
  7. Princy
    Princy avatar
    17421 posts
    Member since:
    Mar 2007

    Posted 26 Dec 2012 Link to this post

    HI,

    The function "checkUncheckParent" is called in the prerender event of the radgrid. Please check the code behind.
    C#:
    void RadGrid1_PreRender(object sender, EventArgs e)
       {
           List<GridGroupHeaderItem> headerItems = RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader).Cast<GridGroupHeaderItem>().ToList();
           foreach (GridGroupHeaderItem item in headerItems)
           {
               var checkBox = item.FindControl("CheckBox1") as CheckBox;
               List<GridDataItem> childItems = item.GetChildItems().Cast<GridDataItem>().ToList();
               foreach (var child in childItems)
               {
                   CheckBox selectColumnCheckBox = child["selectColumn"].Controls[0] as CheckBox;
                   selectColumnCheckBox.Attributes.Add("onclick", string.Format("checkUncheckParent('{0}','{1}'); return false;", selectColumnCheckBox.ClientID, checkBox.ClientID));
               }
           }
       }

    The parent checkbox is passed as "checkBox.ClientID" in the above code.

    Thanks,
    Princy.    
  8. Chris Trina
    Chris Trina avatar
    86 posts
    Member since:
    Mar 2006

    Posted 27 Dec 2012 Link to this post

    That did it.  Thanks
  9. Chris Trina
    Chris Trina avatar
    86 posts
    Member since:
    Mar 2006

    Posted 14 Jan 2013 Link to this post

    I have one more problem with my app.  If a section is collapsed and you check/uncheck it, any items that were not visible are unchanged.  Is there a way to change the items that are hidden?
  10. Chris Trina
    Chris Trina avatar
    86 posts
    Member since:
    Mar 2006

    Posted 15 Jan 2013 Link to this post

    I got it.  I had to add  --  MasterTableView-GroupLoadMode="Client"
  11. John Mutters
    John Mutters avatar
    1 posts
    Member since:
    Aug 2013

    Posted 20 Aug 2013 Link to this post

    Good code, but don't forget to check for null references on the currentNode in the while loops ;-)
  12. Ray
    Ray avatar
    4 posts
    Member since:
    Apr 2013

    Posted 06 Aug 2015 Link to this post

    Hi princy,

    I've implemented the example of the client side code in my app. It all works great except I no longer have the group header text.

    I tried to add a label to the group template. But all examples i've come across presume that the group by columns will not be changing at runtime. Mine can be changed by drag and drop. And may have have multiple levels of grouping. Is there a solution to this issue?

  13. Radoslav
    Admin
    Radoslav avatar
    1564 posts

    Posted 11 Aug 2015 Link to this post

    Hello Ray,

    There is not straight solution for your case. When you have multiple groups you need to write your own logic for traversing all group items (in all nested group levels) and check manually the checkboxes. However please note that this is a custom scenario and it is out of our support scope. You can use my example as a starting point and modify it for your case.

    Regarding the issue with not showing the group header texts:
    Can you send us a small runnable example where the problem can be reproduced? Thus we will be able to gather more details about your scenario and provide you with more to-the-point answer.

    Looking forward for your reply.

    Regards,
    Radoslav
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  14. vijay kumar
    vijay kumar avatar
    7 posts
    Member since:
    Nov 2016

    Posted 22 Nov in reply to Radoslav Link to this post

    Hi, I have added check box at group header level from code behind. but i am not able to get selected values. please see below my code.

    Code used for adding check box only at second group.

    protected void RadGrid1_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e)
            {
                CreateHeaderControls(e);
            }

            protected void RadGrid1_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
            {
                CreateHeaderControls(e);
            }

            private void CreateHeaderControls(GridItemEventArgs e)
            {
                if (e.Item is GridGroupHeaderItem)
                {
                    GridGroupHeaderItem item = e.Item as GridGroupHeaderItem;
                    DataRowView groupDataRow = (DataRowView)e.Item.DataItem;
                    if (groupDataRow != null && groupDataRow.Row.ItemArray.Count() == 4)
                    {
                        CheckBox check = new CheckBox();
                        check.ID = "CheckInvite";
                        check.Text = groupDataRow.Row.ItemArray[0].ToString() + " To " + groupDataRow.Row.ItemArray[1].ToString();
                        item.DataCell.Controls.Add(check);
                    }
                }
            }

     

    Trying to get selected values from my button click

    protected void btnInvite_Click(object sender, EventArgs e)
            {
                List<GridGroupHeaderItem> headerItems = RadGrid1.MasterTableView.GetItems(GridItemType.GroupHeader).Cast<GridGroupHeaderItem>().ToList();
                foreach (GridGroupHeaderItem item in headerItems)
                {
                    var checkBox = item.FindControl("CheckInvite") as CheckBox;
                }
            }

     

    but always checkBox coming as null. Please see attached my screen shot also. (Note my radgrid i created on modal popup, hope this will not be any problem. i do not want any post back or auto post back.) Just I need to get selected groups from code behind.

     

  15. vijay kumar
    vijay kumar avatar
    7 posts
    Member since:
    Nov 2016

    Posted 22 Nov in reply to vijay kumar Link to this post

    Please find attached my aspx code aslo.
  16. Eyup
    Admin
    Eyup avatar
    3015 posts

    Posted 23 Nov Link to this post

    Hello Vijay,

    I've already replied to your colleague for this query. I suggest that we continue our technical conversation on the formal support thread.

    Regards,
    Eyup
    Telerik by Progress
    Telerik UI for ASP.NET AJAX is ready for Visual Studio 2017 RC! Learn more.
  17. vijay kumar
    vijay kumar avatar
    7 posts
    Member since:
    Nov 2016

    Posted 23 Nov in reply to Eyup Link to this post

    Thank you Eyup.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017