I've recently upgraded a DNN 4.8.0 module with an 'Ajaxified' Prometheus RadGrid. Everything works great BUT... When I add a second instance of the module to the page I get an error stating only one RadAjaxManager permitted on a page.
I suspect the solution is to dynamically register the RadAjaxManager programatically as the DotNetNuke core handles Ajax Script Managers. Does anyone know if this will work? And if so, any code examples on how to do this?
Thank you...
19 Answers, 1 is accepted
Have you tried adding a single RadAjaxManager Prometheus on the main page and RadAjaxManagerProxy in your custom module to ajaxify the grid? Indeed only single RadAjaxManager Prometheus is allowed to reside on the form (as with the asp ScriptManager controls from the ASP.NET AJAX framework).
More about the RadAjaxManagerProxy you can learn from the following online resources:
http://www.telerik.com/DEMOS/ASPNET/Prometheus/Ajax/Examples/Manager/UserControl/DefaultCS.aspx
http://www.telerik.com/help/radcontrols/prometheus/?ajxWhatsNew.html
Best regards,
Stephen
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center
I did come up with a solution however. It's a derivation of the solution you provided though more specific for the DNN environment. The DNN core handles AJAX ScriptManagers by dynamically adding one (if one hasn't been added already) to the Default.aspx page, if AJAX is installed. I created a class that dynamically adds a RadAjaxManager to the Default.aspx page if one doesn't already exist. This code is called in the page init event of each module that will utilize the RadAjaxManager. I then placed a RadAjaxManagerProxy to handle the specific <AjaxSettings>.
Now I can have multiple modules per page all utilizing the RadAjaxManager that was dynamically placed on Default.aspx. If AJAX isn't installed the RadAjaxManager is not added to Default.aspx and the grid is simply not 'Ajaxified' but still funtions as a standard server control.
Thank you.
I am glad that you found a solution adding the RadAjaxManager programmatically to the main page and disabling the manager detecting whether RadAjax is installed. I will really appreciate if you post your implementation in this forum post - thus other community members can benefit from it and reuse it for their DNN modules. As a token of gratitude I will reward you with 3000 Telerik points which can be used for future discounts when purchasing/upgrading our controls.
Best regards,
Stephen
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center
Thank you Stephen. I hope this helps those that are dealing with a similar scenario.
Below is the implementation of adding the RadAjaxManager programmatically in DotNetNuke that I've found to work very well.
1) Add the RadAjaxManagerProxy to the ascx page:
<telerik:radajaxmanagerproxy runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="myRadGrid">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID=" myRadGrid" LoadingPanelID="RadAjaxLoadingPanel1"/>
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:radajaxmanagerproxy>
<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server"
Height="75px" Width="75px" Transparency="25">
<img alt="Loading..." src='<%= RadAjaxLoadingPanel.GetWebResourceUrl(Page,"Telerik.Web.UI.Skins.Default.Ajax.loading.gif") %>' style="border:0;" />
</telerik:RadAjaxLoadingPanel>
2) Add the following to the code behind of the ascx page:
protected void Page_Init(System.Object sender, System.EventArgs e)
{
if (DotNetNuke.Framework.AJAX.IsInstalled())
{
RadAjaxUtilities.RegisterRadAjaxManager(Page);
}
}
3) And the RadAjaxUtilities static class. I based this class on the DNN core implementation found at ~\Library\Components\Framework\AJAX.vb. This is where DNN handles the AJAX ScriptManager. It does more than my RadAjaxUtilities class so for your needs you can review the DNN core class and add to the implementation I provided below if needed. I only used what was needed for my purpose.
By default the core adds a ScriptManager to default.aspx. You can see this in the InitializePage() method in the default.aspx code behind. If a ScriptManager isn’t needed the DNN core removes it at runtime. In the case of the RadAjaxManager, you’ll be adding it at the module level by passing a reference to default.aspx (RegisterRadAjaxManager() - pass Page not this.Page). This way you don’t need to modify any part of the core. Also, I added this class to the App_Code directory of my module. Now that it’s working as I intend I’ll add it to my own custom library so I can use it thoughout all of my modules.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
using System;
using System.Web;
using System.Web.UI;
using System.Web.Compilation;
using System.Reflection;
using System.Xml;
using System.Xml.XPath;
using DotNetNuke;
using DotNetNuke.Framework;
using DotNetNuke.Common.Utilities;
namespace YourCompany.Modules.YourModule
{
public static class RadAjaxUtilities
{
//private static Page m_Page;
private static bool m_Initialized = false;
private static Type m_ScriptManagerType;
private static Type ScriptManagerType()
{
if (m_ScriptManagerType == null)
{
if (!m_Initialized)
{
m_ScriptManagerType = Reflection.CreateType("Telerik.Web.UI.RadAjaxManager", true);
}
m_Initialized = true;
}
return m_ScriptManagerType;
}
/// -----------------------------------------------------------------------------
/// <summary>
/// IsHostEnabled is used to determine whether the Host user has enabled .
/// </summary>
/// <remarks>
/// </remarks>
/// <history>
/// </history>
/// -----------------------------------------------------------------------------
public static bool IsHostEnabled()
{
if (DotNetNuke.Common.Globals.HostSettings.ContainsKey("EnableAJAX"))
{
if (DotNetNuke.Common.Globals.HostSettings["EnableAJAX"].ToString() == "Y")
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
/// -----------------------------------------------------------------------------
/// <summary>
/// IsEnabled can be used to determine if has been enabled already as we
/// only need one RadAjaxManager per page.
/// </summary>
/// <remarks>
/// </remarks>
/// <history>
/// </history>
/// -----------------------------------------------------------------------------
public static bool IsEnabled()
{
if (HttpContext.Current.Items["Telerik.Web.UI.RadAjaxManager"] == null)
{
return false;
}
else
{
return (bool)HttpContext.Current.Items["Telerik.Web.UI.RadAjaxManager"];
}
}
/// -----------------------------------------------------------------------------
/// <summary>
/// IsInstalled can be used to determine if is installed on the server
/// </summary>
/// <remarks>
/// </remarks>
/// <history>
/// </history>
/// -----------------------------------------------------------------------------
public static bool IsInstalled()
{
//First check that the script module is installed
XmlDocument configDoc = Config.Load();
XPathNavigator moduleNavigator = configDoc.CreateNavigator().SelectSingleNode("/configuration/system.web/httpModules/add[@name='ScriptModule']");
if (moduleNavigator == null)
{
return false;
}
else
{
return !(ScriptManagerType() == null) & IsHostEnabled();
}
}
/// -----------------------------------------------------------------------------
/// <summary>
/// RegisterRadAjaxManager must be used by developers to instruct the framework that is required on the page
/// </summary>
/// <remarks>
/// </remarks>
/// <history>
/// </history>
/// -----------------------------------------------------------------------------
public static void RegisterRadAjaxManager(Page m_Page)
{
if (!IsEnabled())
{
AddRadAjaxManager(m_Page);
}
}
/// -----------------------------------------------------------------------------
/// <summary>
/// AddRadAjaxManager is used to add a RadAjaxManager control to the page
/// </summary>
/// <remarks>
/// </remarks>
/// <history>
/// </history>
/// -----------------------------------------------------------------------------
public static void AddRadAjaxManager(Page objPage)
{
if (IsInstalled() && objPage.FindControl("RadAjaxManager") == null)
{
object objScriptManager = Reflection.CreateInstance(ScriptManagerType());
Control objControl = (Control)objScriptManager;
objControl.ID = "RadAjaxManager1";
try
{
objPage.Form.Controls.AddAt(0, objControl);
if (HttpContext.Current.Items["Telerik.Web.UI.RadAjaxManager"] == null)
{
HttpContext.Current.Items.Add("Telerik.Web.UI.RadAjaxManager", true);
}
}
catch (Exception ex)
{
// AddRadAjaxManager can not be added to a page if running in Medium Trust and not installed in GAC
m_ScriptManagerType = null;
// Reset to false or it will always indicate a RadAjaxManager is present.
m_Initialized = false;
}
}
}
}
}
Thank you for sharing this with the community, Vinny. I have updated your Telerik points for the involvement.
Best wishes,
Steve
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center
_applyUpdatePanelsRenderMode:
function(_e7){
var
_e8=Sys.WebForms.PageRequestManager.getInstance();
var
ids=_e8._updatePanelClientIDs;
for
(var i=0;i<ids.length;i++){
var
_eb=$get(ids[i]);
if
(_eb){
if
(_eb.tagName.toLowerCase()=="span"){
continue
;
}
_eb.style.display=(_e7==0)?
"block":"inline";
}
}
It seems that due to some reason the ids of the dynamically generated update panels are not referenced properly in your case. Can you please check whether the same scenario will work with plain MS UpdatePanels when you remove the RadAjaxManager? Let us know what you findings are.
Best regards,
Stephen
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center
I am having another problem, however. I am using a RadComboBox to filter a RadGrid. Both controls use linqdatasources. The grid datasource has a Where clause that uses the selected value in from the combobox. It works fine with no AJAX enabled or with MS AJAX enabled (by checking the checkbox described above.)
When I add in the RadAjaxManagerProxy as described in this thread, I get the following javascript error when I change my selection in the combobox:
Sys.InvalidOperationException: A control is already associated with the element.
I also get text beneath the combobox like the following:
6022|updatePanel|dnn_ctr393_List_RadGrid1Panel|
I am using the latest version of RadControls for ASP.NET AJAX and Dotnetnuke.
My RadAjaxManagerProxy code looks like:
<
telerik:RadAjaxManagerProxy ID="RadAjaxManagerProxy1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="rcbLocations">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadGrid1" LoadingPanelID="RadAjaxLoadingPanel1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManagerProxy>
<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" Runat="server" height="75px" InitialDelayTime="200" MinDisplayTime="200" Transparency="50" width="75px">
<img alt="Loading..." src='<%= RadAjaxLoadingPanel.GetWebResourceUrl(Page, "Telerik.Web.UI.Skins.Default.Ajax.loading.gif") %>' style="border:0px;" />
</telerik:RadAjaxLoadingPanel>
<dotnetnuke version="3.0" type="Module">
<folders>
<folder>
<modules>
<module>
<controls>
<control>
<supportspartialrendering>true</supportspartialrendering>
</control>
</controls>
</module>
</modules>
</folder>
</folders>
</dotnetnuke>
I'm working on DNN under medium trust, I tested the proposed solution, but I get this error message:
Not enough permissions. Inherit your page class from RadAjaxPage if you are running under Medium trust level.
Then, I tried objControl.RestoreOriginalRenderDelegate = False, when instantiating the RadAjaxManager in the AddRadAjaxManager method, this way I don't get the error but ajax do not work
Running under full trust, it works perfect.
Any suggestion will be appreciated.
Thanks
Javier
I suspect that the behavior you are experiencing is due to that fact that the proposed solution by Vinny is using reflection in order to create AjaxManager instance. As you may know in medium trust the reflection is not allowed.
Therefore I suggest you to try adding RadAjaxManager directly in the code for example in default.aspx or in the module's init event. Similar to this:
Dim ajaxManager As RadAjaxManager = RadAjaxManager.GetCurrent(Page) |
If ajaxManager Is Nothing Then |
ajaxManager = New RadAjaxManager() |
ajaxManager.ID = "ajaxManager" |
ajaxManager.RestoreOriginalRenderDelegate = False |
Page.Form.Controls.AddAt(0, ajaxManager) |
End If |
Please give it a try and let us know how it goes.
Greetings,
Rosen
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center
Here is the code:
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
If DotNetNuke.Framework.AJAX.IsInstalled Then
DotNetNuke.Framework.AJAX.RegisterScriptManager()
'_ajaxManager = RadAjaxManager.GetCurrent(Page)
For Each ctrl As Control In Page.Form.Controls
If ctrl.ID = "ajaxManager" Then
_ajaxManager = CType(ctrl, RadAjaxManager)
Exit For
End If
Next
If _ajaxManager Is Nothing Then
_ajaxManager = New RadAjaxManager()
_ajaxManager.ID = "ajaxManager"
_ajaxManager.RestoreOriginalRenderDelegate = False
Page.Form.Controls.AddAt(0, _ajaxManager)
End If
End If
InitializeComponent()
End Sub
Like you can see, I'm using a loop to find the RadAjaxManager, because RadAjaxManager.GetCurrent was not working (always returns nothing).
_ajaxManager is a class variable, I use it later (in the load handler) to add ajaxSettings.
I found that the same problem is presented using a RadAjaxPanel with RestoreOriginalRenderDelegate = False (when two module instances are added to one page, only one instance do ajax requests, and the other does full postbacks). Any suggestion?
With the AJAX I found it to work soundly with v4.8.2 when I set the Control to Support Partial Rendering. Once I set this I can specify which control handle other controls and it works. Mainly I have on my user control a grid, couple buttons, textbox, and a drop down (all being telerik other than the buttons). I included the LinqDataSources and other data sources when dealing with the Grid and AJAX also found not to include the RadWindow and AJAX manager. Once I got all those set the modules worked great.
To test if you are getting to these controls without postbacks run the program locally and see if you hit the code behind of the control without postbacks for some event.
Best Regards,
Bob
I have tried your code in my application. But I got the following error when the code is trying to add the RadAjaxmangaer dynamically:
"The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."
Do you have any idea?
Dan