Radio Button inside grid view control not firing oncheckedchanged event - asp.net

I have following code in my application I have a gridview control insde my grid view I have radio button defined as templetefield.
<asp:View ID="View3" runat="server">
<script type = "text/javascript">
function RadioCheck(rb) {
var gv = document.getElementById("<%=grdAllPartsRequestList.ClientID%>");
var rbs = gv.getElementsByTagName("input");
var row = rb.parentNode.parentNode;
for (var i = 0; i < rbs.length; i++) {
if (rbs[i].type == "radio") {
if (rbs[i].checked && rbs[i] != rb) {
rbs[i].checked = false;
break;
}
}
}
}
</script>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton ID="rbSelected" runat="server" AutoPostBack="True"
oncheckedchanged="rbSelected_CheckedChanged" GroupName="RequestSelection" onclick="RadioCheck(this);" />
<asp:HiddenField ID="HiddenField1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</<asp:View>
Code Behind .CS
protected void rbSelected_CheckedChanged(object sender, EventArgs e)
{
}
Now my problem is upon running my page when I click the radio button the Event doesn't fire. oncheckedchanged is not firing.
Surprisingly The same functionality works fine in another page with in the grid view.
I have searched the web for this answers. But so far nothing worked out. I have Update Panel in my Master Page.. I have tried to play with UpdateMode="Always" and ChildrenAsTriggers="true" but so far nothing worked out please help!

Try this,
void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
Radiobutton rb = e.Row.FindControl("rbSelected") as Radiobutton;
rb.oncheckedchanged += this.rbSelected_CheckedChanged;
}
}
The event will be added to the radiobutton on rowdatabound event of GridView...
Hope this helps you...

Related

Why do I have to click a button twice in an ASP.NET repeater to get the command to fire?

I have an ASP.NET page with the following 3 main areas:
1 - list of checkboxes on the left for fitlering results
2 - Repeater that displays the matching results in the middle (with a button for each item)
3 - Repeater that displays the selected items on the right
On initial page load the page will show the data bound checkboxes and will show all results (since nothing has been checked in the filters). As the user checks or unchecks the checkboxes, the page will reload and the matching results will change. So far this part works great.
In the Results Repeater, each item has a Button. When the user clicks the button for an item in the Results the idea is that the item will get added to the Selected Repeater on the right. What is happening is that after I check or uncheck filter checkboxes - the first time that I then try and click on the buttons in the Results repeater, nothing happens. The page just reloads. Then if I click the button a second time, the Repeater Command will fire and the item will get added to the Repeater on the right hand side. Then, as long as I don't change any of the checkboxes I can click on one of the command buttons and it will work right away. But if I check one of the checkboxes in the filters area (which causes the Results to get re-bound) then I have to click one of the buttons twice to get it to fire.
I have a sense that this has something to do with ViewState but I have no idea. Does anyone know why this would be happening?
Below is my code for both the ASPX page and the code behind.
ASPX Code:
<h3>Filters</h3>
<asp:Repeater ID="rptTechnologies" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Technology</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptVerticals" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Vertical</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptIndustries" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Industry</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptSolutions" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Solution</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<h3>Results</h3>
<asp:Repeater ID="rptMatchingSlides" runat="server" OnItemDataBound="rptMatchingSlides_ItemDataBound" OnItemCommand="rptMatchingSlides_Command">
<ItemTemplate>
<h4><asp:Literal ID="litName" runat="server"></asp:Literal></h4>
<asp:Button ID="btnSelect" runat="server" Text="Select" CommandName="Select" />
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
<h3>Selected</h3>
<asp:Repeater ID="rptSelectedSlides" runat="server" OnItemDataBound="rptSelectedSlides_ItemDataBound">
<ItemTemplate>
<h4><asp:Literal ID="litName" runat="server"></asp:Literal></h4>
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
Here is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.BindData();
}
}
public List<string> SelectedSlides
{
get
{
if (Session["SelectedIDs"] != null)
{
string[] _ids = Session["SelectedIDs"].ToString().Split(new char[] { '|' });
List<String> _retVal = new List<string>();
foreach (string _id in _ids)
{
_retVal.Add(_id);
}
return _retVal;
}
else
{
return new List<string>();
}
}
set
{
//Set the session value
string _val = "";
foreach (string _id in value)
{
if (_val == "")
{
_val = _id;
}
else
{
_val += "|" + _id;
}
}
Session["SelectedIDs"] = _val;
}
}
protected void BindData()
{
//Filters
rptTechnologies.DataSource = Repository.GetTaxonomyItems();
rptTechnologies.DataBind();
rptVerticals.DataSource = Repository.GetTaxonomyItems();
rptVerticals.DataBind();
rptIndustries.DataSource = Repository.GetTaxonomyItems();
rptIndustries.DataBind();
rptSolutions.DataSource = Repository.GetTaxonomyItems();
rptSolutions.DataBind();
this.BindMatchingSlides();
}
protected void BindMatchingSlides()
{
...build list of ids from checkboxes...
rptMatchingSlides.DataSource = Repository.GetMatchingSlides(_selectedIDs);
rptMatchingSlides.DataBind();
}
protected void BindSelectedSlides()
{
if (this.SelectedSlides.Count > 0)
{
rptSelectedSlides.DataSource = this.SelectedSlides;
rptSelectedSlides.DataBind();
}
else
{
divSelectedSlides.Visible = false;
}
}
protected void rptMatchingSlides_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Literal _litName = (Literal)e.Item.FindControl("litName");
Button _btnSelect = (Button)e.Item.FindControl("btnSelect");
_litName.Text = ...set name here...
_btnSelect.CommandArgument = ...use unique ID of item from database...
_btnSelect.ID = "btnSelect_" + e.Item.ItemIndex;
}
}
protected void rptMatchingSlides_Command(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Select")
{
Item _slide = ...get data from database based on Command Argument...
if (_slide != null)
{
List<string> _selectedSlides = this.SelectedSlides;
_selectedSlides.Add(_slide.ID.ToString());
this.SelectedSlides = _selectedSlides;
}
this.BindSelectedSlides();
}
}
Thanks to Jeremy - removing the line of code where I was setting the ID fixed it. Doh! Somewhere else I had read that you needed to set a unique value for the IDs of the buttons in a repeater. So that must have been the culprit. Thanks to Jeremy.

