I have the following markup / code block in the ASPX file.
The binding of the ddl is triggered after Page_Load event which is in the code behind file.
This results me not able to get the selected value of the dropdownlist if I were to use such flow.
However for some purpose I require it to work this way.
Any idea how I could get the dropdownlist selected value when a post back is being triggered (click of the button)?
Page URL: page.aspx?para1=0¶2=value
ASPX PAGE
<%
if (Convert.ToInt32(Request.QueryString["para1"]) == 0)
{
ddl.DataValueField = "value";
ddl.DataTextField = "text";
ddl.DataSource = ds; //ds is valid, exact code not shown
ddl.DataBind();
} else {
//write in this area
Response.Write("Not 0");
}
%>
<form runat="server" id="user_form" class="form-horizontal">
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</asp:ToolkitScriptManager>
<asp:UpdatePanel ID="updPanel" runat="server">
<ContentTemplate>
<asp:DropDownList runat="server" ID="ddl">
</asp:DropDownList>
<%-- this button will call btnSave_Click to get the ddl's value--%>
<asp:Button runat="server" ID="btn" Text="Button" OnClick="btn_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
CODE BEHIND
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//do my stuff
}
}
protected void btn_Click(object sender, EventArgs e)
{
int intValue = Convert.ToInt32(ddl.SelectedValue);
//do my stuff
}
The ASPX Page code block will run after Page_Load / page's lifecycle, then will determine what to do base on the url parameters.
Thanks in advance!
You could always throw in a hidden object and use jquery to copy the value to the hidden value based on a certain action without a postback and would do it client side like it sounds like you want it to do
Related
I can't get the dropdown onselectedindexchanged event to fire, and when I make a selection it resets the value of the dropdown onpostback, even though I have the if (!ispostback) in the page load event.
this is a content page in a master page in asp in case that matters.
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:DropDownList ID="EventSVCProgList" runat="server"
EnableViewState="true"
OnSelectedIndexChanged="EventSVCProgList_SelectedIndexChanged"
AutoPostBack="true"></asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SqlConnection constr = new SqlConnection(ConfigurationManager.ConnectionStrings["CBTestDBConnectionString"].ConnectionString);
SqlCommand eventsvcprogCMD = new SqlCommand("select*from SvcProg where eventatteligable=1", constr); // table name
SqlDataAdapter eventsvcadapt = new SqlDataAdapter(eventsvcprogCMD);
DataSet eventsvcset = new DataSet();
constr.Open();
eventsvcadapt.Fill(eventsvcset); // fill dataset
EventSVCProgList.DataTextField = eventsvcset.Tables[0].Columns["SvcProgID"].ToString(); // text field name of table dispalyed in dropdown
EventSVCProgList.DataValueField = eventsvcset.Tables[0].Columns["eventatteligable"].ToString();
EventSVCProgList.DataSource = eventsvcset.Tables[0]; //assigning datasource to the dropdownlist
EventSVCProgList.DataBind(); //binding dropdownlist
constr.Close();
}
}
protected void EventSVCProgList_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("Eat Poop");
var somevalue = EventSVCProgList.SelectedValue;
}
There are couple of things.
1) You need to add a Script Manager to the page at the top if not added already(it will give you a runtime error if you have not added a script Manager to the page)
2) You need to change the Update Panel content as shown below
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="EventSVCProgList" runat="server" AutoPostBack="True" OnSelectedIndexChanged="EventSVCProgList_SelectedIndexChanged">
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="EventSVCProgList" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
There seems that any parent control or page leven ViewState is disabled. please check in debug mode that what value you getting for EventSVCProgList.EnableViewState and other parent controls' as well.
thanks for the help. its still not working so i'm just going to try to use javascript instead. its got to be some fundamental flaw with the way the master page or content page is setup.
It seems I am struggling with the order of the page life cycle. Based on the user selecting button 1 or 2, I need to have respective controls added dynamically during the Page_Load event. My problem is when a button is clicked the Page_Load event is executed before Button_Click event code is read. There for my variable "doWhat" is not assigned a value until after the Page_Load event. How can I have the "doWhat" variable assigned a value to be read during the Page_Load?
Below is asp.net form code for the two buttons:
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button 1" onclick="Button_Click" />
<asp:Button ID="Button2" runat="server" Text="Button 2" onclick="Button_Click" />
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
</div>
</form>
Below is the code behind:
int doWhat;
protected void Page_Load(object sender, EventArgs e)
{
doWhat = Convert.ToUInt16(ViewState["doWhat"]);
if (doWhat == 1)
{
// code to dynamically load group 1 controls
}
else
{
// code to dynamically load group 2 controls
}
Label1.Text = Convert.ToString(doWhat);
}
protected void Button_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn.ID == "Button1")
{
doWhat = 1;
}
else
{
doWhat = 2;
}
ViewState.Add("doWhat", doWhat);
}
If you are comfortable with javascript then you can achieve it by making following changes in your design and code. Add a hidden field in your aspx page. Your HTML code should be like this.
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button 1" OnClick="Button_Click" OnClientClick="return doWhatAction(1);" />
<asp:Button ID="Button2" runat="server" Text="Button 2" OnClick="Button_Click" OnClientClick="return doWhatAction(2);" />
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
<asp:HiddenField ID="HiddenField1" Value="1" runat="server" />
<script type="text/javascript">
var doWhatAction = function (actionIndex) {
//alert(actionIndex);
document.getElementById("<%=HiddenField1.ClientID%>").value = actionIndex;
return true;
}
</script>
</div>
</form>
And your code will be something like...
int doWhat;
protected void Page_Load(object sender, EventArgs e)
{
//doWhat = Convert.ToUInt16(ViewState["doWhat"]);
doWhat = Convert.ToUInt16(HiddenField1.Value);
if (doWhat == 1)
{
// code to dynamically load group 1 controls
}
else
{
// code to dynamically load group 2 controls
}
Label1.Text = Convert.ToString(doWhat);
}
protected void Button_Click(object sender, EventArgs e)
{
//Do Nothing
//Button btn = sender as Button;
//if (btn.ID == "Button1")
//{
// doWhat = 1;
//}
//else
//{
// doWhat = 2;
//}
//ViewState.Add("doWhat", doWhat);
}
You can use jquery or javascript i this case.
Took on hidden variable in form
initialize it on click event of button in javascript
Read value of hidden variable in page load
<head >
<title>Hidden Variable</title>
<script type="text/javascript">
function SetHDNValue()
{
var hdnControlID = '<%= hdnControl.ClientID %>';
document.getElementById(hdnControlID).value=1;
}
</script>
</head>
<body >
<form id="form1" runat="server">
<div>
<input id="hdnControl" type="hidden" runat="server" />
<asp:Button ID="btnJSValue" Text="Click" runat="server" OnClientClick="SetHDNValue()"
/>
</div>
</form>
</body>
And in code behind file hdnControl.value
Since long ago I am not working with asp.net forms. And forgot doing things.But I found how you can do. As on stackoverflow link like answers is wrong. I copied main statements from the link which indicate how post-back events works and how you can use it for your purpose. For more http://aspsnippets.com/Articles/How-to-find-the-control-that-caused-PostBack-in-ASP.Net.aspx
All controls accept Button and ImageButton use JavaScript for causing a postback. To enable postback on these controls one has to set AutoPostBack property to true.
When you set this property to true, __doPostBack function is called on event which causes a postback.
The __doPostBack function is not visible in Source of the page until you place a LinkButton or set AutoPostBack to true for any of the above discussed controls.
Here is how generated __doPostBack looks:
<script type = "text/javascript">
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
</script>
The __doPostBack function simply stores the below two arguments in two hidden fields
eventTarget – The name of the control that caused the postback
eventArgument – The argument to be sent to server.
In two hidden fields which also appear only when AutoPostBack is set to true
Finally, here is how you can distinguish by getting control's ID that caused the postback :
if (IsPostBack)
{
string CtrlID = string.Empty;
if (Request.Form["__EVENTTARGET"] != null &&
Request.Form["__EVENTTARGET"] != string.Empty)
{
CtrlID = Request.Form["__EVENTTARGET"];
/****implement Your logic depending on control ID****/
}
}
This is my best attempt to simplify the code to ask the question well. Hopefully it helps.
The short: I need to get the value of a dynamically created Control whose path is loaded from the database and added to a Repeater that contains a PlaceHolder. The value needs to be retrieved from a function on the child page that is called from the master page.
The long:
I have a master page that has a lot of settings on it, and an area where a child page can add its own configuration options. Let's say the master page is as follows:
<%# Master Language="C#" MasterPageFile="~/MainTemplate.master" CodeBehind="ConfigureChoices.master.cs" Inherits="Demo.ConfigureChoices"
AutoEventWireup="true" %>
<asp:Content ID="Content1" ContentPlaceHolderID="RenderArea" runat="Server">
<asp:Panel runat="server" ID="PanelConfiguration">
<asp:TextBox ID="TextBoxForSomething" runat="Server"/>
<asp:DropDownList ID="AnotherConfigurableThing" runat="server" OnSelectedIndexChanged="DropDownConfiguration_Click" AutoPostBack="true">
<asp:ListItem Text="Option 1" Selected="True" Value="1"></asp:ListItem>
<asp:ListItem Text="Option 2" Value="2"></asp:ListItem>
<asp:ListItem Text="Option 3" Value="3"></asp:ListItem>
</asp:DropDownList>
<!--etc-->
<asp:ContentPlaceHolder ID="CustomSettings" runat="server">
</asp:ContentPlaceHolder>
<asp:Button ID="ButtonSubmit" runat="Server" Text="Submit" OnClick="ButtonSubmit_Click" />
</asp:Panel>
</asp:Content>
In codebehind, I need to persist the settings to the database, including custom settings from the user page. The child pages need some of the data created from the master page in order to persist its data. To accomplish this, I have an event that gets populated on child page load and called prior to redirect. It looks like this:
public delegate void BeforeSubmitEventHandler(int configInfoID);
public event BeforeSubmitEventHandler BeforeSubmit;
protected void ButtonSubmit_Click(object sender, EventArgs e)
{
ConfigInfo config = new ConfigInfo;
config.EnteredText = TextBoxForSomething.Text;
config.SelectedValue = AnotherConfigurableThing.SelectedValue;
int configID = AddToDatabase(config);
if (BeforeSubmit != null)
BeforeSubmit(configID);
Response.Redirect("RedirectURL.aspx");
}
The custom section of the user page has a Repeater, a DropDownList, and an "Add" Button. The Repeater has the name of the option, a short description, a delete image, and a PlaceHolder for loading custom controls from the database. More on that after the code:
<%# Page Title="" Language="C#" MasterPageFile="~/ConfigureChoices.master" ValidateRequest="false"
AutoEventWireup="true" Inherits="Demo.CustomChoicePage1" Codebehind="CustomChoicePage1.aspx.cs"
MaintainScrollPositionOnPostback="true" %>
<asp:Content ID="MyContent" ContentPlaceHolderID="CustomSettings" runat="server">
<asp:Repeater ID="RepeaterSelectedOptions" OnItemCreated="OnOptionAdded" runat="server">
<HeaderTemplate>
<table id="SelectedOptionsTable">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<%# Server.HtmlEncode(Eval("Name").ToString()) %>
</td>
<td>
<%# Server.HtmlEncode(Eval("Description").ToString()) %>
</td>
<td>
<asp:ImageButton ImageUrl="delete.png" ID="ImgDeleteOption" runat="server" OnCommand="DeleteOption_Click"
CommandArgument='<%# Eval("OptionID") %>' />
</td>
</tr>
<asp:PlaceHolder runat="server" ID="optionConfiguration" />
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
<br />
<asp:DropDownList ID="DropDownListAvailableOptions" runat="server" />
<asp:Button ID="ButtonAddOption" runat="server" Text="Add Option" OnCommand="AddOption_Click" />
</asp:Content>
In codebehind, the Repeater is populated the first time on Page_Load using the following code (combination of C# and pseudocode to shorten this already-long question):
protected void Page_Load(object sender, EventArgs e)
{
((ConfigureChoices)Master).BeforeSubmit += OnSubmit;
if (!Page.IsPostBack)
{
RefreshOptions();
}
}
protected void RefreshOptions()
{
List<Option> fullList = GetOptionsFromDB();
List<Option> availableList = new List<Option>();
List<Option> selectedList = new List<Option>();
List<int> selectedOptions = GetSelectedOptions();
// Logic here to set the available/selected Lists
DropDownListAvailableOptions.DataSource = availableList;
DropDownListAvailableOptions.DataBind();
RepeaterSelectedOptions.DataSource = selectedList;
RepeaterSelectedOptions.DataBind();
}
public List<short> GetSelectedOptions()
{
List<int> selectedOptions = this.ViewState["SelectedOptions"];
if (selectedOptions == null)
{
selectedOptions = new List<int>();
foreach (Option option in GetOptionsFromDB())
{
selectedOptions.Add(option.OptionID);
}
}
return selectedOptions;
}
If the add or remove buttons are clicked, the following methods are used:
public void AddOption_Click(object sender, CommandEventArgs e)
{
List<int> selectedOptions = GetSelectedOptions();
selectedOptions.Add(Convert.ToInt32(DropDownListAvailableOptions.SelectedValue));
this.ViewState["SelectedOptions"] = selectedTests;
RefreshOptions();
}
public void DeleteOption_Click(object sender, CommandEventArgs e)
{
List<int> selectedOptions = GetSelectedOptions();
selectedOptions.Remove(Convert.ToInt32(e.CommandArgument));
this.ViewState["SelectedOptions"] = selectedOptions;
RefreshOptions();
}
Finally, the meat of where I think the issue might be, and some explanation of what I've tried. When an option is added to the control, a different table is queried to see if there's an additional ascx that must be loaded into the placeholder. This happens in the method pointed to by OnItemCreated in the Repeater:
protected void OnOptionAdded(Object sender, RepeaterItemEventArgs e)
{
if (e.Item == null || e.Item.DataItem == null)
return;
short optionID = ((Option)e.Item.DataItem).OptionID;
OptionControl optionControl = GetControlForOptionFromDB(optionID);
if (optionControl == null)
return;
CustomOptionControl control = (CustomOptionControl)this.LoadControl(optionControl.Path);
control.ID = "CustomControl" + optionID.ToString();
TableRow tableRow = new TableRow();
tableRow.ID = "CustomControlTR" + optionID.ToString();
tableRow.CssClass = "TestConfiguration";
TableCell tableCell = new TableCell();
tableCell.ID = "CustomControlTC" + optionID.ToString();
tableCell.ColumnSpan = 3;
e.Item.FindControl("optionConfiguration").Controls.Add(tableRow);
tableRow.Cells.Add(tableCell);
tableCell.Controls.Add(control);
}
So all of the above "works" in that I see the control on the page, the lists work correctly, and stuff like that. When I click the "Submit" button, I see the configuration (for the sake of this example, let's just say it's a single checkbox) in the Request form variable. However, setting a breakpoint in my callback method on the child page, the CustomOptionControl does not appear to be in the RepeaterSelectedOptions. Only the Option is present.
I have tried at least the following, and more (but I honestly can't recall every step I've tried):
adding a call to RefreshOptions to an overridden LoadViewState
after the call to load the base
doing my initial Repeater binding
in Page_Init instead of Page_Load
different orders of adding the table row, cell, and custom controls to each other and the main
page
How should I be structuring this page and its necessary databinding events so that I can make something like the commented lines in the following code work? When I break at the start of the method and look through the RepeaterOptions.Controls, the CustomOptionControls are gone.
protected void OnSubmit(int configID)
{
//List<CustomOptionControl> optionsToInsert = find CustomOptionControls in RepeaterOptions (probably an iterative search through the Controls);
//foreach (CustomOptionControl control in optionsToInsert)
//{
// control.AddOptionToDatabase(configID);
//}
}
I'm not sure what changed, maybe it was taking the break to rubber duck debug using all of the above. I've gone back and tried tweaking some of the things I had before (order of insertion, which call to use, etc) to see if they make a difference, but either way, the Control is now being persisted in the ViewState properly with the above code. It is available on postback from the master page call so long as the following is added (bullet #1 of what I tried before):
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
RefreshOptions();
}
Earlier, savedState was only showing the List<int> added to it to maintain selected options. At some point in tweaking and debugging, I saw that the controls I created were now in the viewstate, and adding a RefreshOptions call worked. This means on postback for add/remove there are two calls to RefreshOptions, but I can either work around that or ignore it, since behavior is still correct. Thanks for looking!
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.
I have the following code in my aspx page:
<asp:Button id="display_button" runat="server" Text="Display" OnClick="Button1_Click" />
<asp:Button id="edit_button" runat="server" Text="Edit" OnClick="Button2_Click" />
<asp:Button id="save_button" runat="server" Text="Save" OnClick="Button3_Click" Visible="false" />
<asp:MultiView id="MultiView1" runat="server" ActiveViewIndex="0">
<asp:View id="View1" runat="server">
<asp:FormView id="view_program" runat="server">
<ItemTemplate>
<%# Eval("status").ToString().Trim() %>
</ItemTemplate>
</asp:FormView>
</asp:View>
<asp:View id="View2" runat="server">
<asp:FormView id="edit_program" runat="server">
<ItemTemplate>
<asp:DropDownList id="p_status" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:FormView>
</asp:View>
</asp:MultiView>
and the following functions attached to the buttons in the code-behind page:
protected void Button1_Click(object sender, EventArgs e)
{
MultiView1.SetActiveView(View1);
save_button.Visible = false;
}
protected void Button2_Click(object sender, EventArgs e)
{
MultiView1.SetActiveView(View2);
save_button.Visible = true;
}
protected void Button3_Click(object sender, EventArgs e)
{
DropDownList p_status = edit_program.FindControl("p_status") as DropDownList;
var status = p_status.SelectedValue;
Label1.Text = status;
//save_button.Visible = false;
//MultiView1.SetActiveView(View1);
}
The idea being, that there are two views, the first displays the information, if the user wants to edit the information, they click button 2 which changes the view to the edit mode, which has the controls (drop downs, text fields, etc). It also makes the 'save' button appear.
What I am trying to make happen is, when the save button is clicked, it will grab all of the values from the various fields, update the object and then update the database. Then it would flip back to view1 with the updated info.
Problem is, as you can see in void Button3_Click, I try grab the values from the control, p_status, but it only gets the original value. example, the menu has three values, 'Green', 'Yellow', and 'Red'. Green is the default value and is selected when view2 is displayed. However, if I select Yellow or Red, and click save, rather than the label being updated to display one of those two values, it always displays Green.
Any ideas?
edit: page load function per request below
protected void Page_Load(object sender, EventArgs e)
{
try
{
Person myPerson = new Person(userid);
TestProgram myProgram = new TestProgram(id);
List<TestProgram> program = new List<TestProgram> { myProgram };
view_program.DataSource = program;
view_program.DataBind();
edit_program.DataSource = program;
edit_program.DataBind();
DropDownList p_status = edit_program.FindControl("p_status") as DropDownList;
p_status.Items.Add(new ListItem("Green", "Green"));
p_status.Items.Add(new ListItem("Yellow", "Yellow"));
p_status.Items.Add(new ListItem("Red", "Red"));
//myProgram.Status = "Red";
p_status.SelectedValue = myProgram.Status;
}
catch (Exception ex)
{
Response.Write(ex);
Label1.Text = ex.ToString();
}
}
Whoops...missed a little someting.. my
bad
when asp.net is not behaving as expected this is your best friend: MSDN: ASP.NET PAGE LIFECYLE
Upon Further Review...
there are a couple of problems here. your drop down list control with an id of "p_status" is contained inside a multiview (I forgot about what that meant...) you need to move the code to populate p_status into pre-render after checking to see if Multiveiw1.ActiveView = View2. Since it will always be a post back you need to bind values late in the page cycle