Welcome Guest Search | Active Topics | Sign In | Register

TabStrip state multiple browser windows Options
Joel N
Posted: Tuesday, October 7, 2008 5:36:26 PM
Rank: Member
Groups: Member

Joined: 10/7/2008
Posts: 14
Hi, today we have a TabStrip on our Content.master page.

We store the tab's (and which is selected in the session)

On the Page_Load of the Content.master we do:

(AppContext is a wrapper around the session in this case)
this.navigationTabStrip.DataSource = AppContext.GetCurrentTabs();
this.navigationTabStrip.DataBind();

The problem with this is if a user opens multiple browser tabs or windows, it can lead to very confusing results, because the tab set on one window can be totally different than another window.

I was thinking we could switch to viewstate and it might solve the problem? The problem is not all navigation on my site is a postback of the form, so I fear it might get lost.

anyone had this problem? Also can you point me to an example of how to get & set the current tabs from viewstate?

If not the right answer, any other suggestions?

thanks
Joel
eo_support
Posted: Tuesday, October 7, 2008 5:56:32 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi Joel,

I am not exactly sure what you meant by "the problem with this is if a user opens multiple browser tab or windows....because the tab set on one window can be totally different than another window".

My understanding is that allowing user to have different things in different browser tab is exactly the purpose of tabbing. While the user is on one page and they want to see something different but they do not want to lose the current page, they open a new tab. So having different things on different browser tabs is not only common, but also pretty much the purpose.

There is no significant difference between ViewState and Session as far as storing data. Both are server side technology. ViewState relies on form data, so it does not expire. However the same form data usually works together with session data on the server (imaging a shopping cart in view state with user login in the session). The other option is cookie. Cookie itself is on the client side but it's for small amount of data. So it's not practical to store the whole tab set in it. People usually use it to store a key (for example, log in session data as you see in the "Remember Me" login option).

Hope this helps. Please feel free to let us know if you meant something else.

Thanks
Joel N
Posted: Wednesday, October 8, 2008 5:03:27 AM
Rank: Member
Groups: Member

Joined: 10/7/2008
Posts: 14
Hi,

For the sake of clarity I will call EO Tabstrip tabs Application Tabs to distinguish from browser tabs. Also note that my application has a infinite dynamic list of tabs that can be shown (I show the last N groups they have visited in a system with thousands of groups)

so lets say I have a browser window open with 3 application tabs in it A,B,C and B is selected.

Then I open another browser tab/window and do some work and end up with 4 tabs D,E,F,G with G selected, now I go back to the original browser window and I clip tab A, the problem is in my session I dont even have A,B,C at this point, I have D,E,F,G.

This is a typical session/multiple browser window problem, that shows very badly in the case where you have dynamic applicaiton tabs. The way I have solved this in the past with other technologies is to store a "version number" along with the session, so when a new tabset is created, instaed of destroying the old state in the session I save off the previous version. So when in the case described above I can show them the same tabset associated with their version.

For this version token you need to put it into the url or into the form as a hidden field because that is the only way you can differentiate the 2 browser windows as they share the session.

Does that make more sense?
eo_support
Posted: Wednesday, October 8, 2008 5:56:14 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi Joel,

I see what you meant now. Our TabStrip can store all the tabs in the view state. So a combined solution using both session and view state is the easiest. The only issue for this, as you have noticed, is that it only works with post backs.

It's fairly easy when the page posts back. I can think of the following logic that might work for you:

Page_Load:

Code: C#
//Load from session only when the page is a fresh get.
//When the page is posted back, ignore data in the session,
//The TabStrip will automatically load from view state 
if (!Page.IsPostBack)
{
    this.navigationTabStrip.DataSource = AppContext.GetCurrentTabs();
    this.navigationTabStrip.DataBind();
}


The key at here is that, while you use both Session (which contains the last tabset on the server side) and ViewState (which contains the "active" tabset on the client side), ViewState takes priority over Session. So in the case you have two browser tabs, one with A, B, C and the other have D, E, F, G, and then user click A, your ViewState has A, B, C, even though session has D, E, F, G. Because ViewState takes priority over Session, your app continues based on A, B, C, not D, E, F, G.

In order to have the TabStrip to post back the page for you, you will need to:

1. Clear the TabItem's NavigateUrl. When you have NavigateUrl set, the TabStrip does a straight window.open on the client side and the page won't be posted back to the server;
2. Set the TabStrip's RaisesServerEvent to true. Without setting this property, the TabStrip will not post back to the server either;

When this two conditions are meet, the TabStrip posts back to the server and raises ItemClick server side event when a tab is clicked. Inside your ItemClick handler, you may update your session data to have the latest "app tab list" based on the user selection.

You do not need to manually select the new Tab in this case because everything is automatically loaded from view state. If you do need to switch to some other tab, you can do so by:

Code: C#
//Note usually you do not need to do this because everything
//is automatically loaded from view state
navigationTabStrip.SelectedIndex = new_index;


As noted above, this only works when ViewState data exists, in another word, only when the page posts back. When the page is a fresh get, no ViewState data is available. Hidden field won't work either because that too rely on post back. In that case it will completely fall back to rely on session data.

Storing a "version number" along with the session can address non-postback scenario. However that would require you to put the version number in the Url (hidden field won't work), which in my opinion, would be much more complicated to implement than just let the page to post back and then redirect. Comparing with post back, using "version number" may have a slight performance advantage in term of bandwidth, but it does have a performance disadvantage on server resources because it needs to store more data on the server side.

In order to have the TabStrip to postback and then redirect, you can store the target Url for a TabItem in the item's Value property (instead of NavigateUrl). Then call Response.Redirect in your server side ItemClick event handler:

Code: C#
private void navigationTabStrip_ItemClick(
    object sender, EO.Web.NavigationItemEventArgs e)
{
    //Do other work such as update your session data.....
    ......

    Response.Redirect(e.TabItem.Value);
}


Hope this helps.

Thanks
Joel N
Posted: Wednesday, October 8, 2008 8:31:06 AM
Rank: Member
Groups: Member

Joined: 10/7/2008
Posts: 14
cool thanks, good ideas, I will give them a try!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.