I need to know how to link (via a regular href anchor on a different page) to content that is inside a tab that is not the default tab. Can this be done? My code will explain hopefully what I require:

My Code:

The following is my profile_edit.php page:
-----------------------------------------

The javascript:

<script src="Javascript/jquery-1.4.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
	$(function () {
	var tabContainers = $('div.tabs > div');
	tabContainers.hide().filter(':first').show();
			
	$('div.tabs ul.tabNavigation a').click(function () {
			tabContainers.hide();
			tabContainers.filter(this.hash).show();
			$('div.tabs ul.tabNavigation a').removeClass('selected');
			$(this).addClass('selected');
			return false;
	}).filter(':first').click();
	});	
	$(function () {
    var tabs = [];
    var tabContainers = [];
    $('ul.tabs a').each(function () {
      // note that this only compares the pathname, not the entire url
      // which actually may be required for a more terse solution.
        if (this.pathname == window.location.pathname) {
            tabs.push(this);
            tabContainers.push($(this.hash).get(0));
        }
    });

    // sniff for hash in url, and create filter search 
    var selected = window.location.hash ? '[hash=' + window.location.hash + ']' : ':first'; 
    
    $(tabs).click(function () {
        // hide all tabs
        $(tabContainers).hide().filter(this.hash).show();
        
        // set up the selected class
        $(tabs).removeClass('selected');
        $(this).addClass('selected');
        
        return false;
    }).filter(selected).click();
});
</script>

The html and PHP (a portion):

<div class="tabs">
  <ul class="tabNavigation">
     <li><a href="#account_div">Account</a></li>
     <li><a href="#change_password_div">Password</a></li>
     <li><a href="#favorites_div">Favorites</a></li>
     <li><a href="#avatar_div">Avatar</a></li>
  </ul> 
  <div id="account_div">
     <?php include("personal_info_edit.php"); ?> 
     </div>
     <div id="change_password_div">
     <?php include("change_password.php"); ?> 
     </div>
     <div id="favorites_div">
     <?php include("favorites.php"); ?> 
     </div> 
     <div id="avatar_div">
     <?php include("avatar.php"); ?> 
     </div>
   </div>

The following is contained in my change_password_submit.php page:

$update_pass= ("Password changed successfully.");
header("location:profile_edit.php?update_pass=$update_pass");	
exit();

By default, whenever profile_edit.php is loaded, the personal_info_edit div is shown and the others are hidden. What do I need to change in the code so that I can reference the 2nd div (ie. change_password div and hide the rest after someone changes their password?
Any help will be greatly appreciated.

Recommended Answers

All 20 Replies

Kkjay,

You need to be careful with window.location.hash and anchor.location.hash . Some js engines include the leading # symbol in the returned string, and some don't. This makes any solution slightly ugly, but not necessarily any more lines that you already have.

Try this:

//replace
//  var selected = window.location.hash ? '[hash=' + window.location.hash + ']' : ':first';
//with
    var selected = (window.location.hash==''||window.location.hash=='#') ? tabs[0].hash : window.location.hash;//tabs[0].hash is the default

//replace
//  }).filter(selected).click();
//with
    }).filter(function(){ return this.hash==selected; }).click();

I did some rudimentary testing. It seems to work.

Airshow

Thank you very much irshow for your reply. I am very new to this and do not understand it fully.

As you can see from the code I poster earlier, the default tab in profile_edit.php is personal_info_edit.php.

ie.

<div class="tabs">
   <ul class="tabNavigation">
       <li><a href="#account_div">Account</a></li>
       <li><a href="#change_password_div">Password</a></li>
       <li><a href="#favorites_div">Favorites</a></li>
       <li><a href="#avatar_div">Avatar</a></li>
   </ul> 
<div id="account_div">
   <?php include("personal_info_edit.php"); ?> 
</div>
<div id="change_password_div">
    <?php include("change_password.php"); ?> 
</div>
<div id="favorites_div">
    <?php include("favorites.php"); ?> 
</div> 
<div id="avatar_div">
     <?php include("avatar.php"); ?> 
</div>
</div>

My question was after, making the changes to the javascript as in your previous reply, what do i need to change in the code below (in the change_password_submit.php) so that after successful password change, the user is redirected to profile_edit.php with the change_password div tab showing.

$update_pass= ("Password changed successfully.");
header("location:profile_edit.php?update_pass=$update_pass");	
exit();

Kkjay,

Add #div_id to the end of the redirect URL.

