0
votes

I am dynamically binding a typed list to a GridView control. The Grid View Control is in an asp.net page that is wrapped in an asp:UpdatePanel (Ajax). The first column contains a checkbox control. Only one checkbox may be checked in this column. If the user checks a checkbox, all other checkbox must be unchecked.

I am trying to achieve this using client-side script without success. In the handler for the GridView’s RowDatabound event, have attempted to add an attribute to the CheckBox contained within the cell.

protected void ErrorGridView_RowDatabound(object sender, GridViewRowEventArgs e)
  {

     if (e.Row.RowType == DataControlRowType.DataRow)
     {

        if(e.Row.Cells[0].HasControls())
        {
           foreach (var control in e.Row.Cells[0].Controls)
           {
              if (!(control is CheckBox)) continue;

              var checkBox = (CheckBox)control;
              checkBox.Attributes.Add("CheckedChanged", "errorCheckChanged");
              return;
           }
        }           
     }

The client side script is registered on the Page_Load event handler - as below:

if (!Page.ClientScript.IsClientScriptBlockRegistered("ErrorsCheckBoxHandler")) Page.ClientScript.RegisterClientScriptBlock(GetType(),"ErrorsCheckBoxHandler", "function errorCheckChanged() {window.alert(\"here\"); }");

The problem is that the function is not called when any checkboxes are clicked. Hopefully someone can shed some light as to what am I missing here?

Also, what would be the best way to perform the de-selection of the any other checkboxes that are checked in the target column?

My plan would be to change the 'errorCheckChanged' function to take one parameter (the checkbox object). I would change the above code; adding to the attribute addition signature:

checkBox.Attributes.Add("CheckedChanged", "errorCheckChanged(this)");

Hopefully, I will then be able to:
(1) determine if the checkbox state is 'checked'. (If it is 'checked', then continue below steps)
(2) find the checkbox parent (= cell) and then determine the affected GridView Row.
(3) Loop through all rows setting the checkboxes to 'Checked=false' except of the current row.

Would this be considered the right approach?

Thanks

Grant

2

2 Answers

1
votes

You can also add the onclick event of checkbox in design time.

<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkSelect" onclick="errorCheckChanged(this)" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>

And the JavaScript looks like

function errorCheckChanged(chkBox){  
    var gridView = document.getElementById('<% =GridView1.ClientID %>');   
    var Elements = gridView.getElementsByTagName('input');   

    for(var i = 0; i < Elements.length; i++){
        if(Elements[i].type == 'checkbox' && Elements[i].id != chkBox.id && chkBox.checked)
            Elements[i].checked = false;
    }
}
0
votes

use the onclick attribute rather than CheckChanged. i don't think that's a valid js event. so

checkBox.Attributes.Add("onclick", "errorCheckChanged(this);");

to get a list of checkboxes you can do

js:

var grid = document.getElementById('<% =GridView1.ClientID %>');
var checks = grid.getElementsByTagName('input');

you'll have to check the type attribute to make sure it's a checkbox, or you can give all the checkboxes a specific class to logically group them. anyway you can check your clicked element id against the list.