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

Two components with the same id....

14 Answers 199 Views
Dock
This is a migrated thread and some comments may be shown as answers.
Kurt
Top achievements
Rank 1
Kurt asked on 26 Jun 2009, 07:38 AM
Hi, I have read through pretty much every post I could regarding this issue, but have yet to find the answer to my problem.  I am dynamically loading docks to give the appearance of a "web os".  When a user clicks to open a new dock, it will usually open it.  However, if there are any docks "on the stage", it throws the above error.  I'm not using a raddockzone as I require windows that float only.  The docks are loaded in an AJAX update panel that is set to a conditional update mode. 

Code snippet below:

 

 

Protected Sub LoadDock(ByVal sender As Object, ByVal e As CommandEventArgs)

 

 

Dim id As String = e.CommandName

 

lblErr.Text = id.ToString

 

Dim ds As New DataSet

 

ds = odata.ReturnDS(

"sp_GadgetsByGadgetName", "@GadgetName", id.ToString)

 

 

If LoadedGadgets(ReturnUserName() & "_" & ds.Tables("Generic").Rows(0).Item("GN")) = "False" Then

 

 

 

 

 

 

'Create Dock

 

 

 

 

 

 

Dim dock As New RadDock()

 

 

Dim widget As New UserControl

 

widget = LoadControl(ds.Tables(

"Generic").Rows(0).Item("GadgetContent"))

 

 

Dim X As Integer = (ResolutionX / 2) - (CInt(ds.Tables("Generic").Rows(0).Item("GadgetWidth")) / 2)

 

 

Dim Y As Integer = (ResolutionY / 2) - (CInt(ds.Tables("Generic").Rows(0).Item("GadgetHeight")) / 2)

 

 

With dock

 

.ID = ReturnUserName() &

"_" & ds.Tables("Generic").Rows(0).Item("GN")

 

.Title = ds.Tables(

"Generic").Rows(0).Item("GN")

 

.Skin =

"WebBlue"

 

 

 

 

 

.UniqueName = Guid.NewGuid().ToString()

.Width =

CInt(ds.Tables("Generic").Rows(0).Item("GadgetWidth"))

 

.Height =

CInt(ds.Tables("Generic").Rows(0).Item("GadgetHeight"))

 

.Left = X

.Top = Y

.Resizable =

False

 

 

 

 

 

.Pinned =

False

 

 

 

 

 

.OnClientDragEnd =

"Moved"

 

 

 

 

 

.OnClientDragStart =

"OnClientDragStart"

 

 

 

 

 

.DockHandle = DockHandle.TitleBar

.DockMode = DockMode.Floating

.BorderStyle = BorderStyle.None

.Attributes.Add(

"style", "filter:progid:DXImageTransform.Microsoft.Shadow(direction=145, color=#4b4b4b, strength=5) progid:DXImageTransform.Microsoft.Alpha(opacity=95);")

 

.OnClientCommand =

"OnClientCommand"

 

 

 

 

 

.EnableViewState =

False

 

 

 

 

 

 

End With

 

 

 

 

 

RadDockLayout1.Controls.Add(dock)

dock.ContentContainer.Controls.Add(widget)

PlaceGadgetInternal(ds.Tables(

"Generic").Rows(0).Item("GN"), X.ToString, Y.ToString, ReturnUserName)

 

 

End If

 

 

 

 

 

ds.Clear()

ds.Dispose()

ds =

Nothing

 

 

 

 

 

 

 

End Sub

 

14 Answers, 1 is accepted

Sort by
0
Kurt
Top achievements
Rank 1
answered on 30 Jun 2009, 05:45 PM
Nothing huh?  Should I just use a 3rd party library like ExtJS or JQuery for this? 
0
Obi-Wan Kenobi
Top achievements
Rank 1
answered on 01 Jul 2009, 02:17 PM
The error means that you have 2 RadDocks with the same ID on the page.
You could receive such an error if you create two RadDocks with equal ID's or update via AJAX a floating dock.
If you want to use Ajax with RadDock control  all RadDocks should be docked and you should update all RadDockZones.
A simple example which illustrates how to use RadDock with RadAjax is available here:
http://demos.telerik.com/aspnet-ajax/dock/examples/myportal/defaultcs.aspx
0
Kurt
Top achievements
Rank 1
answered on 01 Jul 2009, 09:44 PM
Obi-Wan, thanks for your reply.

