How to re-run this jQuery plugin on window resize? - javascript

I have a list where the first-child element is visible on desktop, and is hidden on screens under 767px, and then every other element cycles through on a loop for all screen sizes.
I have been trying to re-run this jQuery plugin on window resize without success, please could someone help implement window resize function?
I have put together an example here
(function ($){
$.fn.extend({
rotaterator: function(options) {
var defaults = {
fadeSpeed: 500,
pauseSpeed: 100,
child:null
};
var options = $.extend(defaults, options);
return this.each(function() {
var o =options;
var obj = $(this);
var obj2 = "ul li:first-child";
var items = $(obj.children(), obj);
var items2 = $(obj.children(), obj2);
if ($(window).width() < 767) {
items.each(function() {$(this).hide();})
items2.each(function() {$(obj2).hide();})
} else {
items.each(function() {$(this).hide();})
items2.each(function() {$(obj2).show();})
}
if(!o.child){var next = $(obj).children(':nth-child(2)');
}else{var next = o.child;
}
$(next).fadeIn(o.fadeSpeed, function() {
$(next).delay(o.pauseSpeed).fadeOut(o.fadeSpeed, function() {
var next = $(this).next();
if (next.length == 0){
next = $(obj).children(':nth-child(2)');
}
$(obj).rotaterator({child : next, fadeSpeed : o.fadeSpeed, pauseSpeed : o.pauseSpeed});
})
});
});
}
});
})(jQuery);
and call
(function ($) {
$('ul').rotaterator({fadeSpeed:5000, pauseSpeed:1000});
})(jQuery);
Thanks for looking.
UPDATE:
I have added window resize, it seems it's had an affect of how it initially loads and performs thereafter, showing all elements first, please see updated fiddle demo

Your current implementation already adapts to the new window size as soon as the fade-out completes and the next call to rotaterator is made.
If however you want an immediate effect at the resize event, so that the animation restarts taking the new window size into account, then use the jQuery stop method to stop any current animations of an ul child element.
For instance:
$(window).resize(function() {
$('ul *').finish();
$('ul').rotaterator({fadeSpeed:5000, pauseSpeed:1000});
});

Related

Remove transparency on menu drop down Javascript

I've been trying to implement a feature that removes the transparency of the dropdown menu on my website so that it is actually readable for visitors.
The code I am currently using, which removes transparency on scroll but not on drop down is:
$(document).ready(function(){
var stoptransparency = 100; // when to stop the transparent menu
var lastScrollTop = 0, delta = 5;
$(this).scrollTop(0);
$(window).on('scroll load resize', function() {
var position = $(this).scrollTop();
if(position > stoptransparency) {
$('#transmenu').removeClass('transparency');
} else {
$('#transmenu').addClass('transparency');
}
lastScrollTop = position;
});
$('#transmenu .dropdown').on('show.bs.dropdown', function() {
$(this).find('.dropdown-menu').first().stop(true, true).slideDown(300);
});
$('#transmenu .dropdown').on('hide.bs.dropdown', function() {
$(this).find('.dropdown-menu').first().stop(true, true).slideUp(300);
});
});
I tried changing it to this (and variations of this) but can't seem to get it to work:
$(document).ready(function(){
var stoptransparency = 100; // when to stop the transparent menu
var lastScrollTop = 0, delta = 5;
$(this).scrollTop(0);
$(window).on('scroll load resize', function() {
var position = $(this).scrollTop();
if(position > stoptransparency) {
$('#transmenu').removeClass('transparency');
} else {
$('#transmenu').addClass('transparency');
}
lastScrollTop = position;
});
$('#transmenu .dropdown').on('show.bs.dropdown', function() {
$(this).find('.dropdown-menu').first().stop(true, true).slideDown(300);
$('#transmenu').removeClass('transparency');
});
$('#transmenu .dropdown').on('hide.bs.dropdown', function() {
$(this).find('.dropdown-menu').first().stop(true, true).slideUp(300);
$('#transmenu').addClass('transparency');
});
});
Any help would be greatly appreciated!
Thanks!
Without the html that this is hooking into it's a bit difficult to answer your question.
But given the fact that scrolling gets the job done, the only element I can see that could be preventing the functionality you want is that your selector to add show event handler is either selecting nothing in particular or an element in the DOM that is not the bootstrap dropdown element that triggers 'show.bs.dropdown', which is my reasoning for the first statement.
You can try the following debug code to verify:
// Should log to console with 'selected' if selector works alternatively 'not selected'
console.log($('#transmenu .dropdown').length > 0 ? 'selected' : 'not selected');
// Log to console when show event triggered
$('#transmenu .dropdown').on('show.bs.dropdown', function() {
console.log('triggered');
});
Hope that helps you find a solution. Happy coding!
see the documentation at http://api.jquery.com/on/ and it should become obvious why your fancy named events are never being triggered (without defining any event namespace in the first place).
$('#transmenu .dropdown')
.on('show', function() {})
.on('hide', function() {});
the DOM selector also might be #transmenu.dropdown instead of #transmenu .dropdown (depending if id and class attributes are present on the DOM node to select - or if one selects the parent node by id and there is/are nested node/s with a class attribute present).

