Another SelectedIndexChanged PostBack Resetting Index - c#

I really hate asking since there are so many similar issues related to SelectedIndexChanged not firing. However, I can't figure this one out. Here is my DDL:
<asp:DropDownList runat="server" ID="ddlPart1Country"
CssClass="form-control"
AutoPostBack="true"
OnSelectedIndexChanged="ddlPart1Country_SelectedIndexChanged" />
I have a master page setting EnableViewState="True", and it also has my ScriptManager and form element. Really, nothing out of the ordinary here. With it like this the SelectedIndexChanged will fire just fine. My problem comes in when wrapped by any other element, (e.g.: Panel, div, etc.) My DDL will fire a PostBack, but the index doesn't change, therefore not firing the SelectedIndexChanged event.
So, it will not change the index when for instance:
<div class="row">
<div class="form-group">
<label for="ddlPart1Country" class="col-sm-3 control-label">Country<i class="required"></i></label>
<div class="col-sm-4">
<asp:DropDownList runat="server" ID="ddlPart1Country" CssClass="form-control" AutoPostBack="true" OnSelectedIndexChanged="ddlPart1Country_SelectedIndexChanged" />
</div>
</div>
</div>
Identical DDL control, the only difference is its placement in the div.
And here is my codebehind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
FillPart1Countries();
}
protected void FillPart1Countries()
{
var lstOptions = CacheValues.Countries;
if (lstOptions == null)
{
return;
}
ddlPart1Country.Items.Add(new ListItem(" -- Select Your Country -- ", ""));
foreach (var option in lstOptions.Result)
{
ddlPart1Country.Items.Add(new ListItem(option.Ctry, option.GENC0));
}
}
protected void ddlPart1Country_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlPart1Country.SelectedItem.Value == "")
return;
var lstOptions = FormPopulation.GetStatesAndProvences(ddlPart1Country.SelectedItem.Value);
ddlPart1StateOrProvence.Items.Clear();
ddlPart1StateOrProvence.Items.Add(new ListItem(" -- Select Your State/Provence -- ", ""));
foreach (var option in lstOptions.Result)
{
ddlPart1StateOrProvence.Items.Add(new ListItem(option.Name, option.GENC1));
}
lblCountrySelected.Text = ddlPart1Country.SelectedItem.Text;
upnlPart1State.Update();
}
I'm not rebuilding the DDL on PostBack. ViewState is enabled. I know it has to be something dumb I'm doing or not doing, but I can't see it. What am I missing?

After thinking about this, I think I may have fixed something like this a while ago by switching the <div> to <asp:Panel>. I'm not sure what the problem was, though, since it normally works fine.

Thanks to Steve's idea about CSS, I removed the script libraries I was using, too. One of them is for my client-side validation and there was a line there:
$.each($('div').children(), function() {
$(this).attr("name", $(this).attr("id"));
});
That forces the DOM to rename the name attribute to the ID of the ASP control. Removing that of course solved the issue. That's what I get for using a hack for client-side validation in the first place. Thanks to everyone that gave this a look.

Related

Repeater pulling as Null is code behind?

I have a repeater for Frequently asked questions on a Website that I'm trying to get separated into categories depending on which treeid it is related to.
When I reference the repeater (rp_FAQ) in the code behind to check if it is null so I can pass the category id to the stored procedure it keeps returning null when I need the item to exist when check that it's null.
I can't seem to find the route of the problem so as second set of eyes would be really grateful.
Thanks.
I have this repeater:
<asp:Repeater ID="rp_FAQ" DataSourceID="DS_GetFAQs" runat="server" OnItemDataBound="rp_FAQCategories_ItemDataBound">
<HeaderTemplate>
<div class="container-full fares_container">
<div class="row">
</HeaderTemplate>
<ItemTemplate>
<dt>Q: <%# Eval("Question") %></dt>
<dd>A: <%# Eval("Answer") %></dd>
</ItemTemplate>
<FooterTemplate>
</dl>
</div>
</div>
</FooterTemplate>
</asp:Repeater>
Here is my code behind:
protected void rp_FAQCategories_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rp_FAQRep = e.Item.FindControl("rp_FAQ") as Repeater;
if (rp_FAQRep != null)
{
if (TreeData.CurrentDefault.IsRelation(Convert.ToInt32(Resources.Pages.FAQ)))
{
DS_GetFAQs.SelectParameters["CategoryID"].DefaultValue = "1";
}
rp_FAQRep.DataSource = DS_GetFAQs;
rp_FAQRep.DataBind();
}
}
The FindControl method is only needed if you are trying to get a reference to a control which is inside the control which raised the event (in this case ItemDataBound). So you can either reference the control directly if it's not nested inside another control or use sender. For example:
var rp_FAQRep = rp_FAQ; //A bit pointless but demonstrates the point
or
var rp_FAQRep = (Repeater)sender;
The problem is that you are trying to find the rp_FAQ control in a control inside rp_FAQ itself.
Since e.Item is the RepeatItem under rp_FAQ, you can just cast e.Item.Parent, or sender if you will.
e.Item is the RepeaterItem within the Repeater - it does not contain the Repeater itself. Just cast the sender of the event:
var rp_FAQRep = (Repeater)sender;

