Layout Widgets

As I outlined in the JS Widgets page, we've separated our code into a section for code that creates html objects and those that dress up layouts. Anyway, I've already gone over the javascript widgets (code that creates html objects) and here I'll go into the layout widgets.

carousel.js

docs | svn

On CNET, we have a rather common layout that you've no doubt seen elsewhere on the web. We call it a carousel but who knows what others call it. At it's heart, it's some sort of box with content and buttons that cycle through it.

Here are some examples of carousels on our network (these are just images):

cnet.jpg mp3.jpg

So in it's most basic form, a carousel is a bunch of elements (slides) and related interactive elements (buttons). It is animated (i.e. it "plays" through the items) and the user can optionally stop the animation either by clicking a button or mousing over it.

Enter the CNETcarousel class, which handles all that interactivity for you - again, the html and what it looks like is up to you entirely.

CNETcarousel

Here's a very, very simple carousel:

The html we'll use:

<style>
#simpleCarousel td div {
  position: absolute;
}
#simpleCarousel td.button {
  padding: 5px;
}
#simpleCarousel td.selected {
  font-weight: bold;
}
#simpleCarousel td.slides {
  height: 20px;
}
</style>
<table id="simpleCarousel">
  <tr><td colspan="4" class="slides">
   <div class="slide">I'm the first content slide</div>
   <div class="slide">I'm the second content slide</div>
   <div class="slide">I'm the third content slide</div>
   <div class="slide">I'm the fourth content slide</div>
  </td></tr>
  <tr>
    <td class="button">one</td>
    <td class="button">two</td>
    <td class="button">three</td>
    <td class="button">four</td>
  </tr>
</table>

...here's that html rendered:

I'm the first content slide
I'm the second content slide
I'm the third content slide
I'm the fourth content slide
one two three four

new CNETcarousel($('simpleCarousel'), {slideInterval: 1000});
//the default slideInterval is 4 seconds, 
//let's make this example go a little faster
execute this code

In it's default state, the carousel just makes the slides animate. Note that it doesn't position these elements. You'll need your CSS to do that for you. Each slide should be positioned absolutely (on top of each other).

The buttons don't do anything related to the animation in this example. As each slide cycles, it adds a class name to the button ("selected" when the corresponding slide is visible, "off" when it isn't).

Your buttons will probably be links to the content on some other page, and you'll probably make the slide content also clickable. The CNETcarousel class has several options:

carouselContainer
the id of the parent element (or the element itself) that contains the carousel (which is typically hidden in css with visibility: hidden) default: "Carousel"
slidesSelector
the css selector for the slide elements note: this is relative to the carouselContainer object, so only elements that match this selector within that object will be included in the carousel default: ".slide"
buttonsSelector
the css selector for the buttons; same rules as slidesSelector default: ".button"
startIndex
the first item to show default: 0
buttonOnClass
the class for the "on" state of the buttons default: "on"
buttonOffClass
the class for the "off" state of the buttons default: "off"
rotateAction
the action the user takes to rotate to the next button; options: mouseover, click, or none default: 'none'
slideInterval
the interval between slide rotations in the slideshow default: 4000
transitionDuration
the duration of the transition effect default: 700
autoplay
turn the slideshow on on instantiation default: true
onRotate
callback for when a slide is automatically shown durring autoplay
onStop
callback for when the slideshow stops playing
onAutoPlay
callback for when autoplay starts
onShowSlide
callback for when a slide transition occurs (whether in autoplay or by user action)

A more complex example

Jesse Sykes & The Sweet Hereafter
Jesse Sykes & The Sweet Hereafter

With its hippie-baroque script and solo portrait, Sykes' "Like Love Lust" album cover evokes the era of Joni and Judy. Inside is a record that culls the group's wise sense of song but little of its sentimentality, favoring instead fuzzy guitars and a Grant Lee Buffalo brand of wry resignation.

Filed in: Alternative Country-Rock

The Early Years
The Early Years