Need help getting custom slideshow to autoplay

I've taken over a project that was built by someone else. The site features a custom slideshow on the home page. I've made some changes to the look/feel of the slideshow per client requests, but the last thing it needs is autoplay.
Below is the script for the slideshow. I know about setInterval but I'm not sure where to put it, or if the code needs to be adjusted a bit before dropping that in.
$(document).ready(function() {
// A little script for preloading all of the images
// It"s not necessary, but generally a good idea
$(images).each(function(index, value){
// Ski first image since it is already loaded
if( index != 0 ) {
$("<img/>")[0].src = this;
}
});
// Feature Slider Navagitaion
$('.feature .ei-slider-nav li a').click( function(e) {
e.preventDefault();
var thisLink = $(this);
var navIndex = thisLink.parent('li').index();
thisLink.parents('ul').children('li').removeClass('active');
thisLink.parent('li').addClass('active');
// Is this item already active?
if( !$('.feature .ei-slider-title .ei-slider-title-item:eq('+navIndex+')').hasClass('active')) {
// Fade in/out feature image
$('.feature .ei-slider-large img').animate({opacity: 0}, 500, function() {
// Support for non-opacity browsers
$(this).css('visibility', 'hidden');
// Load new feature image
$(this).attr('src', images[navIndex]);
$(this).attr('alt', imagesAlt[navIndex]);
$(this).css('visibility', 'visible');
$('.feature .ei-slider-large img').animate({opacity: 1}, 500);
});
// Fade in/out feature text
$('.feature .ei-slider-title .ei-slider-title-item.active').fadeOut(500, function() {
$(this).parent().children().removeClass('active');
$('.feature .ei-slider-title .ei-slider-title-item:eq('+navIndex+')').addClass('active').fadeIn();
});
// Fade in/out feature credit
$('.content .ei-slider-credit span.active').fadeOut(500, function() {
$(this).parent().children().removeClass('active');
$('.content .ei-slider-credit span:eq('+navIndex+')').addClass('active').fadeIn();
});
}
});
// Feature Slider Learn More
$('.feature .ei-slider-title-item-learn').click( function(e) {
e.preventDefault();
thisPrev = $(this).prev();
if( thisPrev.css('display') == 'none') {
thisPrev.slideDown();
thisPrev.css('visibility', 'visible');
thisPrev.animate({'opacity': 1}, 500, function() {
});
$(this).html('Hide');
} else {
thisPrev.animate({'opacity': 0}, 500, function() {
thisPrev.slideUp();
thisPrev.css('visibility', 'hidden');
});
$(this).html('Hide');
$(this).html('Learn More');
}
});
});
Thanks!
This would probably be a little bit easier if there were a way to keep track of the current state of the slideshow outside the context of clicking on a slide's navigation link. The first thing I would add, right above $('.feature .ei-slider-nav li a').click( function(e) {... would be:
var eiSlider = {
currentSlideIndex: 0,
nextSlide: null, // we will define this later
autoPlay: null // we will define this later too
};
Then, inside of the function I mentioned above, as the first order of business inside of the check for whether the slide is already active, I'd add this:
// Set the currentSlide index on the global eiSlider tracking object
eiSlider.currentSlide = navIndex;
Next, you'll want to make a function to handle advancing the slideshow automatically:
eiSlider.nextSlide = function() {
var currentSlideIndex = eiSlider.currentSlideIndex,
nextSlideIndex = currentSlideIndex + 1,
totalSlides = $('.ei-slider-large img').length;
// If we are already at the end of the images, loop back to the beginning
if ( nextSlideIndex < totalSlides ) {
nextSlideIndex = 0;
}
// Trigger a click to move forward to the next slide
$('.feature .ei-slider-nav li:eq(' + nextSlideIndex + ') a').trigger('click');
};
I've also moved the work of setting the "active" class on a given slide's nav link to happen inside of the logic around making sure the slide you clicked on wasn't already active, to make sure it doesn't get set incorrectly.
Finally, you can use setInterval (at the bottom of all of the above code) to handle the autoplay portion.
// Auto-advance the slides every 5 seconds. Adjust the value as necessary
eiSlider.autoPlay = window.setInterval(function(){
eiSlider.nextSlide();
}, 5000);
Your final, updated code would look something like this:
$(document).ready(function() {
// A little script for preloading all of the images
// It"s not necessary, but generally a good idea
$(images).each(function(index, value){
// Ski first image since it is already loaded
if( index !== 0 ) {
$("<img/>")[0].src = this;
}
});
// Object for basic state tracking and namespacing of slideshow functions
var eiSlider = {
currentSlideIndex: 0,
nextSlide: null, // we will define this later
autoPlay: null // we will define this later too
};
// Feature Slider Navagitaion
$('.feature .ei-slider-nav li a').click( function(e) {
e.preventDefault();
var thisLink = $(this),
navIndex = thisLink.parent('li').index();
// Is this item already active?
if( !$('.feature .ei-slider-title .ei-slider-title-item:eq('+navIndex+')').hasClass('active')) {
thisLink.closest('li').siblings().removeClass('active');
thisLink.closest('li').addClass('active');
// Set the currentSlide index on the global eiSlider tracking object
eiSlider.currentSlideIndex = navIndex;
// Fade in/out feature image
$('.feature .ei-slider-large img').animate({opacity: 0}, 500, function() {
// Support for non-opacity browsers
$(this).css('visibility', 'hidden');
// Load new feature image
$(this).attr('src', images[navIndex]);
$(this).attr('alt', imagesAlt[navIndex]);
$(this).css('visibility', 'visible');
$('.feature .ei-slider-large img').animate({opacity: 1}, 500);
});
// Fade in/out feature text
$('.feature .ei-slider-title .ei-slider-title-item.active').fadeOut(500, function() {
$(this).parent().children().removeClass('active');
$('.feature .ei-slider-title .ei-slider-title-item:eq('+navIndex+')').addClass('active').fadeIn();
});
// Fade in/out feature credit
$('.content .ei-slider-credit span.active').fadeOut(500, function() {
$(this).parent().children().removeClass('active');
$('.content .ei-slider-credit span:eq('+navIndex+')').addClass('active').fadeIn();
});
}
});
// Feature Slider Learn More
$('.feature .ei-slider-title-item-learn').click( function(e) {
e.preventDefault();
thisPrev = $(this).prev();
if ( thisPrev.css('display') === 'none') {
thisPrev.slideDown();
thisPrev.css('visibility', 'visible');
thisPrev.animate({'opacity': 1}, 500, function() {});
$(this).html('Hide');
} else {
thisPrev.animate({'opacity': 0}, 500, function() {
thisPrev.slideUp();
thisPrev.css('visibility', 'hidden');
});
$(this).html('Hide');
$(this).html('Learn More');
}
});
// Function to handle slide advancement
eiSlider.nextSlide = function() {
var currentSlideIndex = eiSlider.currentSlideIndex,
nextSlideIndex = currentSlideIndex + 1,
totalSlides = $('.ei-slider-large img').length;
// If we are already at the end of the images, loop back to the beginning
if ( currentSlideIndex < (totalSlides - 1) ) {
nextSlideIndex = 0;
}
// Trigger a click to move forward to the next slide
$('.feature .ei-slider-nav li:eq(' + nextSlideIndex + ') a').trigger('click');
};
// Auto-advance the slides every 5 seconds. Adjust the value as necessary
eiSlider.autoPlay = window.setInterval(function(){
eiSlider.nextSlide();
}, 5000);
});
Bear in mind this answer makes a few assumptions, the main one being that the eiSldier namespace is available; if it's not, just use a different namespace than the one I provided, OR add these three new items to the existing namespace so it doesn't get overwritten. The only change in that case would not be defining eiSlider as an object with three properties, but instead defining simply eiSlider.currentSlide = 0, and then proceeding to define the other two functions the way they already are defined later on in the example.
If the eiSlider namespace already exists, it's entirely possible that currentSlide or some equivalent property exists on it already, so you could take advantage of that if it does, rather than making a duplicate (or worse, overriding it in a way that could cause errors in the rest of its functionality).
One thing I should note that the code above doesn't currently do is stop/clear the autoplay out when you manually click on a slide's navigation link. That's a pretty important usability issue that will need to get cleaned up. You can accomplish this by using clearInterval(eiSlider.autoPlay), but to make that really work correctly, you'd need to separate out the code that handles slide advancement from the actual click event.
Check out this slightly modified JS Bin that shows the auto-advance working as intended, plus the changes I mentioned above with clearInterval:
http://jsbin.com/gumaqefere/1/edit?html,js,console,output

