ListView with multiple Checkboxes/RadioButtons.

I had a little struggle working with multiple checkboxes/radiobuttons inside a ListView. For Checkboxes inside the ListView, I needed to associate multiple column values from the underlying DataTable, as part of the value attribute. These values again needed to be available at client end as well as on server. For the server part, I obtained these values from DataKeyNames property of the container ListView. I had to pre-populate the checkbox, alter (check/uncheck the checkboxes) and then do a postback. The example below uses HtmlInputCheckBox in ItemTemplate of the ListView. Everything’s same for radiobuttons too, except, I had to handle the grouping issue with radio buttons. Namely, when multiple radio buttons are a part of any databound control, since the name attribute is rendered unique — mutually-exclusive property won’t work.There are many existing approaches with JQuery/custom RadioButton, but I personally found dynamically generating the radio buttons from code-behind, is the simplest and solid. For all the radiobuttons which have same groupname, are kept in the same ItemTemplate, to take care of the grouping bug.

Here’s the datatable, for the ListView binding.

img1
First — CheckBox & ListView. Here’s the output page screen-shot.

CheckBoxOutput

//markup

<head runat="server">
<title></title>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.js" type="text/javascript"></script>
</head>
<script type="text/javascript">
$(document).ready(function () {
    $('input[type=checkbox]').click(function () {
        if ($(this)[0].checked == true) {
            var _temp =  $(this)[0].value;
        }
    });
});
</script>
<asp:ListView ID="lv1" GroupItemCount="3" runat="server" DataKeyNames="id1,id2" onitemdatabound="lv1_ItemDataBound" >
<LayoutTemplate>
<fieldset>
    <legend>MyGroups</legend>
    &nbsp;
    <asp:PlaceHolder runat="server"  ID="groupPlaceholder"></asp:PlaceHolder>
</fieldset>
</LayoutTemplate>
<GroupTemplate>
<fieldset>
    <legend>Individual Group</legend>
    <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</fieldset>    
</GroupTemplate>
<GroupSeparatorTemplate>
&nbsp;
</GroupSeparatorTemplate>
<EmptyDataTemplate>No records present.</EmptyDataTemplate>
<ItemTemplate>
&nbsp;&nbsp;
<input id="c1"  runat="server" value='<%# Eval("id1")+","+Eval("id2") %>' type="checkbox" /><%# Eval("Text1") %>
</ItemTemplate>  
</asp:ListView>
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
        BindListView();
}

private void BindListView()
{
    lv1.DataSource = GetData();
    lv1.DataBind();
}

private DataTable GetData()
{
    DataTable dt = new DataTable();
    dt.Columns.Add("id1", System.Type.GetType("System.Int32"));
    dt.Columns.Add("id2", System.Type.GetType("System.Int32"));
    dt.Columns.Add("Text1", System.Type.GetType("System.String"));
    dt.Columns.Add("Text2", System.Type.GetType("System.String"));
    int k = 0;
    string strTemp = "grp1";
    for (int i = 0; i < 12; i++)
    {
        DataRow dr = dt.NewRow();
        dr["id1"] = i + 13;
        dr["id2"] = i + 14;
        dr["Text1"] = "SomeText1-" + i.ToString();
        dr["Text2"] = strTemp;
        k++;
        if (k == 3)
        {
            strTemp = "grp1" + i.ToString();
            k = 0;
        }
        dt.Rows.Add(dr);
    }
    return dt;
}

private void FetchListViewRecords()
{
    foreach(ListViewItem _item in lv1.Items)
    {
        HtmlInputCheckBox c1 = (HtmlInputCheckBox)_item.FindControl("c1");
        if (c1.Checked)
        {
            //Get the individual values from DataKeyNames array
            //instead of checkbox value.
            string val1 = lv1.DataKeys[_item.DataItemIndex].Values[0].ToString();
            string val2 = lv1.DataKeys[_item.DataItemIndex].Values[1].ToString();
        }
    }
}

protected void lv1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    if (e.Item.ItemType == ListViewItemType.DataItem)
    {
        ListViewDataItem dataItem = (ListViewDataItem)e.Item;
        DataRowView drv = (DataRowView)dataItem.DataItem;
        HtmlInputCheckBox c1 = (HtmlInputCheckBox)e.Item.FindControl("c1");
        if (drv["id2"].ToString() == "16")
        {
            c1.Checked = true;
        }
    }
}

protected void Button1_Click(object sender, EventArgs e)
{
    FetchListViewRecords();
}

Next — RadioButtons & ListView.

