This is a migrated thread and some comments may be shown as answers.

ScriptManager.RegisterStartupScript failde when in an ajaxrequest

7 Answers 450 Views
Ajax
This is a migrated thread and some comments may be shown as answers.
CSurieux
Top achievements
Rank 2
CSurieux asked on 26 May 2008, 11:45 PM
Hello,

I need to convert the telerik Dynamic Dock creation sample to use RadAjaxManager because I have one included in a masterPage used by my page.

So I replaced the updatePanel by a simple Panel and added another panel around the RadDockLayout.
This is working fine until I decided to Ajaxify the button creating the dock.
In its click handler, it creates a script to move new dock from the Panel to the RadDockZone selected.
using ScriptManager.RegisterStartupScript. but when the button is Ajaxified, this last register stops working, refusing to add any startup script to the PAge.
How to implement a ScriptManager.RegisterStartupScript in these conditions.

Thanks

7 Answers, 1 is accepted

Sort by
0
Konstantin Petkov
Telerik team
answered on 27 May 2008, 06:46 AM
Hello Christian Surieux,

Have you tried adding the script to the RadAjaxControl.ResponseScripts collection instead? An example is available here:

http://www.telerik.com/DEMOS/ASPNET/Prometheus/Ajax/Examples/Common/RecreateScripts/DefaultCS.aspx

All the best,
Konstantin Petkov
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
CSurieux
Top achievements
Rank 2
answered on 27 May 2008, 07:42 AM
Hello Konstantin,

I tried something like this:
using System;  
using System.Collections;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Web;  
using System.Web.SessionState;  
using System.Web.UI;  
using System.Web.UI.WebControls;  
using System.Web.UI.HtmlControls;  
using Telerik.Web.UI;  
 
namespace TEstDock  
{  
    public partial class _Default : System.Web.UI.Page  
    {  
        private List<DockState> CurrentDockStates  
        {  
            get 
            {  
                //Store the info about the added docks in the session. For real life  
                // applications we recommend using database or other storage medium   
                // for persisting this information.  
                List<DockState> _currentDockStates = (List<DockState>)Session["CurrentDockStatesDynamicDocks"];  
                if (Object.Equals(_currentDockStates, null))  
                {  
                    _currentDockStates = new List<DockState>();  
                    Session["CurrentDockStatesDynamicDocks"] = _currentDockStates;  
                }  
                return _currentDockStates;  
            }  
            set 
            {  
                Session["CurrentDockStatesDynamicDocks"] = value;  
            }  
        }  
 
        private RadDock CreateRadDockFromState(DockState state)  
        {  
            RadDock dock = new RadDock();  
            dock.ID = string.Format("RadDock{0}", state.UniqueName);  
            dock.ApplyState(state);  
            dock.Command += new DockCommandEventHandler(dock_Command);  
            dock.Commands.Add(new DockCloseCommand());  
            dock.Commands.Add(new DockExpandCollapseCommand());  
            dock.DockPositionChanged += new DockPositionChangedEventHandler(dock_DockPositionChanged);  
            return dock;  
        }  
 
        void dock_DockPositionChanged(object sender, DockPositionChangedEventArgs e)  
        {  
            ((RadDock)sender).Text  =   ((RadDock)sender).Text+"_A";  
        }  
 
        private RadDock CreateRadDock()  
        {  
            int docksCount = CurrentDockStates.Count;  
 
            RadDock dock = new RadDock();  
            dock.UniqueName = Guid.NewGuid().ToString();  
            dock.ID = string.Format("RadDock{0}", dock.UniqueName);  
            dock.Title = "Dock";  
            dock.Text = string.Format("Added at {0}", DateTime.Now);  
            dock.Width = Unit.Pixel(300);  
 
            dock.Commands.Add(new DockCloseCommand());  
            dock.Commands.Add(new DockExpandCollapseCommand());  
            dock.Command += new DockCommandEventHandler(dock_Command);  
            dock.DockPositionChanged += new DockPositionChangedEventHandler(dock_DockPositionChanged);  
 
            return dock;  
        }  
 
        void dock_Command(object sender, DockCommandEventArgs e)  
        {  
            if (e.Command.Name == "Close")  
            {  
                ScriptManager.RegisterStartupScript(  
                UpdatePanel1,  
                this.GetType(),  
                "RemoveDock",  
                string.Format(@"function _removeDock() {{
    Sys.Application.remove_load(_removeDock);
    $find('{0}').undock();
    $get('{1}').appendChild($get('{0}'));
    $find('{0}').doPostBack('DockPositionChanged');
}};
Sys.Application.add_load(_removeDock);", ((RadDock)sender).ClientID, UpdatePanel1.ClientID),  
                true);  
            }  
        }  
 
