I need a DropDownlist which can cause SelectedIndexChanged event but do not do post back(do not need page_load event when ddl index changed).
After looking into solutions in Stack here is my code:
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:DropDownList ID="a" runat="server" OnSelectedIndexChanged="a_SelectedIndexChanged">
<asp:ListItem Text="a"></asp:ListItem>
<asp:ListItem Text="b"></asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="a" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
and C# code:
public partial class TestApp : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
txtDate.Text = DateTime.Now.ToString("yyyy-MM-dd");
}
protected void a_SelectedIndexChanged(object sender, EventArgs e)
{
int a = 1;
}
}
But the break point in put in a_SelectedIndexChanged never gets fired. What could be the issue here?
As you see the above is an accpeted answer on stack, then how its not workining:
How DropDownList's SelectedIndexChanged() works without PostBack?
Edit: While the below answer correctly explains that page_load should fire all the times. I still want to know why SelectedIndexChanged never gets fired. So what EventName="SelectedIndexChanged" in the Trigger does?
While a update panel (UP for this post) will "ajax" up, and ONLY post-back that part of the page. (and code behind for that UP can only update controls in that UP?).
The page load even will ALWAYS fire each time.
In fact, page load fires for any button click, post-back, changed event or anything at all.
Thus, as a STANDARD design pattern?
If your page load event loads up a drop down list, listbox, gridview etc.?
Then you ONLY want that code to run on the "real" first page load.
As a result, the last 200+ web pages I have built?
They have this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
Repeater1.DataSource = General.MyRst("SELECT * from tblHotelsA");
Repeater1.DataBind();
}
So, in above example, I am loading up a "repeater" with some data.
However, REGARDLESS if you using a UP or not?
Your page load code, first time MUST quite much do the above.
If you don't do the above, then simple code that say loads up a dropdown list (combo box) will fire each and every time.
If then if you select a combo box value, then say click a button on the page?
the page load fires first, AND THEN your button code. But, if page load re-loads the combo box, then you lose your selection.
So, update panel or not?
Your page load event fires each and every time - including when you use that UP.
So, even without a UP, it stands to reason you can't really even build a working web page if you page load event EVERY time loads up data and controls, since then any changes to such controls will be "blowen" out, and over written each time.
So, while the UP results in what "appears" to not be a post-back?
it is in fact what we call a partial post-back. And the standard page life cycle does occur, but ONLY the bits and parts in the UP are posted back to the server, and in that case, ,then the code behind of course can only change/modify the controls inside of that UP (quite much the whole idea).
So, while the UP will "eliminate" the browser spinner, and while it KEEP your current scroll position on the page?
Make no mistake here - that partial post-back is in fact a page post-back, but just a smaller one, and one that looks to the user that no post-back occurred.
so, it is fine and dandy to have auto-post back for that dropdown list. (and you do NOT even require a trigger, and I suggest you remove the trigger, and put back in the auto post-back.
So, the UP does not "eliminate" the post-back, but hides this from the end user, and for the most part it can be rather nice, quick, and of course will not refresh the whole page. But, page load still fires each and every time.
So, for your code to work correctly, and only fire on the VERY first time, and what amounts to the "real" first page load?
Then your code has to be this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
txtDate.Text = DateTime.Now.ToString("yyyy-MM-dd");
}
}
Now, if you really don't want any kind of post back?
Then you have to start writing some JavaScript, and start making ajax calls to some web methods.
Now, a ajax call certainly is "less" of a post-back then a UP, which in turn is less of a full page post-back.
If you absolute have a "poor" page design in which a UP can't be used, then yes, you have to start writing and adding client side js code, and thus you can setup a ajax call, and no page post-back will occur. it is quite rare that a UP can't be used, but ajax calls are better, but they also take significantly more time to setup, write and adopt.
However, keep in mind that a ajax call to server code does not have any use of controls on the page. So, you have to return values, and then have your js code update the controls on the page.
So, if a UP can suffice, then that's the least effort. The fantastic part is you don't have to write up and wire up a whole bunch of JavaScript code in place of using that UP.
For sure, a ajax call is best, but that takes more code, more time, and has more moving parts (and requires JavaScript skills on your part). Often this extra effort and time (cost) can't be justified to adopt ajax calls for the page, so a UP is a good middle ground. it is somewhat of a compromise compared to ajax calls, but it boatloads of less work, and thus often a great choice cost and time wise. In other words, in most cases a UP is "good enough".
Related
I am working on a legacy service that has 30 aspx pages with years of business logic
There is a parent aspx page which acts as a base page that the above aspx pages inherit from.
I need to add a Response header and I am having trouble finding the right place to add it to the ParentPage.aspx.cs so that it gets applied to all aspx pages.
Ideally I would want to add after PageLoad() is done for the the data to be available to add to the header.
I tried using the onPreRender() and onLoadComplete() stages to add the header. But it is not guaranteed that this would get called because the aspx pages have logic that do Response.Redirect() Because of the redirect onPreRender() and onLoadComplete() do not get called. I would not be able to change the logic on redirects
However UnLoad() does get called all the time. But response cannot be altered in the UnLoad() stage
Are there any suggestions where the header to the response could be added in the ParentPage.aspx.cs ?
Do you have a master page?
Just drop in the code to add a header in the page load event.
I mean, code can fill out text boxes, change things, and then you can toss in a new header - the order of such events don't matter.
So, if you have a master page that all pages use?
Then do this in site master:
protected void Page_Load(object sender, EventArgs e)
{
Response.AddHeader("Test", "My Test Value");
}
So, it not clear if you have a master page, but page load triggers in site master each time any navigate to any page occurs. And also the above runs each time any post-back or button click occurs on any page.
So, just add the header in the page load in master.
The above thus results in this:
So, it don't matter if you add the header at the start of code, or end of code say in a page. The other code behind can run, make changes to the "DOM" via code behind, but everything WAITS 100% until ALL of the code behind is done running, and THEN and only THEN does the WHOLE page make the trip back down to the client side, the client side re-loads the page, re-starts any JavaScript code (and re-sets, all JavaScript values and variable to fresh start), and then the page life cycle is complete, ready to start again on the next button click etc. And on the server side, the page class is disposed, and all its variables etc. also goes out of scope (hence the term state-less). So, both ends, including client side js code variables are re-set in this process.
So, in fact the "order" or what event you use to inject/add that header? it really don't matter when it runs, only as long as it runs at "some point" in time during that whole page life cycle on the server.
In fact, what I am saying, it is REALLY hard to mess this up, since just about any event can add the header - but page load looks to be as good as any event here.
Edit: The page load event
You thus should see/be able to add the event to page master like this:
I'm working with ASP.NET webforms and I'm wondering if it is possible to change/ignore the PostBackUrl so it won't change pages.
My button:
<asp:Button ID="continuebtn" OnClick="Continuebtn_Click" runat="server" PostBackUrl="~/client/profile.aspx" CssClass="btn btn-success btn-sm" Text="Continue"/>
And the OnClick function is:
protected void Continuebtn_Click(object sender, EventArgs e)
{
//some code
if(condition == false)
//change the url from PostBackUrl so it won't change pages
else
//keep the current Url
}
I've tried :
continuebtn.PostBackUrl = "";
continuebtn.Attributes["PostBackUrl"] = "return false";
continuebtn.Attributes.Remove("OnClick");
continuebtn.Attributes.Add("OnClick","return false");
continuebtn.OnClientClick = "return false;";
add return; to if
I tried to remove the PostBackUrl from the button and add it from the code behind with continuebtn.PostBackUrl = "~/client/profile.aspx" but it didn't work either.
There are two big reasons to use post-back URL in place of say using a code behind click event and say then response.Redirect("some web page").
First up, post-back url passes the previous page!!!!!
So, if you have say a text box and a button like this: (or evne a grid view)
Now you can use code behind to jump to the next page, or you can use/set/have post-back url set.
If you use post-back URL. Then you don't need to write a code behind stub, and you ALSO get use of previous page in the next page on-load event (you ONLY can pick up previous page in load - first time).
eg:
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
{
TextBox tbox;
tbox = Page.PreviousPage.FindControl("TextBox1");
Debug.Print("Text box = " + tbox.Text);
TextBox1.Text = s;
}
}
}
so post-back url = a great way to pass/get at/use the previous page values with find control. Now if you not needing to do this, then you probably should not use post-back URL, since you are bulking up the payload for the next page (it will contain the current page, and you have as noted use of "previous page". However, it is a fantastic way to avoid parameters and/or cluttering up session() just to pass a bunch of values. Just use post-back URL and then like "magic" then previous page can be used. if you don't use post-back URL then previous page is null and not valid.
And if you place two buttons on the page? Can you set postback url? Sure you can set that control, text box or do anything you like - but do keep in mind that the code behind is running AFTER a post-back, and it will of course be too late to change a button that CAUSED the post back.
So, you can certainly do this in button2 click even to change button1:
protected void Button3_Click(object sender, EventArgs e)
{
Button1.PostBackUrl = "";
}
So in above, button3 click event and code behind wiped out the post-back URL of button one. Or we can of course set the url to anything we want.
Now, the code behind is done, page is rendered and THEN sent back down to the browser with the above change. If user hits button1, then no postback url exists - we blew it out with the above code.
However, in the SAME button event? no, it is too late to change or modify the post-back.
In that case, and if you need "conditional" jump? Then you need to delete and remove the post-back url, and simply put the logic you need to determine the ya, or nay jump based on the code behind for that click event.
HOWEVER - and a BIG WHOPPER however? If you JUST use a response.Redirect("some web page") in that code behind, then you DROPPIGN THE MAIN reason as to why the developer used post-back URL in the first place. That main, big, huge, large reason is that post-back URL gives the next page in line FULL USE of the previous page values with "previous page". If you do NOT use post-back URL, then you can't use previous page to pass all those values and inspect and get and grab control values from the previous page.
So what if you really did need the "abilities" that post-back URL provides (that ability of course is "previous" page in the next page load!
In that case, then you have to use Server.Transfer() in that code stub to get use of previous page in the next page that loads.
So, regardless:
You can't change post-back URL in the same button code event - it is too late.
If you are going to then put the logic in the code event? Then be VERY VERY aware that if you use a response.Redirect("some web page"), then you may VERY well be breaking the functionally of why in the first place the developer used post-back url (to have use of "previous page".
Your suggested idea to modify client side the post-back url in one button click, and then do a js "click" of that button you just changed the post-back url should also work (good idea!!!).
But, I would thing that just using a code behind stub in the click event, and then the code can choose to navagate or jump to the next page based on that code? Right?
However, if you do that, then you will break the "features" of post-back URL in pasing page prevous.
In that case? Then you need to use a server.Transfer("to next web page") in place of response.Redirect("to next web page), since a server.Transfer will give you use of "page previous" in the next page load event JUST LIKE post-back URL does!
Of course with a server.Transfer, you will note that the web page URL does not change or update - and this is a fall out of having to do this. (and may, or may not matter to you).
I have a Update Panel inside a User Control i use on 2 pages in my website
Both pages use the same MasterPage, ScriptManger is declared in the MasterPage.
Both pages call the UC the same way:
<uc:SearchCube runat="server" ID="searchCube" />
in the Update panel i have many RadioButtons that on change generate a server side event that fill dropdown in the update panel and update the panel
protected void SearchCategoryChanged(object sender, EventArgs e)
{
FillDropdowns();
SearchOptions.Update();
}
Update Panel is set like this:
<asp:UpdatePanel ID="SearchOptions" runat="server" UpdateMode="Conditional"
hildrenAsTriggers="true"/>
Each RadioButton is set like this:
<asp:RadioButton ID="RadioButton1" GroupName="SearchCategory" runat="server"
AutoPostBack="true" OnCheckedChanged="SearchCategoryChanged" Text="Text"/>
I also have an AsyncPostBackTrigger on each Radio Button Controller
The problem i have is that on one page when i call the Update() function the panel is updated and Page_Load is triggered which causes the UC to refresh and reload the default settings of the UC
I can see in DEBUG mode that on the working page Update() does not generate Page_Load.
Can anyone explain to me why this is happening?
Everytime a request goes to the server, it executes the Page_Load event.
What you need to do is make sure you have a PostBack validation on all your pages:
protectec void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
//Not a postBack: Normal page load
//Init your page here
}
else
{
//It's a PostBack (from a command).
//Do nothing or init stuff your all your commands.
}
}
If you put some breakpoints in your Page Load and your SearchCategoryChanged method, you'll be able to see what the pipeline looks like.
Fixed my problem.
the problematic page is an index page that takes a few parameters in.
I have a Response.Redirect() on the page to avoid duplication of pages.
Apparently when the PostBack() is made it calls the page without any parameters and i was forcing it to be redirected into a default view since no parameters were sent to the page.
i found a lead to my problem in a Microsoft help forum that stated:
By calling Response.Write() directly you are bypassing the normal
rendering mechanism of ASP.NET controls. The bits you write are going
straight out to the client without further processing (well,
mostly...). This means that UpdatePanel can't encode the data in its
special format.
Anyway the page was reloading every time which caused it to reload the User Control with it's default values.
I have a aspx Page where I am using AJAX. like
<asp:UpdatePanel runat="server" ID="upPanelDDLProgram">
<ContentTemplate>
<asp:DropDownList ID="DDLProgram" runat="server" Width="194px" Height="18px" OnSelectedIndexChanged="OnDDLProgramChanged" AutoPostBack="true">
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
and my code behind is like
protected void Page_Load(object sender, EventArgs e)
{
//if (!IsPostBack)
//{
// BindProgramDDL();
//}
BindProgramDDL();
}
protected void BindProgramDDL()
{
List<CcProgramEntity> programEntities = FormSaleSubmit_BAO.GetAllPrograms();
DDLProgram.DataSource = programEntities;
DDLProgram.DataTextField = "Shortname";
DDLProgram.DataValueField = "Id";
DDLProgram.DataBind();
string programCode = programEntities[DDLProgram.SelectedIndex].Code;
}
protected void OnDDLProgramChanged(object sender, EventArgs e)
{
List<CcProgramEntity> programEntities = FormSaleSubmit_BAO.GetAllPrograms();
string programCode = programEntities[DDLProgram.SelectedIndex].Code;
}
the If condition is the page load event, is commented out. If I toggle the comment part of the page load event, it works perfect in both cases. My question is why is this heppening?
IsPostBack tells you if it is a second request to the page. The benefit here is if you need to do anything costly, such as a database call to fill a dropdownlist or similar, you can do it when !IsPostback, then use ViewState to retain the values.
To put it specific to your situation
Using:
if (!IsPostBack)
{
BindProgramDDL();
}
Will result in BindProgramDDL being called ONLY on the first time the page is loaded, all AJAX or other user interaction with the page will NOT call BindProgramDDL;
Without that, in place EVERY page load would call the method, un-necessarily hitting the database for the records.
If I am getting you correct .......
DropDown list has data even you are not binding it second time after post back..........its becasuse its server side control and each serverside control has its view state with it thats y its not removing data.
IsPostBack - it true when do the post back by using serverside control like dropdown, checkbox , textbox............When you load page first time this property is false but in subsequent request to same page value of this property is true. you can check msdn document for more detail about it.
It's basically saying are you visiting the page for the first time (not a post back), or has the user clicked on a control (a post back).
Useful for when you only want to run methods once when the page is initially loaded
You're code should probably look like this to achieve best results
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindProgramDDL();
}
}
I suspect that the DropDownList saves the items in the ViewState and then work with them during all subsequesnt requests. That is why your code works even if the editor's DataSource is set only when IsPostBack returns false.
PostBack event appears on every action (ajax too), except of first page load.
Page.IsPostBack
indicates whether the page is being rendered for the first time or is being loaded in response to a postback.
see http://msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx
Since you've bound your datasource the first time the page was loaded, the data are still in the viewstate and you don't need to update the control (unless the datasource has changed).
Take also into account that, since you're using ajax, you may also want to intercept if there was an 'asynchronous postback'.
See http://encosia.com/are-you-making-these-3-common-aspnet-ajax-mistakes/
I'm building an asp.net cutom control inside which I have two dropdownlists: companyIdSelection and productFamilySelection.I populate the companyIdSelection at Page_Load and in order to populate the productFamilySelection depending on the selected item in companyIdSelection.I'm using UpdatePanels to achieve this, but for some reason every time I update companyIdSelection Page_Load is being called ( which as far as I know should happen only when the entire page is reloaded ), the list is being reloaded again and the item the user selected is lost( the selected item is always the top one ).Here's the code
<asp:UpdatePanel ID="updateFamilies"
runat="server"
UpdateMode="Always">
<ContentTemplate>
Company ID:<br>
<br></br>
<asp:DropDownList ID="companyIdSelection"
runat="server"
AutoPostBack="True"
OnSelectedIndexChanged="companyIdSelection_SelectedIndexChanged">
</asp:DropDownList>
<br></br>
Product Family:
<br></br>
<asp:DropDownList ID="productFamilySelection" runat="server"
AutoPostBack="True"
onselectedindexchanged="productFamilySelection_SelectedIndexChanged">
</asp:DropDownList>
<br>
</ContentTemplate>
</asp:UpdatePanel>
protected void Page_Load(object sender, EventArgs e)
{
this.companyIdSelection.DataSource = companyIds(); //companyIds returns the object containing the initial data items
this.companyIdSelection.DataBind();
}
protected void companyIdSelection_SelectedIndexChanged(object sender, EventArgs e)
{
// Page_Load is called again for some reason before this method is called, so it
// resets the companyIdSelection
EngDbService s = new EngDbService();
productFamilySelection.DataSource = s.getProductFamilies(companyIdSelection.Text);
productFamilySelection.DataBind();
}
Also, I tried setting the UpdateMode of the UpdatePanel to "Conditional" and adding an asyncpostback trigger
but the result was the same.
What am I doing wrong?
PS:
I fixed the updating problem, by using Page.IsPostBack in the Page_Load method, but I would still want to avoid a full postback if possible
I think you misunderstand how UpdatePanels work. They DO actually do a full page postback, it's just that during the rendering stage they capture only a portion of the output and send it back in the AJAX response so the page can be updated. More info here.
So you will still need to check whether it is a postback in your page_load event and only perform your data load if it isn't one.
The update panel call back will go through the page load on every call back. In face, the pull page lifecycle (minus render and prerender) will occur. Update panels give the appearance of ajax, but your client side code still posts back to the same page - which is the problem you are describing. If you can avoid using Update Panels, I suggest you do so. Use something like jQuery instead. If not, then use this in your Page_Load
if (Page.IsCallback) { } //Do callback specific code here
else { } //Do Postback specific code here
Hope this helps. Good Luck.