+ Start a Discussion

Select Custom Tabs and Visualforce Pages using jQuery

I developed to 2 custom VF Pages with associated custom tabs. The first VF page used a commandLink to navigate to the second VF with using a PageReference in a CustomController. Like so



<apex:commandLink action="{!SearchPage}" id="SearchLink">Do Search</apex:commandLink> <br/>



All good, the 2nd Page opened fine, EXCEPT that the Tab associated with the find page wasn't selected, instead the first tab was selected. Put more accurately the CSS wasn't updating to reflect the currently selected page. The target VF page in question isn't associated with an SObject (haven't tested this so I'm not sure if this is relevant). In this instance its a custom SearchPage


Ok what to do - I couldn't find any documentation or help, but I realised that the issue actually lay with the CSS... If I could manipulate the CSS I could fix the issue - step forward jQuery. I needed to change the CSS in the DOM and jQuery is just the tool.


**** WARNING***** this is a hack, if SFDC change the CSS or structure this code could break.


First setup you reference to the jQuery Lib in your target VF page



<script type="text/javascript"  src="{!URLFOR($Resource.jQuery, '/jquery-1.4.2.min.js')}"></script>



The tabs on the standard interface are wrapped in a table with the class name '.tab'



<table cellspacing="0" cellpadding="0" border="0" id="tabBar" class="tab"><tbody>
<td nowrap="nowrap">
<a title="Home Tab" href="https://na7.salesforce.com/home/home.jsp">Home</a>



The td element of the currently selected tab will have a class added with the values like so:



<td nowrap="nowrap" class="currentTab primaryPalette">



So what we need to do is remove the class from the incorrectly highlighted tab and add it to the tab we want highlighted. Here is the jQuery to do this. (My jQuery skills aren't going to win any prizes, someone may have a shorter/better way of achieving this)



<script type="text/javascript">
j$ = jQuery.noConflict();
	j$(document).ready(function($) {
		var title = j$('.tab').find('.currentTab > div > a').attr('title');
		if (title != 'Search Tab - Selected') {
			j$('.tab').find('.currentTab').removeClass('currentTab primaryPalette');
			var x= j$('a[title|=Search Tab]').attr('title', 'Search Tab - Selected');
			j$(x).parent().parent().addClass('currentTab primaryPalette');


 The title of the a link of the seleted tab is always myTabName Tab, if its currently selected is myTabName Tab -Selected. The code basically removes the class from the incorrect tab and adds it to the one we want.


The double use of .parent() (please feel free to offer a better technique) navigates from the <a> through the <div> back the current <td>, this is where the class needs to be added. And it works!!! But its a hack










Thanks for posting your problem and solution... interesting.   Just to be conversational, I'd like to make sure I understand.


You've got a link in your first page, and the goal is when that link is clicked to open a new TAB (uppercase to denote a new tab in the Browser), and you want that new TAB to be navigated to the new tab (lowercase to denote a Salesforce tab) which is "holding" your custom search VF page.


If I have that right, could you create a command link button like:


<apex:commandLink action="{!URLFOR($Page.MySecondVFPage)}" id="SearchLink" target="_blank" value="Do Search" />


This seems to work for me in that it opens a new Tab (I suppose if your browser is set to force the opening of a new Window, it would do that instead), on the given VF page, and in my case the Salesforce tab is highlighted/selected, etc. as it would be if a user had clicked on it.


Or am I missing what problem you're solving?  :-)


Best, Steve.


Actually I hadn't gone as far as to open a new browser window, but I guess it would work. The problem was that a link using (commandLink or outputLink) to navigate from the first VF to another VF page (which had also had a custom tab associated with it) resulted in the correct navigation BUT the SFDC tab on the 2nd VF page did not reflect the move. Basically the SF CSS was not reflecting the move to the page


I'm guessing your solution is the correct method for achieving what I was trying to do (which I'll test) but I just couldn't find any documentation related to this issue. I'm not certain if the issue arose because the 2nd page is not associated with an SObject, again I need to check this


Obviously if I simply clicked the tab for the second VF page everything worked as expected.


All that said the use of JQuery to manipulate the DOM on SF pages opens up all kinds of interesting possibilities, its a pity jQuery can't be inserted into the standard pages :smileytongue:




Just tried your code sample and it does create a new TAB in the browser BUT without the jQuery it doesn't highlight the SFDC tab associated with the SFDC VF page as the currently selected one.


FYI it is now JQuery best practice to hotlink the Google CDN since many people will have it cached.


Hey Richard, I reproduced your example.   My tests worked because I had navigated to pages by directly typing in the ".../apex/vfpage" name which seemed to do something that worked.


Either way... I believe the solution we seek is:


<apex:page tabStyle="First_VF_Page_Name__tab">


Seems to do the job.   Best, Steve.


It was only long afterwards that I realised what you've just posted is the 'official' solution but the jQuery approach opens up some interesting possibilities EG hide the setup link and create you own customised User preference area.


I also wonder if this opens up the possibility of having multiple tabs of the same object type open - Accounts- Company A, Accounts-Company B



FYI it is now JQuery best practice to hotlink the Google CDN since many people will have it cached.



On the issue about using CDN is there anywhere that provides the jQuery libraries over https. In IE, every page using a CDN displays the really annoying dialog about unsecure items, with the even more annoying press 'No' to say Yes to allow the content. I tried adding the 's' to the URL but even Microsoft don't provide the library over https.


The dialog can be switch off but explaining this to every user isn't going to work. Using an embedded library gets around this




I use this address over ssl without issue...