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

Suggestion: dynamically switch between server- and client-side behaviour and predictive loading

5 Answers 208 Views
TabStrip
This is a migrated thread and some comments may be shown as answers.
Rob
Top achievements
Rank 2
Rob asked on 11 Jul 2008, 02:57 PM
Hi there,

I'm not sure if this is possible without a lot of custom code, but the following suggestion would be extremely useful in our current implementation of the rad tabs.

We are developing a very large web application with many records/pages each having up to 15 tabs and each tab containing up to 20 controls.

Using update panels, we have changed the control to dynamically load the tab being switched to to reduce the amount of information (and load time) we initially got when the record was first loaded.

Therefore, on load only the first tab is rendered. Subsequent tab switches load the associated tab page on demand.

It would be very useful if the tabs were aware of which tab panels had been downloaded so that switching back to a previous tab wouldn't require it to be downloadeed again, just displayed. Effectively changing the tab switch from a server-side one to a client-side one.

This could then be further enhanced by downloading the first tab initially and then as users are filling it out, downloadeing subsequent tab content behind the scenes using ajax calls.

A large requst I knowm, but may be useful to many.

Cheers,

Rob

5 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 14 Jul 2008, 02:33 PM
Hello Rob,

I beleive this online example demonstrates similar implementation.

Regards,
Albert
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Zoe
Top achievements
Rank 2
answered on 17 Jul 2008, 01:01 PM
Hi,

This doesn't quite do what is being asked, because with each postback on a tab (when clicked for the first time), all the previous pageview content that has been loaded, is being downloaded again. So if you had 10 tabs and click each in order, when you click the last one all the content of each of the 10 tabs is being downloaded. I guess this is because the AjaxManager is updating the whole of the RadMultiPage control, rather than individual pages as required. I have managed to do this, but it requires using update panels within the pages and then a container within that (div or panel) to toggle visibility of the content within the update panels, and some extra javascript - it isn't a nice implementation!

It may be we haven't implemented the example correctly, but it is incomplete, in that nowhere in the example does it show you any actual tabs being created (either in markup or dynamically in code) - that I can see anyway. I've also implemented it slightly differently because it is useful to have the pages and their content created in markup, so I have done as follows instead, which seems to work:
    <telerik:RadTabStrip ID="RadTabStrip1" runat="server" MultiPageID="RadMultiPage1" OnTabClick="RadTabStrip1_TabClick" SelectedIndex="0" EnableAjaxSkinRendering="False" EnableEmbeddedSkins="False" OnClientTabSelecting="onTabSelecting"
        <Tabs> 
            <telerik:RadTab runat="server" Text="Tab1" PageViewID="Tab1"
            </telerik:RadTab> 
            <telerik:RadTab runat="server" Text="Tab2"
            </telerik:RadTab> 
            <telerik:RadTab runat="server" Text="Tab3"
            </telerik:RadTab> 
        </Tabs> 
    </telerik:RadTabStrip> 
    <telerik:RadMultiPage ID="RadMultiPage1" runat="server" SelectedIndex="0"
        <telerik:RadPageView ID="Tab1" runat="server"
            1 
        </telerik:RadPageView> 
        <telerik:RadPageView ID="Tab2" runat="server" Visible="false"
            2 
        </telerik:RadPageView> 
        <telerik:RadPageView ID="Tab3" runat="server" Visible="false"
            3 
        </telerik:RadPageView> 
    </telerik:RadMultiPage> 

        protected void RadTabStrip1_TabClick(object sender, Telerik.Web.UI.RadTabStripEventArgs e) 
        { 
            e.Tab.PageViewID = e.Tab.Text; 
            e.Tab.PageView.Selected = true
            e.Tab.PageView.Visible = true
        } 
 
0
Rob
Top achievements
Rank 2
answered on 22 Jul 2008, 03:42 PM
Hi there,

is there any feedback on how this could be accomplished?

Cheers,

Rob
0
Atanas Korchev
Telerik team
answered on 23 Jul 2008, 07:17 AM
Hello Rob,

