From: | Geoff Bannoff |
To: | Rick Strahl |
.. Geoff
Ok thank you Geoff,
I was able to find the problem, and yes you're right there was a hardcoded reference to 'Tabs' in the new script. I wasn't able to track this down before because I wasn't clear that your main issue was the postback of activating the correct tab. I was looking for some other rendering failure.
Anyway to fix this replace this code in webcontrolsjquery.prg:
************************************************************************ * wwWebTabControl :: OnPreRender **************************************** *** Function: *** Assume: *** Pass: *** Return: ************************************************************************FUNCTION OnPreRender()LOCAL lcScript, loTabDODEFAULT()this.Page.jQueryConfig.IncludejQuery()IFEMPTY(this.SelectedTab) AND this.TabPages.Count> 0 loTab = this.TabPages.aItems[1,2]this.SelectedTab =loTab.TabPageClientIdENDIFthis.Page.HiddenFormVars.Add("__TABSELECTION_" + this.UniqueId,this.SelectedTab)IF !EMPTY(this.OnClientActivate )this.Page.RegisterStartupScript(this.UniqueId + "OnActivate",;this.UniqueID + ".onActivate = " + this.OnClientActivate + ";")ENDIFTEXTTO lcScript NOSHOW TEXTMERGEfunction ActivateTab(tabId, num) { var _Tabs = eval(tabId);if (typeof (num) == 'string') {for (var x = 0; x < _Tabs.length; x++) {if (_Tabs[x].pageId == num) { num = x; break; } } }if (typeof (num) == 'string') num = 0; // default first pageif (_Tabs.onActivate) { if (_Tabs.onActivate(num)) return; } var Tab = _Tabs[num];for (var i = 0; i < _Tabs.length; i++) { var t = _Tabs[i]; $("#" +t.tabId).removeClass("tabbutton") .removeClass("tabbutton-disabled") .removeClass("tabbutton-selected") .addClass(t.enabled ? 'tabbutton' : 'tabbutton-disabled');if (t.pageId) $("#" + t.pageId).hide(); } $("#" + Tab.tabId).removeClass("tabbutton") .removeClass("tabbutton-disabled") .addClass("tabbutton-selected"); $("#" + Tab.pageId).show(); $('#__TABSELECTION_' + tabId).val(Tab.pageId); }ENDTEXTthis.Page.RegisterClientScriptBlock("___ActivateTab",lcScript)ENDFUNC* wwWebTabControl :: OnPreRender
The code that was a problem was this:
$('#__TABSELECTION_Tabs' ).val(Tab.pageId);
and it has to be this:
$('#__TABSELECTION_' + tabId).val(Tab.pageId);
to correctly assign the tab id whenever a tab is selected.
Your sample now works.
+++ Rick ---
OK, here's the simplest page I can come up with. HTML first:
<%@ Page Language="C#"
ID="test2_Page"
GeneratedSourceFile="/vfp/source/test2_Page.prg" %>
<%@ Register Assembly="WebConnectionWebControls" Namespace="Westwind.WebConnection.WebControls" TagPrefix="ww" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><metahttp-equiv="Content-Type"content="text/html;CHARSET=iso-8859-1" /><linkrel="stylesheet"type="text/css"href="westwind.css"media="screen" /></head><body><formid="form1"runat="server"><ww:wwWebTabControlrunat="server"id="Tabs" SelectedTab="pageSelection"><TabPages><ww:wwWebTabPagerunat="server"id="Page1" TabPageClientId="pageInfo"Text=" Information"> </ww:wwWebTabPage><ww:wwWebTabPagerunat="server"id="Page2" TabPageClientId="pageSelection"Text="Selection"></ww:wwWebTabPage><ww:wwWebTabPagerunat="server"id="Page3" TabPageClientId="pagePostBack"Text="PostBacks"></ww:wwWebTabPage><ww:wwWebTabPagerunat="server"id="Page4" TabPageClientId="pageDisplay"Text="Display"></ww:wwWebTabPage><ww:wwWebTabPagerunat="server"id="Page5" TabPageClientId="pageDisplay"Text="Disabled"></ww:wwWebTabPage><ww:wwWebTabPagerunat="server"id="Page6" TabPageClientId="pageSamples"Text="Samples"></ww:wwWebTabPage></TabPages></ww:wwWebTabControl><!-- You can use wwWebPanels or just plain HTML elements -->><divid="pageInfo"class="blackborder tabpage"style="display: none"><h3>div 1 - keeps correct tab</h3></div><!-- Here we use a plain DIV tag for the tab page -->><divid="pageSelection"class="blackborder tabpage"style="display: none"><h3>div 2 - keeps correct tab</h3></div><divid="pagePostBack"class="blackborder tabpage"style="display: none"> <h3>div 3 - keeps correct tab</h3><ww:wwWebButtonrunat="server"ID="btnSubmit"Text="Post It to Server" Click="btnSubmit_Click" /></div><divid="pageDisplay"class="blackborder tabpage"style="display: none"><h3>div 4 - keeps correct tab</h3></div><divid="pageSamples"class="blackborder tabpage"style="display: none"><h3>div 5 -keeps correct tab</h3></div><br /><br /><ww:wwWebTabControlrunat="server"id="notTabs"><TabPages><ww:wwWebTabPagerunat="server"id="bad1" TabPageClientId="divNew"Text="div1"> </ww:wwWebTabPage><ww:wwWebTabPagerunat="server"id="bad2" TabPageClientId="divReceive"Text="div2"></ww:wwWebTabPage></TabPages></ww:wwWebTabControl><divid="divNew"><h3>div 1 - losing tab</h3></div><divid="divReceive"><h3>Div 2 - losing tab</h3><ww:wwWebButtonID="btnSearch"runat="server" Click="btnSubmit_Click"Text="Lose the tab" /></div></form></body></html>
Then, the Foxpro code:
*****************************************************************DEFINECLASS test2_Page as WWC_WEBPAGE OF WWC_WEBPAGE_FILE***************************************************************** *** Your Implementation Page Class - put your code here *** This class acts as base class to the generated page below *****************************************************************#IF .F.*** This line provides Intellisense: Ensure your path includes this page's locationLOCALthis as test2_Page_WCSX of test2_page.prg#ENDIFFUNCTION OnLoad()ENDFUNC* OnloadFUNCTION btnSubmit_click()endfuncENDDEFINE
The top tab bar is the most scaled down version from the samples that ship with Web Connection. Click on the "Postbacks" tab -- there is a web button there. When you click the button, the "Postbacks" tab stays active.
The second tab bar is similar, except that the ID is "notTabs". Click on the "div 2" tab and click the "lose the tab" button.
I've put up a live version of this code at
http://173.240.183.131/fpp/test2.fp
And, if you swap the ID tags between the wwTabControls, you can make the bottom one work, but not the top one.
..Geoff
But that's what I'm saying. It shouldn't be that way - it works fine with other names unless your code somewhere hardcodes that name.
Check with a JavaScript debugger to see if you get errors when loading the page. I bet when you do you'll get an error and it'll stop at some hard coded reference to a Tabs variable.
It's possible there is a bug somewhere, but I don't see it in the sample I'm running and you haven't given me anything I can check directly. If you can duplicate, set up a reproducible example (or make my sample fail) and send it back and I can take look. If there is a bug I'd like to fix it...
+++ Rick ---
What I'm saying is that if I rename each of my tab controls to "Tab", then my screens start working the way that they used to.
But the original name of all the tab controls in my application--I believe there are about 60 of them, is not "Tab". So all the ones that I haven't renamed fail.
My guess is that, instead of a variable, something in your tab control code is looking for the actual word "Tab". And it has to be case sensitive, too.
.. Geoff
Sorry I guess I'm not sure what you're saying exactly...
Yes if you rename the tab control in the demo it fails, but only because there are some additional manually added scripts in the page that depend on the local name for the tab control. Bascally the browser will throw because of the invalid name and stop processing the rest of the scripts which is why all the pages will show.
If I comment those (optional) custom scripts out however everything works just fine.
+++ Rick ---
Well, that took an a fair amount of trial and error to finally pin down the problem.
If the tabcontrol has an ID of (exactly) "Tabs", then it works, with the tab staying correctly selected.
<ww:wwWebTabControlID="Tabs"runat="server">
If the tab control has an ID of anything else, this behaviour breaks.
.. Geoff
Ok so I took another look at this and I can't duplicate your behavior.
The demo works with the PostBack page which keeps track of the active tab and redisplays it automatically.
Explicitly assigning a selected tab too works fine for me. If in the demo I do:
this.Tabs.SelectedPage = "pagePostBack"
and that page selects just fine.
There have been changes in this class. It's been moved to WebControlsJQuery.prg and it now depends on jquery and ww.jquery, but these files should automatically be included in the page. Check for script errors and see if something is causing the page to not load properly.
+++ Rick ---
We went from 5.62 to 5.65 yesterday. There is a behaviour change reported by some of our users.
When one of the tab pages, say the 5th tab, has a wwWebButton, and that button is clicked, the 'SelectedTab' property appears to get lost. When the page refreshes, the 1st tab is selected, rather than the 5th tab that the user was working with.
If I put in an explicit
this.tabCONTROL.selectedtab="tabActions"
in the wwWebButton_click(), then strange things happen--the content of all tab pages becomes visible.
Any ideas on how to make this work like it used to?
.. Geoff