Activating two jQuery functions with one link

I'm trying to do the following:
Open a div with slideToggle
Move the users window to the top of the div with scrollTop
Then basically reverse the process when the user closes the div.
I have the whole process almost finished, but I am having one problem. When I open the div my window doesn't move to the top of the div. But when I close the div my window does move to where I want it.
Here is my jQuery code:
// Find the location of a div (x, y)
function divLoc(object) {
var topCord = 0;
// If browser supports offsetParent
if(object.offsetParent) {
do {
topCord += object.offsetHeight;
}
while (object === object.offsetParent);
return topCord;
}
}
$("#open").click(function () {
var newInfo = document.getElementById("newInfo");
var location = divLoc(newInfo);
$("#newInfo").slideToggle('slow', function() {
$('html,body').animate({ scrollTop: location }, 2000);
});
});
And I uploaded an example of the problem on jsFiddle: Here
You need change slide function:
$("#newInfo").slideToggle('slow', function() {
var self = $(this)
$('html,body').animate({ scrollTop: self.offset().top }, 2000);
});
http://jsfiddle.net/hSHz5/

Trying to animate with on change

I am trying to animate the width of something when the .change() function is called, but it doesn't seem to be working.
Any idea why?
Here is my code:
$(document).ready(function(){
$('#code').change(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
Here is a js fiddle with the issue recreated: http://jsfiddle.net/BUSSX/
If you really want a change event for input controls, then here's a jQuery plug-in method I wrote a little while ago that does this and works for nearly all ways that the content of the input control can be changed including drag/drop, copy/paste, typing, etc... It takes advantage of newer events that help with this if they exist, otherwise it falls back to listening for lots of other events and looking to see if the data has changed.
(function($) {
var isIE = false;
// conditional compilation which tells us if this is IE
/*#cc_on
isIE = true;
#*/
// Events to monitor if 'input' event is not supported
// The boolean value is whether we have to
// re-check after the event with a setTimeout()
var events = [
"keyup", false,
"blur", false,
"focus", false,
"drop", true,
"change", false,
"input", false,
"textInput", false,
"paste", true,
"cut", true,
"copy", true,
"contextmenu", true
];
// Test if the input event is supported
// It's too buggy in IE so we never rely on it in IE
if (!isIE) {
var el = document.createElement("input");
var gotInput = ("oninput" in el);
if (!gotInput) {
el.setAttribute("oninput", 'return;');
gotInput = typeof el["oninput"] == 'function';
}
el = null;
// if 'input' event is supported, then use a smaller
// set of events
if (gotInput) {
events = [
"input", false,
"textInput", false
];
}
}
$.fn.userChange = function(fn, data) {
function checkNotify(e, delay) {
var self = this;
var this$ = $(this);
if (this.value !== this$.data("priorValue")) {
this$.data("priorValue", this.value);
fn.call(this, e, data);
} else if (delay) {
// The actual data change happens aftersome events
// so we queue a check for after
// We need a copy of e for setTimeout() because the real e
// may be overwritten before the setTimeout() fires
var eCopy = $.extend({}, e);
setTimeout(function() {checkNotify.call(self, eCopy, false)}, 1);
}
}
// hook up event handlers for each item in this jQuery object
// and remember initial value
this.each(function() {
var this$ = $(this).data("priorValue", this.value);
for (var i = 0; i < events.length; i+=2) {
(function(i) {
this$.on(events[i], function(e) {
checkNotify.call(this, e, events[i+1]);
});
})(i);
}
});
}
})(jQuery);
Then, your code would look like this:
$(document).ready(function(){
$('#code').userChange(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
In looking at your code, you are increasing the width of the input control by 16px on every change. You probably should be looking at the number of characters in the control and assessing what to do about the width based on that because this will make things wider event if the user hits the backspace key. I'd probably do something like this that grows the item as content is added, but doesn't shrink it:
$(document).ready(function(){
$('#code').userChange(function(){
// on change animate width as chars are added
// only grow it when the width needs to be larger than it is currently
var item = $(this);
var origWidth = item.data("initialWidth");
var curWidth = item.width();
if (!origWidth) {
origWidth = curWidth;
item.data("initialWidth", origWidth);
}
var newWidth = origWidth + (8 * item.val().length);
if (newWidth > curWidth) {
item.stop(true, true).animate({width: newWidth}, 500);
}
});
});
Working code example: http://jsfiddle.net/jfriend00/BEDcR/
If you want the userChange method to execute when you programmatically set the value with .val(), then you can make your own method for that:
$(document).ready(function(){
function updateWidth() {
// on change animate width as chars are added
// only grow it when the width needs to be larger than it is currently
var item = $(this);
var origWidth = item.data("initialWidth");
var curWidth = item.width();
if (!origWidth) {
origWidth = curWidth;
item.data("initialWidth", origWidth);
}
var newWidth = origWidth + (8 * item.val().length);
if (newWidth > curWidth) {
item.stop(true, true).animate({width: newWidth}, 500);
}
}
$('#code').userChange(updateWidth);
$.fn.valNotify = function(value) {
this.val(value);
this.each(function() {
updateWidth.call(this);
});
return this;
}
});
Then, you can change your values with this and it will automatically resize too:
$("#code").valNotify("foo");
If based on your previous question HTML markup :
<button class="I button">I</button>
<button class="O button">O</button>
<input id="code" type="text" disabled />
So if you want to animate the width of the textbox, you need to animate it when click the button:
$('.button').click(function(event) {
var text = $(this).text();
$('input:text').val(function(index, val) {
return val + text;
});
$('#code').animate({width: '+=16'});
});
Working Demo
If based on your above question HTML markup, you need to use keyup instead of change as well as include the jQuery library in the jsFiddle:
$(document).ready(function(){
$('#code').keyup(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
Updated Demo
You just need to check which key was pressed:
$(document).ready(function(){
$('#code').keyup(function(e){
//on change animate a width of +16px increase.
if(e.keyCode == 8) { // Backspace pressed
$(this).animate({width: '-=16'});
} else {
$(this).animate({width: '+=16'});
}
});
});
Updated Demo
You forgot to load jQuery, working fine here http://jsfiddle.net/BUSSX/13/ - also you need the click event. Or even better use the keyup event so that as soon as something is typed, the textbox increases in width - http://jsfiddle.net/BUSSX/15/
you have a bad implementation check http://jsfiddle.net/3dSZx/ and you need add jquery to fiddle
JS
$(document).ready(function(){
$('#push').click(function(){
//on change animate a width of +16px increase.
$('#code').animate({ width: '+=16'});
});
});
IrfanM, instead of incrementing by a fixed amount, you might consider incrementing by just the right amount to accommodate each character as it is typed.
Unless I've overcomplicated things (not completely unknown), this is moderately tricky.
In the following jQuery plugin :
text input fields are each given a hidden <span> with the same font-family and font-size as its respective input element.
the <span> elements act as "measuring sticks" by accepting a copy of their input field's entire text every time a character is typed.
the width of the <span> plus one generous character width is then used to determine the width of the input field.
Here's the code :
(function ($) {
var pluginName = 'expandable';
$.fn[pluginName] = function () {
return this.each(function (i, input) {
var $input = $(input);
if (!$input.filter("input[type='text']").length) return true;
// Common css directives affecting text width
// May not be 100% comprehensive
var css = {
fontFamily: $input.css('fontFamily'),
fontSize: $input.css('fontSize'),
fontStyle: $input.css('fontStyle'),
fontVariant: $input.css('fontVariant'),
fontWeight: $input.css('fontWeight'),
fontSizeAdjust: $input.css('fontSizeAdjust'),
fontStretch: $input.css('fontStretch'),
letterSpacing: $input.css('letterSpacing'),
textTransform: $input.css('textTransform'),
textWrap: 'none'
};
var $m = $("<span/>").text('M').insertAfter($input).css(css).text('M').hide();
var data = {
'm': $m,
'w': $m.width()
};
$input.data(pluginName, data).keyup(function (e) {
$this = $(this);
var data = $this.data(pluginName);
var w = data.m.html($this.val().replace(/\s/g, " ")).width();
$this.css({
'width': w + data.w
});
}).trigger('keyup');
});
};
})(jQuery);
$(document).ready(function () {
$('input').expandable();
});
DEMO
This works because a <span> element automatically expands to accommodate its text, whereas an <input type="text"> element does not. A great feature of this approach is that the keystrokes don't need to be tested - the plugin automatically responds to character deletions in the same way it responds to character strokes.
It works with proportional and monospaced fonts and even responds appropriately to cut and paste.
The only precaution necessary is to convert spaces to non-breaking spaces, $nbsp;, otherwise HTML renders multiple spaces as a single space in the <span> element.
Of course, it you really want exactly 16px growth for every keystroke, then stick with what you already have.

.show() doesnt work on IE

I am working on this project: http://www.arbamedia.com/test/
if you go to Dyer dhe dritare on the left menu and drag one of the elements (the door or the window) into the right side (the desk) in Chrome and FF the 3 options that I have added for that elements show, so this: $("p", this).show(); works, but in IE9 when I drag an element it doesn't show the the options for dragging, rotating or deleting! I dont know what is wrong.
This is where it happens:
$(".drag").draggable({
revert : 'invalid',
helper : 'clone',
containment : 'desk',
cursorAt : { left:-11,top:-1 },
//When first dragged
stop : function(ev, ui) {
/*========================================================================*/
var pos = $(ui.helper).offset();
var left_ = ev.originalEvent.pageX - $("#desk").position().left;
var top_ = ev.originalEvent.pageY - $("#desk").position().top;
// get widht and height of the container div#desk element
var w_ = $("#desk").width();
var h_ = $("#desk").height();
objName = "#clonediv"+counter++;
objNamex = "clonediv"+counter;
$(objName).css({"left":left_,"top":top_});
var gag = 0;
$(objName).click(function () {
$("p", this).show();
$(this).addClass("selektume");
$('.rotate_handle').unbind('click');
$('.rotate_handle').click(function(){
gag += 45;
$('.selektume').rotate(gag+'deg');
});
$('.delete_handle').click(function() {
$('.selektume').remove();
});
return false;
});
$(document).click(function () {
$("p").hide();
$(".lgutipT").removeClass("selektume");
});
//check if dropped inside the conteiner div#des
if((left_ >= 0) && (left_ <= w_) && (top_ >= 0) && (top_ <= h_))
{
$(objName).css({"left":left_,"top":top_});
// assign a z-index value
zindex = left_ + top_;
$(objName).css({"z-index":zindex});
$(objName).addClass("lgutipT");
//$(objName).addClass("ui-widget-content");
$(objName).removeClass("drag");
$(objName).append('<p><img class="handler" src="images/move_button.png"><img class="rotate_handle" src="images/rotate_button.png"><img class="delete_handle" src="images/delete_button.png"></p>');
$("p", this).show();
}
/*========================================================================*/
//When an existiung object is dragged
$(objName).draggable({
containment : "#desk",
handle : ".handler",
cursor : "move"
});
}
});
Very tricky problem since there's no good documentation on how jQuery UI treats events at a core level. The solution was to unbind and rebind the click event. In IE, the click event is treated differently than other browsers. The solution was simply to rebind the click event after everything is done (1/1000 of a second delay).
My solution was to move the click event, add an unbinding on drag start, and to add a setTimeout() on rebinding the $(document).click() event listener when drag was complete.
View the source below to view the working solution.
http://jsfiddle.net/MattLo/AbF6t/
Copy and Paste the HTML to your dev environment.

Categories