Hazy psych-rock effects, vocal frailty, punishing drums, and a big ol' flange pedal complete the rock- history roundabout in this London group's "All Ones & Zeros." It's just one of many tours they take on the LP of the same name, but the '80s of Echo & the Bunnymen always sounds like home.

Filed in: Indie Rock

Fiona Apple
Fiona Apple

On the LP "Extraordinary Machine," the most controversial--and fantastically talented--alto in all of singer-songwriterdom grudgingly gives us what we wanted: a straight-up terrific record. Like much of her best work, it's rather an enigma, every sultry purr threatening to become a snarl.

Filed in: Adult Alternative Pop/Rock

Full album stream: Stomp The Yard Soundtrack
Full album stream: Stomp The Yard Soundtrack

The beat-tastic film about a step competition proves, not surprisingly, to offer one of the most stellar hip-hop soundtracks in '07. In one sense, it's a document of ambitious urban music circa Chemist's turntable madness and the Roots' organic live beats.

Filed in: Film Soundtracks


This doesn't look so hot until you execute the carousel code:

new CNETcarousel('musicCarousel', {
  rotateAction: 'click', /*lets make the user click to jump*/
  slideInterval: 2000,
  onShowSlide: function(){
    /*this layout uses images that change, not classes
      so we have to add a little more logic here*/
    $$('#musicCarousel div.panel-top a.off img').each(function(button, index){
      button.src = button.src.replace('_on', '_off');
    });
    $$('#musicCarousel div.panel-top a.selected img').each(function(button, index){
      button.src = button.src.replace('_off','_on');
    });
  }
});
execute this code

You can click the numbers at the top to manually see a slide. This also stops the animation.

.hide, .show, .stop and more

You can call .hide() on your instance to hide the component from view (sets visibility to hidden; does not alter display property), and .show() to show the component. This is useful if you want to make sure it looks good before it's visible to the user.

.stop will stop the animation (autoplay). .rotate will iterate to the next slide. .autoplay will start the animation.

MooScroller

On (CNET's TV site) site they use flash a lot (understandibly; it's all about video and stuff). They had this component:

It was a flash app, but it's presence (there were several on the page) was negatively affecting the performance of the video player for some reason, so we recreated it in javascript:

Insider secrets: Upgrade your laptop's RAM
Looking less like a milk crate, the redone xB offers some car tech firsts.
Automobiles: 2008 Scion xB
Looking less like a milk crate, the redone xB offers some car tech firsts.
Reviews: Buzz Report: Facebook is...
Looking less like a milk crate, the redone xB offers some car tech firsts.
CNET Top 5: CNET Top 5: iPhone dream...
Looking less like a milk crate, the redone xB offers some car tech firsts.
Insider secrets: Upgrade your laptop's RAM
Looking less like a milk crate, the redone xB offers some car tech firsts.
Automobiles: 2008 Scion xB
Looking less like a milk crate, the redone xB offers some car tech firsts.
Reviews: Buzz Report: Facebook is...
Looking less like a milk crate, the redone xB offers some car tech firsts.
CNET Top 5: CNET Top 5: iPhone dream...
Looking less like a milk crate, the redone xB offers some car tech firsts.
Insider secrets: Upgrade your laptop's RAM
Looking less like a milk crate, the redone xB offers some car tech firsts.
Automobiles: 2008 Scion xB
Looking less like a milk crate, the redone xB offers some car tech firsts.
Reviews: Buzz Report: Facebook is...
Looking less like a milk crate, the redone xB offers some car tech firsts.
CNET Top 5: CNET Top 5: iPhone dream...
Looking less like a milk crate, the redone xB offers some car tech firsts.


MooScroller lets you re-create the overflow scrollbar and style it however you want. You can do horizontal or vertical scrolling or both (by having two instances of the class on the same container). You have to provide it the elements that are the scroll bar, the up-scroll and down-scroll (these two are optional), and you have to style it all yourself.

The class will figure out the content and resize the scrollbar element appropriately. Additionally, you can update this if the content changes. So, for example, if you ajax in some new stuff into the container, you can execute .update() on the instance of the class and the scrollbar will resize, just like a real scroll bar.

