Telerik RadAjaxManager loads controls slow the first time - c#

So I have a RadPanelBar, and within that a RadTreeView. On a node click event I want so update some control.. for now I am just trying to update a textbox. It works fine except that the first time I click on a child node it takes a very long time to update the control.. Just a simple text change. I set a break point in my function and I noticed that it is taking long to fire the OnNodeClick event.. If I click a parent node in the tree view it loads fine on the first click. Also, after the first time I've clicked it.. it loads quickly.. If I refresh the page, it is slow on the first click again.. Is there something I am missing.. Is the structure of my HTML inappropriate for these AJAX calls? I feel like this is a really simple example that should work..
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<telerik:RadAjaxManagerProxy ID="RadAjaxManagerProxy1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="IncidentReportPanel">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="IRViewPanel" LoadingPanelID="LoadingPanel1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManagerProxy>
<telerik:RadAjaxLoadingPanel ID="LoadingPanel1" runat="server" Style="width: 320px;
padding-top: 125px;" Skin="Vista">
</telerik:RadAjaxLoadingPanel>
<table width="100%">
<tr style="height: 25px">
<td>
</td>
<td>
</td>
</tr>
<tr style="height: 100%">
<td style="width: 250px">
<telerik:RadPanelBar ID="IncidentReportPanel" runat="server" Height="450px" CssClass="IRPanel">
<Items>
<telerik:RadPanelItem runat="server" Text="Incident Reports" ImageUrl="./Images/folder.gif"
Value="IncidentReports">
<Items>
<telerik:RadPanelItem>
<ItemTemplate>
<telerik:RadTreeView ID="IncidentReportsTreeView" runat="server" OnNodeExpand="LoadTreeNodes"
OnNodeClick="PopulateIRData">
<Nodes>
<telerik:RadTreeNode Text="Pending" ExpandMode="ServerSideCallBack" ImageUrl="./Images/completed.gif">
</telerik:RadTreeNode>
<telerik:RadTreeNode Text="Completed" ExpandMode="ServerSideCallBack" ImageUrl="./Images/completed.gif">
</telerik:RadTreeNode>
</Nodes>
</telerik:RadTreeView>
</ItemTemplate>
</telerik:RadPanelItem>
</Items>
</telerik:RadPanelItem>
<telerik:RadPanelItem runat="server" Text="Calendar" ImageUrl="./Images/calendar.gif"
Value="Calendar">
<Items>
<telerik:RadPanelItem>
<ItemTemplate>
<telerik:RadCalendar runat="server" ID="IRCalendar" Width="100%" />
</ItemTemplate>
</telerik:RadPanelItem>
</Items>
</telerik:RadPanelItem>
</Items>
</telerik:RadPanelBar>
</td>
<td>
<asp:Panel ID="IRViewPanel" runat="server">
<telerik:RadTextBox ID="RadText" runat="server">
</telerik:RadTextBox>
</asp:Panel>
</td>
</tr>
</table>
protected void PopulateIRData(object sender, RadTreeNodeEventArgs e)
{
RadText.Text = "Hello, World!";
}
EDIT: I updated my code according to this article, http://www.telerik.com/help/aspnet-ajax/ajax-client-side-performance.html , and the problem persisted... again it only happens the first time..
EDIT: Just to clarify, by updating according to that article, I mean that I removed all the tables and relative widths and replaced them with css positioning and fixed widths.. the problem only happens the first time.. and it only happens sometimes.. quite a few times i thought i solved the problem as it would start responding quickly.. but then after I change my .aspx and change it back (even to the exact same thing when it was working quickly).. I get the same problem..
EDIT: So, I removed the AJAX component.. and setup the control so that it does a PostBack.. and it still takes long to hit my break point.. so it seems that its not an AJAX issue... but for some reason my events are taking long to fire..
EDIT:
So I followed the advice on this post and I used the webservices to do my binding and handle everything from the client side code.. All seemed to be ok until I decided that I wanted to return nodes from my webservice that could also be expanded.. So in my webservice I set the ExpandMode of my RadTreeNodeData object to Webservice.. and it renders the data correctly when I expand the child nodes.. However now I see the same problem from before where some calls take 20-30 seconds.. It takes 20-30 seconds to even hit the break point in my webservice.. Should I use the OnClientNodeExpand event instead? I don't understand why this is so slow!! Any help is greatly appreciated!

