Posts from December, 2009

Combining navigation on the easySlider jQuery plugin

Dec 23

Today, I was putting together a proof-of-concept for a new website design that included a media ‘slider’ on the home page. I did a bit of searching and came across the Easy Slider 1.7 plugin which uses jQuery to simplify this task. Score! We love jQuery here at TPI because it takes heavy-coding Javascript tasks and makes them really simple to accomplish and usually more interactive and fun.

This plugin seemed to have all we needed except one thing. There was a choice in navigation between arrows left and right (previous and next) OR numeric/individual item navigation below. (For this case, we’ll use actual ‘Sliders’ as our representation of the easySlider. Hungry yet?)

Navigation illustration

For the design we’re envisioning, both systems needed to be utilized. It seemed like a simple fix and I set about combining both  navigation types to show up at the same time. Problem. For some reason, the next/previous buttons weren’t behaving properly when you used the numeric navigation below to choose an item! If you clicked on an item in the numeric nav, the next button would inexplicably send the gallery zooming off into space and then slowly return to the first item in the list.

How do we fix this!? Good ol’ scheming and know-how to the rescue! I’ll give you the quick-and-dirty since I’m pretty sure that’s what you’re interested in, anyway.

First, to show both navigations, go into easySlider1.7.js and find this part:

if(options.controlsShow){
var html = options.controlsBefore;
if(options.numeric){
html += '<ol id="'+ options.numericId +'"></ol>';
} else {
if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
html += ' <span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span>';
if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';
};

html += options.controlsAfter;
$(obj).after(html);
};

And change it to this:

if(options.controlsShow){
var html = options.controlsBefore;
if(options.numeric){
html += '<ol id="'+ options.numericId +'"></ol>';
if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
html += ' <div id="arrows"><span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span></div>';
if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';
} else {
if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
html += ' <span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span>';
if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';
};

html += options.controlsAfter;
$(obj).after(html);
};

Then find this part:

if(options.numeric){
for(var i=0;i<s;i++){
$(document.createElement("li"))
.attr('id',options.numericId + (i+1))
.html('<a rel='+ i +' href=\"javascript:void(0);\">'+ (i+1) +'</a>')
.appendTo($("#"+ options.numericId))
.click(function(){
animate($("a",$(this)).attr('rel'),true);
});
};
} else {
$("a","#"+options.nextId).click(function(){
animate("next",true);
});
$("a","#"+options.prevId).click(function(){
animate("prev",true);
});
$("a","#"+options.firstId).click(function(){
animate("first",true);
});
$("a","#"+options.lastId).click(function(){
animate("last",true);
});
};

And change it to this:

if(options.numeric){
for(var i=0;i<s;i++){
$(document.createElement("li"))
.attr('id',options.numericId + (i+1))
.html('<a rel='+ i +' href=\"javascript:void(0);\">'+ (i+1) +'</a>')
.appendTo($("#"+ options.numericId))
.click(function(){
animate($("a",$(this)).attr('rel'),true);
});
};
$("a","#"+options.nextId).click(function(){
animate("next",true);
});
$("a","#"+options.prevId).click(function(){
animate("prev",true);
});
$("a","#"+options.firstId).click(function(){
animate("first",true);
});
$("a","#"+options.lastId).click(function(){
animate("last",true);
});
} else {
$("a","#"+options.nextId).click(function(){
animate("next",true);
});
$("a","#"+options.prevId).click(function(){
animate("prev",true);
});
$("a","#"+options.firstId).click(function(){
animate("first",true);
});
$("a","#"+options.lastId).click(function(){
animate("last",true);
});
};

NOW, to make it work properly (and here’s the kicker), parseInt!!!!!

Find the ‘animate’ function (~line 140):