Need help asp.net other textbox

In my project i have kept source info in dropdownlist. Like source of info: in dropdownlist three items website, Newspaper and others. If user select Others item, then only other text box should be visible otherwise should be invisible. For that i have set in page load event
lblother.visible=false;
txtother.visible=false;
And in Btnsubmit event i have written the condition like.
if(dropdownlistinfo.selectedindex==2)
{
lblother.visible=true;
txtother.visible=true;
}
But in my case i m not getting my desire output. Its always invisible when i am selecting Others item from drowdownlist also. Pls somebody help me where is my mistake?
Thanks,
Sumit
I think the problem is here.
if (!IsPostBack)
{
lblother.visible = false;
txtother.visible = false;
}
This will work if you set Selected property of the default list item.
<asp:DropDownList ID="DropDownList" runat="server">
<asp:ListItem Text="Website" Selected="True"></asp:ListItem>
<asp:ListItem Text="Newspaper"></asp:ListItem>
<asp:ListItem Text="Other"></asp:ListItem>
</asp:DropDownList>
<asp:Label ID="lblOther" runat="server" Text="Other"></asp:Label>
<asp:TextBox ID="txtOther" runat="server"></asp:TextBox>
Hide the controls in the Page Load event.
protected void Page_Load(object sender, EventArgs e)
{
this.txtOther.Visible = false;
this.lblOther.Visible = false;
}
Then show the controls in the button click event.
protected void Button1_Click(object sender, EventArgs e)
{
if (DropDownList1.SelectedIndex == 2)
{
this.txtOther.Visible = true;
this.lblOther.Visible = true;
}
}

Bit of help with DataPager template & LinkButton please?

I have a datapager with a pagertemplate. In the template I have a "Show All" button, which sets the PageSize of the datapager to show all records. This works fine but I want to be able to hide the button when it's clicked. It's in an UpdatePanel so I don't know if that makes a difference?
<asp:DataPager ID="Pager" runat="server" PagedControlID="rangeList" PageSize="15" EnableViewState="false">
<Fields>
<asp:TemplatePagerField>
<PagerTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandArgument="<%# Container.TotalRowCount.ToString() %>"
oncommand="LinkButton1_Command" >Show All Ranges</asp:LinkButton>
</PagerTemplate>
</asp:TemplatePagerField>
<asp:numericpagerfield ButtonCount="10" NextPageText="..." PreviousPageText="..." CurrentPageLabelCssClass="pageOn" />
</Fields>
</asp:DataPager>
And the codebehind:
protected void LinkButton1_Command(object sender, CommandEventArgs e)
{
this.Pager.PageSize = int.Parse(e.CommandArgument.ToString());
LinkButton lb = (LinkButton)sender;
if (lb != null)
{
lb.Visible = false;
}
rangeList.DataBind();
}
The first click works fine, and refreshes the ListView which in turn adjusts the pager to show one page with all the results on it, but the button doesn't disappear as I want it to.
Any ideas?
If there's nothing to display within the pager, why not hide the Pager control itself:
protected void LinkButton1_Command(object sender, CommandEventArgs e)
{
this.Pager.PageSize = int.Parse(e.CommandArgument.ToString());
this.Pager.Visible = false;
lnkShowPages.Visible = true; // EDIT only
rangeList.DataBind();
}
EDIT:
You could have a second "Show Pages" LinkButton that's initially not visible and becomes visible when the Show All LinkButton is clicked (above). When this new LinkButton is clicked, it could then enable paging by setting the Pager's PageSize and visibility and hiding itself:
protected void lnkShowPages_Command(object sender, CommandEventArgs e)
{
this.Pager.PageSize = int.Parse(e.CommandArgument.ToString());
this.Pager.Visible = true;
lnkShowPages.Visible = false;
rangeList.DataBind();
}

