Posts in ‘Programming’

My favorite web tricks: The short list

Jan 20

I love a good list.

I have a slightly Type A personality and, to me, organization is a beautiful thing (Although I have to admit that all the recent ‘Best ____ of 2011’ lists that every publication on earth seemed to be putting out around New Year’s were getting a little out of hand, amiright?). That being said, I’m intending to keep this list fairly short and just give a little shout out to a few of my current favorite bookmarks that I hope might be useful and interesting.

I do most of the front-end programming (HTML, CSS, Javascript, etc.) here at TPI World Headquarters, so anything that I come across to help me streamline that process is aces is my book. I’m also fortunate enough to have a few friends in the industry who help keep me in the know and introduce me to the latest and greatest technology for creating beautiful and functional websites:

  1. Visual jQuery – (http://visualjquery.com/)Ok, ok, this Javascript library (jquery) isn’t news to anyone in the industry. It’s been around for a while now, but I gotta admit that I am still enamored with the way jquery simplifies javascript and makes things like animations and manipulations so easy and, dare I say, fun. This site is one of the most easy and useful documentation sources I’ve ever seen. It’s clean and easy to navigate and I can find what I’m looking for, usually, in a matter of seconds. Bonus: Each entry has syntax, examples and options all lined up and organized (Type A, remember? *sigh*).
  2. Chosen – (http://harvesthq.github.com/chosen/)Speaking of jQuery, this little gem is a great plugin if you’re digging on some creative ways to utilize select lists.  Whoa. Did I just get a little excited about using select lists? I did. What can I say? A few lines of code and your oft-unwieldy multiple selects become an enchanting experience for the user. Ok, I have to stop now before this gets embarrassing.
  3. CSS3 PIE – (http://css3pie.com/)Mmmmm, pie. If you’ve been reluctant to embrace the new-fangled awesomeness that comes with CSS3 because you’ve been worried about IE compatibility, fret no more! My friend, early-adopter, and programming wunderkind, Skye, introduced this to me on a recent project we worked on together. What a difference! While I haven’t had much opportunity to utilize it on other applications just yet, I’m definitely going to be putting it through its paces on some upcoming victims, er… projects we have in the works.

A short list, but a good one.

There’s new plugins, languages and tricks coming out all the time, it seems, to make our lives as developers ever more exciting. Have you come across something lately that’s changed your coding life forever? Let us know! We love expanding our knowledge and keeping our clients happy with interesting and engaging websites and applications.

Are You Ready for Facebook’s SSL October 1st Deadline?

Sep 30

We know, we know, Facebook has had so many changes lately it’s hard to keep up with them all. If you are a casual user, there are plenty of new features to explore. You may see some changes in accessing some of your games, or notice different content on some business pages, but generally you’re good to go.

However, it gets trickier if you’re a business owner who has developed Facebook apps. Starting October 1st, apps that run on Facebook must be hosted from a secure server. Facebook is requiring this to help protect the privacy of its users. What does it mean to you? If you don’t have a SSL certificate for your app’s site domain, your app will not show up on Facebook anymore – meaning your fans won’t see it!

Don’t worry, we’re here to help. If you host your application with us, we can get a SSL certificate set up for your domain. If you use a different host, they’ll be able to help you. Either way, you’ll just need to provide some specific information that verifies you are the owner of the site, and you’ll likely have to pay a small amount to buy the certification from the company that provides it. The most commonly known certificate provider is VeriSign, but there are plenty to choose from, with a variety of features and prices.

If we can help you, let us know. In the meantime, enjoy the latest features on Facebook… we will be back soon to guide you through more of the interesting changes that are happening there — stay tuned!

Better Mobile Sites For Smartphones

Oct 06

Check out these web sites:

http://2011.uxlondon.com/
http://www.saltercane.com/

Any person or company with a consumer-facing web site, if they are paying any attention at all, will want their site to be mobile phone accessible soon if not sooner. Assuming 1024 pixel wide screens isn’t going to cut it, these two sites show how it can be done really well in just one smart design, rather than the usual way (sniffing out the client browser and redirecting mobile phones to a different version).

Resize your browser and watch what happens as it get narrower. (Use Firefox or a webkit browser like Safari — IE need not apply.) The first site re-flows in each section and the bio pictures shrink down as the page gets narrower. The second site dynamically re-flows from three columns to two columns to one.  If you have a browser on your mobile phone, look at the sites there too. Very cool!

You can read about the technique from the guy who designed those sites here:

http://adactio.com/journal/

Something to think about.

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

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