I've a gridview in which a radiobutton is used to select a particular row of data. The radiobutton onclick event is done through Javascript.
Now I need to save the data in this selected row into some session value so that I can use in another page. How do I achieve this?
I'm not using JQuery or Ajax, my entire coding is done on ASP.NET 3.5
Session ( 'VariableHere' ) = 'Data';
// display variable anywhere on your site
Out ( 'Your variable is ' + Session ( 'VariableHere' ) );
i don't understand why you would need it in session, the session is per user, you could use Application variables as I don't think you need it per session.
The blog post HERE has the code for this:
Add data keys to your GridView:
<asp:GridView ID="GridView1" runat="server" DataKeyNames="ItemID" ... >
Add a value to your radio button (intellisense doesn't support it, but it's there):
<asp:RadioButton ID="RadioButton1" runat="server" onclick="radioClick(this);" Value='<%#Container.ItemIndex%>' />
In your JavaScript method:
radioClick = function(radioCtrl){
__doPostBack("<%=GridView1.UniqueID%>", radioCtrl.value);
}
And add the RaisePostBackEvent method to your code behind:
protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
{
//call the RaisePostBack event
base.RaisePostBackEvent(source, eventArgument);
if (source is GridView)
{
if (source == GridView1)
{
int itemID = (int)GridView1.DataKeys[Int32.Parse(eventArgument)]["ItemID"];
}
}
}
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
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;
}
}
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.
I have a panel control in gridview's template.
I need to hide/unhide panel in javascript function, for that i need to pass panel's id to the javascript.
The problem is that all panels have the same id in gridview, so I need to set unique id to each panel.
I tried to do:
<asp:Panel id= "Panel_<%# Eval("ID")%>"
and some other variations but always get an error.
The panel contains some other controls, I need it to be server side because I need to set at code-behind (after checking if user is authenticated)
What can I do?
p.s.
It doesn't have to be Panel, any other control that I can find with Findcontrol and can hold other controls.
Update:
I set the the js event in code behind:
protected void gvw_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (UserIsAuthenticated)
{
HyperLink title = e.Row.FindControl("lnkTitle") as HyperLink;
Panel panel = e.Row.FindControl("panel") as Panel;
title.Attributes.Add("onmouseover", "ShowHidePanel(" + panel.ClientID +")");
//All get the same id!!!
}
}
}
To use server-side control's ids in javascript you should use ClientID property of the control.
<script type="text/javascript">
function hidePanel(panelId){
var panel = document.getElementById(panelId);
panel.style.display = 'none';
}
</script>
So you can use it in some handler like hidePanel(<%=panel.ClientID%>);.
I guess, to set the panel's id to a unique value, you should use this (note the use of single- and double-quotes):
<asp:Panel id='<%# "Panel_" + Eval("ID") %>'
Although, this will probably still not help, because the client-side ID will be composed from from the IDs of the panel's parent controls and the panel's ID, e.g. ctl00_MyGridView_Panel_1.
As an alternative, you could set the CssClass property of the panel to a unique value (since this will not be changed by ASP.NET) and then use client-side code based to select the panel. E.g. when using jquery:
$('Panel_1').click( ... )
Let ASP.NET generate the ID for you. Then, use the ClientID property.
As long as it's in the same template column, you should be able to use it directly there. Something like this:
<asp:Panel ID="MyGridViewPanel" runat="server" style="display:none;">Hello World!</asp:Panel>
<a href='javascript:open_the_panel(<%=MyGridViewPanel.ClientID%>);'>Open the panel</a>
I have added a RadControl, RadGrid and I need to add a radComboBox in the edit mode.
When user clicks on the radComboBox, I need to get both "text" and "value" of the radComboBox to save to table when user updates values.
<telerik:RadComboBox ID="RadComboBox1" Runat="server"
DataSourceID="SqlDataSource1" DataTextField="docCategoryName"
DataValueField="docCategoryID" Height="200px" Skin="Vista">
When user selects from the radComboBox, I need to get the value of DataTextField & DataValueField into a HiddenField.
The approach described by Program.X is very good. This, of course, works if you're using a RadCombobox inside of a GridTemplateColumn in RadGrid.
RadGrid also provides a built-in GridDropDownColumn that can automatically render a RadCombobox during edits. If you choose to use the built-in column type, you need to programmatically set the client-side event handlers for the rendered RadGrid, like this:
protected void RadGrid1_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
//Find GridEditableItems when in Edit mode
if (e.Item is GridEditableItem && e.Item.IsInEditMode)
{
//Get reference to item (i.e. Row)
var item = e.Item as GridEditableItem;
//Get reference to auto-generated RadCombobox in
//specific column (in this case, a column called Title)
var rcb = item["Title"].Controls[0] as RadComboBox;
if (rcb == null)
return;
//Customize the RadCombobox properities
rcb.OnClientSelectedIndexChanged = "onselectedindexchanged";
}
}
Where "onselectedindexchanged" is the name of a client-side JavaScript function on your page designed to handle the RadCombobox event.
Either of these approaches should enable you to achieve your goal.
Telerik are the best people to help you with this, but from their site (and from memory):
http://www.telerik.com/help/aspnet-ajax/combo_clientsideonclientselectedindexchanged.html
If you have your radCombo:
<telerik:RadComboBox
ID="RadComboBox1"
runat="server"
OnClientSelectedIndexChanged="OnClientSelectedIndexChanged">
</telerik:RadComboBox>
With your JS event:
<script language="javascript" type="text/javascript">
function OnClientSelectedIndexChanged(sender, eventArgs)
{
var item = eventArgs.get_item();
// get the text and value elements
var text=item.get_text();
var val=item.get_value();
$('#hiddenField').val(val);
}
</script>
Where hiddenField is the ID of the hidden field.
I got a templated control (a repeater) listing some text and other markup. Each item has a radiobutton associated with it, making it possible for the user to select ONE of the items created by the repeater.
The repeater writes the radiobutton setting its id and name generated with the default ASP.NET naming convention making each radiobutton a full 'group'. This means all radiobuttons are independent on each other, which again unfortunately means I can select all radiobuttons at the same time. The radiobutton has the clever attribute 'groupname' used to set a common name, so they get grouped together and thus should be dependant (so I can only select one at a time). The problem is - this doesn't work - the repeater makes sure the id and thus the name (which controls the grouping) are different.
Since I use a repeater (could have been a listview or any other templated databound control) I can't use the RadioButtonList. So where does that leave me?
I know I've had this problem before and solved it. I know almost every ASP.NET programmer must have had it too, so why can't I google and find a solid solution to the problem? I came across solutions to enforce the grouping by JavaScript (ugly!) or even to handle the radiobuttons as non-server controls, forcing me to do a Request.Form[name] to read the status. I also tried experimenting with overriding the name attribute on the PreRender event - unfortunately the owning page and masterpage again overrides this name to reflect the full id/name, so I end up with the same wrong result.
If you have no better solution than what I posted, you are still very welcome to post your thoughts - at least I'll know that my friend 'jack' is right about how messed up ASP.NET is sometimes ;)
ASP.NET Tip: Using RadioButton Controls in a Repeater
This is the code for the JavaScript function:
function SetUniqueRadioButton(nameregex, current)
{
re = new RegExp(nameregex);
for(i = 0; i < document.forms[0].elements.length; i++)
{
elm = document.forms[0].elements[i]
if (elm.type == 'radio')
{
if (re.test(elm.name))
{
elm.checked = false;
}
}
}
current.checked = true;
}
The code is linked to the Repeater through the ItemDataBound event. For it to work properly, you need to know the name of the Repeater control, as well as the GroupName you're assigning to the RadioButtons. In this case, I'm using rptPortfolios as the name of the Repeater, and Portfolios as the group name:
protected void rptPortfolios_ItemDataBound(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType
!= ListItemType.AlternatingItem)
return;
RadioButton rdo = (RadioButton)e.Item.FindControl("rdoSelected");
string script =
"SetUniqueRadioButton('rptPortfolios.*Portfolios',this)";
rdo.Attributes.Add("onclick", script);
}
REF: http://www.codeguru.com/csharp/csharp/cs_controls/custom/article.php/c12371/
Google-fu: asp.net radiobutton repeater problem
Indeed an unfortunate consequence of the id mangling. My take would be creating a - or picking one of the many available - custom control that adds support for same name on the client.
Vladimir Smirnov has already created a great custom control that resolves this issue. We have been using the GroupRadioButton in our projects and it has been working perfectly with radio buttons created inside of a repeater and others outside the repeater all being a part of the same group.
I use jQuery script:
<script type="text/javascript">
function norm_radio_name() {
$("[type=radio]").each(function (i) {
var name = $(this).attr("name");
var splitted = name.split("$");
$(this).attr("name", splitted[splitted.length - 1]);
});
};
$(document).ready(function () {
norm_radio_name();
});
// for UpdatePannel
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
norm_radio_name();
});
</script>
I know this is an old post, but here's what I ended up doing with a listview. My listview is bound in VB codebehind, so I'm not sure if this will work well with a repeater, but I imagine it could be similar.
What I did was handle the OnCheckChanged event of the radiobuttons with a function that unselected any other radio buttons. Then I looked for the selected radio button when I navigated away from the page.
This solution avoids JavaScript and jQuery, and ignores the GroupName issue completely. It's not ideal, but it functions as (I) expected. I hope it's helpful for others.
Markup:
<asp:ListView ID="lvw" runat="server">
<LayoutTemplate>`
<table>
<th>Radio</th>
<tr id="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><asp:RadioButton ID="rdbSelect" runat="server" AutoPostBack="true"
OnCheckedChanged="rdbSelect_Changed"/></td>
</tr>
</ItemTemplate>
</asp:ListView>
Code:
Protected Sub rdbSelect_Changed(ByVal sender As Object, ByVal e As System.EventArgs)
Dim rb1 As RadioButton = CType(sender, RadioButton)
For Each row As ListViewItem In lvw.Items
Dim rb As RadioButton = row.FindControl("rdbSelect")
If rb IsNot Nothing AndAlso rb.Checked Then
rb.Checked = False
End If
Next
rb1.Checked = True
End Sub
And then when the Submit button is clicked:
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
For Each row As ListViewItem In lvw.Items
Dim rb As RadioButton = row.FindControl("rdbSelect")
Dim lbl As Label
If rb IsNot Nothing AndAlso rb.Checked = True Then
lbl = row.FindControl("StudentID")
Session("StudentID") = lbl.Text
End If
Next
Response.Redirect("~/TransferStudent.aspx")
End Sub
This might be a little better..
I have a usercontrol which is essentially a set of radiobuttons inside a repeater, each instance of the usercontrol has a public property called FilterTitle, which is unique per instance.
add these two properties to your radiobutton replacing FilterTitle with your own public property name
onclick='<%# "$(\"input[name$=btngroup_" + FilterTitle + "]\").removeAttr(\"checked\"); $(this).attr(\"checked\",\"checked\");" %>' GroupName='<%# "btngroup_" + FilterTitle %>'
more simply..
onclick="$('input[name$=btngroup1]').removeAttr('checked'); $(this).attr('checked','checked');" GroupName="btngroup1"
Here's a pure Javascript solution for the sake of completeness.
Just add this onclick attribute to your RadioButton element(replace GroupName with your RadioButton's GroupName):
<asp:RadioButton ... GroupName="GroupName" onclick="SelectRadioButton('GroupName$',this)" ... />
And include this Javascript in your page:
<script type="text/javascript">
function SelectRadioButton(regexPattern, selectedRadioButton)
{
regex = new RegExp(regexPattern);
for (i = 0; i < document.forms[0].elements.length; i++)
{
element = document.forms[0].elements[i];
if (element.type == 'radio' && regex.test(element.name))
{
element.checked = false;
}
}
selectedRadioButton.checked = true;
}
</script>
Create a Custom Control and override UniqueID to the listview UniqueID + GroupName
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MYCONTROLS
{
[ToolboxData("<{0}:MYRADIOBUTTON runat=server></{0}:MYRADIOBUTTON >")]
public class MYRADIOBUTTON : RadioButton
{
public override string UniqueID
{
get
{
string uid = base.UniqueID;
//Fix groupname in lisview
if (this.Parent is ListViewDataItem && GroupName != "")
{
uid = this.Parent.UniqueID;
uid = uid.Remove(uid.LastIndexOf('$'));
uid += "$" + GroupName;
}
return uid;
}
}
}
}
It’s a custom control that inherits from RadioButton (public class MYRADIOBUTTON : RadioButton).
If you do nothing in the class you get a normal RadioButton. Overriding the UniqueId you can change the logic for how the name attribute is rendered.
To still keep the name unique to other controls on the page (outside the listview) you can get the UniqueId from the ListView and add GroupName to that and add it to the RadioButton.
This fix the problem with Grouping RadioButtons on different rows in a listview. You may want to add some more logic with a property to turn this feature on/off so it behaves like a normal RadioButton.
I know this question is bit old, but I think it might help somebody, therefore posting my solution to this issue.
This issue has 2 parts:
To prevent selection of more than one radio button at a time.
To know which radio button was clicked in server-side code.
I had the similar issue with Radio button in Repeater. I found partial solution here:
Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery
Please read the above article to get the understanding of the issue. I referred this article and it was good help. As mentioned above this issue has two parts, first is to prevent selection of more than one radio button at a time. Second, to know which radio button was clicked in server-side code. The solution posted in above article worked for me only for the first part. However code written there as well as updates to solution posted there did not work for me. So I had to modify it a bit to get it working. Here is my solution.
I wanted to create poll with Vote button. Name of my radio button (ID) is PollGroupValue with Groupname set to PollGroup in a repeater. Remember Groupname attribute in ASP.net is rendered as name attribute in generated html. My code is as follows:
<script type="text/javascript">
/* Step-01: */
$(document).ready(function () {
/* Step-02: */
$("[name*='PollGroup']").each(function () {
$(this).attr('ci-name', $(this).attr('name'));
});
/* Step-03: */
$("[name*='PollGroup']").attr("name", $("[name*='PollGroup']").attr("name"));
$('#Poll1_BtnVote').click(function (e) {
/* Step - 04: */
if ($("[name*='PollGroup']").filter(':checked').length == 0) {
alert('Please select an option.');
e.preventDefault();
}
/* Step - 05: */
$("[name*='PollGroup']").each(function () {
$(this).attr('name', $(this).attr('ci-name'));
});
});
});
Step 1:
Whenever a radio button is used in repeater, its groupname gets changed, since asp.net changes it so as to make it unique. Therefore each radio button gets different groupname (name attribute in client-side generated markup). Due to this, user is able to select all of the options at the same time. This issue is resolved by using jquery code as explained by subsequent comments.
Step 2:
This block of code creates a new custome attribute called ci-name and copies original value of name attribute into this new custom attribute. This process repeats for every radio button in poll. This step would help us in later step.
Step 3:
This block of code sets the value of name attributes of all radio buttons in poll to the value of name attribute of first radio button. This step prevents user from selecting more than one option at a time.
Step 4:
This code inside event handler of vote button click event, checks whether user has checked at least one option. If he hasn't, an error message is shown.
Step 5:
This code inside event handler of vote button click event, sets value of name attribute of all radio buttons to their original values. This is achieved by copying value from custom attribute ci-name. This allows asp.net server side code to know which button was actually clicked.
I was also baffled by this bug and decided to just drop the repeater in favor of dynamically building a table with the controls inside. In your user control or on your page, simply add the following elements:
<asp:Table ID="theTable" runat="server">
<asp:TableHeaderRow runat="server">
<asp:TableHeaderCell runat="server" Text="Column 1"/>
<asp:TableHeaderCell runat="server" Text="Column 2"/>
<asp:TableHeaderCell runat="server" Text="Column 3"/>
</asp:TableHeaderRow>
</asp:Table>
Then add the data rows in the code behind with radio buttons and other required controls. You can of course do the same with other elements like the DIV:
<div runat="server" ID=theDiv">
</div>
But let us still hope for the ASP.NET team to get around to fixing this unfortunate issue with repeaters and list views. I still like the repeater control and use it whenever possible.
This is a pure server side approach using reflection. The RadioButton control uses the UniqueGroupName property to determine the group name. The group name is cached inside the _uniqueGroupName field. By setting this field using reflection, we can override the default group name and use a group name that is the same across all radio buttons in a repeater. Please note this code must be run in the 'PreRender' event of the 'RadioButton' control to ensure the new group name is persisted across post backs.
protected void rbOption_PreRender(object sender, EventArgs e)
{
// Get the radio button.
RadioButton rbOption = (RadioButton) sender;
// Set the group name.
var groupNameField = typeof(RadioButton).GetField("_uniqueGroupName", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
groupNameField.SetValue(rbOption, "MyGroupName");
// Set the radio button to checked if it was selected at the last post back.
var groupValue = Request.Form["MyGroupName"];
if(rbOption.Attributes["value"] == groupValue)
{
rbOption.Checked = true;
}
}
RadioButton source code: http://reflector.webtropy.com/default.aspx/Net/Net/3#5#50727#3053/DEVDIV/depot/DevDiv/releases/whidbey/netfxsp/ndp/fx/src/xsp/System/Web/UI/WebControls/RadioButton#cs/2/RadioButton#cs
This may not be the ideal solution for everyone, but I did the following using jQuery.
<asp:RadioButton ID="rbtnButton1" groupName="Group1" runat="server" />
<asp:RadioButton ID="rbtnButton2" groupName="Group1" runat="server" />
etc...
Then include the following code in your master page. (or all your pages)
$(function() {
//This is a workaround for Microsoft's GroupName bug.
//Set the radio button's groupName attribute to make it work.
$('span[groupName] > input').click(function() {
var element = this;
var span = $(element).parent();
if (element.checked) {
var groupName = $(span).attr('groupName');
var inputs = $('span[groupName=' + groupName + '] > input')
inputs.each(function() {
if (element != this)
this.checked = false;
});
}
});
});
A custom control/override to work around the HtmlInputControl.RenderAttributes() method by ignoring the RenderedNameAttribute property:
/// <summary>
/// HACK: For Microsoft's bug whereby they mash-up value of the "name" attribute.
/// </summary>
public class NameFixHtmlInputRadioButton : HtmlInputRadioButton
{
protected override void RenderAttributes(HtmlTextWriter writer)
{
// BUG: Usage of 'HtmlInputControl.RenderedNameAttribute'
// writer.WriteAttribute("name", this.RenderedNameAttribute);
writer.WriteAttribute(#"name", Attributes[#"Name"]);
Attributes.Remove(#"name");
var flag = false;
var type = Type;
if (! string.IsNullOrEmpty(type))
{
writer.WriteAttribute(#"type", type);
Attributes.Remove(#"type");
flag = true;
}
base.RenderAttributes(writer);
if (flag && DesignMode)
{
Attributes.Add(#"type", type);
}
writer.Write(#" /");
}
}
I used same Technic to uncheck other radio with jquery please find below code
<asp:RadioButton ID="rbSelectShiptoShop" runat="server" onchange="UnCheckRadio(this);" CssClass="radioShop" />
and script below
function UnCheckRadio(obj) {
$('.radioShop input[type="radio"]').attr('checked', false);
$(obj).children().attr('checked', true);
}