I recommend using OnClientNodeClicked and then you can update the controls client side. If you need more data from the server you can call a web service from the client code. Otherwise, to speed this up I would probably have to see your whole page and look at what requests are being sent back and forth. Perhaps you have a lot of viewstate that is getting serialized or something.

IMO, the fastest solution is to use a web service for binding. The standard AJAX functionality will still send ViewState and other flotsome across the wire that isn't necessary. You can find more here TreeView / Load on Demand Modes . So, your tree view would look something like the following where you would create an ASMX or WCF service that retrieves the nodes (in this case the LoadNodes method on the service at Default.asmx).
<telerik:RadTreeView ID="IncidentReportsTreeView" runat="server" >
<WebServiceSettings Path="Default.asmx" Method="LoadNodes" />
</telerik>

Have you tried putting the content in an UpdatePanel to see if the EnablePartialRendering makes any difference? Not sure if the RadAjaxLoadingPanel makes a difference
How many elements are in the tree?

Related

RadAjaxLoadingPanel does not works with DNN

I have a dnn site, which has a label and an imagebutton, clicking on which replaces the label with textbox and user can enter their text, once submitted the label will be updated with this text. Now clicking on the imagebutton causes the page to postback, i don't want a postback for this, hence i have placed telerik RadAjaxLoadingPanel control, so the cool loading div gets displayed while processing is going on, but for some reason it's not working, It always throws below error:
Please, see whether wrapping the code block, generating the exception, within RadCodeBlock resolves the error.
Below is the markup of my page: (I tried the wrapping the code with RadScriptBlock and RadCodeBlock, in both case it throws same error as above)
<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" Skin="Default">
</telerik:RadAjaxLoadingPanel>
<telerik:RadAjaxPanel ID="RadAjaxPanel1" runat="server" LoadingPanelID="RadAjaxLoadingPanel1">
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
<a class="subscribetoday" href="#">
<strong>Subscribe Today!</strong> <asp:Label ID="lblsubscribemsg" runat="server" Text="12 issues for $14.95"></asp:Label>
<asp:ImageButton ID="imgEditSubscribe" runat="server"
OnClick="imgEditSubscribe_Click" ToolTip='Edit' ImageUrl="~/images/edit.gif" AlternateText='Edit' Visible="false" />
<div id="editsubscribe" runat="server" visible="false">
<asp:TextBox ID="txtSubscribe" runat="server"></asp:TextBox> <asp:ImageButton ID="imgSave" runat="server"
OnClick="imgSave_Click" OnClientClick="return validateSubscribeNote();" ToolTip='Save' ImageUrl="~/images/save.gif" AlternateText='Save' /> <asp:ImageButton ID="imgCancel" runat="server"
OnClick="imgCancel_Click" ToolTip='Cancel' ImageUrl="~/images/cancel.gif" AlternateText='Cancel' />
</div>
<img src="img/prosound-subscribe.png" alt="Subscribe Today!">
</a>
</telerik:RadScriptBlock>
</telerik:RadAjaxPanel>
Can anyone tell me where i am going wrong with this.
The problem is with other server code blocks on the page (<%=%> for example, generally - <% ... %>), not with this concrete piece of code you are trying to AJAX-enable. You can read more here: http://docs.telerik.com/devtools/aspnet-ajax/controls/ajax/radcodeblock-and-radscriptblock
So, you should find the place where those code blocks are used and wrap THEM in a RadCodeBlock controls. It is often scripts that reference controls, e.g.:
<telerik:RadCodeBlock runat="server" ID="RadCodeBlock1">
<script>
function getReference() {
return $find("<%=someControl.ClientID%>");
}
</script>
</telerik:RadCodeBlock>
With DNN, however, I cannot say where these may originate.
Thus, your other option is to use an <asp:UpdatePanel> control to get AJAX requests instead of full postbacks. The native AJAX toolset also offers the <asp:UpdateProgress> control that you can use instead of RadAjaxPanel.

