AJAX Partial Page Load? - asp.net

I have a page results page (you get there after submitting your search query elsewhere) whit a whole bunch of gridviews for different type of data objects.
Obviously, some of the queries take longer than the others. How can I make each gridview render as soon as it has the data it needs?
This has been tricky for me because it must work on a postback as well as a pageload. Also, the object data sources just fire automatically on page load/postback; I'm not calling any methods programatically to get the data. Will I have to change this?

#Gareth Jenkins
The page will execute all of the queries before returning even the first update panel, so he won't save any time there.
The trick to do this is to move each of your complex gridviews into a user control, in the user control, get rid of the Object DataSource crap, and do your binding in the code behind.
Write your bind code so that it only binds in this situation:
if (this.isPostBack && ScriptManager.IsInAsyncPostback)
Then, in the page, programaticly refresh the update panel using javascript once the page has loaded, and you'll get each individual gridview rendering once its ready.

Could you put the DataGrids inside panels that have their visibility set to false, then call a client-side javascript function from the body's onload event that calls a server side function that sets the visibility of the panels to true?
If you combined this with an asp:updateProgress control and wrapped the whole thing in an UpdatePanel, you should get something close to what you're looking for - especially if you rigged the js function called in onload to only show one panel and call a return function that showed the next etc.

Related

Prevent UpdatePanel loading entire page on server

As I understand, when an UpdatePanel is updated, the entire page is rebuilt but only content inside the UpdatePanel is actually reloaded on the page.
Some parts of my page are quite slow to render (due to database calls) and I don't want all these to reload on every postback if it only needs to reload a small part of the page.
Example - At the top of the page (outside the UpdatePanel) I display a set of totals, and inside the UpdatePanel I have a grid with 'Next Page' buttons. When I click 'next', I want the grid to update but I don't want the server to query the database for all the totals again.
What's the best way to do this?
You can check if the postback is from the updatepanel. If thats the case then you just don't calculate the totals.
If you have multiple updatepanels then you can check what updatepanel did the postback by checking this:
bool isUpdatePanelPostBack
= ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID
.Equals(yourUpdatePanel.UniqueID);
if(!isUpdatePanelPostBack) {
//calculate your totals
}
If you have only one updatepanel on your page then you can just check the IsInAsyncPostback for setting the bool:
bool isUpdatePanelPostback = ScriptManager.GetCurrent(Page).IsInAsyncPostBack;
You can always check the IsAsync property of the page to exclude code blocks from running.
The standard approach would be to have a !PostBack check before running the totals logic. That way they're only calculated the first time the page loads and after that they're held in the ViewState of the control you're using to display them.
Alternatively, if you use databinding (with ObjectDataSource) then this would be handled for you automatically since the databinding would only happen the first time the page loads.

Is there a way to trigger an updatepanel without a click event?

