How to use radio button inside ASP.Net GridView - c#

I want to dipslay in a Gridview with radiobutton list the current date when I run the project. I don't know if the best way is to use JavaScript or C# (I'm using it on Code Behind) and how to do it. If is need to show some code, say it. The grid is filled with a sql statement. The image below shows how I want the grid. Thank you

Unfortunately, you cannot use RadioButton.GroupName Property in GridView.
Easiest way is to place RadioButton in TemplateField, and use jQuery to manipulate it.
ASPX
<asp:GridView runat="server" ID="GridView1">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton runat="server" ID="MyRadioButton"
CssClass="myRadioButton"
onclick='<%# "myRadioButtonClick(this)" %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<script type="text/JavaScript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
function myRadioButtonClick(sender) {
$('.myRadioButton input').attr('checked', false);
$(sender).attr('checked', true);
}
</script>
Code Behind
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
GridView1.DataSource = new List<Customer>
{
new Customer {Id = 1, Name = "John"},
new Customer {Id = 2, Name = "Marry"},
};
GridView1.DataBind();
}

Related

How can I change the text of a button on every Click of My Gridview Row?

I am using ASP.NET C#. I have a Gridview (example shown below) and a Button. As I click on the rows of the gridview, my button’s text needs to change depending on the info of the gridview.
For example: If I click on the first row, the text of my Button should be Alpha (Operation name). If I click on the third row, it should have Charlie on it and so on. The user could click any row any number of times.
I have learnt the use of onRowDataBound and SelectedIndexChanged event of the gridview to play around with the value in the gridview. I was able to print out each row of the gridview using labels. However I do not understand how I can change the text of a button using this method.
Any help in either Javascript/JQuery would be greatly appreciated. Please let me know if the question is unclear in anyway.
Using SelectedIndexChanged is possible to change button label based on selected row on gridview. Set AutoGenerateSelectButton as true and create an event OnSelectedIndexChanged.
public class MyModel
{
public int Id { get; set; }
public string Operation { get; set; }
public string Month { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
var data = new List<MyModel>()
{
new MyModel() { Id = 101, Operation = "Alpha", Month = "Jan" },
new MyModel() { Id = 102, Operation = "Beta", Month = "Feb" },
new MyModel() { Id = 103, Operation = "Charlie", Month = "Mar" }
};
myGridView.DataSource = data;
myGridView.DataBind();
}
protected void myGridView_SelectedIndexChanged(object sender, EventArgs e)
{
var data = myGridView.DataSource as List<MyModel>;
if (data == null) return;
myButton.Text = data[myGridView.SelectedIndex].Operation;
}
aspx:
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:GridView ID="myGridView" runat="server" AutoGenerateSelectButton="true" AutoGenerateColumns="true" OnSelectedIndexChanged="myGridView_SelectedIndexChanged">
<SelectedRowStyle BackColor="Red" />
</asp:GridView>
<asp:Button ID="myButton" runat="server" Text="---" />
</asp:Content>
As an alternative you can use Javascript on the client side:
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:GridView ID="myGridView" ClientIDMode="Static" runat="server" AutoGenerateColumns="true"></asp:GridView>
<asp:Button ID="myButton" runat="server" Text="---" ClientIDMode="Static" />
<script>
// Add event onclick on rows
document.querySelectorAll("#myGridView tbody tr").forEach(a => a.addEventListener("click", _ => {
document.querySelector("#myButton").value = a.children[1].innerText;
}));
</script>
</asp:Content>

Dynamically added control and buttons postback

Hi I have a problem with my GridView.
Let's say that I create a GridView with 4 columns
|NAME|LASTNAME|OWNER|ADMINISTRATOR|
Owner and Administrator are columns that can contain a checkbox.
Second step: I fill the grid in some way.
Third step: I add dynamically the check box on the owner and admin columns, depending on some strange method.
Four step: When I click the Button below the gridview, the click event will read how many checkbox are checked and pass that number to another method.
This last step is quite difficult because all the checkboxes disappear, due to the postback of the button.
I looking for a method to save the checkboxes from the postback.
Can I call a method after the click, and before the postback?
Can I avoid the postback of a button?
(PS: I prefer to not go for js solution)
If you place the method call to dynamically add the check boxes in Page_Init they will not be removed on postback
It's not clear from your question why you need to have dynamically added CheckBox controls, when you can just set their state server-side in the RowDataBound event of the GridView. Here is a worked example of your requirment boiled down to the barest minimum to illustrate:
CheckboxGrid.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="CheckboxGrid.aspx.cs" Inherits="CheckboxGrid" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvResourceUsers" runat="server" AutoGenerateColumns="False" OnRowDataBound="gvResourceUsers_OnRowDataBound">
<Columns>
<asp:BoundField HeaderText="Name" DataField="Name"/>
<asp:BoundField HeaderText="Surname" DataField="Surname"/>
<asp:TemplateField HeaderText="Owner">
<ItemTemplate>
<asp:CheckBox ID="cbxOwner" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Administrator">
<ItemTemplate>
<asp:CheckBox ID="cbxAdministrator" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button runat="server" ID="btnSubmit" Text="Save" OnClick="btnSubmit_Click"/>
</div>
</form>
</body>
</html>
CheckboxGrid.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class CheckboxGrid : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Get data and bind the grid
gvResourceUsers.DataSource = GetData();
gvResourceUsers.DataBind();
}
}
protected void gvResourceUsers_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
//As each row is data-bound, set the checkbox state.
if (e.Row.RowType == DataControlRowType.DataRow)
{
var resourceUser = e.Row.DataItem as ResourceUser;
var cbxOwner = e.Row.FindControl("cbxOwner") as CheckBox;
var cbxAdministrator = e.Row.FindControl("cbxAdministrator") as CheckBox;
cbxOwner.Checked = resourceUser.Owner;
cbxAdministrator.Checked = resourceUser.Administrator;
}
}
protected void btnSubmit_Click(Object sender, EventArgs e)
{
var resourceUsers = new List<ResourceUser>();
//Iterate the gridview rows and populate the collection from the postback data.
foreach (GridViewRow row in gvResourceUsers.Rows)
{
resourceUsers.Add(
new ResourceUser
{
Name = row.Cells[0].Text,
Surname = row.Cells[1].Text,
Owner = ((CheckBox)row.Cells[2].FindControl("cbxOwner")).Checked,
Administrator = ((CheckBox)row.Cells[3].FindControl("cbxAdministrator")).Checked
});
}
}
private IEnumerable<ResourceUser> GetData()
{
//We just create some data for demo purposes. Here you would normally populate the collection from your database.
var resourceUsers = new List<ResourceUser>
{
new ResourceUser{Name = "Bob", Surname = "Taylor", Owner = true, Administrator = true },
new ResourceUser{Name = "Ann", Surname = "Carter", Owner = false, Administrator = true },
new ResourceUser{Name = "Toni", Surname = "Wong", Owner = false, Administrator = false}
};
return resourceUsers;
}
//A data view model to contain our view data for the grid
private class ResourceUser
{
public String Name { get; set; }
public String Surname { get; set; }
public Boolean Owner { get; set; }
public Boolean Administrator { get; set; }
}
}