I am updating the floating dock locations to a database whenever a new dock is added or a dock is moved.  Docking to a zone however, is out of the question as these panels must remain floating.  Is this a limitation of RadDock?  I seem to remember seeing a post to that effect and that the Q12009 release was supposed to fix it?
0
Obi-Wan Kenobi
Top achievements
Rank 1
answered on 07 Jul 2009, 12:43 PM
"The problem you experience is happening because you update a floating RadDock with AJAX. When dragging the dock you move it outside the update panel and this causes AJAX not to work properly as it attempts to recreate the dock at the place it was previously located and  the dock is moved to the new place and stays there. In this way two docks with the same id appear on the page and this leads to an exception. Note that this is a common problem of controls which can be moved in the DOM tree."

You could use RadDock with ajax as is described below:
1)    You can update RadDockZones while all RadDocks are docked.
2)    You can update only the RadDock's content via AJAX, e.g. Add the entire content in UpdatePanel and add the UpdatePanel in the RadDock

Hope this helps.
0
Kurt
Top achievements
Rank 1
answered on 07 Jul 2009, 07:02 PM
Obi,

I have no RadDockZones on the page, so that is not an option.  Also, I cannot simply update the dock's content as I must also inquire about it's floating location as well.

Basically, this is the flow of events:

There is a stage or desktop that houses the floating docks.  A user can add a particular dock to that stage by adding it from a menu.  When they add a new floating dock to the stage it refreshes the two update panels (1 for the menu- to remove the added dock from the menu, and 1 for the stage where the new floating dock appears).  When a user moves a floating dock on the stage it updates the stage's update panel to save the position for the user's next visit.
0
Obi-Wan Kenobi
Top achievements
Rank 1
answered on 13 Jul 2009, 11:12 AM
I managed to create an example(based on the old MyPortal example) where RadDocks are added dynamically via AJAX to the form(you should choose  AddItToThePage from the DropDownZone) . Also the state will be saved on each RadDock's move,close, expand or collapse action.
ASPX:
<%@ 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 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" /> 
        <div class="module">  
            Select Module: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  
            <asp:dropdownlist runat="server" id="DroptDownWidget" width="150">  
                <asp:listitem text="ExchangeRates.ascx" value="Controls/ExchangeRates.ascx" selected="true"></asp:listitem> 
                <asp:listitem text="Horoscopes.ascx" value="Controls/Horoscopes.ascx"></asp:listitem> 
                <asp:listitem text="News.ascx" value="Controls/News.ascx"></asp:listitem>                  
                <asp:listitem text="Weather.ascx" value="Controls/Weather.ascx"></asp:listitem> 
            </asp:dropdownlist> 
            <br/>Select Docking Zone:  
            <asp:dropdownlist id="DropDownZone" runat="server" datasource="<%#GetZones() %>" 
                datatextfield="ID" datavaluefield="ClientID" width="150">  
            </asp:dropdownlist> 
            <asp:button runat="server" id="ButtonAddDock" text="Add Dock" onclick="ButtonAddDock_Click" /> 
        </div> 
        <br/> 
        <telerik:raddocklayout runat="server" id="RadDockLayout1"   
            onsavedocklayout="RadDockLayout1_SaveDockLayout" 
            onloaddocklayout="RadDockLayout1_LoadDockLayout">  
            <table> 
                <tr> 
                    <td> 
                        <telerik:raddockzone runat="server" id="RadDockZone1" width="300"   
                        FitDocks="true" Height="400" > 
                        </telerik:raddockzone>          
                    </td> 
                    <td> 
                        <telerik:raddockzone runat="server" id="RadDockZone2" width="300"   
                        FitDocks="true" Height="400" > 
                        </telerik:raddockzone>          
                    </td> 
                </tr> 
            </table> 
              
            <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:updatepanel runat="server" id="UpdatePanel1">  
                    <triggers> 
                        <asp:asyncpostbacktrigger controlid="ButtonAddDock" eventname="Click" /> 
                    </triggers> 
                </asp:updatepanel> 
            </div> 
        </telerik:raddocklayout> 
    </form> 
</body> 
</html> 
 