At the time being only the approach demonstrated in our online examples is supported. RadPageView cannot be updated on its own by RadAjaxManager because it is part of another control (RadMultiPage).

Regards,
Albert
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Rob
Top achievements
Rank 2
answered on 15 Aug 2008, 06:26 PM
After quite a lot of fiddling, I thought I'd share two different methods of how the tabstrip can be updated.
Rather than have the whole page rendered and client-side tabbing, each tab can be rendered on demand when it is switched to. This can be achieved with appropriate update panels and by switching on autopostback and clickselectedtab on the tabstrip and switching on renderselectedpageonly on the multipages like so:

<asp:UpdatePanel runat="server" ID="updTabs" RenderMode="Inline"
    <ContentTemplate> 
        <telerik:radtabstrip id="radTabs" runat="server" enableviewstate="false" autopostback="True" clickselectedtab="True" multipageid="rmpMainPages" selectedindex="0"
            <Tabs> 
                <telerik:RadTab runat="server" PageViewID="pgvPerson" Text="Person" /> 
                <telerik:RadTab runat="server" PageViewID="pgvContact" Text="Contact" /> 
                <telerik:RadTab runat="server" PageViewID="pgvRelations" Text="Relations" /> 
            </Tabs> 
        </telerik:radtabstrip> 
    </ContentTemplate> 
</asp:UpdatePanel> 
<asp:UpdatePanel runat="server" ID="updPages" RenderMode="Inline" ChildrenAsTriggers="false" UpdateMode="Conditional"
    <ContentTemplate> 
        <telerik:radmultipage id="rmpMainPages" runat="server" selectedindex="0" renderselectedpageonly="True"
            <telerik:RadPageView ID="pgvPerson" runat="server"
                Person Details 
            </telerik:RadPageView> 
            <telerik:RadPageView ID="pgvContact" runat="server"
                Contact Details 
            </telerik:RadPageView> 
            <telerik:RadPageView ID="pgvRelations" runat="server"
                Relation Details 
            </telerik:RadPageView> 
        </telerik:radmultipage> 
    </ContentTemplate> 
    <Triggers> 
        <asp:AsyncPostBackTrigger ControlID="radTabs" EventName="TabClick" /> 
    </Triggers> 
</asp:UpdatePanel> 

The next approach is a bit more involved which is to load the first tab page onto the client and then allow the user to begin using it while other tabs are preloaded and enabled in the background using partial postbacks.

The ASP.Net code requires all but the first tab to be disabled and all tabpages except the first to contain an updatepanel and placeholder with visible set to false:

<telerik:radtabstrip id="radTabs" runat="server" multipageid="rmpMainPages" selectedindex="0"
                        <Tabs> 
                            <telerik:RadTab runat="server" PageViewID="pgvPerson" Text="Person" /> 
                            <telerik:RadTab runat="server" PageViewID="pgvContact" Text="Contact" enabled="false" /> 
                            <telerik:RadTab runat="server" PageViewID="pgvRelations" Text="Relations" enabled="false" /> 
                        </Tabs> 
                    </telerik:radtabstrip> 
                    <telerik:radmultipage id="rmpMainPages" runat="server" selectedindex="0" cssclass="recordPage"
                        <telerik:RadPageView ID="pgvPerson" runat="server"
                            Person Details 
                        </telerik:RadPageView>       
                        <telerik:RadPageView ID="pgvContact" runat="server"
                            <asp:UpdatePanel runat="server" ID="UpdatePanel1" RenderMode="Inline" ChildrenAsTriggers="false" UpdateMode="Conditional"
                                <ContentTemplate> 
                                    <asp:PlaceHolder ID="ph2" runat="server" Visible="false"
                                        Contact Details 
                                    </asp:PlaceHolder> 
                                </ContentTemplate> 
                            </asp:UpdatePanel> 
                        </telerik:RadPageView> 
                        <telerik:RadPageView ID="pgvRelations" runat="server"
                            <asp:UpdatePanel runat="server" ID="UpdatePanel2" RenderMode="Inline" ChildrenAsTriggers="false" UpdateMode="Conditional"
                                <ContentTemplate> 
                                    <asp:PlaceHolder ID="ph3" runat="server" Visible="false"
                                        Relation Details 
                                    </asp:PlaceHolder> 
                                </ContentTemplate> 
                            </asp:UpdatePanel> 
                        </telerik:RadPageView> 
                    </telerik:radmultipage> 