Losing data in LoginView after binding parent Repeater

I'm having some trouble with a LoginView that is nested inside a Repeater in my ASP.NET 4.5 site. The data gets properly bound when the page loads. But if some external event rebinds the repeater, the content inside the LoginView templates doesn't rebind. I've simplified my code down about as much as I can to make it repeatable. Run this page, then click the Rebind Data button. The button labels disappear. How do I get those to properly rebind (ex: show the Text of the data item that it's bound to)? I would think that calling DataBind() on the repeater would rebind all child controls, but I guess not. I tried a couple different iterations of manually binding (and none worked), but would prefer a clean implementation.
RepeaterTest.aspx
<%# Import Namespace="MyNamespace" %>
<asp:Repeater runat="server" ID="MyRepeater">
<ItemTemplate>
<asp:LoginView runat="server">
<LoggedInTemplate>
<asp:Button runat="server" Text='<%# ((Container.Parent as RepeaterItem).DataItem as TestClass).Text %>' /><br />
</LoggedInTemplate>
<AnonymousTemplate>
<asp:Button runat="server" Text='<%# ((Container.Parent as RepeaterItem).DataItem as TestClass).Text %>' /><br />
</AnonymousTemplate>
</asp:LoginView>
</ItemTemplate>
</asp:Repeater>
<asp:Button runat="server" Text="Rebind Data" OnClick="Unnamed_Click" />
RepeaterTest.aspx.cs
namespace MyNamespace
{
public partial class RepeaterTest : System.Web.UI.Page
{
List<TestClass> list = new List<TestClass>()
{
new TestClass("hi"),
new TestClass("hello"),
new TestClass("bonjour"),
new TestClass("hola")
};
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MyRepeater.DataSource = list;
MyRepeater.DataBind();
}
}
protected void Unnamed_Click(object sender, EventArgs e)
{
MyRepeater.DataSource = list;
MyRepeater.DataBind();
}
}
public class TestClass
{
public string Text { get; set; }
public TestClass(string text)
{
Text = text;
}
}
}

Gridview click on row enable controls

