AnneSKS
asked on
Mutually exclusive checkbox in a gridview
Hi,
I have a gridview with 4 rows, and a checkbox on the first column.
When a user click on the checkbox in any one row, the checkboxes from the other rows should become uncheck.
Below is the Gridview,
The javascript code to uncheck the checkboxes from the other rows
The javascript onclick event generated on the RowDataBound event of the grdview.
The code run successfully on the RowDataBound, and populate the onclick even. However when I click on a checkbox, the other checkboxes are not unticked.
I am just starting to work with JavaScript, could you please help me with this one.
Thank you
Gridview:
JavaScript function:
C# event:
I have a gridview with 4 rows, and a checkbox on the first column.
When a user click on the checkbox in any one row, the checkboxes from the other rows should become uncheck.
Below is the Gridview,
The javascript code to uncheck the checkboxes from the other rows
The javascript onclick event generated on the RowDataBound event of the grdview.
The code run successfully on the RowDataBound, and populate the onclick even. However when I click on a checkbox, the other checkboxes are not unticked.
I am just starting to work with JavaScript, could you please help me with this one.
Thank you
Gridview:
<asp:Panel ID="pnlParameter" runat="server" Visible="false">
<asp:Label ID="lblFQID" runat="server"/>
</asp:Panel>
<asp:GridView ID="GV" runat="server" AutoGenerateColumns="false" OnRowDataBound="GV_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Correct answer">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="true" HeaderText="Description">
<ItemTemplate>
<asp:TextBox ID="txtQuestionDesc" Text='<%# Eval("QuestionDesc") %>' runat="Server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
JavaScript function:
<script type="text/javascript" language="javascript">
function uncheckOthers(id) {
var elm = document.getElementsByTagName('input');
for (var i = 0; i < elm.length; i++) {
if (elm.item(i).id.substring(id.id.lastIndexOf('_')) == id.id.substring(id.id.lastIndexOf('_'))) {
if (elm.item(i).type == "checkbox" && elm.item(i) != id)
elm.item(i).checked = false;
}
}
}
</script>
C# event:
protected void GV_RowDataBound(object source, GridViewRowEventArgs e)
{
if (e.Row is GridViewRow & e.Row.RowType == DataControlRowType.DataRow)
{
string strScript = "uncheckOthers(" + ((CheckBox)e.Row.Cells[0].FindControl("CheckBox1")).ClientID + ");";
((CheckBox)e.Row.Cells[0].FindControl("CheckBox1")).Attributes.Add("onclick", strScript);
}
}
ASKER
Hi Julian,
Thank you for your comment.
I'm ok with radio button, however
there is only 1 radio button/checkbox per row. And you can only select one in the gridview.
I've got the impression that your 4 radio buttons are on the same row.
Thank you for your comment.
I'm ok with radio button, however
there is only 1 radio button/checkbox per row. And you can only select one in the gridview.
I've got the impression that your 4 radio buttons are on the same row.
If you look at the sample I posted (and read the Breakdown) you will see in the third group of buttons I have mixed them.
The whole purpose of the design is that you can put the checkbox anywhere on your page and link them to any other checkbox simply by
a) Adding the "exclusive" class to the checkbox
b) Adding the data-link custom attribute to the checkbox and setting it to the group name you want the checkbox to be part of
c) Including the jQuery code I posted in my post above and the sample
Here is a link to the sample again - look at the Group 3 (Mixed) group. That is made up of items from group1 and group2 - when you click the checkboxes in this group it changes the state of the checked buttons in Group 1 and Group 2
The whole purpose of the design is that you can put the checkbox anywhere on your page and link them to any other checkbox simply by
a) Adding the "exclusive" class to the checkbox
b) Adding the data-link custom attribute to the checkbox and setting it to the group name you want the checkbox to be part of
c) Including the jQuery code I posted in my post above and the sample
Here is a link to the sample again - look at the Group 3 (Mixed) group. That is made up of items from group1 and group2 - when you click the checkboxes in this group it changes the state of the checked buttons in Group 1 and Group 2
ASKER
The problem in my post is not the grouping of checkbox and the exclusivity.
The problem is how to set up the exclusivity or the group in a the gridview, when the checkbox are in different rows, therefore the group cannot be hardcoded.
If you look at my code, in the GV_RowDataBound event of the gridview, I am attempting to create a group. However it is not working.
The problem is how to set up the exclusivity or the group in a the gridview, when the checkbox are in different rows, therefore the group cannot be hardcoded.
If you look at my code, in the GV_RowDataBound event of the gridview, I am attempting to create a group. However it is not working.
when the checkbox are in different rows, therefore the group cannot be hardcoded.I don't see the problem - the solution I provided allows for this?
You can have this
<table>
<tr>
<td><input type="checkbox" class="exclusive" data-link="group1" value="1"/></td>
</tr>
<tr>
<td><input type="checkbox" class="exclusive" data-link="group1" value="2"/></td>
</tr>
<tr>
<td><input type="checkbox" class="exclusive" data-link="group1" value="3"/></td>
</tr>
<tr>
<td><input type="checkbox" class="exclusive" data-link="group1" value="4"/></td>
</tr>
</table>
It will work - all you need to do is give the checkboxes a class of "exclusive" and for all those that are in the same group a custom attribute data-link="group1"
when the checkbox are in different rows, therefore the group cannot be hardcoded.Can you explain why you think they cannot be grouped?
ASKER
Julian,
I am talking about a gridview, not a table. They don't work the same. As I said, hard coding in html the group will not work. Believe me.
The group has to be generated in the RowDatabound event of the gridview, please check the code below. But in the work that I have done, it does not work.
In the event, I am 'grouping' the checkbox using the following code. It should theoretically call a javascript function 'UncheckOthers' when one of the 'onclick' event of any of these check box is fired.
string strScript = "uncheckOthers(" + ((CheckBox)e.Row.Cells[0]. FindContro l("CheckBo x1")).Clie ntID + ");";
((CheckBox)e.Row.Cells[0]. FindContro l("CheckBo x1")).Attr ibutes.Add ("onclick" , strScript);
However, the RowDataBound event is fired and theoretically the script is added to the onclick event, when I run the form, the checkbox are not unticked when I tick one.
So I don't know, if there is a problem in either the strscript or in adding the script to the onclick event, or maybe the problem is in the javascript function. As I said previously I am not very good at JavaScript, so I could have missed something.
Also, I am using an <asp:Checkbox/>, as I need to save the gridview result and which box has been ticked/unticked. There is a lot more in this gridview, but I have streamlined it to just show the current requirements.
Thank you for your help.
I am talking about a gridview, not a table. They don't work the same. As I said, hard coding in html the group will not work. Believe me.
The group has to be generated in the RowDatabound event of the gridview, please check the code below. But in the work that I have done, it does not work.
In the event, I am 'grouping' the checkbox using the following code. It should theoretically call a javascript function 'UncheckOthers' when one of the 'onclick' event of any of these check box is fired.
string strScript = "uncheckOthers(" + ((CheckBox)e.Row.Cells[0].
((CheckBox)e.Row.Cells[0].
However, the RowDataBound event is fired and theoretically the script is added to the onclick event, when I run the form, the checkbox are not unticked when I tick one.
So I don't know, if there is a problem in either the strscript or in adding the script to the onclick event, or maybe the problem is in the javascript function. As I said previously I am not very good at JavaScript, so I could have missed something.
Also, I am using an <asp:Checkbox/>, as I need to save the gridview result and which box has been ticked/unticked. There is a lot more in this gridview, but I have streamlined it to just show the current requirements.
Thank you for your help.
<asp:GridView ID="GV" runat="server" AutoGenerateColumns="false" OnRowDataBound="GV_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Correct answer">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="true" HeaderText="Description">
<ItemTemplate>
<asp:TextBox ID="txtQuestionDesc" Text='<%# Eval("QuestionDesc") %>' runat="Server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void GV_RowDataBound(object source, GridViewRowEventArgs e)
{
if (e.Row is GridViewRow & e.Row.RowType == DataControlRowType.DataRow)
{
string strScript = "uncheckOthers(" + ((CheckBox)e.Row.Cells[0].FindControl("CheckBox1")).ClientID + ");";
((CheckBox)e.Row.Cells[0].FindControl("CheckBox1")).Attributes.Add("onclick", strScript);
}
}
<script type="text/javascript" language="javascript">
function uncheckOthers(id) {
var elm = document.getElementsByTagName('input');
for (var i = 0; i < elm.length; i++) {
if (elm.item(i).id.substring(id.id.lastIndexOf('_')) == id.id.substring(id.id.lastIndexOf('_'))) {
if (elm.item(i).type == "checkbox" && elm.item(i) != id)
elm.item(i).checked = false;
}
}
}
</script>
The table was to demonstrate a concept
1. Can you add a class to your checkbox items
2. Can you add a custom attribute
That is all you need. You appear to be trying to handle the unchecking in the Event handler which is unnecessary as you can handle it in the client with a few lines of JavaScript.
Remember your ASP code generates HTML - it does not matter what HTML it generates as long as you can add a class to your checkbox controls and a custom data attribute. That is all you need to do and the JavaScript code I provided will work.
1. Can you add a class to your checkbox items
2. Can you add a custom attribute
That is all you need. You appear to be trying to handle the unchecking in the Event handler which is unnecessary as you can handle it in the client with a few lines of JavaScript.
Remember your ASP code generates HTML - it does not matter what HTML it generates as long as you can add a class to your checkbox controls and a custom data attribute. That is all you need to do and the JavaScript code I provided will work.
Ok I went ahead and built an ASPX version of this. One little fact I was unaware of was that ASP wraps checkboxes inside a <span> so you need to modify the jQuery a bit to take that into account.
Here is how I defined my checkbox
Here is the updated jQuery code
Here is how I defined my checkbox
<asp:TemplateField HeaderText="Correct answer">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" CssClass="exclusive" data-linked="group1"/>
</ItemTemplate>
</asp:TemplateField>
Here is the updated jQuery code
<script>
$(function () {
$('span.exclusive').mousedown(function () {
var linked = $(this).data('linked');
$('span[data-linked="' + linked + '"] input:checkbox').prop('checked', false);
});
});
</script>
Works as expected
ASKER
Hi Julian,
You are fantastic. I am in meeting all morning, but will implement it early afternoon (Australian time), and let you know how I am going.
So if I understand, I have to create a user control for my checkbox and create a data-linked property and add the CSSClass . This usercontrol can go into the gridview.
Now if I only have one set of checkbox, and they are all in the same group, do I need the data-linked property, or the cssclass can be enough? Which mean in this case that I don't need to create the usercontrol.
Then in the RowDataBound event of the gridview I have to add your function to the onclick event of this usercontrol.
And then of course add the function into my page.
Thank you
Anne
You are fantastic. I am in meeting all morning, but will implement it early afternoon (Australian time), and let you know how I am going.
So if I understand, I have to create a user control for my checkbox and create a data-linked property and add the CSSClass . This usercontrol can go into the gridview.
Now if I only have one set of checkbox, and they are all in the same group, do I need the data-linked property, or the cssclass can be enough? Which mean in this case that I don't need to create the usercontrol.
Then in the RowDataBound event of the gridview I have to add your function to the onclick event of this usercontrol.
And then of course add the function into my page.
Thank you
Anne
ASKER
Hi Julian,
I cannot make it work. There is too many parameters that I don't know to solve the issue.
Would you mind having a look at my code, and see if it works for you, and if not what does not work.
Theoretically it should be working, and it could be a simple mistake.
Thanks
Anne
I cannot make it work. There is too many parameters that I don't know to solve the issue.
Would you mind having a look at my code, and see if it works for you, and if not what does not work.
Theoretically it should be working, and it could be a simple mistake.
Thanks
Anne
I can - if you post what you have done.
Here is my code
Code behind I use to create the data source for the grid
Here is my code
Code behind I use to create the data source for the grid
using System;
using System.Data;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Multi-Dimensional Array
string[,] arrMultiD = {
{ "John", "21", "Berlin", "Germany" },
{ "Smith", "33" ,"London", "UK"},
{ "Ryder", "15" ,"Sydney", "Australia"},
{ "Jake", "18", "Tokyo", "Japan"},
{ "Tom","34" , "Mumbai", "India"}
};
DataTable dt = new DataTable();
dt.Columns.Add("Name", Type.GetType("System.String"));
dt.Columns.Add("Age", Type.GetType("System.String"));
dt.Columns.Add("City", Type.GetType("System.String"));
dt.Columns.Add("Country", Type.GetType("System.String"));
for (int i = 0; i < 5; i++)
{
dt.Rows.Add();
dt.Rows[dt.Rows.Count - 1]["Name"] = arrMultiD[i, 0];
dt.Rows[dt.Rows.Count - 1]["Age"] = arrMultiD[i, 1];
dt.Rows[dt.Rows.Count - 1]["City"] = arrMultiD[i, 2];
dt.Rows[dt.Rows.Count - 1]["Country"] = arrMultiD[i, 3];
}
GridMultiD.DataSource = dt;
GridMultiD.DataBind();
}
}
Here is my aspx file<%@ Page Language="C#" AutoEventWireup="true" Inherits="_Default" Codebehind="CSharp.aspx.cs" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Binding Array to GridView Example</title>
<script src="http://code.jquery.com/jquery.js"></script>
<script>
$(function () {
$('span.exclusive').mousedown(function () {
var linked = $(this).data('linked');
$('span[data-linked="' + linked + '"] input:checkbox').prop('checked', false);
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<br />
<asp:GridView ID="GridMultiD" runat="server"
AutoGenerateColumns = "false" Font-Names = "Arial"
Font-Size = "11pt" AlternatingRowStyle-BackColor = "#C2D69B"
HeaderStyle-BackColor = "green" AllowPaging ="true"
PageSize = "10" Caption = "Multi-Dimensional Array" >
<Columns>
<asp:TemplateField HeaderText="Correct answer">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" CssClass="exclusive" data-linked="group1"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField ItemStyle-Width = "150px" DataField = "Name" HeaderText = "Name" />
<asp:BoundField ItemStyle-Width = "150px" DataField = "Age" HeaderText = "Age" />
<asp:BoundField ItemStyle-Width = "150px" DataField = "City" HeaderText = "City" />
<asp:BoundField ItemStyle-Width = "150px" DataField = "Country" HeaderText = "Country" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
I have a working sample here
ASKER
Hi Julian,
I am almost there, I have managed to make it work if the checkbox and the functions are in a page. However it does not work if it is in a user control.
Any suggestions?
Thanks again for your help.
Anne
I am almost there, I have managed to make it work if the checkbox and the functions are in a page. However it does not work if it is in a user control.
Any suggestions?
Thanks again for your help.
Anne
ASKER
I found the problem, the problem is with postback in an update panel. After the postback, the checkboxes are not mutually exclusive anymore.
Any idea how to change/prevent it
Thank you
Anne
Any idea how to change/prevent it
Thank you
Anne
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Julian,
Thank you so much for your help, it was fantastic.
I am just starting to learn JavaScript and JQuery, I am using Lynda.com to learn.
Is there any website that you would recommend, especially one with samples, or that could explain when they are best to use.
Once again thank you so much.
Anne
Thank you so much for your help, it was fantastic.
I am just starting to learn JavaScript and JQuery, I am using Lynda.com to learn.
Is there any website that you would recommend, especially one with samples, or that could explain when they are best to use.
Once again thank you so much.
Anne
You are most welcome.
To tell the truth - I learned most of what I know hanging around EE looking at the questions people ask, trying to answer them and looking at the solutions.
There are a couple of good books out there recommended by various experts - I will try and dig up the URLS.
JavaScript is very mature the Net is littered with thousands of resources so Google could also be your friend here.
To tell the truth - I learned most of what I know hanging around EE looking at the questions people ask, trying to answer them and looking at the solutions.
There are a couple of good books out there recommended by various experts - I will try and dig up the URLS.
JavaScript is very mature the Net is littered with thousands of resources so Google could also be your friend here.
Here are the resources I mentioned
https://www.manning.com/books/secrets-of-the-javascript-ninja
http://shop.oreilly.com/product/9780596802806.do
There is also this site which has some good resources
http://ejohn.org/apps/learn/
https://www.manning.com/books/secrets-of-the-javascript-ninja
http://shop.oreilly.com/product/9780596802806.do
There is also this site which has some good resources
http://ejohn.org/apps/learn/
Failing that you can do this quite easily with jQuery
HTML
Open in new window
jQueryOpen in new window
Working sample here