If you haven’t seen Apple’s product slider in action, you must check it out. It’s a horizontal gallery of their products with horizontal slider controlled with javascript. I believe they are using the scriptaculous motion for this, but there should be a way to build this in jQuery.
Truth be told, I was a die-hard fanatic for scriptaculous/prototype, but after ExpressionEngine announce their adoption of jQuery for EE 2.0, it was time to grow beyond the one framework pony.
Luckily, someone already set out to build the slider in jQuery. And major hat’s off to Remy Sharp for a great approach to this. If you looking for a way to build your own slider, start there first.
The Problem
Actually, there was no problem until I had a client to didn’t fit into the strict mold set out for this widget. As with most inventive solutions, they are begat from necessity.
The slider is built on an unordered list, but doesn’t support nested lists. For my needs, the slider had to be able to not only show multiple categories of products, but also visually differentiate.
Now, this can be resolved by manually setting css values. This approach would “hard code” the positions of the categories. That isn’t very code may be puled from a database.
Also, the slider needs to work without javascript. I know. Who doesn’t use javascript? The answer is, I don’t know, but someone always points out if something doesn’t degrade properly.
The Solution
I built this out backwards, but it works. So don’t question it. This demo shows the slider with wireframes to show off the block level div’s and li’s.
You can see by this code example that the lists are simple and even has a space for the category description if your site requires it.
HTML
This is a simple template shoing how to format your product groups and your categories for them. There can be as many needed. This example should be able to display them all successfully.
CSS
I threw in a dash of YUIs css reset. Most of the id and class names are generic. I would recommend renaming these to something more specific to avoid conflict.
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, img {border-width: 0px;margin:0;padding:0;}
#mlSlideWidget {
font:11px arial,helvetica,clean,sans-serif;
*font-size:small;
*font:x-small;
position: relative;
height: 361px;
width: 659px;
background: url(images/slider-background.jpg) left top no-repeat;
}
#sliderWindow {
margin: 1px;
height: 365px;
position: relative;
width: 655px;
}
.sliderGallery {
overflow: auto;
}
.sliderGallery ul.sliderList {
top: 0px;
left: 0px;
margin-top: 135px;
padding-bottom: 0;
position: absolute;
list-style: none;
height: 210px;
overflow: auto;
width: 2000px;
white-space: nowrap;
}
#mlSlideWidget .sliderGallery ul li.group {
margin-left: 7px;
margin-right: 7px;
display: inline;
float: left;
}
#mlSlideWidget .sliderGallery ul li.group .groupContent {
margin-right: 10px;
padding-left: 10px;
padding-top: 10px;
padding-bottom: 10px;
}
ul.groupButtons {
height: 120px;
}
li.group {
background: url(images/group-backgroundcap.png) no-repeat right top;
}
li.group .groupContent{
background: url(images/group-background.png) no-repeat left top;
}
li.group p {
width: 430px;
height: 70px;
font-size: 10px;
line-height: 12px;
white-space: normal;
}
li.group ul.groupButtons {
list-style: none;
white-space: nowrap;
}
li.group ul.groupButtons li.singleButton {
width: 140px;
float: left;
height: 118px;
text-align: center;
}
#scroll {
position: absolute;
top: 0px;
left: 0px;
z-index: 100;
width: 639px;
margin-left: 10px;
margin-right: 8px;
}
#scroll ul {
height: 123px;
list-style: none;
}
#scroll li.marker {
margin-top: 4px;
padding-top: 60px;
text-align: center;
z-index: 90;
font-size: 10px;
height: 30px;
width: 55px;
padding-left: 20px;
padding-right: 20px;
margin-left: 10px;
margin-right: 10px;
float: left;
}
.handle {
position: absolute;
top: 8px;
left: 0;
z-index: 110;
height: 115px;
}
.fakeHandle {
position: absolute;
top: 8px;
left: 0;
z-index: 80;
height: 115px;
}
jQuery UI will need to be built with UI Core, Draggable, Slider, Effects Core, and Slide. Some of the values of this rules in the example are built to my specs and can be modified to whatever specs fit your site. Note the versions of jQuery at the time of this article.
This example doesn’t know how many objects exist in the slider. If you use a set amount, this example can be greatly reduced. However, if your categories are managed via a database or cms tool, the number of objects used can change.
Javascript
Try not to laugh at my n00b code. I’m sure there are much better ways to write this.
Notice the versions of jQuery and UI. 1.7.1 has issues with this solution. As of yet, I haven’t found a fix.
Wrap it all together
Here is the slider in action.
example
Not all lists are the same. Here is the same page with an expanded and uneven list. In this example, one group has more products and another has fewer. The total list is longer so the scroll bar handle will be shorter.
example 2
Finally, and sadly, here is it with Jquery 1.3.2 / UI 1.7.1. The handle interaction is wonky across the board. Also, I had to subtract the length of the slider so the handle wouldn’t go careening off the widget.
example fail
that is pretty badass.