Hi
I am implementing a reporting dashboard ASP.NET page. To do this I have an ASPX page with multiple RadDockZones and RadDocks, each containing a reference to a user control (ASCX page) which contains the RadHtmlChart.
Several of these charts have drill-downs which use RadAjaxManager and a client side function called from the chart. See...
https://demos.telerik.com/aspnet-ajax/htmlchart/examples/drilldownchart/defaultvb.aspx
Individually, the charts work fine but when incorporated within the parent dashboard page I get a message saying you can't have more than one RadAjaxManager on the same page.
Google searches told me to use RadAjaxManagerProxy instead, with the RadAjaxManager on the parent page. However, I have no idea how to do this. None of the solutions I found seem to be suitable for my problem. One said that RadAjaxManagerProxy does not have client-side object or functions. I am using the ajaxRequest client-side function, so perhaps this is my problem.
Is what I am trying to do even possible? If so, how?
Thanks
Nick
11 Answers, 1 is accepted
The following article explains how you can trigger the ajaxRequest() from the client through the RadAjaxManager, but handle the server event in the user control: https://docs.telerik.com/devtools/aspnet-ajax/controls/ajaxmanager/how-to/radajax-and-webusercontrols.
An alternative is to use hidden buttons on the user controls that will do the postbacks. Something like this:
<!-- on the user control itself -->
<telerik:RadAjaxManagerProxy runat=
"server"
ID=
"ramp1"
>
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID=
"btn1"
>
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID=
"rhc1"
/>
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManagerProxy>
<asp:Button Text=
""
style=
"display: none;"
ID=
"btn1"
OnClick=
"btn1_Click"
runat=
"server"
/>
<telerik:RadHtmlChart runat=
"server"
ID=
"rhc1"
></telerik:RadHtmlChart>
<script>
function
drillDownChart_<%=
this
.ClientID%>() {
__doPostBack(
"<%=btn1.UniqueID%>"
,
""
);
//OR something like
document.getElementById(
"<%=btn1.ClientID%>"
).click();
//you can use any DOM traversal here to get the button from the current DOM, like during the chart seriesClick event
}
//the way the function above is called depends entirely on the project logic/architecture
function
theGenericHandlerDispatchingDrilldowns() {
drillDownChart_<%=
this
.ClientID%>();
}
</script>
protected
void
btn1_Click(
object
sender, EventArgs e)
{
//do the drilldown with the chart here
}
Ultimately, there are many different ways to invoke a postback or get new data from the server and it mostly depends on the project. The chart drilldown example is merely a postback that includes the chart in the response and changes its settings/series/data on the server, so you can implement this in any way suitable for your case, it does not have to be a RadAjaxManager.
Regards,
Marin Bratanov
Progress Telerik
Thanks Marin, that has resolved the error. I now have another problem.
I have several charts on my page, each included as their own user control and each with drilldown functionality using RadAjaxManagerProxy. Whenever I click a particular chart to drill down, all of the drilldown events on my page fire, not just the one I clicked. I don't seem to be able to segment or isolate the drilldown functionality, even if I individualise the IDs on my user control page (RadHtmlChart ID, OnClientSeriesClicked event).
Do you know how I can achieve this?
If you add buttons next to the charts you can easily handle their unique clicks.
If you keep using the RadAjaxManager's .ajaxRequest() method, you must be aware that:
- it requires that the ajax manager be the initiator
- all charts will participate in the response
- to differentiate them, you should pass an argument to the method that you can generate (e.g., based on the chart ID, something like ajaxManagerRef.ajaxRequest("drillDown|chart1");)
Regards,
Marin Bratanov
Progress Telerik
Hi Marin
Many thanks, the button idea worked perfectly.
For reference, my code is as follows:
--------------------------------------------------------------
Parent page
--------------------------------------------------------------
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
</telerik:RadAjaxManager>
--------------------------------------------------------------
Child ASPX page
--------------------------------------------------------------
<telerik:RadCodeBlock ID="RadCodeBlock2" runat="server">
<script type="text/javascript">
function OnClientSeriesClicked_PRN_BTL(sender, args) {
var btn = $find("<%=RadButton_PRN_BTL.ClientID%>");
var myParam = String(args.get_category());
btn.set_commandName(myParam);
document.getElementById("<%=RadButton_PRN_BTL.ClientID%>").click();
}
</script>
</telerik:RadCodeBlock>
..............
<div style="display: none;">
<telerik:RadButton ID="RadButton_PRN_BTL" runat="server" Text="Button1" OnClick="RadButton_PRN_BTL_Click" />
</div>
..............
telerik:RadHtmlChart runat="server" ID="RadHtmlChart_PRN_BTL" Height="400" Width="100%" Skin="Bootstrap"
DataSourceID="SqlDS_DrillDown1" OnClientSeriesClicked="OnClientSeriesClicked_PRN_BTL">
..............
<telerik:RadAjaxManagerProxy ID="AjaxManagerProxy1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadButton_PRN_BTL">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadHtmlChart_PRN_BTL" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManagerProxy>
<telerik:RadAjaxLoadingPanel ID="LoadingPanel1" Height="77px" Width="113px" runat="server">
</telerik:RadAjaxLoadingPanel>
--------------------------------------------------------------
Child code behind page
--------------------------------------------------------------
Protected Sub RadButton_PRN_BTL_Click(sender As Object, e As EventArgs)
Ugh, that posted by mistake.
To finish off...
Protected Sub RadButton_PRN_BTL_Click(sender As Object, e As EventArgs)
Dim MyVar = RadButton_PRN_BTL.CommandName
End Sub
Hi Marin
I'd like to reopen this thread if that's ok as we have a related problem. The drill-downs work perfectly with distinct user controls on the same page. However, we encounter a problem where we add the same RadHtmlChart user control with drill-down functionality to our page more than once. This is something we are likely to see as some users will want to see a particular RadHtmlChart in different forms (column vs. bar vs. area etc).
The behaviour we see is that a series click on one chart instance causes the drill-down to occur on a different instance. Could this have something to do with the shared id of the button which fires the drill-down event in the user control? Is there a way around this?
Thanks
Nick
You need to ensure that each user control encapsulates its functionality successfully - the buttons must be unique and trigger unique functions. By default, the last user control on the page will overwrite the function object coming from the previous ones and you will get the described behavior. A solution is explained in the following article: https://www.telerik.com/support/kb/aspnet-ajax/details/using-dynamic-unique-names-for-javascript-functions. Another solution is to traverse the DOM to ensure you use the correct buttons/functions/elements.
Regards,
Marin Bratanov
Progress Telerik
Thanks Marin, that worked. There is no longer any conflict between by drilldown charts.
However, I now have a slightly different issue.
In order to implement your solution, I now call my drilldown javascript function from the code behind. The result is that my chart does not render on page load anymore. I have to refresh the page. I am wondering if it's something to do with the javascript function not being registered on page load.
This is my ASPX.
<telerik:RadCodeBlock ID="RadCodeBlock1" runat="server">
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
<script type="text/javascript">
function OnClientSeriesClicked_BTL_<%= ClientID %>(sender, args) {
var btn = $find("<%=RadButton_BTL.ClientID%>");
var myParam = String(args.get_category());
btn.set_commandName(myParam);
document.getElementById("<%=RadButton_BTL.ClientID%>").click();
}
</script>
</telerik:RadScriptBlock>
</telerik:RadCodeBlock>
and this is my code behind.
Private Sub BTL_Init(sender As Object, e As EventArgs) Handles Me.Init
RadHtmlChart_BTL.OnClientSeriesClicked = "OnClientSeriesClicked_BTL_" + Me.ClientID
End Sub
Any ideas?
Thanks
Nick
Try removing the telerik:RadCodeBlock element, the RadScriptBlock should take care of registering it during partial rendering. I've never tried nesting these controls and I don't know what might happen, as they are not designed for this.
If the button is a RadButton, replace document.getElementById("<%=RadButton_BTL.ClientID%>") with the btn reference - the RadButton is a more complex HTML structure and exposes its own click() client-side method that's different than the DOM method.
The three other ideas I can offer are:
- make sure the page renders valid HTML and that there are no JavaScript errors
- make sure the charts' Visible property is not set to false somewhere in the code, and that they have data in the initial page load
- disable AJAX and test again - follow this article for more details: https://www.telerik.com/support/kb/aspnet-ajax/ajaxmanager/details/how-to-disable-ajax-temporarily
If neither of this helps, I advise that you open a support ticket and send us a small runnable example that demonstrates the chart problem. We don't need actual business logic and data, an MCVE works better: https://stackoverflow.com/help/minimal-reproducible-example. Having that will let us see and debug the problem, and avoid further guesswork.
Lastly, if you want to render and rebind/re-create charts dynamically, you can consider using the underlying Kendo Chart widget directly. This will let you instantiate and destroy instances with only JavaScript, without the need for any postbacks, and will also let you use JavaScript data easily (for example, JSON obtained from a web service). It may also be easier to create instances based on data coming from a service, as they instantiate on the client, as opposed to the server-side rendering of RadHtmlChart that needs an actual Page object and cannot instantiate from its settings only or from data coming from a service. Not the least of all is that this will let you use an actual Kendo DataSource widget, which is a very powerful tool that can call services or parse JSON data.
Regards,
Marin Bratanov
Progress Telerik
Hi Marin
I returned from holiday a week or so ago and revisited this, only to find that all my charts with drilldown functionality are working perfectly, even with the RadCodeBlock element, so I've left them as is.
I wanted to say many thanks for your help, it's much appreciated.
I'll post all my revelant code to this thread at some stage to help anyone else that has this problem.