$update_pass = ("Password changed successfully.");
header("location:profile_edit.php?update_pass=$update_pass#change_password_div");	
exit();

Airshow

$("#tabs").tabs('select':1);

Thank you both for your replys. So this is my javascript after the changes:

<script src="Javascript/jquery-1.4.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
	$(function () {
	var tabContainers = $('div.tabs > div');
	tabContainers.hide().filter(':first').show();
			
	$('div.tabs ul.tabNavigation a').click(function () {
			tabContainers.hide();
			tabContainers.filter(this.hash).show();
			$('div.tabs ul.tabNavigation a').removeClass('selected');
			$(this).addClass('selected');
			return false;
	}).filter(':first').click();
	});	
	$(function () {
    var tabs = [];
    
    $('ul.tabs a').each(function () {
      // note that this only compares the pathname, not the entire url
      // which actually may be required for a more terse solution.
        if (this.pathname == window.location.pathname) {
            tabs.push(this);
            tabContainers.push($(this.hash).get(0));
        }
    });

    // sniff for hash in url, and create filter search 
    var selected = (window.location.hash==''||window.location.hash=='#') ? tabs[0].hash : window.location.hash;//tabs[0].hash is the default
    
    $(tabs).click(function () {
        // hide all tabs
        $(tabContainers).hide().filter(this.hash).show();
        
        // set up the selected class
        $(tabs).removeClass('selected');
        $(this).addClass('selected');
        
        return false;
    }).filter(function(){ return this.hash==selected; }).click();
});
</script>

I tried the following as you suggested, Airshow:

$update_pass = ("Password changed successfully.");
header("location:profile_edit.php?update_pass=$update_pass#change_password_div");
exit();

After a password change, the redirect takes me to the default 1st div which is the account_div. I don't know where im going wrong with this.

@Vsmash, where do I place that code?

Kkjay,

Vsmash's suggestion assumes use of the jqueryui .tabs function (a jQuery plugin). If we can't get your code working, then we'll have to consider that as an alternative. For now, don't try to mix the two approaches.

After a password change, do you see the url "profile_edit.php?update_pass=$update_pass#change_password_div" in your browser's address bar?

If not, there's a problem with the redirect in php.

If so, then insert alert(selected) after the line var selected = .... . What does the alert give?

Airshow

Airshow is right - I thought you were using jqueryui & themeroller.

Vsmash, if I fail to get kkjay's code working, I'll hand over to you to get jqueryui.tabs working for him. You probably know more in that department than I.

Airshow

Thanks again to both of you.

I originally got the code off this site

http://jqueryfordesigners.com/jquery-tabs/

Unfortunately, even after reading through the comments from people who had the same problem, i was unable to fix it.

I will now answer Airshow's questions:

I used it to redirect to the avatar_div after deleting a photo: I get this in the URL

http://localhost/NNL/profile_edit.php?update_avatar=Image%20deleted%20successfully.#avatar_div

After placing the line alert(selected), I get the following alert

#avatar_div

But it does not redirect.

Could the problem be in the var tabs and var tab containers?

If you look at the first javascript code I posted?

After all this, it does not redirect to the correct div.

Kkjay,

The alert appears to be correct.

I can only think that it's failing (in your browser) at the point where the comparison is made:

}).filter(function(){ return this.hash==selected; }).click();

Try alerting the two strings that are compared:

}).filter(function(){ alert([selected,this.hash]); return this.hash==selected; }).click();

You should get one alert per tab (I think). What does the alert for the tab in question say?

Also, which browser are you testing in? I'm guessing it's not IE.

Airshow

It shows the same in the url after i added your code:

}).filter(function(){ alert([selected,this.hash]); return this.hash==selected; }).click();

http://localhost/NNL/profile_edit.php?update_avatar=Image%20deleted%20successfully.#avatar_div

The alert is also the same:

#avatar_div and this happens on the profile_edit page where the account div is showing(the default div)

I am using Mozilla Firefox 3.6.13

I really appreciate the time you are taking to help me out. Im green at this. Best of luck in your endeavors.

Kkjay,

I can't quite see what's going wrong.

The redirect URL is correct. You can comment that alert out. selected is correct. You can also comment that alert out.

With my latest alert in the .filter fn, you should get one alert per tab (ie separate 4 alerts), each of the format #xxx_div,#yyy_div . With ...#avatar_div in the URL, the final alert should be #avatar_div,#avatar_div .

If you don't get these four alerts, then the filter (and hence the simulated click) is not being applied, which suggests a coding error higher up in the function (and an entry in Firefox's error console).

Airshow