        private void CreateSaveStateTrigger(RadDock dock)  
        {  
            //Ensure that the RadDock control will initiate postback  
            // when its position changes on the client or any of the commands is clicked.  
            //Using the trigger we will "ajaxify" that postback.  
            dock.AutoPostBack = true;  
            dock.CommandsAutoPostBack = true;  
            if ( Panel1 != null && AjaxMan.AjaxSettings != null )  
                AjaxMan.AjaxSettings.AddAjaxSetting(dock,Panel1);  
            }  
 
        protected void Page_Init(object sender, EventArgs e)  
        {  
            base.OnLoad(e);  
            int nb  =   CurrentDockStates.Count;  
            for (int i = 0; i < nb; i++)  
            {  
                RadDock dock = CreateRadDockFromState(CurrentDockStates[i]);  
                //We will just add the RadDock control to the RadDockLayout.  
                // You could use any other control for that purpose, just ensure  
                // that it is inside the RadDockLayout control.  
                // The RadDockLayout control will automatically move the RadDock  
                // controls to their corresponding zone in the LoadDockLayout  
                // event (see below).  
                RadDockLayout1.Controls.Add(dock);  
                //We want to save the dock state every time a dock is moved.  
                //CreateSaveStateTrigger(dock);  
            }  
 
        }  
          
        protected override void OnLoad(EventArgs e)  
        {  
            AjaxMan.AjaxSettings.AddAjaxSetting(ButtonAddDock,Panel1);  
 
 
            //Recreate the docks in order to ensure their proper operation  
            for (int i = 0; i < RadDockLayout1.Controls.Count; i++)  
            {  
                Control ctrl    =   RadDockLayout1.Controls[i];  
                if ( !(ctrl is RadDock ) )  
                    continue;  
                RadDock dock = (RadDock)ctrl;  
                //We will just add the RadDock control to the RadDockLayout.  
                // You could use any other control for that purpose, just ensure  
                // that it is inside the RadDockLayout control.  
                // The RadDockLayout control will automatically move the RadDock  
                // controls to their corresponding zone in the LoadDockLayout  
                // event (see below).  
                //We want to save the dock state every time a dock is moved.  
                CreateSaveStateTrigger(dock);  
            }  
        }  
 
        protected void RadDockLayout1_LoadDockLayout(object sender, DockLayoutEventArgs e)  
        {  
            //Populate the event args with the state information. The RadDockLayout control  
            // will automatically move the docks according that information.  
            foreach (DockState state in CurrentDockStates)  
            {  
                e.Positions[state.UniqueName] = state.DockZoneID;  
                e.Indices[state.UniqueName] = state.Index;  
            }  
        }  
 
        protected void RadDockLayout1_SaveDockLayout(object sender, DockLayoutEventArgs e)  
        {  
            //Save the dock state in the session. This will enable us   
            // to recreate the dock in the next Page_Init.   
            CurrentDockStates = RadDockLayout1.GetRegisteredDocksState();  
        }  
 
        protected void ButtonAddDock_Click(object sender, EventArgs e)  
        {  
            RadDock dock = CreateRadDock();  
            //In order to optimize the execution speed we are adding the dock to a   
            // hidden update panel and then register a script which will move it  
            // to RadDockZone1 after the AJAX request completes. If you want to   
            // dock the control in other zone, modify the script according your needs.  
            UpdatePanel1.Controls.Add(dock);  
            /*
            string scr  =   string.Format(@";function _addDock() {{
                Sys.Application.remove_load(_addDock);
                $find('{1}').dock($find('{0}'));
                $find('{0}').doPostBack('DockPositionChanged');
            }};
            Sys.Application.add_load(_addDock);", dock.ClientID, RadDockZone1.ClientID);
            
            ScriptManager.RegisterStartupScript(
            dock,
            this.GetType(),
            "AddDock",
            scr,
            true);
             */ 
            /*
            string scr  =   string.Format(@";function _addDock() {{
                $find('{1}').dock($find('{0}'));
                $find('{0}').doPostBack('DockPositionChanged');
            }};
            if (typeof(Sys) != 'undefined'){{
            if (Sys.Application != null && Sys.Application.notifyScriptLoaded != null){{
            Sys.Application.notifyScriptLoaded();}}}}", dock.ClientID, RadDockZone1.ClientID);
            
            */ 
            string scr  =   string.Format(@";function _addDock() {{alert('{0}');alert('{1}');alert($find('{0}'));
                $find('{0}').doPostBack('DockPositionChanged');
            }};", dock.ClientID, RadDockZone2.ClientID);  
              
              
            ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "AddDock", scr,true);  
            AjaxMan.ResponseScripts.Add("_addDock()");  
            //Right now the RadDock control is not docked. When we try to save its state  
            // later, the DockZoneID will be empty. To workaround this problem we will   
            // set the AutoPostBack property of the RadDock control to true and will   
            // attach an AsyncPostBackTrigger for the DockPositionChanged client-side  
            // event. This will initiate second AJAX request in order to save the state  
            // AFTER the dock was docked in RadDockZone1.  
            CreateSaveStateTrigger(dock);  
        }  
    }  
}  
 

