Dynamically creating multiple docks on a button click

7 posts, 1 answers
  1. Hrvach
    Hrvach avatar
    19 posts
    Member since:
    Aug 2012

    Posted 02 May 2012 Link to this post

    Hello!

    I'm having some problems trying to dynamically create multiple docks at the same time.

    What I'd like to achieve is to have multiple Docks added to the DockZone on a button click, but the only thing I get is first Dock properly created and displayed when the rest of them aren't displayed (they are displayed after I refresh the webpage) and they are created but floating outside of the zone.

    I have similar scenario when creating one Dock at a time and it works like a charm.

    This is the code:
    protected void rbAddTickets_Click(object sender, EventArgs e)
            {
                var ticketList = (from t in db.Ticket
                                  where t.idManager == idManager && t.Zatvoren == false || t.idManager == null && t.Zatvoren == false
                                  select t).ToList();
     
                var memoTicketList = from t in ticketList
                                     where t.Memo == null || t.Memo == false
                                     orderby t.Firma.Naziv, t.idNadredeniTicket, t.RedniBroj, t.Opis
                                     select t;
     
                foreach (var ticket in memoTicketList)
                {
                    RadDock dock = new RadDock();
                    dock.UniqueName = ticket.idTicket.ToString();
                    dock.ID = string.Format("RadDock{0}", dock.UniqueName);
                    dock.Title = ticket.idNadredeniTicket + "-" + ticket.RedniBroj + " (" + ticket.Firma.Naziv + ")";
                    dock.Text = ticket.Opis;
                    dock.DockMode = DockMode.Docked;
                    //dock.Index = Convert.ToInt32(Session["MinIndex"]) - 1;
     
     
                    dock.Commands.Add(new DockCloseCommand());
                    dock.Commands.Add(new DockExpandCollapseCommand());
                    dock.Command += new DockCommandEventHandler(DockCommands);
     
                    //ticket.Memo = true;
                    //db.SaveChanges(); OMOGUĆI KASNIJE
     
                    UpdatePanel1.ContentTemplateContainer.Controls.Add(dock);
     
                    ScriptManager.RegisterStartupScript(
                    dock,
                    this.GetType(),
                    "AddDock",
                    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, rdzIncidenti.ClientID),
                    true);
                    CreateSaveStateTrigger(dock);
     
                }
            }

    So, to sum everything up. I would like to generate Docks properly; display them immediately, without having to refresh the page and create them inside DockZone.

    Any help would be appreciated.

    Regards,

    Hrvoje
  2. Slav
    Admin
    Slav avatar
    1355 posts

    Posted 03 May 2012 Link to this post

    Hi Hrvoje,

    The encountered behavior appears to be caused by problems in saving/loading the layout of the RadDock controls on the page (the missing docks) and setting different ID or/and UniqueName, when recreating the RadDocks after a postback (the floating docks).

    The online demo Dock / My Portal is a good example of dynamically creating and persisting the state of RadDocks and the scenario it implements is similar to yours, so I would suggest using it as a reference for your further development. The help article Dynamically Creating RadDock Controls will also be useful, as it lists the main steps for dynamically creating RadDocks.

    Overall, the code that you have provided appears to be correct, although I would suggest adding the new RadDocks in the Controls collection of RadDockLayout and docking them in a particular RadDockZone via the Dock method, when inserted in the page on button click. This is implemented in the ButtonAddDock_Click event handler in the linked demo via the following lines of code:
    RadDockZone dz = (RadDockZone)FindControl(DropDownZone.SelectedItem.Text);
     
    //adding the dock to the docklayout and then docking it to the zone to avoid ViewState issues on subsequent postback
    RadDockLayout1.Controls.Add(dock);
    dock.Dock(dz);

    Since I am mostly guessing as to what the rest of your implementation is, I would recommend examining the provided resources and utilizing them in order to achieve the desired functionality.

    All the best,
    Slav
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Hrvach
    Hrvach avatar
    19 posts
    Member since:
    Aug 2012

    Posted 04 May 2012 Link to this post

    Hello Slav and thank you for the answer!

    However, as I already wrote on the StackOverflow, this isn't exactly the solution of it. Instead I had to use the code from My Portal demo and, most important, it works!

    I have one more question though. What is the best practice for storing DockState in the database. I'm asking this because I wasn't able to find any example of storing to database.

    My scenario is as follows: I have 2 user roles with couple of users in each group. First role group can only browse through the displayed Docks and the second group (administrators) can edit them in every possible way. Important thing is that second group adds Docks only for the selected user.

    So, I thought it should look like this in database; I have fields: [idUser], [DockState]. The problem is I don't know how to code PrivateDockStates to get the string values from the and convert them to the DockState list.

    Thank you in advance.

    Regards,

    Hrvoje
  5. Slav
    Admin
    Slav avatar
    1355 posts

    Posted 04 May 2012 Link to this post

    Hello Hrvoje,

    The code library article Saving State of Dynamically Created RadDocks in DataBase using Hidden UpdatePanel includes an example of storing the RadDocks' layout in a database. What you need to do in order to incorporate this approach in your project is to create a new sql connection and configure the property CurrentDockStates and the event-handler RadDockLayout1_SaveDockLayout as shown in the sample. The dock state is saved in the States table of the DockState database so you can check the updated records after every change in the RadDock's configuration.

    Regards,
    Slav
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  6. Hrvach
    Hrvach avatar
    19 posts
    Member since:
    Aug 2012

    Posted 04 May 2012 Link to this post

    Hello Slav,

    I have tried both examples you posted here and I'm still not able to solve the problem because code seems to be fine. What bothers me the most is that I'm able to dynamically add Docks one by one (on a button click), but when it comes to dynamically adding couple of them everything goes wrong (floating Docks).

    So, in my opinion, it should be working because mechanism of functioning should be pretty much the same in both cases. Here are the SaveDockLayout and LoadDockLayout events.

    protected void rdlIncidenti_SaveDockLayout(object sender, Telerik.Web.UI.DockLayoutEventArgs e)
    {
        string dockState;
        System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        List<DockState> stateList = rdlIncidenti.GetRegisteredDocksState();
        StringBuilder serializedList = new StringBuilder();
        int i = 0;
        while (i < stateList.Count)
        {
            serializedList.Append(serializer.Serialize(stateList[i]));
            serializedList.Append("|");
            i++;
        }
        dockState = serializedList.ToString();
        if (dockState.Trim() != String.Empty)
        {
            try
            {
                if (idOvlasti == 1)
                {
                    if (idManager != 0)
                    {
                        int dockDBCount = db.Dock.Where(d => d.idManager == idManager).Count();
     
                        if (dockDBCount == 1)
                        {
                            Dock dockDB = db.Dock.SingleOrDefault(d => d.idManager == idManager);
                            dockDB.DockProperties = dockState;
     
                            db.SaveChanges();
                        }
                        else
                        {
                            Dock dockDB = new Dock();
                            dockDB.DockProperties = dockState;
                            dockDB.idManager = idManager;
     
                            db.AddToDock(dockDB);
                            db.SaveChanges();
                        }
                    }
                }
            }
            catch
            {
            }
        }
    }

    protected void rdlIncidenti_LoadDockLayout(object sender, Telerik.Web.UI.DockLayoutEventArgs e)
    {
        System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        string dockState = "";
        try
        {
            if (idOvlasti == 1)
            {
                if (idManager != 0)
                {
                    Dock dockDB = db.Dock.SingleOrDefault(d => d.idManager == idManager);
                    dockState = dockDB.DockProperties.ToString();
                }
            }
            else
            {
                Dock dockDB = db.Dock.SingleOrDefault(d => d.idManager == idAuthenticatedUser);
                dockState = dockDB.DockProperties.ToString();
            }
     
        }
        catch
        {
        }
     
        string[] currentDockStates = dockState.Split('|');
        foreach (string stringState in currentDockStates)
        {
            if (stringState.Trim() != string.Empty)
            {
                DockState state = serializer.Deserialize<DockState>(stringState);
                e.Positions[state.UniqueName] = state.DockZoneID;
                e.Indices[state.UniqueName] = state.Index;
            }
        }
    }

    Regards,

    Hrvoje
  7. Answer
    Slav
    Admin
    Slav avatar
    1355 posts

    Posted 09 May 2012 Link to this post

    Hello Hrvoje,

    As I noted, floating RadDock controls usually means that the value of their properties ID and UniqueName is not restored correctly and the mechanism for persisting their layout is not able to locate their position in the DOM three. In the examples that I provided the ID and UniqueName of every initially created RadDock is set with unique vales:
    dock.UniqueName = Guid.NewGuid().ToString().Replace("-", "a");
    dock.ID = string.Format("RadDock{0}", dock.UniqueName);
    and when the dock controls are recreated, the UniqueName stored in the saved state is used to recover the correct ID:
    dock.ID = string.Format("RadDock{0}", state.UniqueName);

    The attached sample will help you configure properly your actual project. It is based on the project from the Code Library article and includes some modifications from the demo My Portal. I have also added a button that includes several RadDocks in one request to the server, as required in your scenario.

    Greetings,
    Slav
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  8. Hrvach
    Hrvach avatar
    19 posts
    Member since:
    Aug 2012

    Posted 09 May 2012 Link to this post

    Hello Slav!

    Thank you, that was exactly what I was looking for and most important, it solved my problem!

    I hope others will also find this example useful.

    Regards,

    Hrvoje
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017