In the page_load event, the following code needs to be called:
PreLoadTabs(radTabs, UpdatePanel1);

protected void PreLoadTabs(RadTabStrip TabStrip, UpdatePanel FirstHiddenPanel) 
        { 
            string Script = string.Empty; 
            UpdatePanel ScriptTarget = FirstHiddenPanel; 
 
            if (Page.IsPostBack) 
            { 
                string eventTarget = Request.Params.Get("__EVENTTARGET"); 
                if (!string.IsNullOrEmpty(eventTarget)) 
                { 
                    for (int i = 0; i < TabStrip.Tabs.Count; i++) 
                    { 
                        RadTab rt = TabStrip.Tabs[i]; 
 
                        // Check to see if the tab is in use 
                        if (rt.Visible) 
                        { 
                            if (rt.PageView.Controls[1] is UpdatePanel) 
                            { 
                                UpdatePanel up = (rt.PageView.Controls[1] as UpdatePanel); 
 
                                if (up.UniqueID == eventTarget) 
                                { 
                                    if (up.Controls[0].Controls[1] is PlaceHolder) 
                                    { 
                                        PlaceHolder ph = (up.Controls[0].Controls[1] as PlaceHolder); 
 
                                        if (!ph.Visible) 
                                        { 
                                            ph.Visible = true
                                            up.Update(); 
 
                                            Script += " function enableTab(){$find('" + TabStrip.ClientID + "').get_tabs().getTab(" + i + ").enable();}"
                                            ScriptTarget = up; 
 
                                            break
                                        } 
                                    } 
                                } 
                            } 
                        } 
                    } 
                } 
 
                for (int i = 0; i < TabStrip.Tabs.Count; i++) 
                { 
                    RadTab rt = TabStrip.Tabs[i]; 
 
                    // Check to see if the tab is in use 
                    if (rt.Visible) 
                    { 
                        if (rt.PageView.Controls[1] is UpdatePanel) 
                        { 
                            UpdatePanel up = (rt.PageView.Controls[1] as UpdatePanel); 
 
                            if (up.Controls[0].Controls[1] is PlaceHolder) 
                            { 
                                PlaceHolder ph = (up.Controls[0].Controls[1] as PlaceHolder); 
 
                                if (!ph.Visible) 
                                { 
                                    Script += " function preLoadTab(){__doPostBack('" + up.UniqueID + "', '');}"
 
                                    break
                                } 
                            } 
                        } 
                    } 
                } 
            } 
            else 
            { 
                Script += " function preLoadTab(){__doPostBack('" + FirstHiddenPanel.UniqueID + "', '');}"
            } 
 
            if (!string.IsNullOrEmpty(Script)) 
                ScriptManager.RegisterStartupScript(ScriptTarget, TabStrip.GetType(), "TabScript", Script, true); 
        } 

Client-side a function is required which is called once the page has loaded after an initial page render (using window.onload or page_load) AND also runs after each postback has completed:

function preLoadTabs() 
    if ((typeof enableTab == "function") || (typeof preLoadTab == "function")) 
    { 
        window.setTimeout(function(){ 
            if (typeof enableTab == "function"){ enableTab(); enableTab = null;} 
            if (typeof preLoadTab == "function"){ preLoadTab(); preLoadTab = null;} 
        }, 250); 
    } 

This can be tied into the postback end event as follows:

    with(Sys.WebForms.PageRequestManager.getInstance()){ 
        add_endRequest(preLoadTabs); 
    } 

I hope these two tab loading methods can help others in some way.

Cheers,

Rob


Tags
TabStrip
Asked by
Rob
Top achievements
Rank 2
Answers by
Atanas Korchev
Telerik team
Zoe
Top achievements
Rank 2
Rob
Top achievements
Rank 2
Share this question
or