Wednesday, March 21, 2012

TabContainer preventing the user from switching tabs if some textbox changed in a previous

Hello,

I have a TabContainer control with 3 tabs. On each tab I dynamically add textboxes. Each one of the textboxes has an OnTextChanged event. What I am trying to do is, to prevent the user from being able to switch between tabs if some of the text has changed in the textboxes, but the save button was not clicked.

So what I really want to do is, to detect when a user clicks on a different tab, then check my current tab see if any of the textboxes were updated and if they were I don't want to allow the other tab to be selected. Can someone please give me some hints or an example of how I can do this?

Thank You,

Vadim


You can hook into the tab changed event as follows:

var tabs = $find('TabsClientID');
tabs.add_activeTabChanged(YourHandler);

In YourHandler, you can do the necessary checks to see if the user should be moving away from a tab and return them to the previous tab if the checks fail. You will need to track the active tab index manually so that you can return them to the correct tab.

Jason


So calling the tabs.add_activeTabChanged(serversideHandler), will cause a postback correct? I will need to be able to pop up an alertbox or something like it notifying the user that they can't switch tabs from the serverEvent. Is there a way to cause some javascript to run from a function on the server?


this is my tab control here:

<cc1:TabContainer ID="tbcSettings" OnActiveTabChanged="ActiveTabChanged" runat="server" Width="300" Height="300">
<cc1:TabPanel ID="tbpGlobal" OnClientClick="ActiveTabChanged" TabIndex="0" BorderWidth="2" runat="server" HeaderText="Global">
<ContentTemplate>
<asp:UpdatePanel ID="upTab_List" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<slc:SettingList ID="settingListGlobal" runat="Server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="tbcSettings" EventName="ActiveTabChanged" />
</Triggers>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel ID="tbpCommercial" OnClientClick="ActiveTabChanged" TabIndex="1" runat="server" HeaderText="Commercial">
<ContentTemplate>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<slc:SettingList ID="settingListCommercial" runat="Server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="tbcSettings" EventName="ActiveTabChanged" />
</Triggers>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel ID="tbpMedicaid" OnClientClick="ActiveTabChanged" TabIndex="2" runat="server" HeaderText="Medicaid">
<ContentTemplate>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<slc:SettingList ID="settingListMedicaid" runat="Server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="tbcSettings" EventName="ActiveTabChanged" />
</Triggers>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
</cc1:TabContainer>

<script language="javascript">

function ActiveTabChanged(sender, e)
{
__doPostBack('<%= tbcSettings.ClientID %>');
}

</script>

c# code:

protected void ActiveTabChanged(object sender, EventArgs e)
{
//bcSettings.ActiveTabIndex = ((AjaxControlToolkit.TabContainer)sender).ActiveTabIndex;
//((AjaxControlToolkit.TabContainer)sender).
string tabname = tbcSettings.Tabs[((AjaxControlToolkit.TabContainer)sender).ActiveTabIndex].HeaderText;
switch (tabname)
{
case "Global":
stl = settingListGlobal;
break;
case "Commercial":
stl = settingListCommercial;
break;
case "Medicaid":
stl = settingListMedicaid;
break;
default:
break;
}
if (!stl.Saved)
{
string js = @."if (alert('you made changes, do you want to save now'))";
js += "{";
js += "__doPostBack('" + btnSave.ClientID + "');";
js += "}";

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "savepostback", js, true);
}
}


No, the sample code I provided was for clientside handling of the event when the tab is changed...it does not cause a postback. The tab container is supposed to be able to automatically postback when a tab is changed although I have seen some posts that indicate that this might not be happening correctly. Check the forums to see if this is working or not.

Personally, I think it might be a nicer user experience to handle all of this clientside but understand if this is not practical. This would make it easier to show the alert and would avoid extra postbacks.

One thought...do you have to save the changes to every tab individually or can you just have a save button that saves the stuff in all of the tabs in one big go. This sounds like it would eliminate the problem altogether.


Well, I would rather make them press save before moving between tabs, but it seems like what I want to do is a pretty complicated task.

My take on tabs is that they are more designed for segmenting content and that the user can hop around with quick clientside UI control. I think this creates a better and snappier user experience. What do you gain by forcing the user to save every tab first? Sure, you can still have a save button on every tab so that the user can save their changes if they want to, but why force them to do it? It's the same as most tabbed windows in the Windows UI...you get an option to hit an Apply button to save your changes so far or continue changing settings on multiple tabs until you are ready to save.

No comments:

Post a Comment