Codebehind:
  public partial class DefaultCS : 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["CurrentDockStatesMyPortal"];  
                if (Object.Equals(_currentDockStates, null))  
                {  
                    _currentDockStates = new List<DockState>();  
                    Session["CurrentDockStatesMyPortal"] = _currentDockStates;  
                }  
                return _currentDockStates;  
            }  
            set 
            {  
                Session["CurrentDockStatesMyPortal"] = value;  
            }  
        }  
 
        protected void Page_Load(object sender, EventArgs e)  
        {  
            if (!IsPostBack)  
            {  
                DropDownZone.DataBind();  
                DropDownZone.Items.Add("AddItToThePage");  
            }  
        }  
 
        public ArrayList GetZones()  
        {  
            ArrayList zones = new ArrayList();  
            zones.Add(RadDockZone1);  
            zones.Add(RadDockZone2);  
 
            return zones;  
        }  
 
        protected void Page_Init(object sender, EventArgs e)  
        {  
            //Recreate the docks in order to ensure their proper operation  
            for (int i = 0; i < CurrentDockStates.Count; i++)  
            {  
                if (CurrentDockStates[i].Closed == false)  
                {  
                    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);  
                    //Load the selected widget  
                    LoadWidget(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();  
        }  
 
        private RadDock CreateRadDockFromState(DockState state)  
        {  
            RadDock dock = new RadDock();  
            dock.ID = string.Format("RadDock{0}", state.UniqueName);  
            dock.Width = Unit.Pixel(300);  
            dock.Height = Unit.Pixel(300);  
            dock.ApplyState(state);  
            dock.Command += new DockCommandEventHandler(dock_Command);  
            dock.Commands.Add(new DockCloseCommand());  
            dock.Commands.Add(new DockExpandCollapseCommand());  
 
            return dock;  
        }  
 
        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.Height = Unit.Pixel(300);  
            dock.Style.Add("zIndex""0");  
 
            dock.Commands.Add(new DockCloseCommand());  
            dock.Commands.Add(new DockExpandCollapseCommand());  
            dock.Command += new DockCommandEventHandler(dock_Command);  
 
            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;  
            dock.Style.Add("zIndex""0");  
 
            AsyncPostBackTrigger saveStateTrigger = new AsyncPostBackTrigger();  
            saveStateTrigger.ControlID = dock.ID;  
            saveStateTrigger.EventName = "DockPositionChanged";  
            UpdatePanel1.Triggers.Add(saveStateTrigger);  
 
            saveStateTrigger = new AsyncPostBackTrigger();  
            saveStateTrigger.ControlID = dock.ID;  
            saveStateTrigger.EventName = "Command";  
            UpdatePanel1.Triggers.Add(saveStateTrigger);  
        }  
 
        private void LoadWidget(RadDock dock)  
        {  
            if (string.IsNullOrEmpty(dock.Tag))  
            {  
                return;  
            }  
            Control widget = LoadControl(dock.Tag);  
            dock.ContentContainer.Controls.Add(widget);  
        }  
 
 
        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.ContentTemplateContainer.Controls.Add(dock);  
 
            
 
            if (DropDownZone.SelectedValue != "AddItToThePage")  
            {  
                ScriptManager.RegisterStartupScript(  
                          dock,  
                          this.GetType(),  
                          "AddDock",  
                          string.Format(@"function _addDock() {{
                    Sys.Application.remove_load(_addDock);
                    $find('{0}').originalZIndex = '';
                    $find('{1}').dock($find('{0}'));
                    $find('{0}').doPostBack('DockPositionChanged');
                }};
                Sys.Application.add_load(_addDock);", dock.ClientID, DropDownZone.SelectedValue),  
                 true);  
            }  
            else 
            {  
                //Add RadDock to the form/not in zone.  
                ScriptManager.RegisterStartupScript(  
                        dock,  
                        this.GetType(),  
                        "AddDockToPage",  
                        string.Format(@"function _addDockToPage() {{
                Sys.Application.remove_load(_addDockToPage);
                var dock = $find('{0}');
                dock._form.appendChild(dock.get_element());
                dock.set_closed(false);
                dock.set_left(100);
                dock.set_top(100);
                $find('{0}').doPostBack('DockPositionChanged');
            }};
            Sys.Application.add_load(_addDockToPage);", dock.ClientID),  
                        true);  
            }  
 
            //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);  
 
            //Load the selected widget in the RadDock control  
            dock.Tag = DroptDownWidget.SelectedValue;  
            LoadWidget(dock);  
        }  
    } 
You can get the UserControls( ExchangeRates.ascx,Horoscopes.ascx etc.) from the MyPortal example
Hope this helps.
0
Kurt
Top achievements
Rank 1
answered on 13 Jul 2009, 11:36 PM
Obi,

Thanks.  Do you know if this code example will still work if I'm saving and getting the positions of the docks with a database instead of the session method you provided?

