I'm trying to code what I think is a fairly routine AJAX pattern using TreeViews and UpdatePanels. My situation is this:
I have a TreeView within an UpdatePanel. I have a Literal within another UpdatePanel. When the user clicks on a node within the TreeView, the contents of the Literal are updated. Now, since the whole thing is asynchronous, there is of course a time lag between the click and the update of the Literal contents. During this time, I'd like to do two things:
1) Show an UpdateProgress, and
2) Clear the contents of the Literal
This is so that the user doesn't have to stare at the old contents while the new text is getting loaded asynchronously.
I can't seem to figure out an easy way to accomplish (2). I've been reading up on client side callbacks and using GetCallbackEventReference, but it seems like a very complicated approach to what is seemingly a simple problem.
Ideally, I would like to leave TreeView alone to do it's work. I don't want to get the contents myself and add them to the TreeView using JS. I'd just like to detect the node change event at the client side, clear up the Literal, and let TreeView go about with its normal operation.
Is this possible? Or are client call backs my only option?
You'll be wanting to play with the PageRequestManager from the ASP.NET AJAX library. Here's the MSDN reference for the PRM - http://msdn.microsoft.com/en-us/library/bb311028.aspx.
Just be for warned Microsoft have stated that the TreeView can be problematic within the UpdatePanel and you'll also want to be very careful of the performance, particularly if you have a large TreeView (see my article on optimising the UpdatePanel performance - http://www.aaron-powell.com/blog.aspx?id=1195). You should really look at something like a jQuery plugin (eg: http://bassistance.de/jquery-plugins/jquery-plugin-treeview/).
But to actually answer you're question you need to:
Have a BeginRequest event handler which will then clear your literal and can even show a Loading (I'm not a fan of the UpdateProgress, I prefer much more granular control I get from doing it myself)
Use the EndRequest event to ensure that the Loading component vanises
You could also make the TreeView a AsyncPostbackTrigger of the 2nd UpdatePanel on the page, or just call the Update method on it during the async postback of the TreeView
i had the same problem and fixed it by creating a hidden html element that overlaps the area i want to hide. I show it onSubmit and hide it in the window.onload during a postback. It's not pretty, but it works and should be fast.
Related
I have a repeater control that displays a playlist for my users, this control can sometimes hold say 1000 or more songs. This is a great feature, I was previously using jQuery to do client side sorting, but that has limitations. So I implemented server side sorting which works great, the only issue i am seeing is that when playlist are this long it takes a second or 2 before the postback and sorting is actually started.
I have watched the actions in firebug and done some research and understand that the databound values are not preserved, which makes sence. My question is, When watching in Firebug, it looks like the repeater control removes all the items in the collection before it starts the postback? is this true have others experienced this?
The repeater control ceases to exist entirely between postbacks. The repeater control is called into existance when you make a page request. It is populated, etc. then rendered to the browser. Once done, ASP.NET will delete all the objects on the page (or rather the garbage collector will get them when required. Either way, you can't get them any more).
When the postback happens it has to re-create the entire repeater all over again. There are some mechanisms, such as viewstate, that try to make this as seamless as possible (i.e. recreating controls just as you left them in the previous request) but they sometimes don't work the way you might expect.
In asp.net is it a requirement to rebuild the whole page during every callback? For example my web page is split into three distinct areas and I have an update panel for each area. Lets say I want to update the third area, do I have to bother with any processing of the other two areas?
For example lets say there is a grid view in area two. The update panel in area three callbacks to update its content. Do I have to rebind the grid in area two?
Thanks,
AJ
Yes, this is how ASp.NET is done. If you use an updatePanel / AJAX partial update, you may get away building only part of the page. But then, your viewstate may be a problem.
What you see is basically one of the disadvantages of the ASP.NET model.
By default, "UpdateMode" is set to "Always" for UpdatePanels which means they update whenever anything "happens" on the page.
Try setting "UpdateMode" to "Conditional" for all your three UpdatePanels and see if that helps. (FWIW this is standard practice for me as part of writing the UpdatePanel definition. If you need to update an UpdatePanel when something happens on a different part of the page, you can use Triggers or update it with .Update() in code behind)
bgs264
Edit
I think I misunderstood your question originally; my suggestion above may improve page rendering times as partial postbacks result in less code being sent back and forth between client and server.
But yes as per other answer, all the controls have to go through their lifecycle (Init, Load, Render) on every page load / postback.
I'm writing an asp.net web app. and i've hit a bit of a brick wall.
basically i have 2 pages, the main page with a text box in and a popup that contains a treeview.
My problem is this. when i select a treeview item i want the program to perform some database transactions using asp.net and then pass the value retrieved from the database into a javascript function that passes the data back from the popup page to the parent page. My problem is that i cannot find any way of calling a javascript function from asp.net. I've tried assigning attributes to controls on page load, but this does not work as when the page loads the data has not been retrieved from the database.
Have a look at the ClientScriptManager class. You can register scripts from code-behind that will run when the HTML page loads. Those scripts can call other javascript functions on the page.
There are many tutorials and examples on the Web. Here's one I found that may help but there are many more.
How to use the client script manager
You hit the nail on the head when you said "I've tried assigning attributes to controls on page load, but this does not work as when the page loads the data has not been retrieved from the database." You just need to discover when you're pulling the data from the database, and then assign the values after that. Without looking at your code, there's no way to know for sure, but Page_PreRender is probably a good bet to assign your values...it's probably after you're pulling information from the db...it's pretty much the last place that you can make things happen before the html is generated for the client.
You can invoke a function resided in the Main Page and call that function in the Main Page from the Child Page which is your pop up window.
Please refer to these links for references
http://chiragrdarji.wordpress.com/2007/03/10/call-parent-windows-javascript-function-from-child-window-or-passing-data-from-child-window-to-parent-window-in-javascript/
http://www.webmasterworld.com/forum91/2957.htm
http://hspinfo.wordpress.com/2008/01/12/call-parent-windows-javascript-function-from-child-window/
This one helps with retrieving popups from values using javascript
http://www.eggheadcafe.com/articles/20060117.asp
This one shows how to fire a postback using javascript, and manage it in the codebehind.
http://weblogs.asp.net/mnolton/archive/2003/06/04/8260.aspx
If you put them together, and use Control.ClientID to find the actual "html name" of your asp.net controls, you'll be able to set that up in no time.
Might not be the prettiest way to do it in town, and incidentally make little baby Jesus cry, but anyway, it works.
[edit]Oh. I just saw that it seems I answered the question the other way around, or "how to trigger codebehind from Javascript". I think the method I suggest may help you, if you use it right.
The javascript of the popup should pass the information to the parent window, and the parent window function should call a postback when it receives the information.
The javascript of the popup window should be only registered on a postback with the correct information retrieved, so that when the postback occurs on the popup because of the selection of the right information, the window closes and passes the information to the parent page.
The parent page, triggering postback, does the thingies you need it to, and the app resumes "normally" from there on, doing whatever you need it to, outside of the popup page.
I have a Repeater control that I bind server-side. It repeats a series of divs, and does so with no problem. I have some buttons that I use to sort the repeater (newest, highest ranked, random) and this works the way it should.
I would like to improve my user experience by making the buttons sort the divs using Ajax/jQuery somehow so that there is no page postback and the user does not lose his/her spot on the page.
Is there a way to use jQuery to access server-side code like this, or use Ajax to re-bind a server-side control?
Thanks... if I need to list more details, please let me know!
EDIT I'm aware of UpdatePanels, but I would prefer not to use them if I don't have to.
Have you considered moving the Repeater's functionality to the client-side?
Doing it that way, functionality like paging and sorting is not very difficult to add. In fact, you can lean on the framework pretty heavily by using ADO.NET data services as the service layer.
It's relatively easy.
Move your repeater to a separate custom control, let's say MyControl. Now repeater in your page becomes uc1:MyControl.
Wrap MyControl into a div:
<div id="mydiv">
<uc1:MyControl ID="MyControl1" runat="server" />
</div>
Create a new page, pgMyControl.aspx, that contains MyControl only.
On your main page, add jQuery handlers to your sort links. Use load method to dynamically replace div contents:
$('#link_sort_random').click(function()
{
$("#mydiv").load("pgMyControl.aspx&sort=random");
}
Use QueryStringParameter in datasource inside MyControl to change order. Or use Request.QueryString in code-behind file.
Using an updatePanel or a jquery Ajax postback are the same thing essentially. Both will ask your code to fetch the new query, then make your control render itself, and then feed the HTML back to the client as a partial page render, and then insert the content in place of the old content in the same DOM location.
It is considerably harder to make JQuery and ASP.NET talk to each other this way due to the nature of web controls and their lifecycle that determines when they render. An updatePanel knows how to call all this, maintain proper viewstate and return the result to the correct location.
In this case, don't make things any harder on yourself, use the updatePanel unless you have some very specific reason not to.
EDIT: If you're having JQuery issues with update panels it is probably due to the fact that new DOM nodes being created. JQuery has the live event to handle this. It will notice when new DOM elements are created and match them against your selector even after the document ready.
Maybe it's an OT, but you can consider to change the way you bind even the client and the server control, using XSLT transformation instead od the classics server controls.
You can find an example here (sorry, it's in italian...).
I have a page with a number of ListViews that I want users to be able to sort and page through. Rather than postback and rebind the entire page each time, I would like to do it via jQuery/AJAX selectively for the control in question. I am comfortable making the client-side call to a WebMethod in my page - my question is how do I get the returned data back into the ListView via jQuery?
(Note: I don't want to use an UpdatePanel!)
I'm not sure if it'll actually be achievable to update a ListView without a postback, just because of the underlying data model of the ListView control.
You're best option to having a complete AJAX solution would be to use a JavaScript templating engine. I've done a demo on my blog using jTemplates and the MS AJAX Library v4 preview - http://www.aaron-powell.com/blog.aspx?id=1209
But despite common belief you can use an UpdatePanel and have it efficient, I also looked at that here: http://www.aaron-powell.com/blog.aspx?id=1195. The biggest thing to keep in mind when using UpdatePanels is ViewState. If you don't need ViewState saved on a control make sure it's turned off. You can really reduce your post-load by doing that. Also removing whitespace will help.