Why won't my LinkButton inside a GridView raise its OnClick event?

I have a LinkButton inside a GridView (via an TemplateField). No matter what I try, the LinkButton will not invoke its event handler. I have tried both:
A traditional event handler ("OnClick")
A OnRowCommand event handler at the GridView level.
In both cases, I've debugged and it doesn't even catch the event handler.
If I move the LinkButton out on the page (so it's not in the GridView), it works fine, so I know the syntax is right.
Here is the "traditional" method:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Cancel" ID="DeleteButton" CausesValidation="false" OnClick="CancelThis" runat="server" />
</ItemTemplate>
<asp:TemplateField>
What's interesting is if I remove the "CancelThis" method from the code behind, it throws an error. So I know it's aware of its event handler, because it looks for it when it compiles.
Here is the RowCommand method:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Cancel" ID="DeleteButton" CausesValidation="false" CommandName="CancelThis" runat="server" />
</ItemTemplate>
<asp:TemplateField>
In this case, the GridView has:
OnRowCommand="GridView_RowCommand"
It postsback, but never hints at raising the event.
Any idea what I'm missing here?
How are you binding your GridView? Are you using a datasource control? If you are binding manually during Page_Load, it's possible that since the grid is binding every round trip, the event handler isn't catching properly. If this is the case, you may want to try something like:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
//do binding
}
}
Can you post sample binding code to go with your markup?
If you really want to force the issue, you could hook into the RowDataBound event on the Grid, find the button manually and add the handler in the code behind. Something like:
markup snippet:
<asp:GridView ID="gvTest" runat="server" OnRowDataBound="gvTest_RowDataBound" />
code behind:
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
//find button in this row
LinkButton button = e.Row.FindControl("DeleteButton") as button;
if(button != null)
{
button.Click += new EventHandler("DeleteButton_Click");
}
}
}
protected void DeleteButton_Click(object sender, EventArgs e)
{
LinkButton button = (LinkButton)sender;
// do as needed based on button.
}
I'm not sure what the purpose of the button is, but assuming it is a row delete button, you may not want to take this approach as in the event handler, you don't have direct access to the row in question, like you would using the RowCommand event.
Is there a reason you're using the Template field? Vs say a ButtonField? If you use a ButtonField, then you can hook into the RowCommand event.
markup snippet:
<asp:GridView ID="gvTest" runat="server" OnRowCommand="gvTest_RowCommand">
<columns>
<asp:buttonfield buttontype="Link" commandname="Delete" text="Delete"/>
....
</columns>
</asp:GridView>
code behind:
protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "Delete")
{
//take action as needed on this row, for example
int rowIndex = Convert.ToInt32(e.CommandArgument);
GridViewRow currentRow = (sender as GridView).Rows[rowIndex];
//do something against the row...
}
}
You might want to consult MSDN docs on some of these topics:
RowCommandEvent
ButtonField class
EDIT:
To answer your question on the ButtonField - yes I don't see why you couldn't still deal with a buttonfield. Here's a snippet to find the buttonfield during row data bound and hide it (untested but I think would work...)
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//let's assume your buttonfield is in column 1
// (you'd know this based on your markup...)
DataControlFieldCell cell = e.Row.Cells[1] as DataControlFieldCell;
if(cell != null)
{
ButtonField field = cell.ContainingField as ButtonField;
//based on your criteria, show or hide the button
field.Visible = false;
//or
field.Visible = true;
}
}
}
Is viewstate turned on on your GridView? This has caught me out numerous times.
<button onclick="window.open('<%#Eval("ReportLinks")%>', '_blank');" title='<%#Eval("ReportLinks")%>'> Link</button>

Using event of control under datalist

I have a datalist control which some controls(ex: button) are in it. I want to write some code into click event of button which is in the datalist control. But in the code behind page I can't see the name of controls into datalist. How can I solve this problem?
Attach your event to the controls in the OnItemCreated event of the datalist.
EDITED TO ADD SAMPLE
private void DataList_ItemCreated(object sender,
System.Web.UI.WebControls.DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Button btn = (Button)e.Item.FindControl("btnWhatever");
if (btn != null) btn.Click += new EventHandler(SomHandler);
}
}
If you don't want to add a handler to all the child events, you could instead add your code to the OnItemCommand.
<asp:DataList id="DataList1" runat="server">
<ItemTemplate>
<asp:Button ID="btnDoSomething" Runat=server CommandName="DoSomething"
CommandArgument="<%# DataBinder.Eval(Container.DataItem, "SomeID")
%>"></asp:LinkButton>
</ItemTemplate>
</asp:DataList>
protected void DataList1_ItemCommand(
object source, DataListCommandEventArgs e)
{
if (e.CommandName == "DoSomething")
{
//Do stuff
}
}

Resources