Going through the code again: (what I have currently

<script src="Javascript/jquery-1.4.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
	$(function () {
	var tabContainers = $('div.tabs > div');
	tabContainers.hide().filter(':first').show();
			
	$('div.tabs ul.tabNavigation a').click(function () {
			tabContainers.hide();
			tabContainers.filter(this.hash).show();
			$('div.tabs ul.tabNavigation a').removeClass('selected');
			$(this).addClass('selected');
			return false;
	}).filter(':first').click();
	});	
	$(function () {
    var tabs = [];
    var tabContainers = $('div.tabs > div');
    $('ul.tabs a').each(function () {
      // note that this only compares the pathname, not the entire url
      // which actually may be required for a more terse solution.
        if (this.pathname == window.location.pathname) {
            tabs.push(this);
            tabContainers.push($(this.hash).get(0));
        }
    });

    // sniff for hash in url, and create filter search 
    var selected = (window.location.hash==''||window.location.hash=='#') ? tabs[0].hash : window.location.hash;//tabs[0].hash is the default
	alert(selected)
    
    $(tabs).click(function () {
        // hide all tabs
        $(tabContainers).hide().filter(this.hash).show();
        
        // set up the selected class
        $(tabs).removeClass('selected');
        $(this).addClass('selected');
        
        return false;
    }).filter(function(){ alert([selected,this.hash]); return this.hash==selected; }).click();
});
</script>

I have two functions each with a var: var tabContainers = $('div.tabs > div');

Do you think the error is here?

KK,

I didn't realise the first $(function) was still there. As far as I can see, it is not required. It appears to be an earlier version of the second function which does everything the first function does, plus a bit more.

Comment out the first function and see what happens.

Airshow

And .....

Here's my test page, which works in IE6 and FF (latest):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Airshow :: Untitled</title>
<style type="text/css">
.tabNavigation {
	list-style-type:none;
}
.tabNavigation li {
	display: inline;
	padding: 2px 4px;
	border-right: 1px solid #666;
}
.tabNavigation li:first-child {
	border-left: 1px solid #666;
}
a { text-decoration: none; }
.selected { text-decoration: underline; }
</style>

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(function () {
    var tabs = [];
    var tabContainers = [];
    $('ul.tabNavigation a').each(function () {
      // note that this only compares the pathname, not the entire url
      // which actually may be required for a more terse solution.
//        if (this.pathname == window.location.pathname) {
            tabs.push(this);
            tabContainers.push($(this.hash).get(0));
//        }
    });
    // sniff for hash in url, and create filter search
	var selected = (window.location.hash==''||window.location.hash=='#') ? tabs[0].hash : window.location.hash;
    $(tabs).click(function () {
        // hide all tabs
        $(tabContainers).hide().filter(this.hash).show();
        // set up the selected class
        $(tabs).removeClass('selected');
        $(this).addClass('selected');
        return false;
    }).filter(function(){ return this.hash==selected; }).click();
});
</script>

</head>

<body>

<div class="tabs">
  <ul class="tabNavigation">
     <li><a href="#account_div">Account</a></li>
     <li><a href="#change_password_div">Password</a></li>
     <li><a href="#favorites_div">Favorites</a></li>
     <li><a href="#avatar_div">Avatar</a></li>
  </ul>
  <div id="account_div">
     php include("personal_info_edit.php");
  </div>
  <div id="change_password_div">
     php include("change_password.php");
  </div>
  <div id="favorites_div">
     php include("favorites.php");
  </div>
  <div id="avatar_div">
     php include("avatar.php");
  </div>
</div>

</body>
</html>

You will see that I've commented out a couple of lines to make it work as a local file, and the lines ...

var tabContainers = [];
    $('ul.tabNavigation a').each(function () {

... are slightly different from yours.

I guess that any of these differences could account for my version working as it should (though I can't immediately see why yours shouldn't).

Airshow

Thanks again. I'll get back to you and tell you how it goes.

Haha, I had a made a syntax error that I couldn't see. It works now. It works perfectly in FF, Opera and Chrome. I tested on IE8 and the problem is that the div url redirect won't work. ie, I change the password for instance, and the div that shows after changing is the account div. Does IE handle redirects differently?

I appreciate the time you have been taking to assist me. I will mark this thread as solved because I can get it to redirect in most browsers.
Thanks.

KK,

Whew!

IE in general is OK with redirects but I'm not too sure about IE8. It's probably a browser setting. Try googling "Browser settings redirects" or similar for some discussions on the subject.

Airshow

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.