Simple Veritcal MooScroller

The html used:

<div class="scroller">
	<div class="content">
		<ol>
			<li>one</li>
			<li>two</li>
			<li>three</li>
			<li>four</li>
			<li>five</li>
			<li>six</li>
			<li>seven</li>
			<li>eight</li>
			<li>nine</li>
			<li>ten</li>
		</ol>
		<p>a paragraph</p>
		<ol>
			<li>blah</li>
			<li>blah</li>
		</ol>
		<ol>
			<li>one</li>
			<li>two</li>
			<li>three</li>
			<li>four</li>
			<li>five</li>
			<li>six</li>
			<li>seven</li>
			<li>eight</li>
			<li>nine</li>
			<li>ten</li>
		</ol>
	</div>
	<div class="scrollarea">
		<div class="scrollBack"></div>
		<div class="scrollBarContainer">
			<div class="scrollKnob"></div>
		</div>
		<div class="scrollForward"></div>
	</div>
</div>

The html rendered:

  1. one
  2. two
  3. three
  4. four
  5. five
  6. six
  7. seven
  8. eight
  9. nine
  10. ten

a paragraph

  1. blah
  2. blah
  1. one
  2. two
  3. three
  4. four
  5. five
  6. six
  7. seven
  8. eight
  9. nine
  10. ten

Now execute this code to enable the scrollbar:

new MooScroller($E('div.scroller div.content'), $E('div.scroller .scrollKnob'), {
	scrollLinks: {
		forward: $E('div.scroller div.scrollForward'),
		back: $E('div.scroller div.scrollBack')
	}
});
execute this code

Simple Horizontal MooScroller

a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long

new MooScroller($E('div.horzscroller div.content'), $E('div.horzscroller .scrollKnob'), {
	mode: 'horizontal',
	scrollLinks: {
		forward: $E('div.horzscroller div.scrollForward'),
		back: $E('div.horzscroller div.scrollBack')
	}
});
execute this code

Veritcal & Horizontal MooScroller

a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long a paragraph that is really long

  1. one
  2. two
  3. three
  4. four
  5. five
  6. six
  7. seven
  8. eight
  9. nine
  10. ten

a paragraph

  1. blah
  2. blah

new MooScroller($E('div.bothscroller div.content'), $E('div.bothscroller .vscrollarea .scrollKnob'), {
	scrollLinks: {
		forward: $E('div.bothscroller .vscrollarea div.scrollForward'),
		back: $E('div.bothscroller .vscrollarea div.scrollBack')
	}
});
new MooScroller($E('div.bothscroller div.content'), $E('div.bothscroller .wscrollarea .scrollKnob'), {
	wheel: false,
	mode: 'horizontal',
	width: 400,
	scrollLinks: {
		forward: $E('div.bothscroller .wscrollarea div.scrollForward'),
		back: $E('div.bothscroller .wscrollarea div.scrollBack')
	}
});
execute this code

simple.slideshow.js

docs | svn

The SlideShow class lets you collect dom elements with next and previous links. A quick example:

slide 1

slide 2

slide 3

slide 4

slide of Previous | Next

new SimpleSlideShow({
  startIndex: 0,
  slides: $$('#slideShow p'),
  currentIndexContainer: 'slideNow', //an element or it's id
  maxContainer: 'slideMax',
  nextLink: 'ssNxt',
  prevLink: 'ssPrv'
});
execute this code

And that's pretty much it.

SimpleImageSlideShow

Does pretty much the same thing as SimpleSlideShow but contains functions for handling images.

 of  PreviousNext

new SimpleImageSlideShow({
  startIndex: 0,
  imgUrls: ['http://download.com/i/dl/media/dlimage/10/87/78/108778_medium.jpeg',
'http://download.com/i/dl/media/dlimage/10/87/79/108779_medium.jpeg',
'http://download.com/i/dl/media/dlimage/10/87/81/108781_medium.jpeg'],
  container: 'screenShotImgs',
  currentIndexContainer: 'imgNow',
  maxContainer: 'imgMax',
  nextLink: 'nextImg',
  prevLink: 'prevImg'
});
execute this code