Textbox is empty after filling with javascript

I create textbox by this code:
<div style="clear:left;">
<asp:TextBox TextMode="MultiLine" runat="server" ID="selectText" ReadOnly="true" Width="560px" Height="50px"></asp:TextBox>
</div>
I fill it by this code:
elSelText.value = elSelText.value.substr(0, position) + chosenoption2.value + " ";
And then i try to send value in textbox to server, but it's empty!
protected void btnUseSelectClick(object sender, EventArgs e)
{
sourceDetails.SelectCommand += " and " + selectText.Text;
Session["FilterSelectCommand"] = sourceDetails.SelectCommand;
tableResults.DataBind();
}
On the advice I added AutoPostBack="true":
<div style="clear:left;">
<asp:TextBox TextMode="MultiLine" runat="server" AutoPostBack="true" ID="selectText" ReadOnly="true" Width="560px" Height="50px"></asp:TextBox>
</div>
but it didn't help
Although it's news to me, it seems that the ReadOnly property doesn't keep track of changes from the client. If you want the "readonly" functionality but still get the value on the server, put the following in your Page_Load method:
selectText.Attributes.Add("readonly", "readonly");
And remove the ReadOnly (and AutoPostBack) property in the <asp:TextBox> tag.
( From: http://aspadvice.com/blogs/joteke/archive/2006/04/12/16409.aspx and http://forums.asp.net/t/1467081.aspx - it was a fairly quick find with Google)
Maybe a problems of ViewState. Try add the check of Page.IsPostBack in the page load event like this:
If(!Page.IsPostBack)
{
// Data binding for the first call
}
I believe this is due to ReadOnly: ASP.Net registers which controls are readonly when sending you the page.
The value of these controls is discarded when posting back, and it is regotten (from ViewState I believe).
A workaround for this would be not setting readonly="true" on the aspx page, but setting it with $(document).ready(your_function_here();) (if you're using jQuery) or with the body onLoad event.

radiobutton inside repeater always returns false

I have a repeater with radiobuttons in it.
<script type="text/javascript">
$(document).ready(function ()
{
$("#test input:radio").attr("name", "yourGroupName");
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="test">
<asp:Repeater runat="server" ID="rep" onitemdatabound="rep_ItemDataBound"
onitemcommand="rep_ItemCommand">
<ItemTemplate>
<asp:RadioButton ID="n" runat="server" Text='<%# Eval("name") %>' AccessKey='<%# Eval("id")%>' />
</ItemTemplate>
</asp:Repeater>
</div>
I am using the javascript at the top to fix the radiobutton bug in .net.
i bind a list to the repeater at page load, with a if (!Page.IsPostback) around it.
edit:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
rep.DataSource = z.Table.ToList();
rep.DataBind();
}
}
then i have a button, that when clicked should do something with the radio button that's been selected, this is the problem now:
foreach (RepeaterItem i in rep.Items)
{
RadioButton erb = i.FindControl("n") as RadioButton;
if (erb.Checked)
{
//do stuff
}
}
no matter which radiobutton i select, when i click the button and i debug the entire loop, every checkbox == false. i'm doing more stuff with the code but i've simplified it, because this is the biggest problem.
i have seen countless of topics about this issue and i have looked through them all but i still can't seem to get this to work.
Please try adding OnCheckedChanged="RadioButton1_OnCheckedChanged" AutoPostBack="true" on you radio button this will trigger post back on click of the button and you will be able to find the Checked one
I think this is all down to the sequence of events in ASP.NET .
Try putting your DataBind code in the Page_Init procedure, that way the state of the radiobuttons will be set by the time it reaches the Page_Load procedure.

Switch Div Class in Repeater based on Checkbox.Checked Using C#

I have a repeater that will present a set of titles and checkboxes (some checked some not). Each is wrapped in a div with a background colour. All I want to do is change the background colour for the checkboxes that are already checked so they are easily identified on the page.
Here's the repeater:
<asp:Repeater ID="rptCartridges" runat="server" OnItemDataBound="rp_ItemDataBound">
<ItemTemplate>
<div class="cartridgebox">
<span class="cartridgeboxl"><%#Eval("cartName") %></span>
<span class="cartridgeboxr">
<asp:CheckBox ID="chkCart" name="chkbox" Checked = '<%#Convert.ToBoolean(DataBinder.Eval(Container.DataItem, "cartChecked"))%>' runat="server" />
<asp:HiddenField ID="hfCartID" runat="server" Value='<%#DataBinder.Eval(Container.DataItem, "cartID")%>' />
</span>
</div>
</ItemTemplate>
</asp:Repeater>
All I really want to do is change the class cartridgebox to cartridgeboxchecked if the checkbox is returned as checked.
I have tried manipulating rp_ItemDataBound. Where it goes wrong is the actual changing of the class inline. I've tried using if statements, add runat="server" to the div and populating a variable and then using Response.Write inside the class statement. But nothing seems to work.
What seems the neatest way would be to use rp_ItemDataBound like so:
protected void rp_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
string chkboxClass = "cartridgebox";
CheckBox chk = (CheckBox)e.Item.FindControl("chkCart");
HiddenField hfCartID = (HiddenField)e.Item.FindControl("hfCartID");
// Adding the hide.Value Attribute to the chk.Text field.
chk.Attributes.Add("Text", hfCartID.Value);
if (chk.Checked == true)
{
chkboxClass = "cartridgeboxchecked";
}
else
{
chkboxClass = "cartridgebox";
}
}
But I lack the understanding to pass the variable chkboxClass to the div's class dynamically. Of course I am probably looking at this completely wrong so any guidance would be appreciated.
Use following markup for div in ItemTemplate : <div class='<%# ((bool)Eval("cartChecked"))? "cartridgeboxchecked" : "cartridgeboxl" %>' >
If you need to change div's class on checkbox change immediatelly, consider to add onclick client-side event handler to checkbox in ItemDataBound Repeater's event handler

How to re-bind ListView on OnClick event of a button?

this seemed simple at first but I can't get it to work.
I have the following scenario:
<asp:ListView ID="CommentsListView" runat="server">
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<UC:Comment runat="server" CommentItem="<%# CurrentComment %>" />
<br />
</ItemTemplate>
</asp:ListView>
<asp:TextBox ID="NewComment" runat="server" />
<asp:ImageButton ImageUrl="/images/ball.png" runat="server"
OnClick="SubmitComment" />
Code:
protected void Page_Load(object sender, EventArgs e)
{
RenderListView();
}
protected void RenderListView()
{
CommentsListView.DataSource = //Get the data source objects
CommentsListView.DataBind();
}
protected CommentObject CurrentComment
{
get { return (CommentObject)Page.GetDataItem(); }
}
protected void SubmitComment(object sender, ImageClickEventArgs e)
{
//code to submit comment
RenderListView();
}
basically, when I submit a comment, I want to see it in the ListView, but I don't. "MyControl" gets a null comment in the post-back, for all of the items (not just the new one).
Only after I refresh the page, I can see the new comment that I'v submitted. I can't however refresh the page every submit because this code is inside an UpdatePanel (the issue occurs without the UpdatePanel as well).
Any idea how to solve this?
I can't find any specifics on this, but I have a hunch the user control in your ItemTemplate is causing the issue. Can you remove it and see if it works?
I notice that you are calling RenderListView in both SubmitComment and PageLoad which I believe will cause it to fire twice when the button is clicked (with PageLoad firing first). It looks like the code you posted is simplified. Is it possible that there is something happening in the PageLoad which is sabotaging your SubmitComment steps?
I finally solved it, if anyone else may encounter this -
The solution was to avoid "<%#" and instead use the ItemDataBound event:
<asp:ListView ID="Comments" runat="server"
OnItemDataBound="CommentsItemDataBound">
and the method itself:
protected void CommentsItemDataBound(object sender, ListViewItemEventArgs e)
{
var commentItem = (Comment)(((ListViewDataItem)e.Item).DataItem);
var commentControl = (Comment)e.Item.FindControl("CommentControl");
commentControl.CommentItem = commentItem;
}
This way, the binding of each control works as expected.

Categories