updating/ refreshing the controls which are in Rad ajax panel

I am facing problem in updating/ refreshing the controls which are in Rad ajax panel .
I have a Rad ajax panel in which i have placed a grid, and RadPanelBar side to side by placing them in table.
when the user selects any record in grid the details of that record will be shown in it's beside RadPanelBar. So
in this process of selecting records i am refreshing the Entire Rad ajax panel for getting the correct selected record details.
But additionally what i want is when the user sorts the records of grid i need to refresh the grid only , for this i placed
Radgrid again in other radajaxpanel which is creating the problems. My Radgrid is not getting updated with the click events of grid, when i click on link button of grid
it should highlight the clicked row. But when i placed grid in Ajax panel it is not getting highlighted untill unleass i refresh the Grid.
when i placed it in another nested rad ajax panel. Please help me how can i achieve refreshing the only the Radgrid while sorting?
My design:
<telerik:RadPageView ID="radPage1" runat="server">
<telerik:RadAjaxPanel ID="RadAjaxPanel3" runat="server" EnableAJAX="True" LoadingPanelID="RadAjaxLoadingPanel1"
ClientEvents-OnRequestStart="onRequestStart">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td style="width: 50%">
<%-- <telerik:RadAjaxPanel ID="RadAjaxPanel4" runat="server" EnableAJAX="True" LoadingPanelID="RadAjaxLoadingPanel1"
ClientEvents-OnRequestStart="onRequestStart"> --%>
<telerik:RadGrid ID="radGrid" runat="server" AllowSorting="true" AllowFilteringByColumn="False"
OnNeedDataSource="grdUnResolvedFaxes_NeedDataSource" Skin="Metro" CellSpacing="0"
GridLines="None" Width="99%" PageSize="12" OnItemCommand="grdUnResolvedFaxes_ItemCommand"
EnableViewState="true">....
.....
.....
</telerik:RadGrid>
<%-- </telerik:RadAjaxPanel> --%>
</td>
<td style="width: 50%">
<telerik:RadPanelBar runat="server" ID="pnlBar" ExpandMode="MultipleExpandedItems"
Width="99%" Visible="false">
<Items>
.................
</Items>
</telerik:RadPanelBar>
</td>
</tr>
</table>
</telerik:RadAjaxPanel>
</telerik:RadPageView>
For the Linkbutton click of the grid i added below code to update the grid
if (e.CommandName.ToLower() == "select")
{
RadAjaxPanel4.ResponseScripts.Add(String.Format("$find('{0}').ajaxRequest();", RadAjaxPanel3.ClientID));
}
I am not sure what this linkbutton is, but from what I can gather, you want one action (an update on the grid) to do two different things (update the grid only, or also update the panelbar). This is quite a confusing scenario and I do not thing there is a way for the code to know when to only include one control.
Thus, you can consider using asp:UpdatePanel with UpdateMode=Conditional around the panelbar and call its Update() server method only when you need to rebind data in it. This can give you a conditional update there when needed. In this case, a RadAjaxPanel around the grid only should suffice.
Nesting AjaxPanels can cause issues as you have found, so you should avoid that.
If you know on the client that you need to update the panelbar you can show a RadAjaxLoadingPanel over its element with JavaScript as shown here: http://www.telerik.com/help/aspnet-ajax/ajax-show-hide-loadingpanel.html.

how do i response.write a block of code?