Thanks,
Kurt
0
Obi-Wan Kenobi
Top achievements
Rank 1
answered on 14 Jul 2009, 12:42 PM
It will work with DB. All you need to do is to load State from a DB when the page loads for the first time in the RadDockLayout1_LoadDockLayout handler.
And save the current state in a DB in the RadDockLayout1_SaveDockLayout handler.
0
Kurt
Top achievements
Rank 1
answered on 14 Jul 2009, 04:19 PM
Obi,

Thanks, you're a true Jedi Master!  I'll try it out and let you know.

Best Regards,
Kurt
0
USI
Top achievements
Rank 1
answered on 18 Mar 2011, 04:43 PM
Hi Obi,

I adapt your example to open docks only in floatable mode (basically removing the raddockzone related code). I create an asp site and all is working good.

Now I have to integrate my solution into a sharepoint 2010 web part. The problem I'm facing now is that the script that is executed in client side (AddDockToPage) at the first ajax call is giving an error.

The line var dock = $find('{0}'); is returning null. The HTML generated by the dock is present on the page but it seems that the corresponding raddock javascript instance is not.

Any idea?
0
Pero
Telerik team
answered on 22 Mar 2011, 03:24 PM
Hi,

One problem for the issue might be because you are ajaxifying floating docks. Here is detailed description on why there might be a problem:
Note that, when ajaxifying floating docks, once a dock is moved it goes outside of the UpdatePanel. This initiates new ajax request, and the UpdatePanel refreshes its content. However, since we have dragged the dock outside of the UpdatePanel, an identical dock will be created on its place in the UpdatePanel, and this will result in a JavaScript error. This JS error causes the dock to not be created correctly on the client, and that's why the $find shortcut returns null.
This being said, please make sure the docks are within the update panel when doing ajax calls.

Another thing that might be causing the issue is, the fact that incorrect ID is passed to the $find method. Could you please compare the parameter passed to the method, and the id attribute of the dock's outermost HTML element? If they are different then this is the problem for sure.

Of none of the above helps, please open a new support ticket and send us a sample demo that shows the problem.

Regards,
Pero
the Telerik team
0
USI
Top achievements
Rank 1
answered on 22 Mar 2011, 04:03 PM
Hi,

Thanks for the answer.

I understand the fact that when moved, the dock is placed outside the update panel but my problem occurs at the very first ajax request (no docks exists in the page at this point). This request adds a new Dock to the hidden update panel in server side and then the javascript code is executed at client side after the call is done. This code should move the dock to the page.

                var dock = $find('{0}');
                dock._form.appendChild(dock.get_element());

At this point the $find function returns null on client side. I pass the correct Id to this function as it appears in the dock's Html element.

Other thing I realized is if I make a full postback, the $find function seems to start working.

I managed to make my solution work in simple asp site but when moving to sharepoint the problem occurs.

Could it be a sharepoint 2010 issue or conflict?  I already tried the hidden update panel approach and also using the radAjaxManager but the same problem occurs at the first ajax request. It looks like to me that the RadDock client instance is not created when added via Ajax.



Michael Pinheiro
0
USI
Top achievements
Rank 1
answered on 22 Mar 2011, 05:44 PM
I sent a ticket #406210 regarding this issue.
0
Pero
Telerik team
answered on 23 Mar 2011, 10:53 AM
Hello Michael,

Thank you for opening the support ticket. I provided the solution there, but I will also post it here so it is available to our community. Here it is:

I examined your code, and noticed that the script registered from the server is causing the problem. The script added with the AjaxManager will be immediately executed when the HTML comes to the client, even before the Ajax controls are created on the client. That's why the $find method returns null, the dock's client object is not created yet.
To fix this issue, you should change the script a little bit, so it is executed after all controls are created, like Application.load for example. Here is how the script should look like:

string script = string.Format(@"
        function _addDock()
        {{
            var dock = $find('{0}');
            alert('$find() returning value: '+ dock);
            dock._form.appendChild(dock.get_element());
            Sys.Application.remove_load(_addDock);
        }}
        Sys.Application.add_load(_addDock);
        ", dock.ClientID);
AjaxManager.ResponseScripts.Add(script);

All the best,
Pero
the Telerik team
Tags
Dock
Asked by
Kurt
Top achievements
Rank 1
Answers by
Kurt
Top achievements
Rank 1
Obi-Wan Kenobi
Top achievements
Rank 1
USI
Top achievements
Rank 1
Pero
Telerik team
Share this question
or