RadioOutput

<script type="text/javascript">
$(document).ready(function () {
    $('input[type=radio]').click(function () {
        if ($(this)[0].checked == true) {
            var _temp = $(this)[0].value;
        }
    });
});
</script>
<asp:ListView ID="lv1" GroupItemCount="3" runat="server" DataKeyNames="id1,id2" onitemdatabound="lv1_ItemDataBound" >
<LayoutTemplate>
<fieldset>
    <legend>MyGroups</legend>
    &nbsp;
    <asp:PlaceHolder runat="server"  ID="groupPlaceholder"></asp:PlaceHolder>
</fieldset>
</LayoutTemplate>
<GroupTemplate>
<fieldset>
    <legend>Mutually Exclusive individual Group</legend>
    <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</fieldset>    
</GroupTemplate>
<GroupSeparatorTemplate>
&nbsp;
</GroupSeparatorTemplate>
<EmptyDataTemplate>No records present.</EmptyDataTemplate>
<ItemTemplate>
&nbsp;&nbsp;
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</ItemTemplate>  
</asp:ListView>
private string CurrGrpName = String.Empty;
DataTable dt3 = new DataTable();

protected void Page_Load(object sender, EventArgs e)
{
    BindListView();
}

private void BindListView()
{
    dt3 = GetData();
    lv1.DataSource = dt3;
    lv1.DataBind();
}
private DataTable GetData()
{
    DataTable dt = new DataTable();
    dt.Columns.Add("id1", System.Type.GetType("System.Int32"));
    dt.Columns.Add("id2", System.Type.GetType("System.Int32"));
    dt.Columns.Add("Text1", System.Type.GetType("System.String"));
    dt.Columns.Add("GrpInfo", System.Type.GetType("System.String"));
    int k = 0;
    string strTemp = "grp1";
    for (int i = 0; i < 12; i++)
    {
        DataRow dr = dt.NewRow();
        dr["id1"] = i + 13;
        dr["id2"] = i + 14;
        dr["Text1"] = "SomeText1-" + i.ToString();
        dr["GrpInfo"] = strTemp;
        k++;
        if (k == 3)
        {
            strTemp = "grp1" + i.ToString();
            k = 0;
        }
        dt.Rows.Add(dr);
    }
    return dt;
}
private void FetchListViewRecords()
{
    foreach (ListViewItem _item in lv1.Items)
    {
        PlaceHolder c1 = (PlaceHolder)_item.FindControl("PlaceHolder1");
        foreach (Control c11 in c1.Controls)
        {
            //Interested only in RadioButton
            if (c11.GetType().Name == "RadioButton")
            {
                RadioButton rb = (RadioButton)c11;
                if (rb.Checked)
                {
                    string val0 = rb.Text;
                    //Get the individual values from DataKeyNames array
                    string val1 = lv1.DataKeys[_item.DataItemIndex].Values[0].ToString();
                    string val2 = lv1.DataKeys[_item.DataItemIndex].Values[1].ToString();
                }
            }
        }
    }
}
protected void lv1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    if (e.Item.ItemType == ListViewItemType.DataItem)
    {
        ListViewDataItem dataItem = (ListViewDataItem)e.Item;
        DataRowView drv = (DataRowView)dataItem.DataItem;
        if (CurrGrpName != drv["GrpInfo"].ToString())
        {
            PlaceHolder PlaceHolder1 = (PlaceHolder)e.Item.FindControl("PlaceHolder1");
            //For all records which have same grpInfo and hence making
            //those radio-buttons to have same groupname
            //are placed in the same ItemTemplate.
            DataTable dt2 = dt3.Select("GrpInfo = '" + drv["GrpInfo"].ToString() + "'").CopyToDataTable();
            foreach (DataRow dr in dt2.Rows)
            {
                RadioButton rb = new RadioButton();
                rb.ID = "i" + dr["id1"].ToString();
                rb.GroupName = dr["GrpInfo"].ToString();
                rb.Text = dr["Text1"].ToString();
                rb.Attributes.Add("value", dr["id1"].ToString() + "," + dr["id2"].ToString());
                PlaceHolder1.Controls.Add(rb);
                PlaceHolder1.Controls.Add(new LiteralControl("&nbsp;"));
            }
            CurrGrpName = drv["GrpInfo"].ToString();
        }
    }
}
protected void Button1_Click(object sender, EventArgs e)
{
    FetchListViewRecords();
}

That’s all about it. Thanks for reading.

Advertisements
This entry was posted in General ASP.Net C# and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s