In php you can have the serverside script print back a block of formatted code by using something like
print <<<HERE
<code>
<somemorecode></somemorecode>
</code>
HERE;
What is the asp equivalent (C#)??
It doesn't seem to like when I don't keep all of the string on one line and i'd like to avoid having to concatenate everything as it kind of kills the purpose of preserving the formatting for readability. Here's what I have that it isn't liking. i know why its doing it, but I'd like to know how to achieve what you can in php:
<%
for(int i = 20; i<21;i++){
Response.Write("
<tr>
<td class="style1">
<asp:DropDownList ID="docNumber" runat="server" />
</td>
<td class="style1">
<asp:Label ID="Label1" runat="server" Text="This would be the title of the document." /></td>
<td class="style1">#</td>
<td class="style1">
<asp:DropDownList ID="supervisorName" runat="server" />
</td>
</tr>");
%>
This isn't for anything anyone will ever see. I'm just trying to build a throw away data entry page for myself.
update: nevermind... i just realized this isn't going to work for me as it will duplicate each control id. fail.
At any rate, for future reference. is there a way to do what i was trying to do as far as the code blocks go?
You might consider using an <asp:Repeater /> for this purpose:
<asp:Repeater runat="server" id="repeater1">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="style1">
<asp:DropDownList ID="docNumber" runat="server" /></td>
<td class="style1">
<asp:Label ID="Label1" runat="server"
Text="<%# Container.DataItem("DocTitle") %>"/></td>
<td class="style1">#</td>
<td class="style1">
<asp:DropDownList ID="supervisorName" runat="server" /></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
In your code behind, you would then bind this to a list or datasource on page load (or where ever appropriate). Finally check out the ondataitembound action for custom handling of each item as it's bound.
MSDN Repeater - Everything you need to know
&lt%= Some String Expression Here %>
or
&lt% code with Response.Write("some string"); %>
the first is better if you want to print a single statement. The second is better if you have more than one expression that prints stuff (if you use loops, if/else, etc.)
Keep in mind that this is considered bad practice and is frowned upon in the ASP.NET Web Forms world. You should be using controls.
If you want to create some more complex layout that repeats something you should use databound controls. For tables use the GridView control, for list of options use DropDownList and for other things use layout use the ListView control (you can use it for tables too). These controls use default formatting or template for each item and are bound to a collection of items via code behind. All this is for ASP.NET Web Forms. If you are using ASP.NET MVC things are done differently.

Change rendering order of controls

I found this article on how to manipulate the rendering sequence of asp.net controls.: http://weblogs.asp.net/infinitiesloop/archive/2007/09/07/rendering-asp-net-controls-out-of-order.aspx
I placed some placeholders on the page to encapsulate the controls i want to move around. The problem is, that RenderChildren does render the controls without the html i placed into the placeholder like this:
<asp:PlaceHolder id="phOneToMove" Runat="server" Visible="true">
<tr>
<td><asp:Literal id="label1" Runat="server">Caption</asp:Literal></td>
<td>
<asp:TextBox ID="textbox1" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="validator1" Enabled="true" ControlToValidate="textbox1" runat="server" EnableClientScript="False" ErrorMessage="error"></asp:RequiredFieldValidator>
</td>
</tr>
</asp:PlaceHolder>
The controls are rendered without the tr and td around.
How can I handle this? All I want is to change the order of the placeholders like in this example phOneToMove.
Note: I am running on asp.net 2.0.
HTML tags are stored as controls of tyep Literal or LiteralControl, so however th elogic works has to check for controls of that type to ensure they get to their destination too.
I found the solution. My problem was, that the literal html elements (not LiteralControls) were not in the Controls property of my usercontrol. I did not know why. So I started to debug the .net Framework code itself ans setup a project with no overhead.
Short: I had code in the ascx file itself like <b><%= myOutputVariable %></b>. This causes asp to not put the literal content of a file into the controls collection. After I removed this code it worked like expected.

UpdatePanel Slowness in IE

I'm working on an ASP.Net application and working to add some Ajax to it to speed up certain areas. The first area that I am concentrating is the attendance area for the teachers to report attendance (and some other data) about the kids. This needs to be fast.
I've created a dual-control set up where the user clicks on the icon and via Javascript and Jquery I pop up the second control. Then I use a __doPostBack() to refresh the pop up control to load all of the relevant data.
Here's a little video snippet to show how it works: http://www.screencast.com/users/cyberjared/folders/Jing/media/32ef7c22-fe82-4b60-a74a-9a37ab625f1f (:21 and ignore the audio background).
It's slower than I would like at 2-3 seconds in Firefox and Chrome for each "popping up", but it's entirely unworkable in IE, taking easily 7-8 seconds for each time it pops up and loads. And that disregards any time that is needed to save the data after it's been changed.
Here's the javascript that handles the pop-up:
function showAttendMenu(callingControl, guid) {
var myPnl = $get('" + this.MyPnl.ClientID + #"')
if(myPnl) {
var displayIDFld = $get('" + this.AttendanceFld.ClientID + #"');
var myStyle = myPnl.style;
if(myStyle.display == 'block' && (guid== '' || guid == displayIDFld.value)) {
myStyle.display = 'none';
} else {
// Get a reference to the PageRequestManager.
var prm = Sys.WebForms.PageRequestManager.getInstance();
// Unblock the form when a partial postback ends.
prm.add_endRequest(function() {
$('#" + this.MyPnl.ClientID + #"').unblock({ fadeOut: 0});
});
var domEl = Sys.UI.DomElement;
//Move it into position
var loc = domEl.getLocation(callingControl);
var width = domEl.getBounds(callingControl).width;
domEl.setLocation(myPnl, loc.x + width, loc.y - 200);
//Show it and block it until we finish loading the data
myStyle.display = 'block';
$('#" + this.MyPnl.ClientID + #"').block({ message: null, overlayCSS: { backgroundColor:'#fff', opacity: '0.7'} });
//Load the data
if(guid != '') { displayIDFld.value = guid; }
__doPostBack('" + UpdatePanel1.ClientID + #"','');
}
}}
First, I don't understand why the __doPostBack() introduces such a delay in IE. If I take that and the prm.add_endRequest out, it's VERY speedy as no postback is happening.
Second, I need a way to pop up this control and refresh the data so that it is still interactive. I'm not married to an UpdatePanel, but I haven't been able to figure out how to do it with a Web Service/static page method. As you can see this control is loaded many times on the same page so page size and download speed is an issue.
I'd appreciate any ideas?
Edit: It's the same in IE 6 or 7. I'm thinking it has to do with IE's handling of the UpdatePanel, because the same code is much faster in FF and Chrome.
If speed/performance is a major concern for you, I would strongly suggest against UpdatePanels, as they cause a full page postback that drags the ViewState in the header, among other crap, and forces the page to go through the whole life cycle every time (even though the user doesn't see this).
You should be able to (relatively easily) use PageMethods to accomplish your task.
// In your aspx.cs define the server-side method marked with the
// WebMethod attribute and it must be public static.
[WebMethod]
public static string HelloWorld(string name)
{
return "Hello World - by " + name;
}
// Call the method via javascript
PageMethods.HelloWorld("Jimmy", callbackMethod, failMethod);
Its a known issue with IE only, see KB 2000262. A workaround/fix can be found here. I worked with them on the script and its a shame they cannot put out a real fix.
Noticed in a previous project that IE became terribly slow when we had heaps (150+) textboxes on a page, after checking with fiddler we figured it was the rendering engine that was slow.
(btw, before you all shout, the 150+ textboxes was an explicit customer requirement, we basically recreated customized excel on the web)
Here's the code for the pop up control (there's only one of these on the page that's shared by all of the controls containing the icons):
<script type="text/javascript" src="<%=Response.ApplyAppPathModifier("~/js/jquery-1.2.6.js") %>"></script>
<script type="text/javascript" src="<%=Response.ApplyAppPathModifier("~/js/jquery.blockUI.js") %>"></script>
<asp:Panel CssClass="PopOutBox noPrint" ID="MyPnl" style="display: none; z-index:1000; width:230px; position: absolute;" runat="server">
<cmp:Image MyImageType="SmallCancel" CssClass="fright" runat="server" ID="CloseImg" AlternateText="Close" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:HiddenField ID="AttendanceFld" runat="server" />
<asp:HiddenField ID="DatePickerFld" runat="server" />
<table width="100%">
<tr>
<td valign="top">
<asp:RadioButtonList EnableViewState="false" ID="AttendRBL" runat="server" RepeatDirection="Vertical">
<asp:ListItem Selected="True" Text="On Time" Value="" />
<asp:ListItem Text="Late" Value="Late" />
<asp:ListItem Text="Absent" Value="Absent" />
<asp:ListItem Text="Cleaning Flunk" Value="Other" title="This is used for things like cubby flunks" />
<asp:ListItem Text="Major Cleaning Flunk" Value="Major" title="This is used for things like White Glove flunks" />
</asp:RadioButtonList>
</td>
<td valign="top" style="text-align: center; vertical-align: middle;">
<asp:CheckBox EnableViewState="false" ID="ExcusedCB" runat="server" />
<br />
<asp:Label ID="Label1" EnableViewState="false" AssociatedControlID="ExcusedCB" Text="Excused"
runat="server" />
</td>
</tr>
<tr>
<td colspan="2">
<asp:Label EnableViewState="false" ID="Label2" Text="Notes" runat="server" AssociatedControlID="DataTB" />
<cmp:HelpPopUp EnableViewState="false" runat="server" Text='Must include "Out Sick" to be counted as ill on reports and progress reports' />
<br />
<asp:TextBox ID="DataTB" EnableViewState="false" runat="server" Columns="30" /><br />
<div style="font-size: 10px; text-align:center;">
<a href="#" onclick="setAttendVal('<%=this.DataTB.ClientID%>','Out Sick');return false;">
(Ill)</a> <a href="#" onclick="setAttendVal('<%=this.DataTB.ClientID%>','In Ethics');return false;">
(Ethics)</a> <a href="#" onclick="setAttendVal('<%=this.DataTB.ClientID %>','Warned');return false;">
(Warned)</a>
</div>
</td>
</tr>
<tr>
<td colspan="2">
<cmp:ImageButton ID="DeleteBtn" OnClientClick="showAttendMenu(this,'');" OnClick="DeleteAttendance" ButtonType="SmallDelete"
CssClass="fright" runat="server" />
<cmp:ImageButton ID="SaveBtn" OnClientClick="showAttendMenu(this,'');" OnClick="SaveAttendance" ButtonType="SmallSave" runat="server" />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
To find out why it's taking so long I would recommend using Fiddler to spy on your IE traffic: http://www.fiddlertool.com/fiddler/
You'll be looking at the response of each of the messages to see how large they are. If the messages are >5kb or so then the UpdatePanel is being way too piggy.
It sounds like a fairly simple thing you're trying to do so I'm having a hard time believing the update panel is to blame. Testing it shouldn't be too difficult though. The easiest way to test this without an UpdatePanel would be to use a PageMethod. This page has a great tutorial on it:
http://weblogs.asp.net/sohailsayed/archive/2008/02/23/calling-methods-in-a-codebehind-function-pagemethods-from-client-side-using-ajax-net.aspx
Could you also post your UpdatePanel code so we could get more details?
EDIT: Thanks!
What version of IE are you using?
Working with the DOM and HTTP Requests are inherently slow, it's the browser. The best way to speed it up is to reduce the number of times there is an HTTP request (AJAX or otherwise), and reduce the number of DOM actions, search, edit, replace, etc.
I recommend to do perforamnce tracing with link text. It is a free tool for AJAX performance analysis in Internet Explorer

Categories

Resources