function animate(dir,clicked){
if (clickable){
clickable = false;
var ot = t;
switch(dir){
case "next":
t = (ot>=ts) ? (options.continuous ? t+1 : ts) : t+1;
break;
case "prev":
t = (t<=0) ? (options.continuous ? t-1 : 0) : t-1;
break;
case "first":
t = 0;
break;
case "last":
t = ts;
break;
default:
t = dir;
break;
};

And insert this itttty bitty little parseInt:

function animate(dir,clicked){
if (clickable){
clickable = false;
var ot = t;
t = parseInt(t);
switch(dir){
case "next":
t = (ot>=ts) ? (options.continuous ? t+1 : ts) : t+1;
break;
case "prev":
t = (t<=0) ? (options.continuous ? t-1 : 0) : t-1;
break;
case "first":
t = 0;
break;
case "last":
t = ts;
break;
default:
t = dir;
break;
};

Thats it! Wow, that seemed a lot harder than it was. We figured out that the two navigations were treating the current item differently (one as an integer, one as a string – who knew!) so basically we’re just telling them all to be integers so both methods will work the same.

For reference, here’s another little proof of concept we drew up. Sliders. Get it? We’re hilarious, i know. (click the pickles OR the ketchup. CRAZY!) easySlider plugin ‘Sliders’ demo

Cheap or Chic? Is it ok for Businesses to Send Holiday e-cards?

Dec 22

For the most part, the idea behind sending holiday cards to clients is about showing appreciation and spreading a little goodwill, right? So does it really matter if your good intentions arrive on actual paper? The answer: maybe.

At the risk of looking cheap, lazy and/or impersonal, e-cards are best left to businesses who fit one or more of the following criteria:

  • Tech/Web Companies
  • Environmentally-Related Companies
  • Environmentally-Conscious Companies*

*Good rule of thumb here is whether your business walks the walk on evironmental responsibility the other 365 days a year in ways that are recognizable enough for your clients to be aware of them.

Done well, an e-card from a business like those described above can be an even better approach  to spreading good cheer in a personal and fun way than traditional holiday cards. Speaking of…take a gander at what we drummed up for our ’09 holiday card! (Tooting our own horn? No, not us!)

The Evolution of Web Video

Dec 16

If you’re iffy on the geek-talk surrounding video on the web, you’re not alone. Like everything technical, there are multiple layers of complexity to ‘appreciate’, and nothing is static — it all changes over time. What you knew yesterday is obsolete today. In fact it was probably obsolete yesterday! So what’s the average human to do? Reference a handy visual-aid, of course:

Evolution of Web Video

Sure, this isn’t the complete picture. Why isn’t early MPEG on here? What about player technologies, like Flash Player? Where’s YouTube? Honestly, I left those things off because they dilute the minuscule amount of humor I’m working with here… but, I’ll justify it this way: the story of video quality on the web is mostly about the advancement (and adoption) of compression algorithms — the underlying mathemagic that squeezes video down to something less than than mammoth-magnitude. (I’m not kidding about the magic: one second of uncompressed standard-definition video is about 30MB. Compressed with h.264, it’s about 63KB. That’s a reduction of about 500:1!)

The point is, walk before you run. Know that h.264 and MPEG4 are the compressors that pass for ‘good’ on the web right now, and you won’t be left behind with Australopithecus and the other IE6 users. Then note this: that last guy in the diagram still has a way to go…

Holiday Break Business Reading List

Dec 11

If you’re anything like the crew here at TPI, you probably aren’t taking much of a break this holiday season. Staying busy is the name of the game and we certainly do our best to keep the machine running as much as possible. That said, we sincerely hope you DO get some time to relax, spend time with those most important to you and maybe even take a few minutes to improve your business for 2010! I know, I know… who has time for reading when there so many cookies, candy and pies around just calling your name?! The truth is that investing time in your business (even when you’re not ‘working’) by reading about relevant marketing strategies, business models and successful (and not-so-successful) stories can give valuable insight into areas where your own techniques might be lacking.

To that end, I’ve taken the liberty of compiling a short list (in no particular order) of some great marketing and business books to light your fire and help jumpstart your business in 2010 with new fervor, focus and inspiration. A lot of ideas in these books aren’t earth-shattering, new and different ideas, but common sense practices that sometimes fall by the wayside in business and want for a good reminder. The key is using the good advice you find. Good advice only works if you put it into practice.

Admittedly, I haven’t ready all of these books. For what its worth, its a list I’ve compiled from other business leaders I follow and have been written by or invaluably helpful to them. That’s good enough for me and I will undoubtedly be picking up a few of these to read on a few cold nights this winter.

Have you already read any of these? What are your thoughts? We’d love to add to our library as well so definitely leave us a comment with your own recommendations!

Happy Reading!

1. How to Win Friends and Influence People – Dale Carnegie: An oldie but a goodie. A nice reminder on how the key to being successful is all in how you treat the people around you.

2. Citizen Marketers: When People Are the Message – Ben McConnell and Jackie Huba: If you’re curious about social media and how it might relate to your business, this one is a good resource.

3. Love Is the Killer App – Tim Sanders: I haven’t read this one but its definitely on my list. Its also about dealing with people but with an emphasis on networking and sharing information.

4. Good to Great – Jim Collins: Need I say more? Which one will YOUR business be?

5. Just Ask a Woman: Cracking the Code of What Women Want and How They Buy – Mary Lou Quinlan: This was recommended to me and I’m actually looking forward to reading it. Discover the power of the female buyer!

6. Blue Ocean Strategy – W. Chan Kim and Renée Mauborgne: All about the ‘blue ocean’ of uncrowded and untapped market space.

7. The Long Tail – Chris Anderson: From the Editor-in-Chief of Wired Magazine. If anyone will know about the future of business, this is the guy.

8. How To Be That Guy – Scott Ginsberg: This guy started wearing a nametag everywhere as an experiment and learned a lot about how people responded to it. Now he shares how to be unforgettable.

9. Selling the Invisible: A Field Guide to Modern Marketing – Harry Beckwith: Selling the way you do business and treat customers, rather than a product. Because everyone wants good customer service!

10. Purple Cow – Seth Godin: And just for good measure, Mr. Godin is considered one of the most brilliant minds in marketing. Read this one.

Play .mp4 Videos in the Shadowbox FLV Player

Dec 03

Here at TPI, we love Shadowbox. It is a very clean and simple way of displaying a photo gallery or playing a video on a website. To play a .mp4 video on a site, you would normally initiate the Shadowbox player like this:

<script type="text/javascript>
     Shadowbox.init({
          players: ["img", "qt"]
     });
</script>

And then use an anchor to make the image or text clickable like this:

<a rel="shadowbox" href="my_video.mp4" title="My Video Title">
     Watch The Video
</a>

This works, but it relies on the fact that the clients browser has the quicktime plugin installed. Some of you already know that the Flash player can play .mp4 video files. The Flash plugin is installed on almost all browsers, so it would be ideal if the .mp4 videos would play in the Shadowbox JW Player instead.

Lucky for us, Shadowbox has an option that lets you decide what extensions work with which players. In this case, we want .mp4 videos to use the “flv” player rather than the “qt” player. Here’s how you do it:

<script type="text/javascript">
     var customExt = {
          img:["png","jpg","jpeg","gif","bmp"],
          swf:["swf"],
          flv:["flv", "mp4"],
          qt:["dv","mov","moov","movie"],
          wmp:["asf","wm","wmv"],
          qtwmp:["avi","mpg","mpeg"],
          iframe:["asp","aspx","cgi","cfm","htm","html",
                  "jsp","pl","php","php3","php4","php5",
                  "phtml","rb","rhtml","shtml","txt","vbs"]
     };
     Shadowbox.init({
          players: ["img", "flv"],
          ext: customExt
     });
</script>

Normally, the “qt” player plays all “.mp4″ files. Simply move the “mp4″ extension to the “flv” property. Using this method, you can decide which extensions use which players in Shadowbox.

Now, when a user clicks the Shadowbox link, the .mp4 video uses the “flv” player and plays in the JW Player:

<a rel="shadowbox" href="my_video.mp4" title="My Video Title">
     Watch the .mp4 video in the JW Player.
</a>
Get Your FREE TPI Mug