I have two asp:Labels, the first of which is replaced with a few buttons and the second with a list of items.
I want to click on the buttons to filter the items.
The contents of the buttons are added programmatically by replacing the text with html and works fine.
asp:
<form id="form1" runat="server">
<asp:Label id="filters" runat="server" Text="Filters here"/>
<asp:Label id="itemList" runat="server" Text="List of items here"/>
</form>
resultant html of filters label:
<input type="submit" onclientclick="Load_Items(0)" runat="server" value="First"/>
<input type="submit" onclientclick="Load_Items(1)" runat="server" value="Second"/>
<input type="submit" onclientclick="Load_Items(2)" runat="server" value="Third"/>
relevant c#:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Load_Items(0);
}
}
public void Load_Items(int filterType)
{
//code to load items (pseudo below)
for each row in list
if filterType = itemType
build string
replace second label with string
}
On page load everything happens just as I want it to with the contents being filtered by the first item (hence Load_Items(0)), and if I manually change the 0 to another number in Page_Load, it filters by the other types, but if I click the buttons which are programmatically added, nothing happens other than what looks like the page refreshing.
I know the post back check is working by adding a text replacement before and inside it.
I've also added an asp:button to make sure it's not something to do with the way the buttons are added as below (with some extra things recommended from searches):
<asp:Button runat="server" CausesValidation="False" onclientclick="Load_Items(2); return false;" text="Submit" />
So what could be the issue?
The OnClientClick property specifies the javascript to run in the browser when the button is clicked. Since you probably don't have a javascript function called Load_Items, this will generate a script error, and the button will then cause the form to post back.
The server-side Click event will fire on the server, but doesn't allow you to pass a parameter. You will only get the button instance and an empty EventArgs instance.
You might be better off using the Command event, combined with the CommandArgument property.
<asp:Button runat="server" CommandArgument="2" OnCommand="Load_Items" ...
The event handler would use the CommandArgument property of the CommandEventArgs to access the argument from the clicked button:
protected void Load_Items(object sender, CommandEventArgs e)
{
Load_Items(Convert.ToInt32(e.CommandArgument));
}
Well, that's the common problem which I think every asp.net developer deals some time. The common part of it, that asp.net event system doesn't work, as windows forms.
Page object, and all controls on that page, have lifecycle events, that are triggered during any request, even when it's from update panel.
As you create those controls by code, you have to keep in mind, that all events for those controls should work as part of Page object. That's why you have to create those object in Page_Init event, before all other control's event would be triggered.
Please also keep in mind that you have to create those controls as asp.net objects:
var btn = new Button();
But not by simply adding html markup. And you have to recreate them on each request, following that one, when they were created.
Please take a look on my another answer.
Related
I have a problem understanding where I am losing the ability to catch the PostBack trigger or simply the handler method of serverclick in this setup and placing breakpoints only shows the PostBack occurs on rendering (Page_Load) but not after submit button is clicked. Allow me to elaborate on the scenario and keep in mind I have limited ability to change the way it is done and must figure out a way to make it work with minor changes using ASP.net / C# / WebForms / Bootstrap 4.5 per the client.
Dashboard.aspx [main page] has a simple (top nav showing the logo and logged in user's name with a signout drop down, sidebar menu which upon individual click will load into a display area) and the display area is an asp:PlaceHolder element:
<asp:PlaceHolder runat="server" ClientIDMode="Static" ID="TheScreen">
When the [main page] is loaded, it makes an API call and processes a collection of objects received and generates adding a series of UserControl Control1 objects (this can be zero items or n items) let's call this [default state] of the landing so we can refer to it later.
Each of the Control1 (which have unique IDs) have 3 buttons to perform 3 different actions.
<a class="btn btn-primary btn-sm" id="action1" runat="server" onserverclick="Command_Click">Do First Action</a>
<a class="btn btn-primary btn-sm" id="action2" runat="server" onserverclick="Command_Click">Do Second Action</a>
<a class="btn btn-primary btn-sm" id="action3" runat="server" onserverclick="Command_Click">Do Third Action</a>
Command_Click simply bubbles up an event handler to be processed by Dashboard.aspx
public void Command_Click(object sender, EventArgs e)
{
CommandClicked?.Invoke(sender, e);
}
action1 is handled on the fly with a confirmation modal which contains a simple button that runs onserverclick and reloads the [default state] having deleted that item using an API call.
<button type="button" class="btn" id="do-action1" runat="server" onserverclick="finish-action1">Do It</button>
This all works as expected.
action2 is handled by [main page] where it clears the PlaceHolder's controls and then dynamically creates and loads another UserControl which displays long form details of that object.
UControl2 theObject = (UControl2)Page.LoadControl("~/path/to/Control2.ascx");
TheScreen.Controls.Clear();
TheScreen.Controls.Add(theObject);
This all works as expected also.
action3 button is the one that is giving me the problem and just like action2 it is handled on [main page] where it clears the PlaceHolder's controls and then dynamically creates and loads another UserControl which provide a simple form with one button on it.
UControl3 otherObject = (UControl3)Page.LoadControl("~/path/to/Control3.ascx");
TheScreen.Controls.Clear();
TheScreen.Controls.Add(otherObject);
The form is very simple, contains a <select> elements whose <option> are populated using an asp:Repeater based on an API call that provides the DataSource for it. It also has a simple <input> textbox field and lastly a submit <button>.
<select id="..." name="..." required="required">
<option disabled selected value="">select payment account</option>
<asp:Repeater ID="..." ClientIDMode="Static" runat="server" ItemType="model.namespace">
<ItemTemplate>
<option value="<%#: Eval("...") %>">
<%#: Eval("...") + " " + Eval("...") %>
</option>
</ItemTemplate>
</asp:Repeater>
</select>
<input id="..." name="..." type="text" required="required" runat="server" />
<button id="finish-action3" class="btn" runat="server" onserverclick="do-action3">Do It</button>
What I don't get is why finish-action3 is not performing the actions of the handler method do-action3, it simply refreshes back to the [main page] with the initial state that we started from with the initial Control1s being rendered and nothing else, no PostBack either.
I have searched extensively and found nothing addressing this specific scenario and what I have found, everyone keeps suggesting using asp:Button but that makes no difference for me in the behavior.
As written above, clicking finish-action3 button which is part of Control3 will not cause the basic HTML5 validation and does not trigger the do-action3 handler method and simply refreshes back to the [main page] where we started.
If I add do-action3 to the onsubmit attribute OR add type=submit, I get the validation but once it passes validation, the same behavior, nothing but load the [main page].
Changing the element to an asp:Button made absolutely no difference. The validation is triggered without anything special (like using onsubmit attribute or having a type=submit but once it is validated the same behavior, never calls do-action3 nor does it even trigger a Page_Load/PostBack on control3 just back to the [main page].
I suspect I am overlooking some event or is not bubbling and is getting lost in the process but I can't think what it is and where and why. Why doesn't the form that is last on the screen loaded by Control3 "submitted" by that button click not generating a PostBack or running the onserverclick handler method and simply refreshing to the main default state page, what am I missing here?
Any help would be appreciated as I have been banging my head against the wall trying to figure out what I am missing. I never encountered this in MVC or Core and it is making me crazy.
Let's simplify. Basically, what you are saying is that the following does not work because the btnFinishAction3_Click method of the dynamically-added Control3 user control is not firing:
Default.aspx (main page):
<asp:PlaceHolder runat="server" ID="plhPlaceHolder1"></asp:PlaceHolder>
<asp:Button runat="server" ID="btnAction3"
Text="Do Third Action"
OnClick="btnAction3_Click"/>
Default.aspx.cs:
protected void btnAction3_Click(object sender, EventArgs e)
{
AddControl3();
}
private void AddControl3()
{
Control3 objControl3 = (Control3)Page.LoadControl("~/Control3.ascx");
plhPlaceHolder1.Controls.Clear();
plhPlaceHolder1.Controls.Add(objControl3);
}
Control3.ascx:
<asp:Label runat="server" ID="lblMessage"></asp:Label>
<asp:Button runat="server" ID="btnFinishAction3"
Text="Finish Action 3"
OnClick="btnFinishAction3_Click"/>
Control3.ascx.cs:
protected void btnFinishAction3_Click(object sender, EventArgs e)
{
lblMessage.Text = "Finished Action 3.";
}
This is normal behavior. After postback the dynamically added user control does not exist and the event is "ignored". In ASP.NET Web Forms, every dynamic control must be re-added to the page after every postback. So, you need something like the following:
Default.aspx (main page):
<asp:PlaceHolder runat="server" ID="plhPlaceHolder1"></asp:PlaceHolder>
<asp:HiddenField runat="server" ID="hifControl3Loaded"/>
<asp:Button runat="server" ID="btnAction3"
Text="Do Third Action"
OnClick="btnAction3_Click"/>
Default.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (hifControl3Loaded.Value == "1")
{
AddControl3();
}
}
protected void btnAction3_Click(object sender, EventArgs e)
{
AddControl3();
hifControl3Loaded.Value = "1";
}
private void AddControl3()
{
Control3 objControl3 = (Control3)Page.LoadControl("~/Control3.ascx");
plhPlaceHolder1.Controls.Clear();
plhPlaceHolder1.Controls.Add(objControl3);
}
In other words, you need to add Control3 to the main page at every postback on Page_Load once the user has decided to add it by clicking the btnAction3 button in the first place.
I have an asp:Button that is in a JavaScript dialog window. It has an OnClick event called DialogWindowButton_Click as you can see in the code below. The event is not firing and I have put breakpoints in the C# file and it is not even entering the function. I'm not sure why and have looked at other forum posts to try to figure this out. I have 1) deleted the button and recreated the button and OnClick event themselves (this didn't work), and 2) added CausesValidation="False" to the asp:Button tag. Neither avenue has worked. What I have is shown below:
<div style="margin:auto; width:100px; padding-bottom:15px;">
<asp:Button ID="DialogWindowButton" runat="server" Text="Save Entry"
OnClick="DialogWindowButton_Click" CausesValidation="False"/>
</div>
Then in the C# file, I have:
...
protected void Page_Load(object sender, EventArgs e)
{
}
protected void DialogWindowButton_Click(object sender, EventArgs e)
{
DialogWindowButton_ClickHelper();
...
}
protected AddressBookEntry DialogWindowButton_ClickHelper()
{
...
}
...
I have the correct file for the CodeBehind tag as well as for the Inherits tag. In the C# file you can see that the original OnClick event calls on a helper function defined directly below it, but breakpoints in the top of DialogWindowButton_Click() aren't being reached. There are no build errors either. Could there be something else I'm missing? Thank you!
You need to set UseSubmitBehavior to false (default is true):
<asp:Button ID="DialogWindowButton" runat="server" Text="Save Entry"
UseSubmitBehavior="False" OnClick="DialogWindowButton_Click" CausesValidation="False" />
From Reference:
Use the UseSubmitBehavior property to specify whether a Button control
uses the client browser's submit mechanism or the ASP.NET postback
mechanism. By default the value of this property is true, causing the
Button control to use the browser's submit mechanism. If you specify
false, the ASP.NET page framework adds client-side script to the page
to post the form to the server.
I am unfamiliar with C#/ASP/.NET (learning as I go), so it is very likely that I am going about this in an inferior way, in addition to the problems with my current way of doing this. I will try to be as clear as possible (maybe overly so...).
I have a form with a textbox to take in a list of server hostnames, separated by line returns. Upon pressing the submit button, it uses PostBackUrl="~/btil_Info.aspx". In btil_info.aspx.cs codebehind, I get the info from said textbox (hostnames_tb) from the previous form in Page_Load() using:
string hostnames = ((TextBox)Page.PreviousPage.FindControl("hostnames_tb")).Text;
Within Page_Load(), I loop through this list of hostnames and build a form containing several fields for each host (a few textboxes and a dropdown menu for each host). After filling out these fields, upon pressing the Submit button here which calls Submit_Click() in the same codebehind, the page appears to reload because Page_Load is called again before Submit_Click() is executed. In doing so, the the filled form data is lost and the list of hostnames is also lost.
At an earlier stage in development, I had this all on the very first form page, and the submit button didn't call PostBackURL, it simply called Submit_Click(), which worked perfectly fine. The page didn't reload, the form stayed on the page, and I didn't lose data. But as it is now, the button works the same way. The only difference (that I see) being that this troublesome page is reached via the previous form calling PostBackURL.
I don't believe there's any point where anything should be requesting a page refresh/reload. I don't actually care if the page refreshes/reloads as long as the form data is posted and as long as the list of hostnames from the previous form is also retrievable. I just need to be able to access the form data and list of hostnames so that I can pass it to another method of mine that will update a SharePoint list (the code for that part is already working, though). I tried making the hostnames string a class variable in the 2nd codebehind (btil_Info.aspx.cs) and setting it as soon as soon as the page loads if it is empty, but apparently it does not persist over the page reload and is set back to null.
Here's some snippets of code that I hope will be of some help:
First page, add_BTIL.aspx:
<form id="form1" runat="server">
<div>
<asp:TextBox ID="hostnames_tb" runat="server" Rows="20" TextMode="MultiLine" Width="225px"></asp:TextBox>
<br />
<asp:Button ID="Submit" runat="server" PostBackUrl="~/btil_Info.aspx" Text="Submit" />
<br />
<asp:Literal ID="result" runat="server"></asp:Literal>
<br /><br />
<textarea id="hostnames_textarea" cols="25" rows="20" name="hostnames" title="Hostnames"></textarea></div>
</form>
First page codebehind, add_BTIL.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Submit_Click(object sender, EventArgs e)
{
string hostnames = hostnames_tb.Text;
/*
* Etc.
*/
}
Second page, btil_Info.aspx:
<form id="hosts_form" runat="server">
<p>
<asp:Button ID="Submit" runat="server" Text="Submit" OnClick="Submit_Click" Height="26px" UseSubmitBehavior="False" /><br />
<asp:Literal ID="result" runat="server"></asp:Literal><br />
</p>
<br />
</form>
^ In this form, I read somewhere in my searches that UseSubmitBehavior="False" would prevent a page reload, but it did not help. I didn't use it in my earlier version anyway, and did not have this issue.
Second page codebehind, btil_Info.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
string hostnames = ((TextBox)Page.PreviousPage.FindControl("hostnames_tb")).Text;
// etc.....
}
protected void Submit_Click(object sender, EventArgs e)
{
// etc.....
}
Many thanks for any help!
If you're posting from add_BTIL.aspx to btil_Info.aspx then the Submit_Click function in file add_BTIL.aspx.cs will never be called.
Based on the limited markup you've given us for the btil_Info.aspx page...
If you aren't rendering your host names list inside of server controls inside the form id="hosts_form" then when you hit the submit button nothing is going to be posted to your Submit_Click function.
Personally I don't like post from one page to another so here are some suggestions below.
If you want to do a multi-page wizard then you might consider the asp.net wizard control.
Or if you want to keep it simple, use two asp Panel controls and show the first one, post the data, and then hide the first and show the second one.
How can I check whether a particular button was clicked or not in ASP.NET?
I think I need to perform some operation on Page_Load. This shouldn't be entering to Button_Click event to find. Is there any way that I can find where it was clicked or not on Client Side and take it to Page_Load?
Background: Basically __EVENTTARGET and __EVENTARGUMENT , These two Hidden controls are added to the HTML source, when ever any autopostback attribute is set to true for any of the web control.
The __EVENTTARGET hidden variable will tell the server ,which control actually does the server side event firing so that the framework can fire the server side event for that control.
The __ EVENTARGUMENT variable is used to provide additional event information if needed by the application, which can be accessed in the server.
So we can easily get the control causing postback using:Request.Params.Get("__EVENTTARGET");
PROBLEM:
The method: Request.Params.Get("__EVENTTARGET"); will work for CheckBoxes, DropDownLists, LinkButtons, etc.. but this does not work for Button controls such as Buttons and ImageButtons
The Button controls and ImageButton controls does not call the __doPostBack function. Because of this, the _EVENTTARGET will always be empty. However, other controls uses javascript function __doPostBack to trigger postback.
So, I will suggest to do something as below. Add an OnClientClick property to the buttons. Also, define a hiddenField in your Markup, whose value will contain the actual button causing postback.
<asp:Button ID="Button1" runat="server" Text="Button"
OnClientClick = "SetSource(this.id)" />
<asp:ImageButton ID="ImageButton1" runat="server"
OnClientClick = "SetSource(this.id)" />
<asp:HiddenField ID="hidSourceID" runat="server" />
On the OnClientClick property of the Button and ImageButton Call the SetSource JavaScript function
<script type = "text/javascript">
function SetSource(SourceID)
{
var hidSourceID =
document.getElementById("<%=hidSourceID.ClientID%>");
hidSourceID.value = SourceID;
}
</script>
Here onwards, you can very easily check in your Page_Load as to which Control caused postback:
if (IsPostBack)
{
string CtrlName;
CtrlName=hidSourceID.Value;
}
I just got the same trouble, have to do some logic judgement in the Page_Load method to treat different event(which button was clicked).
I realize the arm to get the as the following example.
The front end aspx source code(I have many Buttons with IDs F2, F3, F6, F12.
<Button Style="display: none" ID="F2" runat="server" Text="F2:Cancel" OnClientClick="SeiGyo(this)" OnClick="F2_Click" />
<Button Style="display: none" ID="F3" runat="server" Text="F3:Return" OnClientClick="SeiGyo(this)" OnClick="F3_Click" />
<Button Style="display: none" ID="F6" runat="server" Text="F6:Run" OnClientClick="SeiGyo(this)" OnClick="F6_Click" />
<Button Style="display: none" ID="F12" runat="server" Text="F12:Finish" OnClientClick="SeiGyo(this)" OnClick="F12_Click" />
The back end aspx.cs source code, what I need to do is judge which button was clicked when Page_Load was triggered. It seems a little stupid, but works.
In your situation, the button be clicked will be added into dic. I hope that will be helpful to some one.
Dictionary<string, string> dic = new Dictionary<string, string>();
foreach(var id in new string[]{"F2","F3","F6","F12"})
{
foreach (var key in Request.Params.AllKeys)
{
if (key != null && key.ToString().Contains(id))
dic.Add(id, Request[key.ToString()].ToString());
}
}
The UniqueID of the button will be in Request.Form["__EVENTTARGET"]
This question is already answered at: ASP.NET : Check for click event in page_load
You can try using the hidden field. Make the client side event on the OnclientClick event and try setting the value of hidden field, may be true or false depending on the condition.
And on the page load you can check the value of Hiidden field.
function click()
{
// set the hidden field here
}
And on the page load, simply check the value.
if(HiddenFieldName.Value=="true")
{
//perform the action
}
private bool button1WasClicked = false;
private void button1_Click(object sender, EventArgs e)
{
button1WasClicked = true;
}
if ( button1WasClicked== false)
{
//do somthing
}
i have the situation: i'm showing many lines from the DB on the page. just creating dynamic lines (<% foreach (res in DBVar) %>). Every line has a button. every button use just 1 OnClick method. I really dont care of the name(value) of these buttons, but i can't take, how can i pass a parameter (e.g. a ID of a line from DB (res.ID)) from the .aspx page to OnClick Method. (Using LINQ to SQL)
I tried to take my param to the name(value) of a button with "<input type="button" value="<%= "string"+DBVar.ID%>" and so on. the runat=server even can't take the variable on the name(value) coz of this i used just input method.
Use OnCommand event and assign CommandArgument
<asp:Button ID="Button1" runat="server" Text="Submit" CommandArgument='<%= res.ID %>' OnCommand="Button1_Click" />
in code behind
protected void Button1_Click(Object sender, CommandEventArgs e)
{
string ID=e.CommandArgument.ToString();
}
Set the CommandName and CommandArgument of the buttons during the bind and read them back out on your onclick event.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.commandname.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.commandargument.aspx
check this link
passing dynamic values for each row in listview
he has done same thing and it also shows how to access the values in code behind