Alternatively, if your images are already in the page, you can use those. In this example I have all three images visible, but you might want to hide them until your javascript executes.

 of  PreviousNext

new SimpleImageSlideShow({
  startIndex: 0,
  slides: $$('div#screenShotImgs2 img'),
  container: 'screenShotImgs2',
  currentIndexContainer: 'imgNow2',
  maxContainer: 'imgMax2',
  nextLink: 'nextImg2',
  prevLink: 'prevImg2'
});
execute this code

Finally, you can use .addImg(url) to insert more images into the gallery at any time. This example is like the one above. There are 3 images already loaded (and hidden until you create the slideshow object) and this code will create the slideshow and then add 3 more images.

 of  PreviousNext

var myGallery = new SimpleImageSlideShow({
  startIndex: 0,
  slides: $$('div#screenShotImgs3 img'),
  container: 'screenShotImgs3',
  currentIndexContainer: 'imgNow3',
  maxContainer: 'imgMax3',
  nextLink: 'nextImg3',
  prevLink: 'prevImg3'
});
/*add some more images later...*/
myGallery.addImg('http://www.download.com/i/dl/media/dlimage/91/30/9/91309_medium.jpeg');
myGallery.addImg('http://www.download.com/i/dl/media/dlimage/91/31/0/91310_medium.jpeg');
myGallery.addImg('http://www.download.com/i/dl/media/dlimage/91/31/2/91312_medium.jpeg');
execute this code

multiple.open.accordion.js

docs | svn

Mootools comes with a set of plugins including the excellent Accordion class. Here's one:

first section
I'm the content for the first section.
second section
I'm the content for the second section.
third section
I'm the content for the third section.

I really like the Accordion class and often recommend its use. But what if you want the user to be able to open more than one section?

At CNET, we use a similar effect for our navigation (on the left side of the site). While you could accomplish this with a set of height effects, I wanted to make it like an accordion so that implementing either one would be pretty much the same for a developer.

Here's an Accordion that lets you toggle individual areas open and shut:

first section
I'm the content for the first section.
second section
I'm the content for the second section.
third section
I'm the content for the third section.

new MultipleOpenAccordion($$('#AccordionMulti dt.stretchtoggle'), $$('#AccordionMulti dd.stretcher'), {openAll: false});
execute this code

As you can see, it's not quite the same concept as the Accordion class, but for something like a navigation area, where the user might prefer to open more than one, it's really easy to implement.

It has numerous options:

openAll
(boolean) open all elements on startup; defaults to true.
allowMultipleOpen
(boolean) allows users to open more than one element at a time; defaults to true.
firstElementsOpen
(array) an array of elements to open on startup; only used if openAll = false and allowMultipleOpen = true; defaults to [0];
start
(string) 'first-open' slides open each element in firstElementsOpen; 'open-first' opens each element in firstElementsOpen immediately using no effects (default)
fixedHeight
(integer), if you want your accordion to have a fixed height. defaults to false.
fixedWidth
(integer), if you want your accordion to have a fixed width. defaults to false.
alwaysHide
(boolean), if you want the ability to close your only-open item. defaults to true.
wait
(boolean). means that open and close transitions can cancel current ones (so if you click on items before the previous finishes transitioning, the clicked transition will fire canceling the previous). true means that if one element is sliding open or closed, clicking on another will have no effect. Defaults to false.
onActive
function to execute when an element starts to show
onBackground
function to execute when an element starts to hide
height
(boolean), will add a height transition to the accordion if true. defaults to true.
opacity
(boolean), will add an opacity transition to the accordion if true. defaults to true.
width
(boolean), will add a width transition to the accordion if true. defaults to false, css mastery is required to make this work!

mouseovers.js

This script contains two functions for handling mousing over things.

docs | svn

imgMouseOverEvents

We've all written javascript a million times to let a user mouse over an image and see a highlight. When I see it, it usually looks like this:

<img src="myImg_off.gif" onmouseover="this.src='myImg_on.gif'"
 onmouseout="this.src='myImg_on.gif'">

And while that works just fine, I got tired of writing it (and, for that matter, seeing other people write it. Now it looks like this:

<img src="myImg_off.gif" class="autoMouseOver">

In action:

Ahhhhh. Much better.

The function itself is imgMouseOverEvents() and here's what it looks like when you call it:

imgMouseOverEvents('_off', '_on', 'img.autoMouseOver');

This will find all elements that match the selector (img.autoMouseOver) and when the user mouses over the image, it will replace any instance of "_off" in the src of the image with "_on". When they mouse out, it will put "_off" back.

This means you can choose a naming convention ("myImg_on", "myImg_off") for your mouseovers, choose a class (like "autoMouseOver") and then just give the class to your image and you're done writing javascript for this very common action.

The script itself executes the example above onDomReady, so you don't even have to write anything at all. Just use the default conventions for naming your files and then give your images (and inputs that are images) the autoMouseOver class.

tabMouseOvers

The tabMouseOvers function is almost identical to imgMouseOverEvents except it toggles classnames. This function will swap out one css class for another when the user mouses over a dom element (doesn't have to be a tab layout) You also have the option of having the class of the DOM element change when the user mouses over a child of the DOM element that's supposed to toggle (for instance, if your tab has a link in it, you can have the tab change when the user mouses over the anchor instead of the whole tab).

Pass in the css class for the 'on' and 'off' states, as well as the css selector for the DOM element, and, optionally, the selector for the sub elements for the mouseover action.

You can also optionally set applyToBoth to set the mouseover class to both the selector and the subselector if you like.


tabMouseOvers('on', 'off', '#tabSwapperExample li', 'a', false);
execute this code

After you execute the code block above, mouse over the items and you'll see their classes change.

tabswapper.js

docs | svn

The TabSwapper class helps you make another very common layout: the tabbed box. This is where the layout has a box with tabs across the top. The user clicks a tab and the content below it is displayed. It's kinda like a carousel without the animation. Unlike the carousel, the content doesn't have to be absolutely positioned over itself, as things are actually set to display:none when they switch.

Example:

<div id="tabBoxExample">
  <ul class="tabSet">
    <li class="off"><a>first tab</a></li>
    <li class="off"><a>second tab</a></li>
    <li class="off"><a>third tab</a></li>
  </ul>
  <div class="panelSet">
    <div class="panel">I'm the content for the first panel.</div>
    <div class="panel">I'm the content for the second panel.</div>
    <div class="panel">I'm the content for the third panel.</div>
  </div>
</div>

I'm the content for the first panel.
I'm the content for the second panel.
I'm the content for the third panel.

new tabSwapper({
  selectedClass: 'on',
  deselectedClass: 'off',
  tabs: $$('#tabBoxExample li'),
  clickers: $$('#tabBoxExample li a'),
  sections: $$('div.panelSet div.panel'),
  /*remember what the last tab the user clicked was*/
  cookieName: 'tabSetExample',
  /*use transitions to fade across*/
  smooth: true
});
execute this code

html.table.js

This just automates creating tables for tabular data.

var myTable = new HtmlTable({
  properties: {
    border: 1,
    cellspacing: 3
  },
  rows: [
    ['apple', 'red'],
    ['lemon', 'yellow']
  ]
});
myTable.table.injectInside($('exampleHtmlTable'));
myTable.push(['lime', 'green']);
myTable.push(['grape', 'purple']);
execute this code

You can also pass in a more sophisticated row element:

var myTable = new HtmlTable({
  properties: {
    border: 1,
    cellspacing: 3
  },
  rows: [
    [{content: 'fruits', properties: {colspan: 2, 'class': "someCssClass", style: "border: 1px solid blue"}}],
    ['apple', 'red'],
    ['lemon', 'yellow']
  ]
});
myTable.table.injectInside($('exampleHtmlTable2'));
execute this code

cnet-libraries/04-layoutwidgets.txt · Last modified: 2007/09/14 15:26 by aaron-n

On this page:

Page index