How to disable first checkbox after other one clicked in repeater - asp.net

I have a repeater and there is a checkbox. When I click first one in checkedchanged event row information appear down below. But after first click I have a trouble. Sometimes informations are same. Because foreach always see the first click. For instance, I checked second one and I saw the informations. Then I click second one ok again I saw the informations, but this time I clicked again first one. Foreach can take first checkbox and the last one still checked before postback it's again doing second one's operation.
Is there any way to fix this?
Here is my sample code.
<asp:Repeater ID="rptInformations" runat="server">
<ItemTemplate>
<asp:CheckBox ID="ckChoose" runat="server" OnCheckedChanged="ckChoose_CheckedChanged" AutoPostBack="true" />
<div id="foo" runat="server"> ... some basic titles ...</div>
</ItemTemplate>
<asp:Repeater>
<div id="info" runat="server"> ... informations in here (textboxes, labels ..etc)</div>
CodeBehind:
foreach (RepeaterItem item in rptInformations.Items)
{
//CheckBox ckChoose= (CheckBox)sender;
CheckBox ckChoose= item.FindControl("ckChoose") as CheckBox;
if (cBoxChoose.Checked)
{
... database process ...
}
}

As for what I understand you are trying to trigger an event everytime you check the checkbox and it will show certain info according to the row of the repeater it belongs to, for this I have made this example on a page called Repeater.aspx, using an event that will only fire for one checkbox and not for all:
Repeater.aspx:
<asp:Repeater runat="server" ID="repeater">
<ItemTemplate>
<asp:CheckBox ID="ckChoose" runat="server" AutoPostBack="true" OnCheckedChanged="ckChoose_CheckedChanged"/>
<div id="foo" runat="server"> <%# Eval("Field2")%></div>
</ItemTemplate>
</asp:Repeater>
<div id="info" runat="server"> ... informations in here (textboxes, labels ..etc)</div>
Repeater.aspx.cs (Codebehind):
partial class Repeater1 : System.Web.UI.Page
{
private System.Collections.Generic.List<Item> Elements()
{
Generic.List<Item> itemList = new Generic.List<Item>();
itemList.Add(new Item("1", "One"));
itemList.Add(new Item("2", "Two"));
return itemList;
}
protected void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack) {
this.repeater.DataSource = this.Elements();
this.repeater.DataBind();
}
}
protected void ckChoose_CheckedChanged(object sender, System.EventArgs e)
{
CheckBox chk = (CheckBox)sender;
this.info.InnerHtml = "checkbox:" + chk.ID + " foo:" + ((HtmlGenericControl)chk.Parent.FindControl("foo")).InnerText;
}
}
Hope this helps.

I guess I fix it with namingcontainer. It works perfect.
foreach (RepeaterItem item in Repeater1.Items)
{
CheckBox cBoxx = item.FindControl("ckChoose") as CheckBox;
current_cbId = cBoxx.NamingContainer.UniqueID.ToString();
if (cBoxx.Checked)
{
... some operations ...
}
if (cBoxChoose.NamingContainer.UniqueID.ToString() != current_cbId)
cBoxChoose.Checked = false;
}

Related

ASP.NET DropDownList SelectedIndexChanged event not working

