Search code examples
asp.netjavascriptasp.net-ajax

GridView with checkbox column. Client-side script to uncheck all except current checkbox


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


Solution

  • 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;
        }
    }