As the average monitor resolution and width increases, the real estate of the browser window changes. When browser windows are often wider than they are tall, it makes sense to focus on new ways to display data, such as tabs, and accordions.
The Accordion Solution
As a part of web development, we needed a solution to display multiple views of information on the same page, and wanted a sleek javascript transition effect. We chose a horizontal accordion solution based on MooTools' kwicks. The horizontal accordion is a wide, animated tab controller. It allows us to have multiple views on a single page without all being displayed at once. When a user clicks on a tab, it will animate, and expand to the selected tab. Thus creating a accordion like javascript animated UI.
Adding accordion object events
The concept of our control is to be able to click through each 'tab' to expand to it's respective view. By using MooTools transitions and effects we create what looks like an accordion. For the clicking to work, we must add events to each tab for it to expand.
init: function() {
if ($$('#kwick')) {
// create the list of kwicks
eyemagine.accordion.kwicks = $$('#kwick .kwick');
// create the transition to animate with
eyemagine.accordion.fx = new Fx.Elements(eyemagine.accordion.kwicks, {
wait: false,
duration: 250,
transition: Fx.Transitions.easeOut
});
// loop through each kwick
kwicks.each(function(kwick, i){
kwick.addEvent('click', function(e){
// call the accordions jump function to expand to that view
eyemagine.accordion.jumpToFrame(kwick.get('id'),false);
e.stop();
});
});
// call the init function for our accordion class to expand to the default view
eyemagine.accordion.initKwick();
}
},
Creating the accordion control
Now that we have our tabs' actions set we need to add functionality to them. In order to expand/contract the views we need to calculate the size of what the view should be based on how many views we currently have. The content of our view is also an issue. We will need to fade the content in and out using style opacity so we do not see the content when it is not active. Here is a sample of how the accordion control would look:
accordion: {
fx: null,
kwicks: null,
transitionLong: 300,
transitionShort: 10,
// initialize the accordion control
initKwick: function() {
$$('#kwick .kwick.init').each(function(kwick, j){
eyemagine.accordion.jumpToFrame(kwick.get('id'),true);
});
},
// jump to a specific view
jumpToFrame: function(id,force) {
var kwick = $(id);
// dont jump if the view is locked
if (kwick.hasClass('locked') && !force) {
return;
} else if ($(id)) {
// get the kwick id
var i = eyemagine.accordion.getAccordianItemId(id);
// our page specific offsets
var obj = {};
var offsetWidth = 37;
var totalWidth = 950 - (eyemagine.accordion.kwicks.length * 5 );
// set up the width of the kwicks
eyemagine.accordion.kwicks.each(function(other, j){
// reset the offset width
offsetWidth = 37;
// loop through each clickable tab
var titles = $$('#' + other.get('id') + ' .kwick_title').each(function(title, j){
offsetWidth = title.offsetWidth + 10;
if (other != kwick){
// set the width
totalWidth -= offsetWidth;
}
});
if (other != kwick){
var w = other.getStyle('width').toInt();
if (w != offsetWidth) obj[j] = {'width': [w, offsetWidth]};
}
// chain the tweens for fade in-out
$$('#' + other.get('id') + ' .accordionContent').each(function(content, j){
if (other != kwick){
other.addEvent('click', function(e){
// jump to a frame based on their link attribute
eyemagine.accordion.jumpToFrame(other.get('link'),false);
e.stop();
});
// create and start the transisition
var cfx = new Fx.Tween(content, {
property: 'opacity',
duration: eyemagine.accordion.transitionLong,
transition: Fx.Transitions.Quart.easeOut
});
cfx.start(0);
} else {
other.removeClass('accordionLink');
other.removeEvents('click');
content.set('tween', {duration: eyemagine.accordion.transitionLong});
content.tween('opacity', 1);
}
});
// nav never gets pushed over so no need to chain it
$$('#' + other.get('id') + ' .accordionNav').each(function(content, j){
if (other != kwick){
// fade out the view
content.set('tween', {duration: 'short'});
content.tween('opacity', '0');
} else {
// fade in the view
content.set('tween', {duration: 'short'});
content.tween('opacity', '1');
}
});
});
// set the total width transition
obj[i] = {
'width': [kwick.getStyle('width').toInt(), totalWidth]
};
// start the total width transition
eyemagine.accordion.fx.start(obj);
}
},
// get the id of the kwick from the kwick object
getAccordianItemId: function (name) {
var id;
eyemagine.accordion.kwicks.each(function(other, j){
if (other.get('id') == name){
id = j;
}
});
return id;
}
},
The Wizard Interface
Using the accordion object is great for selecting individual views to access. But what about a wizard like interface? In order to accomplish this we need to lock and unlock certain tabs. The easiest way to do this is by adding and removing classes. This way we can change the way these locked tabs look without any additional effort in our javascript.
unlock: function (id) {
$(id).removeClass('locked');
},
lock: function (id) {
$(id).addClass('locked','true');
},
Within our functions we will call the unlock functions after our javascript validation, for example:
validateForm: function(valid) {
if (valid) {
// unlock the tab and jump to the next frame
eyemagine.accordion.unlock('next');
eyemagine.accordion.jumpToFrame('next', false);
}
},
Initialing the accordion and controlling the view by URL
One problem we ran into with the accordion control was that if we wanted to link to a specific view, we could only link to the page containing the views. To get around this solution we added a URL hash checker to jump to that hash.
initKwick: function() {
// get the hash URL from the browser
if (window.location.hash) {
var jumpto = window.location.hash.substr(1);
}
// check to see if we have a quick with the hash's name
if ($(jumpto) && $(jumpto).hasClass('kwick')) {
// jump to our hash url
eyemagine.accordion.jumpToFrame(jumpto,true);
} else {
// jump to any kwick with the init class
$$('#kwick .kwick.init').each(function(kwick, j){
eyemagine.accordion.jumpToFrame(kwick.get('id'),true);
});
}
},
Practical use
Many new UI developments, such as iPhone scroll view, have been widely accepted and praised. The horizontal accordion shares many similarities to the scroll view, and is both a great way to conserve real estate and help us keep the user in the view we chose. These UIs are great for both mobile devices, and browser based navigation. By eliminating the use of conventional scroll bars we can fully customize and control what and where the data is going to be displayed. This includes a very easily expandable wizard-like interface that can help ease navigation for the end user.