The Page being
<%@ Page Language="C#" AutoEventWireup="True" CodeBehind="Default.aspx.cs" Inherits="TEstDock._Default" %> 
<%@ register tagprefix="telerik" namespace="Telerik.Web.UI" assembly="Telerik.Web.UI" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/tr/xhtml11/dtd/xhtml11.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml">  
<head id="Head1" runat="server">  
    <!--[if lte IE 6]> 
    <style type="text/css">  
    .raddockzone{height:200px}  
    </style> 
    <![endif]--> 
</head> 
<body class="BODY">  
    <form id="Form1" method="post" runat="server">  
        <asp:scriptmanager id="ScriptManager" runat="server" /> 
        <telerik:RadAjaxManager ID='AjaxMan' runat="server" ></telerik:RadAjaxManager> 
        <asp:button runat="server" CssClass="button" id="ButtonAddDock" text="Add Dock" onclick="ButtonAddDock_Click" /> 
        <asp:button runat="server" id="ButtonPostback" CssClass="button" text="Make Postback" /> 
        <br/><br/>  
        <asp:Panel ID='Panel1' runat=server>  
        <telerik:raddocklayout runat="server" id="RadDockLayout1"   
            onsavedocklayout="RadDockLayout1_SaveDockLayout" 
            onloaddocklayout="RadDockLayout1_LoadDockLayout">  
            <telerik:raddockzone runat="server" id="RadDockZone1" Width="300" MinHeight="200" Style="float:left;margin-right:20px;">  
            </telerik:raddockzone> 
            <telerik:raddockzone Width="300" MinHeight="200" runat="server" id="RadDockZone2" Style="float:left;">  
            </telerik:raddockzone> 
            <div style="display:none">  
                Hidden UpdatePanel, which is used to receive the new dock controls.   
                We will move them with script to the desired initial dock zone.  
                <asp:panel runat="server" id="UpdatePanel1">  
                </asp:panel> 
            </div> 
        </telerik:raddocklayout> 
        </asp:Panel> 
    </form> 
</body> 
</html> 

As you can see, I have problems with this solution because the scrpit added to
 AjaxMan.ResponseScript runs too early in the Page,controls are not loaded and $find returns null.

How to delay this script until page full loading ?

Thanks
CS

0
Sophy
Telerik team
answered on 27 May 2008, 11:17 AM
Hello Christian Surieux,

Currently, there are some problems in RadDock for ASP.NET working with RadAjaxManager. Improving  the ability of RadDock to work with AJAX and simplifying the whole mechanism is in our TODO list for the next release. For the time being we suggest you use UpdatePanels instead of RadAjaxManager to ajaxify the dynamically added docks.

Kind regards,
Sophy
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
CSurieux
Top achievements
Rank 2
answered on 27 May 2008, 11:35 AM
Hello Sophy,

Infortunately my pages are using a common standard MasterPage which must contain a RadAjaxManager to provide overall Ajax management and I have other controls in the page using RadDock which use it.
I wll try to find a way with UpdatePanels but I would appreciate any help to rely only on RadAjaxManager.
Is there any roadmap for the improvments of RadDock you announced ?

Concerning my sample,I only need a javascript instruction to delay the running of my script until full html loading in the explorer bacause it seems that scripts set in the ajaxmanager control are run as soon as the corresponding object is created. As I am not a javascript expert I will try to find something in the Ajax.Net script library.

Thanks for answer.
CS
0
Sebastian
Telerik team
answered on 03 Jun 2008, 06:59 AM
Hello Christian,

Currently, there are several complex scenarios with asp UpdatePanels in which the proper functioning of the RadDock for ASP.NET is disturbed. However, we plan to improve the ability of RadDock to work with ASP.NET AJAX for the next official release as well as simplify the mechanism of ajaxifying the RadDock control.

Additionally, we will do everything possible to improve the interoperability between RadAjax and RadDock for ASP.NET AJAX. I hope that using plain MS UpdatePanels to ajaxify your RadDock instance is feasible temporary workaround for you.

Kind regards,
Stephen
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
CSurieux
Top achievements
Rank 2
answered on 03 Jun 2008, 07:25 AM
Hello Stephen,

Thanks for answer, I know that Telerik is working on this, certainly hard.
For my personnal issue I let my Add button with a standard postback. Not as user friendly as it could be. I will wait for your progress. How long the path to the next release ?

Regards
CS
0
Sophy
Telerik team
answered on 03 Jun 2008, 07:53 AM
Hello Christian,

Thank you for your patience and understanding.
The next official release is scheduled for July.

If you have other questions, do contact us again.

Best regards,
Sophy
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
Tags
Ajax
Asked by
CSurieux
Top achievements
Rank 2
Answers by
Konstantin Petkov
Telerik team
CSurieux
Top achievements
Rank 2
Sophy
Telerik team
Sebastian
Telerik team
Share this question
or