I have a basic drop down list. Upon selection of an item in the list, I expect to update the label with the choice of drop down list. But my code section does not show any update. Here is the code:
MainPage.aspx.cs:
protected void Page_Load(Object sender, EventArgs e)
{
if (!this.IsPostBack)
{
// Use integers to index each item. Each item is a string.
Dictionary<int, string> fruit = new Dictionary<int, string>();
fruit.Add(1, "Kiwi");
fruit.Add(2, "Pear");
fruit.Add(3, "Mango");
fruit.Add(4, "Blueberry");
fruit.Add(5, "Apricot");
fruit.Add(6, "Banana");
fruit.Add(7, "Peach");
fruit.Add(8, "Plum");
// Define the binding for the list controls.
benimDropDownList.DataSource = fruit;
// Choose what you want to display in the list.
benimDropDownList.DataTextField = "Value";
// Activate the binding.
this.DataBind();
}
}
protected void benimDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
lblSonuc.Text = "You picked: " + benimDropDownList.SelectedItem.Text;
lblSonuc.Text += " which has the key: " + benimDropDownList.SelectedItem.Value;
}
MainPage.aspx:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="benimDropDownList" runat="server" OnSelectedIndexChanged="benimDropDownList_SelectedIndexChanged">
</asp:DropDownList>
<asp:Label ID="lblSonuc" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
What is wrong with it?
Add AutoPostBack="true" to the <asp:DropDownList>:
<asp:DropDownList ID="benimDropDownList" runat="server"
OnSelectedIndexChanged="benimDropDownList_SelectedIndexChanged" AutoPostBack="true">
</asp:DropDownList>
By default <asp:DropDownList> do not post back changes to the server.
You might also want to set the DataValueField for your dropdownlist:
benimDropDownList.DataValueField = "Key";

ASP.Net AJAX UpdatePanel not working with Repeater and RadioButtons

I have a repeater which includes a radio button in each item, and the whole thing sites inside an update panel. When I select a radio button the whole page reloads. Why is it not just updating the update panel. I've reduced this to a pretty simple example to avoid clutter. Code here...
ASPX...
<asp:ScriptManager ID="SM1" runat="server" />
<asp:UpdatePanel ID="up1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater runat="server" ID="history">
<ItemTemplate>
<asp:RadioButton runat="server" ID="radioButton" AutoPostBack="true" GroupName="HistoryGroup" OnCheckedChanged="RadioButton_CheckChanged" /><br />
</ItemTemplate>
</asp:Repeater>
<p><asp:Literal runat="server" ID="output" /></p>
</ContentTemplate>
</asp:UpdatePanel>
Code...
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<int> list = new List<int>();
for (int i = 0; i < 20; i++)
list.Add(i);
history.DataSource = list.ToArray();
history.DataBind();
}
}
protected void RadioButton_CheckChanged(Object sender, EventArgs e)
{
output.Text = DateTime.Now.ToString();
}
}
Setting ClientIDMode=Auto on the RadioButton should fix it (it's an infamous .NET bug, http://connect.microsoft.com/VisualStudio/feedback/details/584991/clientidmode-static-in-updatepanel-fails-to-do-async-postback)
please add up1.Update() after output.Text = DateTime.Now.ToString(). Your RadioButton is not the trigger for updatepanel
Turns out the solution was to remove the GroupName from the RadioButton. When I remove this tag it fires asynchronously and just updates the panel. I don't actually need this tag anyway (due to the known bug where GroupName doesn't work on RadioButtons in Repeaters) as I handle the grouping within my click event (i.e. uncheck any other RadioButtons of the same name in other repeater items).

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.

Handling the checkedchanged event of inner repeater Checkbox control in asp.net nested repeaters

