Telerik blogs

While working on a recent "real" project for Telerik, I used the RadTabStrip for ASP.NET AJAX to provide users with a list of content they could navigate. It was simple enough. A RadTabStrip with a few tabs, a RadMultiPage holding each tab's content, and content on each pageview that linked to new pages in the website. With very little effort, I had a rich, tabbed interface that worked completely cross browser. But then during beta testing, a tester reported a bug: if they navigated to a new page by clicking on content in the TabStrip, then clicked their browser's back button, when the page reloaded, the selected tab was lost!

Clearly, what was actually happening is that the selected tab was not being "persisted" across page navigations. It was not a "bug" per se, but it was an usability problem. Fortunately, thanks the rich client-side API of RadTabStrip, it is an easy fix!

To fix this usability problem, there are a number of approaches I could have used. The approach I decided to use is to persist the TabStrip's state in a cookie using JavaScript and the RadTabStrip client-side API. Using a cookie enables the site to "remember" the user's last used tab so that no matter how they get back to the main page, their last used tab is selected (even across browser restarts).

IMPLEMENTATION

The first step is to configure your code to handle the RadTabStrip's OnClientTabSelected event. This event fires after a tab has been selected and passes a reference to the client-side TabStrip object along with the selected tab (in the eventArgs) to the JavaScript function.

ASPNET
<telerik:RadTabStrip runat="server" ID="RadTabStrip1" EnableViewState="false" MultiPageID="RadMultiPage1" OnClientTabSelected="onClientTabSelected" OnClientLoad="onClientTabLoad">
JAVASCRIPT
function onClientTabSelected(sender, args) {    
    //Persist selected tab text  var tabText = args.get_tab().get_text();    
    //Save text to a cookie using JavaScript    
    saveTabIndex(tabText);
}
 
The RadTabStrip client-side API supports few different methods for locating a tab: findTabByValue, ByText, ByUrl, ByAbsoluteUrl, and ByAttribute. I decided to use the tab text to persist and locate my tabs. So I grab the text from the selected tab and then pass it to a function in an external JavaScript file that has my code for saving the value to a cookie.
 
JAVASCRIPT
//Cookie name  var tabCookieName = "myCookieName";

function saveTabIndex(tabText) {    
    //Call JS function to save cookie name, tab text,  //and days before cookie should expire    
    setCookie(tabCookieName, tabText, 1);
}

//Cookie operation helper function  //Save the value to a cookie and set expiration date  function setCookie(c_name, value, expiredays) {    
    var exdate = new Date();    
    exdate.setDate(exdate.getDate() + expiredays);    
    document.cookie = c_name + "=" + escape(value) +        
        ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
}

So, now my selected tab is being persisted to a cookie whenever a new tab is selected (completely client-side- no PostBacks or Ajax). The next thing I need to do is write some code to restore the selected tab when the page loads (and there is a value in the cookie). To do that, I'll start by handling the TabStrip's OnClientLoad event (which fires when the TabStrip is loaded and ready for action) to get a reference to the client-side TabStrip object. I could, of course, also do this with $find('<%= RadTabStrip1.ClientID %>'), but I'm always a fan of avoiding mixing ASP.NET code blocks in JavaScript when I can.

JAVASCRIPT
//Variable to hold reference to tabstrip  var tabstrip;
function onClientTabLoad(sender) {    
    //Get reference to tabstrip    
    tabstrip = sender;
}

Now that we have a reference to our TabStrip, we simply need to recover the selected tab value from our cookie and then use the client-side "findTabByText" function to get a reference to the tab. Once we have a reference to the actual tab, we can just call its "select()" method to restore its selected state.

JAVASCRIPT
function loadTabIndex(tabstrip) {    
    //If tabstrip reference isn't null  if (tabstrip != null) {        
        //Get cookie value  var tabText = getCookie(tabCookieName);        
        //If text from the cookie exists  if (tabText != "" || tabText != null) {            
            //Set tabstrip selected index  var tab = tabstrip.findTabByText(tabText); 
            //Get tab object  if (tab != null) {                
                tab.select(); //Select tab            
            }           
        }    
    }
}

//Cookie helper function  //Gets a cookie based on supplied name and returns value  //as a string  function getCookie(c_name) {    
    try {        
        if (document.cookie.length > 0) {            
            c_start = document.cookie.indexOf(c_name + "=");            
            if (c_start != -1) {                
                c_start = c_start + c_name.length + 1;                
                c_end = document.cookie.indexOf(";", c_start);                
                if (c_end == -1) c_end = document.cookie.length;                
                return unescape(document.cookie.substring(c_start, c_end));            
            }        
        }    
    } catch (err) { }    
    
    //If there is an error or no cookie  //return an empty string  return "";
}

When the "tab.select()" method is called, the RadTabStrip selects the correct tab AND the correct RadMultiPage will also automatically be selected at the same time. No extra code required!

There is a gotcha, though.

GOTCHA ALERT

You do have to be careful about when you call your tab.select() method if you want your RadMultiPage to be automatically updated. By default, you might think that it makes sense to try to reload your tab selected state during the TabStrip's OnClientLoad event. That event, thought, is called as soon as the RadTabStrip is ready to go. And if your RadTabStrip is rendered on the page before your RadMultiPage, that means the event is called before your RadMultiPage is initialized. The result: trying to restore your selected tab during OnClientLoad will only update your TabStrip- your RadMultiPage won't be updated.

To work around this issue, simply use the ASP.NET AJAX JavaScript pageLoad event (which automatically fires when the page is ready to go). That ensures both your RadTabStrip and RadMultiPage are initialized and ready for action.

JAVASCRIPT
//pageLoad automatically called by ASPNET AJAX when page ready  function pageLoad() {    
    //Must do tab strip select here so that   //multipage is initialized and updated    
    loadTabIndex(tabstrip);
}

SUMMARY

And that's it! With a few lines of client-side code you can enhance your RadTabStrip usability for scenarios when your users want their selected tab persisted across page loads and site visits. The RadTabStrip, like all RadControls for ASP.NET AJAX, has an extensive client-side API which you can review in the Telerik Online Docs. Hopefully this demo helps you get more comfortable with the client-side API and shows you how you can use it to enhance your applications.

 

Download complete demo code


ToddAnglin_164
About the Author

Todd Anglin

Todd Anglin is Vice President of Product at Progress. Todd is responsible for leading the teams at Progress focused on NativeScript, a modern cross-platform solution for building native mobile apps with JavaScript. Todd is an author and frequent speaker on web and mobile app development. Follow Todd @toddanglin for his latest writings and industry insights.

Comments

Comments are disabled in preview mode.