jQuery Tabs + iFrame’s

Posted on August 26, 2011 / Posted by Deano

In this tutorial I’m going to talk you through using a great feature of jQuery UI called “tabs” with iFrame’s. Before we get to the actual guide let me first point out that although iFrame’s are greatly shunned by a great number of web developers (including myself) there actually is a great purpose for iFrame’s, it’s just when you use them to build a whole website; for instance a frame for the menu bar, frame for the right column and a frame for the content… Well yeah, go to hell!

Seriously though, iFrame’s are great (if they wasn’t, why would they still be in the HTML specifications?), the thing is though, they should only be used when really necessary.

Right! Lets get to the actual point of this post. I was recently trying to get jQuery’s Tabs UI to show an iFrame for each tab – but to not load the iFrame until you actually click on the tab. There were no great tutorials on the internet explaining how to accomplish this or how to get it working and looking good.
After some work though and tinkering with jQuery I finally got a solution together and thought I would share it with everyone who required the same solution as I did.

Step 1: Setting up jQuery UI Tabs

The first thing you are going to want to do is get the jQuery tabs working, download jQuery and then download jQuery UI from the URL’s below. save the jQuery as “jQuery.js”, when you have the jQuery UI you will see several folders in the package. move the “css” and “js” folders into your project and change the link to the correct css and js file in the html given further below.

Download jQuery.
Download jQuery UI. (for this tutorial I used the “smoothness” theme)

Here is the basic setup to get the jQuery UI Tabs working, if you load the html page up in a browser you should see several tabs which you can click to switch between, but no data will appear in any of the tabs.

<html>
	<head>
		<script type="text/javascript" src="data/js/jquery.js"></script>
		<script type="text/javascript" src="data/js/jquery-ui.js"></script>
		<link href="data/css/smoothness/jquery-ui.css" rel="stylesheet" type="text/css">

		<script>
			$(document).ready(function() {
				var $tabs = $('#tabs').tabs();
			});
		</script>
	</head>
	<body>
		<div id="tabs">
			<ul>
				<li><a class="tabref" href="#tabs-1">google</a></li>
				<li><a class="tabref" href="#tabs-2">yahoo</a></li>
				<li><a class="tabref" href="#tabs-3">bing</a></li>
			</ul>
			<div id="tabs-1" class="tabMain">
			</div>

			<div id="tabs-2">
			</div>

			<div id="tabs-3">
			</div>
		</div>
	</body>
</html>

Step 2: Implementing iFrames

So now we have the basic tabs working we are going to want to show an iFrame depending on which tab we have selected, the trick is to also not load the iFrame until we select the tab (else we could have quite a number of tabs loading when we hit the page!). To accomplish this we need to capture the mouse key press event, our <a> tags have a class assigned to them called “tabref” which we will use only on iFrame required tabs (this allows you to have tabs that don’t iFrame), here is how we do this in jQuery:

$("a.tabref").click(function() {
					//event code
				});

This would go in the $(document).ready under the tabs initialization code like this:

<script>
	$(document).ready(function() {
		var $tabs = $('#tabs').tabs();

		$("a.tabref").click(function() {
			//event code
		});</script>

Ok so now we can do some code when a link on the tab panel is clicked. Now we need to think about how we will get the URL for the iFrame and then build the iFrame into the tabs content.

To hold the URL that the iFrame will load, I have used a HTML attribute called “rel”, so to each <a> tag we will now set a rel tag with the URL to the page we wish to load in the iFrame, like so:

<li><a class="tabref" href="#tabs-1" rel="http://google.co.uk">google</a></li>
<li><a class="tabref" href="#tabs-2" rel="http://yahoo.co.uk">yahoo</a></li>
<li><a class="tabref" href="#tabs-3" rel="http://bing.co.uk">bing</a></li>

Now we can create a function that can grab the “rel” attributes content when we click an <a> tag, and finally to set the panel to a iFrame pointing to that URL. Here is a basic function which will accomplish these tasks:

function loadTabFrame(tab, url) {
	if ($(tab).find("iframe").length == 0) {
		var html = [];
		html.push('<div class="tabIframeWrapper">');
		html.push('<iframe class="iframetab" src="' + url + '">Load Failed?</iframe>');
		html.push('</div>');
		$(tab).append(html.join(""));
	}
	return false;
}

You can see this function needs two variables, the first is the object reference for the <a> tag clicked, and the second is the URL for the iFrame to link to. It’s actually a very simple function and here’s how to call it in your “click” event:

$("a.tabref").click(function() {
	loadTabFrame($(this).attr("href"),$(this).attr("rel"));
});

Congratulations!

We how have a working iFrame Tab UI – BUT WAIT! I’m sure your still not entirely happy with how it functions and how it looks! So lets spruce it up and make it work better in Step 3…

Step 3: Default Tab – Wheres the Iframe?

You may have noticed that when you first load the page a tab is selected as default, but no content or iFrame is shown. This is because we are generating the iFrame when (and only when) we click on a tab. So we need to do a little more code to get the default tabs iFrame loaded (if there is one!) when we first load the site. We can use the same “loadTabFrame”” function!

The first thing we need to do is get the selected tab’s index number, then we would need to use CSS to select the right <li> and finally to grab the <a> object.

Here is a small function that will get the selected tabs index, this would go in the document.ready just below where we initialize the tabs:

function getSelectedTabIndex() {
	return $tabs.tabs('option', 'selected');
}

From this function we can now get a hold on the Object for the <a> we want, place this code directly below the code above:

beginTab = $("#tabs ul li:eq(" + getSelectedTabIndex() + ")").find("a");

Now we have the object we require, we can just call our “loadTabFrame” function once on page load to setup that tabs iFrame, place this below the code above:

loadTabFrame($(beginTab).attr("href"),$(beginTab).attr("rel"));

Now you should see the selected tabs iFrame when the page first loads!

Step 4 – Pretty looking iframe’s please!

Ok! So the iFrames are small and un-stylish compared to the actual tabs. Fortunately this can be changed with some nice CSS. Here is some css that will give your iFrames a 100% width, the height however will require a little bit of Javascript as setting a 100% height is not very pleasing.

<style>
	html {
		font-size:10px;
	}

	.iframetab {
		width:100%;
		height:auto;
		border:0px;
		margin:0px;
		background:url("data/iframeno.png");
	}

	.ui-tabs-panel {
		padding:5px !important;
	}
</style>

The background image set to iFrame is there so we can see a loading message until the iFrame has content – alternatively if the iFrame cannot load any content the image can warn that it may have failed. Here is the image I was using, feel free to use it too:

iframeno

 

To set the height requires some Javascript – We need to edit the “loadTabFrame” so when it loads the iFrame it will also set the height of the iFrame:

function loadTabFrame(tab, url) {
	if ($(tab).find("iframe").length == 0) {
		var html = [];
		html.push('<div class="tabIframeWrapper">');
		html.push('<iframe class="iframetab" src="' + url + '">Load Failed?</iframe>');
		html.push('</div>');
		$(tab).append(html.join(""));
		$(tab).find("iframe").height($(window).height()-80);
	}
	return false;
}

So were getting the window height and removing 80px from it so that it now fits more perfectly in the browser window!

Step 5 – Breaking out of the iFrames

Sometimes we wish to break out of the iFrame… I found it a very useful feature when utilizing this code myself. So I though I would include it. Basically a link just above the iFrame can be clicked to take us directly to the iFrames destination URL without using the iFrame itself, this can be accomplished by editing our “loadTabFrame” function so that it places <a> tags which can be clicked to take us to the destination URL if we please, here is the revised code:

function loadTabFrame(tab, url) {
	if ($(tab).find("iframe").length == 0) {
		var html = [];
		html.push('<div class="tabIframeWrapper">');
		html.push('<div class="openout"><a href="' + url + '"><img src="data/world.png" border="0" alt="Open" title="Remove iFrame" /></a></div><iframe class="iframetab" src="' + url + '">Load Failed?</iframe>');
		html.push('</div>');
		$(tab).append(html.join(""));
		$(tab).find("iframe").height($(window).height()-80);
	}
	return false;
}

world.png refers to this image:

world

To make this pretty I have also done some CSS so that the link appears in the tab bar and the iFrame is moved up to look neat, here is the revised CSS code:

<style>
	html {
		font-size:10px;
	}

	.iframetab {
		width:100%;
		height:auto;
		border:0px;
		margin:0px;
		background:url("data/iframeno.png");
		position:relative;
		top:-13px;
	}

	.ui-tabs-panel {
		padding:5px !important;
	}

	.openout {
		float:right;
		position:relative;
		top:-28px;
		left:-5px;
	}
</style>

There we go!

Final Code

For those of you who could not follow or did not have the time, here is a full final cut of the code:

<html>
	<head>
		<script type="text/javascript" src="data/js/jquery.js"></script>
		<script type="text/javascript" src="data/js/jquery-ui.js"></script>
		<link href="data/css/smoothness/jquery-ui.css" rel="stylesheet" type="text/css">
		<style>
			html {
				font-size:10px;
			}

			.iframetab {
				width:100%;
				height:auto;
				border:0px;
				margin:0px;
				background:url("data/iframeno.png");
				position:relative;
				top:-13px;
			}

			.ui-tabs-panel {
				padding:5px !important;
			}

			.openout {
				float:right;
				position:relative;
				top:-28px;
				left:-5px;
			}
		</style>
		<script>
			$(document).ready(function() {
				var $tabs = $('#tabs').tabs();

				//get selected tab
				function getSelectedTabIndex() {
					return $tabs.tabs('option', 'selected');
				}

				//get tab contents
				beginTab = $("#tabs ul li:eq(" + getSelectedTabIndex() + ")").find("a");

				loadTabFrame($(beginTab).attr("href"),$(beginTab).attr("rel"));

				$("a.tabref").click(function() {
					loadTabFrame($(this).attr("href"),$(this).attr("rel"));
				});

				//tab switching function
				function loadTabFrame(tab, url) {
					if ($(tab).find("iframe").length == 0) {
						var html = [];
						html.push('<div class="tabIframeWrapper">');
						html.push('<div class="openout"><a href="' + url + '"><img src="data/world.png" border="0" alt="Open" title="Remove iFrame" /></a></div><iframe class="iframetab" src="' + url + '">Load Failed?</iframe>');
						html.push('</div>');
						$(tab).append(html.join(""));
						$(tab).find("iframe").height($(window).height()-80);
					}
					return false;
				}
			});
		</script>
	</head>
	<body>

		<div id="tabs">
			<ul>
				<li><a class="tabref" href="#tabs-1" rel="http://google.co.uk">google</a></li>
				<li><a class="tabref" href="#tabs-2" rel="http://yahoo.co.uk">yahoo</a></li>
				<li><a class="tabref" href="#tabs-3" rel="http://bing.co.uk">bing</a></li>
			</ul>
			<div id="tabs-1" class="tabMain">
			</div>

			<div id="tabs-2">
			</div>

			<div id="tabs-3">
			</div>
		</div> 

	</body>
</html>

Conclusion

There we have it! A fully working solution with some nifty extra functionality and nice styling.

Here was my end solution:

image

The code works flawlessly and I don’t see any horrible layout problems either, the solution works in all modern browsers (FF – IE 9 – Safari – Chrome) and doesn’t overload your browser by loading all the iFrame’s at once!

If you have any feedback and/or suggestions please post a comment, it would be awesome to refine this tutorial a little more if required and fix anything I may have goofed on. Also post some screenshots of your final solution and modifications to the code!

And don’t forget to give some credit if this has helped you out Winking smile

About 

I code.

    Find more about me on:
  • googleplus
  • facebook
  • linkedin
  • skype
About Author: Deano
I code.

19 comment(s) on “jQuery Tabs + iFrame’s

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>