I have nested repeaters on my aspx page.In the outer repeater I am displaying a list of products and in the inner repeater I am displaying a list of additional options associated with each product.The inner repeater contains a checkbox,textbox,label and other stuff.I would like to find the controls inside the outer repeater when a user selects a checkbox in the inner repeater.In order to handle this I am using the following code.
<asp:Repeater ID="OuterRepeater" runat="server"
onitemdatabound="OuterRepeater_ItemDataBound" >
<ItemTemplate>
<asp:Label ID="CodeLabel" runat="server" Text='<%# Eval("Code") %>'></asp:Label>
<asp:Repeater ID="InnerRepeater" runat="server" OnItemCreated="InnerRepeater_ItemCreated">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="true"/>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
......
.......
</ItemTemplate>
</asp:Repeater>
......
......
</ItemTemplate>
</asp:Repeater>
protected void InnerRepeater_ItemCreated(object sender, RepeaterItemEventArgs e)
{
RepeaterItem ri = (RepeaterItem)e.Item;
if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem
)
{
CheckBox cb = ri.FindControl("CheckBox1") as CheckBox;
cb.CheckedChanged += new EventHandler(CheckBox1_CheckedChanged);
}
}
private void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = (CheckBox)sender;
if (cb.Checked)
{
//do something
}
else
{
//do something
}
}
But the checkedChanged event of the checkbox is not firing for some reason.Also I am not sure how to access the textbox of the outer repeater in the checked changed event of the innter repeater checkbox control.
Could someone please help me with this?
Thanks
It does not fire the CheckedChanged event, since you have declared the event handler as private, You have to make it Protected or Public
Protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
You can access the Textbox control like..
private void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
Textbox textbox1 = (TextBox)checkBox.Parent.FindControl("TextBox1");
String textboxText = textbox1.Text;
}
It doesn't look like you defined an event handler in your markup.
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="true" OnCheckedChanged="CheckBox1_CheckedChanged" />
Muhammad Akhtar's answer helped me a lot today!
I just needed to set a specific ID to my dynamic generated checkboxes inside my reapeater to recover the origin of the event, and do the rest of the processing, and it worked perfectly.
chkAtivo.ID = DataBinder.Eval(e.Item.DataItem, "id").ToString();
Reovered just as the sample.
Cant vote up yet, but thank you.

Loop in code block on click argument

Basically what i am trying to do is display a list of categories. And if the admin is logged in
i want to show some buttons next to each category. For example a button to delete it. The problem is that i dont know how to pass a parameter to the function that does the action.
Like i specify that on button click the function 'DeleteCat' must be called but if i cant pass the ID of the category to be deleted this wont work.
I know this can be done with commands and a repeater, but its not an option, i cant use a repeater.
So apparanly this is what i am aiming for:
But of course it does not work.
<%For Each Cat In Category.Children%>
<p class="SubCategory">
<%=Cat.Name%>
<%If User.Identity.Name = "Admin" Then%>
<asp:LinkButton ID="LinkButton6" runat="server" OnClick="AddItem" Text="A+" CommandArgument=<%=Cat.ID %> />
<%End If%>
</p>
<%Next %>
Your event handler AddItem should be able to evaluate the sender of the event and the CommandEventArgs
void AddItem(Object sender, EventArgs e)
{
int result;
bool returnValue;
Button clickedButton = (Button)sender;
returnValue = Int32.TryParse(clickedButton.CommandArgument, result);
// then other stuff happens ...
}
See detailed example here.
edit
Completed code sample as suggested by Brandon.
Alternative solution, using a CheckBoxList
...
<script language="C#" runat="server">
void Page_Load(Object Sender, EventArgs e)
{
if (!IsPostBack)
{
// bind data to controls
this.itemRepeater.DataSource = Category.Children;
this.adminList.DataSource = Category.Children;
this.itemRepeater.DataBind();
this.adminList.DataBind();
}
// set visibility according to user
this.itemRepeater.Visible = (User.Identity.Name != "Admin");
this.adminList.Visible = (User.Identity.Name == "Admin");
this.adminButton.Visible = (User.Identity.Name == "Admin");
}
protected void AddItem(object sender, EventArgs e)
{
foreach(ListItem currentitem in this.adminList.Items)
{
if(currentitem.Selected)
{
// do something with the selected value
int i;
bool isparsed = Int32.TryParse(currentitem.value, i);
}
}
}
</script>
</head>
<body>
<form id="mainForm" runat="server">
<asp:Repeater ID="itemRepeater" runat="server">
<ItemTemplate>
<p><%# DataBinder.Eval(Container.DataItem, "value") %></p>
</ItemTemplate>
</asp:Repeater>
<asp:CheckBoxList ID="adminList" runat="server" />
<br />
<asp:Button ID="adminButton" OnClick="AddItem" runat="server" Text="Add seleted Items" />
</form>
</body>

Resources