I'm trying to load parts of a page at a time instead of doing all my calculations in the onLoad page event, then displaying all the calculations at once.
I think one of the ways to mimic a faster loading page is to separate parts of the page into updatepanels (correct me if I'm wrong in this approach). As such, I'm wondering if there is a way to execute some code in the onLoad event, display that on the page, then continue some other work in updatepanels and load those as they get completed.
UpdatePanels are a poor implementation of ajax. Since only a section of the page is being updated, it is easy (too easy) to think that you have reduced the execution time of your page. An UpdatePanel performs a postback and as such executes the entire life cycle of your page (lamely put, it will execute the PageLoad for your page and every usercontrol on your page not just the ones that are in the UpdatePanel). Unless you put lots of if !Page.IsPostBack in your code, you could actually end up slowing your application down. Also, since it is a postback, it will submit the runat='server' form that is on your page and submit every input (not just the stuff in the update panel) to the server, which means you aren't saving anything on payload and bandwidth by using an update panel.
to answer your question though, you just need to call __doPostBack('updatepanel1', ''). reference http://encosia.com/easily-refresh-an-updatepanel-using-javascript/
You can call the .Update method on the UpdatePanel. Set the UpdateMode to be Conditional and handle all of the Update panel updating by hand in code.

Changing Dynamic Controls via DropDownList on Content Page

Problem: Content Page with Wizard Control with UpdatePanel and Placeholder. Above the UpdatePanel is a DropDownList. I need to display different input controls below the drop-down list when the user changes the selection in the drop-down list. When the user clicks 'Next' on the wizard control, I need to be able to get the data out of those dynamic controls as well.
I know all the dynamic controls have to be created in the OnInit method in order to get the data back from those controls during the postback. However, when the drop-down list's SelectedIndexChanged event is fired, the OnInit method is called... then the PageLoad... and finally the handler for the SelectedIndexChanged event is called. ViewState hasn't been restored until well after the OnInit & PageLoad methods have been called, so there is no way to know what the user chose in the list box at the time OnInit is called... which exactly when I'm required to create the dynamic controls.
So... how do you solve this problem? Do you just have to write the entire page, or most of it, using JavaScript?
Thanks in advance.
I tend to use an old school method for this type of requirement. I would write all of the controls that are needed in the update panel, with their Visible property set to false. Then, on post back read the drop down's state and set the approperate controls Visible property to true. This way there is no "dynamic" controls, and due to the fact that controls whose Visible property is false are not rendered, they are not downloaded until the user should see them.
you can also use an asp:hiddenfield and set the value to a case var you mentally create. then run a small jQuery script on top to look at
$(document).on("change", "#ddlSelector", setControls);
then just make a function, for instance:
function setControls(event) {
event.preventDefault();
var selector = hiddenfield.val();
}
then any item to show/hide can be done with getting the tag:
$("#elementName").css("display", "inline");
or display, none to hide.
I used this at work because at times you need to change without firing the postback, but still collect data when they engage the form.
I typically avoid jQuery for many events for strength of code and security, but DOM element manipulation can be much easier at times with jQuery.

How do I trigger a PostBack with arguments from Javascript?

This is what I'm doing: Using jquery, I'm popping up a "form" over the page that lets the user search for branches of the company and select the one they want. When the form pops up, they can type in a textbox, and it will do AJAX requests back to the server to return the top n results for what they've entered, and those results will be put into a list for them. I want the user to be able to select one by clicking a link that says "select" or something, and at that point I want it to do a PostBack have the Branch Selector control that this is in change it's SelectedBranch property to the newly selected branch. I've got this all working right now with a hard coded list of LinkButtons, but how do I do the same thing with a dynamic list of links inserted with jquery?
Look at the HTML that gets emitted for your hard coded LinkButtons. You'll see that each one calls the JavaScript __doPostBack function when clicked. I believe this function takes two arguments: a control ID and an extra command argument you can use for your own purposes.
I would suggest adding a single control to the page whose only job is handling events for the dynamic links. Then, when you are creating the links with jquery, make each one call __doPostBack, passing the event handling control's ID for the first argument and some other string for the second argument that identifies which link was clicked. In the Click event for the handling control, look at the second argument value and do what you need to do.
The short answer is... you don't.
ASP.NET relies on the Viewstate for the current state of the controls, including items in a DropDownList or similar control. Dynamically updating a list on the client will not modify the viewstate, so will not be available on the back end.
The general workaround for this is to just add a hidden field which updates/stores the current selection via js on the client side. Then read it from this field on the backend rather than List.SelectedValue.

ASP.NET Dynamic Page Controls: Is it possible to bind events AFTER Page.Load?

I have a site that I am currently working on in ASP.NET 2.0 using the usual WebForm stuff and ASP.NET AJAX 1.0. Is it possible to bind an event to a dynamically created control after the Page.Load event?
I have a table <td> element that I am dynamically creating similarly to this code:
' Create Link Button
lnk.ID = String.Format("lnkDetails_{0}", dr("Id"))
lnk.Text = dr("Name").ToString()
lnk.CommandArgument = dr("Id").ToString()
AddHandler lnk.Click, AddressOf DetailsLink_Click
cName.Controls.Add(lnk)
This this code is looped over for each row in a database (and of course more cells are added to the table, including an ImageButton with an event. The events work flawlessly when I execute this code during events leading up to and including Page.Load. I need to be able to fill this table with current data, which is updated during a btnClick Event elsewhere on the page, which occurs after this Page_Load event, so I am populating with old data. If I change this code to Page.LoadComplete, events stop working.
This data is a summary display of various components of an application, things like somebody's name, which when updated on a 'detail' form, updates the database by partial postback (a requirement), then it needs to show the update in this 'summary' section after an update. Currently it takes 2 postbacks to actually see the change in the 'summary' section, so effectively the summary is 1 step behind the changes (clear as mud?)
What would be the best way for me to populate this table with current data (which is available during/after Page.LoadComplete), but still have an event fire when a link is clicked (the event causes an UpdatePanel to display the 'detail' form).
I also have jQuery at my disposal and the usual ASP.NET AJAX methods, also javascript is a requirement for the website, so I do not need to degrade for unsupported browsers.
This is my first ASP.NET web application and need some help figuring out the best way to make this happen (I'm well versed in PHP, Django and the usual ways to do web forms - things like having multiple forms on one page o_O).
Update:
There really isn't a good way to bind control events to controls after Page_Load. The overall architecture of the pages is there is one ASP.NET form encompassing the entire page, there is only 1 aspx page. I am using master pages (however it doesn't have any obvious implications to my issue).
The page is split into a left and right 'pane', the left is a summary of all the data (in an update panel), the right 'pane' has 6 'tabs' implemented each as their own user control, each with several form fields and an update button all in it's own UpdatePanel.
An update on any of these tabs only refreshes the summary panel (UpdatePanel.update()) and its own panel. The 'refreshing' and event binding of dynamic controls of the summary from the db happens during Page_Load and the Update Button event updates db data. (The control event happens after Page_Load). I want to avoid doing a double post to get the summary to update, any thoughts are helpful.
You need to postback the whole page after your data changes in the 'btnClick Event elsewhere on the page'. It sounds like you have an UpdatePanel and it sounds like this is catching the postback of your btnClick event handler. Put the btnClick outside the UpdatePanel or change its triggers so that your btnClick forces a postback/refresh of your data. Or, redesign your table so it's AJAXly-refreshed when you click on btnClick, it's hard to get you more details without knowing more about the structure of your page and controls.
Good luck!
You can bind to an event whenever you want. It's just a simple event after all. But not all places might be suitable because you have to take into account when the event fires. And in most cases this happens between Page_Load and Page_PreRender. That includes the click event on a LinkButton. In general, I would recommend to add your dynamically created controls in the Page_Init stage.
You have to add the controls before Page.Load in order to maintain ViewState between postbacks, so use the OnInit event handler for that.
But once they're added, you should be able to bind event handlers (such as OnClick) at any point during or after the Page.Load... for example in your grid's ItemDataBound (or something like) or in the Page.PreRender.

Resources