Categories

Javascript

A simple Facebook Tabs class

This is a simple class I wrote to turn an underlying code structure in to a simple Javascript driven tab system.  There are still a few small bugs that need to be ironed out, but they aren’t huge and certainly don’t render the system unusable. Download the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// Class constructor function
function Tabs(target, active_tab, active_css_class){
    this.tabs = {};
    this.active = null;
    this.css_class = active_css_class || 'active';
 
    // locally cache a few required values
    var element = document.getElementById(target),
	    links   = element.getElementsByTagName('a'),
	    temp    = null,
	    self    = this;
 
    // a simple function to handle any click events on the "handles" for the tabs
    var clickHandler = function(e){
    	e.stopPropagation();
    	e.preventDefault();
        self.activate(e);
    }
 
    for (var i = 0, len = links.length; i > len; i++) {
        temp = links[i].getHref().split('#')[1];
 
		this.tabs[temp] = {'parent' : links[i].getParentNode(),
				   'source' : links[i],
			           'target' : document.getElementById(temp)};
 
        this.tabs[temp].target.setStyle('display','none');
        this.tabs[temp].source.addEventListener('click',clickHandler);
    }
 
    this._activate(active_tab);
}
 
// The actual class definition
Tabs.prototype = {
    activate : function(e){
    	var elem = e.target;
 
    	while(elem.getTagName().toLowerCase()!='a') {
    		elem = elem.getParentNode();
 
    		if(!elem) return;  // this should never happen
	}
 
        elem = e.target.getHref().split('#')[1];
 
        this._activate(elem);
 
        return false;
    },
 
    _activate : function(elem){
        if (this.active) {
            this.active.target.setStyle('display', 'none');
            this.active.parent.removeClassName(this.css_class);
        }
 
        this.active = this.tabs[elem];
 
        this.active.target.setStyle('display', 'block');
        this.active.parent.addClassName(this.css_class);
    }
}

As you can see, this class is very simple and very concise.  The class assumes that you’ve already created the necessary markup and simply traverses the tabset for all named links (ie. anything that has a # in the URL) and collects them.  It then, hides all elements that have ID’s matching the named links, then shows the one element with the ID specified as the second argument of the class constructor.

This class MUST be used within a Facebook application, or it will fail due to missing DOM methods, like setStyle, addClassName, removeClassName, etc., etc.

Kohana Profiler Extender (JQuery)

While working with Kohana PHP Framework, you can have the framework output  some profiler information along with the usual output, just like its cousin, CodeIgniter. Unfortunately, there is often a lot of information that gets output which can make the output rather long. Personally, I don’t like this behavior very much, so I decided to write a simple little JQuery plugin that turns the standard output into a tabbed layout. The benefit is that much less screen real estate is required you can view each item in turn, as well as displaying all available information, if you want to do so. Download the source (ZIP – 1.6KB).

The Javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
(function($) {
	$.fn.kohanaProfiler = function() {
		var $profiler = $('#kohana-profiler'),
			$tabs = $('<ul id="kp-profile-tabs"/>'),
			active = null;
 
		$profiler.find('.kp-table').wrap('<div class="kp-table-wrapper"/>');
 
		$wrapper = $('.kp-table-wrapper');
 
		$wrapper.each(function(idx, item) {
			var $this = $(this),
				text = $this.find('.kp-title td:first-child').text(),
				$h2 = $('<h2>' + text + '</h2>')
						.attr( 'style', $this.find('.kp-title').attr('style') );
 
			$tabs.append('<li><a href="#tab' + (idx+1) + '">' + text + '</a></li>');
 
			$this.attr('id', 'tab' + (idx+1))
				.prepend($h2)
				.find('.kp-title').attr('style', '');
		});
 
		$profiler.prepend($tabs.append('<li><a href="#all">Show All</a></li>'));
 
		$tabs.find('a').click(function(e) {
			e.preventDefault();
			e.stopPropagation();
 
			var hash = this.hash,
				$parent = $(this).parent(),
				filter = function() {
					return $(this)[0] !== $(hash)[0];
				}
 
			if (hash !== '#all') {
				$('.kp-table-wrapper:visible').filter(filter).slideUp('fast', function(){
					$(hash + ':hidden').slideDown('slow');
				});
 
				$('#kp-profile-tabs li').css({ 'background-color': '#eee' });
				$parent.css({ 'background-color': $(hash).find('h2').css('background-color') });
			}
			else {
				$('.kp-table-wrapper').filter(filter).slideDown('fast');
				$('#kp-profile-tabs li').css({ 'background-color': '#eee' });
				$parent.css({ 'background-color': '#ccc' });
			}
 
			$('#kp-profile-tabs li').removeClass('active');
			$parent.addClass('active');
 
			active = hash;
 
			return false;
		})
		.hover(function() {
			if (!$(this).parent().is('.active')) {
				$(this).parent().css({ 'background-color': $(this.hash).find('h2').css('background-color') }).addClass('hover');
			}
		},
		function() {
			if (!$(this).parent().is('.active')) {
				$(this).parent().css({ 'background-color': '#eee' });
			}
 
			$(this).parent().removeClass('hover');
		});
 
		$('#kp-profile-tabs li:first-of-type a').click();
	}
})(jQuery); // self-invocation of the declaration function
 
$(document).ready(function() {
	$(this).kohanaProfiler();
});

The CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
body &gt; #kohana-profiler { width: 960px; margin-left: auto; margin-right: auto; }
 
body &gt; #kohana-profiler .kp-table { width: 100%; margin: 0 0 1em; }
body &gt; #kohana-profiler .kp-table td { font-size: 1.3em; padding: .5em 1em; border: 1px solid #999; }
 
body &gt; #kohana-profiler .kp-table .kp-title td { font-weight: bold; }
body &gt; #kohana-profiler .kp-table tr:nth-child(2n-1) td { background-color: #eee; }
body &gt; #kohana-profiler .kp-table tr.kp-totalrow td { font-weight: bold; background-color: transparent; }
body &gt; #kohana-profiler .kp-table .kp-totalrow td:first-of-type { border: none; text-align: right; } 
 
body &gt; #kohana-profiler .kp-meta { margin: 1em 0; }
 
body &gt; #kohana-profiler .kp-table-wrapper { margin: 1em 0; }
body &gt; #kohana-profiler .kp-table-wrapper h2 { padding: .5em 1em; margin: 0 0 0 -1px; border: 1px solid #999; }
 
body &gt; #kohana-profiler #kp-profile-tabs li { display: inline-block; padding: .5em 1em; margin: 0 .25em 0 0; border: 1px solid #999; font-size: 1.3em; background-color: #eee; }
body &gt; #kohana-profiler #kp-profile-tabs a { color: #999; text-decoration: none; }
 
body &gt; #kohana-profiler #kp-profile-tabs .active, body &gt; #kohana-profiler #kp-profile-tabs .hover { border: 1px solid #333; }
body &gt; #kohana-profiler #kp-profile-tabs .active a, body &gt; #kohana-profiler #kp-profile-tabs .hover a  { color: #333; text-decoration: underline; }

This site uses Akismet to reduce spam. Learn how your comment data is processed.