I have a gridview. The gridview has a textbox multiline that keeps an text. After that I have a column with imagebutton named approved, and one named not approved. I want to force the user before click approved or not approved to read the text inside the multiline box. How can I achieve this programmatically? I know I should create a Rowdatabound Event, but what I should do with the code? I am using c# ASP.NET web application.
I know you can track the scroll bar of the browser using javascript but I've personally never come across similar functionality for a text box. I would suggest trying a slightly different approach, why don't you add an extra column to you grid view which has a check box control for - I've read and accepted the agreement. And the Approve button will only be enabledd when the checkbox is checked, here's an example:
ASPX:
<div>
<asp:ScriptManager ID="sm" runat="server" />
<asp:UpdatePanel ID="updatePanel" runat="server">
<ContentTemplate>
<asp:GridView ID="grid" runat="server" AutoGenerateColumns="false" OnRowDataBound="grid_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox TextMode="MultiLine" runat="server" ID="txtAgreement" Text='<%# Eval("Agreement") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
I have read and accepted the agreement
<asp:CheckBox ID="chkAgreement" AutoPostBack="true" runat="server" OnCheckedChanged="CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnAccept" runat="server" Text="Accept" OnClick="Accept" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
Code behind:
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var items = new List<License> { new License { Agreement = "Agreement 1" }, new License { Agreement = "Agreement 2" } };
grid.DataSource = items;
grid.DataBind();
}
}
protected void Accept(object sender, EventArgs e)
{
}
protected void grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
(e.Row.FindControl("btnAccept") as Button).Enabled = false;
}
protected void CheckedChanged(object sender, EventArgs e)
{
var chkAgreement = sender as CheckBox;
Button btnAccept = null;
if (chkAgreement != null)
{
var row = chkAgreement.Parent.Parent as GridViewRow;
btnAccept = row.FindControl("btnAccept") as Button;
if (btnAccept != null)
if (chkAgreement.Checked)
btnAccept.Enabled = true;
else
btnAccept.Enabled = false;
}
}
}
public class License
{
public string Agreement { get; set; }
}

asp:repeater events - how to postback

I have an ASP:Repeater Which I would like to display a list of check boxes in. These check boxes are related to a list of user preferences and the users resulting answer. See Code Bellow.
I would like to add do one of the following if possible
Option 1: It would be great if I could use the Event in the Repeater:OnItemCommand(...) to fire if any of the items change. It would seem to me that this event will only fire if there is a Button | LinkButton | ImageButton item in the list. IE it will not fire if I put in a check box with AutopostBack="True"
Option 2: Is there a way I could attach a method to an Event of CheckBox:CheckChanged I would need to pass this method a parameter saying which question/answer combo to change.
Option 3: Its your answer if you know an easier way that would be awesome.
The Code:
<asp:Repeater ID="RPTprefs" runat="server" DataSourceID="getAnswers" OnItemCommand="RPTprefs_ItemCommand">
<ItemTemplate>
<li><asp:CheckBox ID='questionID' runat="server"
Checked='<%# Eval("pr.up_is_selected") %>'
Text='<%# Eval("prp.prefs_question") %>'
AutoPostBack="true"
OnCheckedChanged="CheckChanged" /></li>
</ItemTemplate>
</asp:Repeater>
Thanks in advance
Here is what I came up with, which is basically your option #2.
In the ItemTemplate of the repeater, I use a Literal control (Visible set to false) which has the argument you wish to pass to the CheckedChanged function. The reason for using a control is because the control will retain its value in the ViewState after a post back, whereas the original data source for the Repeater will be lost.
In the OnItemCreated function, I bind the CheckChanged function for all of the check boxes to pass in the right argument. Here's my complete example. In this case, I want to pass the Id property of my data to the CheckChanged function.
Markup:
<asp:Repeater ID="Repeater1" runat="server" OnItemCreated="ItemCreated">
<ItemTemplate>
<asp:Literal ID="litArg" runat="server" Visible="false" Text='<%# Eval("Id") %>'>
</asp:Literal><%# Eval("Name") %>
<asp:CheckBox ID="chkCool" runat="server" AutoPostBack="true" Checked='<%# Eval("IsCool") %>' /><br />
</ItemTemplate>
</asp:Repeater>
Code behind:
public class SomeClass
{
public SomeClass(bool c, string n, int id)
{
IsCool = c;
Name = n;
Id = id;
}
public bool IsCool { get; set; }
public string Name { get; set; }
public int Id { get; set; }
}
.
.
.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<SomeClass> people = new List<SomeClass>();
people.Add(new SomeClass(true, "Will", 666));
people.Add(new SomeClass(true, "Dan", 2));
people.Add(new SomeClass(true, "Lea", 4));
people.Add(new SomeClass(false, "Someone", 123));
Repeater1.DataSource = people;
Repeater1.DataBind();
}
}
private void CheckChanged(int id)
{
Response.Write("CheckChanged called for item #" + id.ToString());
}
protected void ItemCreated(object sender, RepeaterItemEventArgs e)
{
//this needs to be set again on post back
CheckBox chk = (CheckBox)e.Item.FindControl("chkCool");
Literal arg = (Literal)e.Item.FindControl("litArg");
Action<object, EventArgs> handler = (s, args) => CheckChanged(Convert.ToInt32(arg.Text));
chk.CheckedChanged += new EventHandler(handler);
}
Hope that helps.

Categories