Posts Tagged ‘HTML5’

March 7, 2013

Script Clip: HTML5 Audio Player with jQuery Controls

By in Development, Tips and Tricks

HTML5 and jQuery provide mind-blowing functionality. Projects that would have taken hours of development and hundreds of lines of code a few years ago can now be completed in about the time it’ll take you to read this paragraph. If you wanted to add your own audio player on a web page in the past, what would it have involved? Complicated elements? Flash (*shudders*)? It was so complicated that most developers just linked to the audio file, and the user just downloaded the file to play it locally. With HTML5, an embedded, cross-browser audio player can be added to a page with five lines of code, and if you want to get really fancy, you can easily use jQuery to add some custom controls.

If you’ve read any of my previous blogs, you know that I love when I find little code snippets that make life as a web developer easier. My go-to tools in that pursuit are HTML5 and jQuery, so when I came across this audio player, I knew I had to share. There are some great jQuery plugins to play music files on a web page, but they can be major overkill for a simple application if you have to include comprehensive controls and themes. Sometimes you just want something simple without all of that overhead:

Oooh… Ahhh…

That song — Pop Bounce by SoftLayer’s very own Chris Interrante — is written in five simple lines of HTML5 code:

<audio style="width:550px; margin: 0 auto; display:block;" controls>
  <source src="http://cdn.softlayer.com/innerlayer/Interrante-PopBounce.ogg" type="audio/ogg">
  <source src="http://cdn.softlayer.com/innerlayer/Interrante-PopBounce.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>

If IE 9+, Chrome 6+, Firefox 3.6+, Safari 5+ and Opera 10+ would all agree on supported file formats for the <audio> tag, the code snippet would be even smaller. I completely geek out over it every time I look at it and remember the days of yore. As you can see, the HTML5 application has some simple default controls: Play, Pause, Scan to Time, etc. As a developers, I couldn’t help but look for a to spice it up a little … What if we want to fire an event when the user plays, pauses, stops or takes any other action with the audio file? jQuery!

Make sure your jQuery include is in the <head> of your page:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

Now let’s use jQuery to script separate “Play” and “Pause” links … And let’s have those links fire off an alert when they are pressed:

$(document).ready(function(){
  $("#play-button").click(function(){
   $("#audioplayer")[0].play();
   alert('You have played the audio file!');
  })    
 
  $("#pause-button").click(function(){
   $("#audioplayer")[0].pause();
   alert('You have paused the audio file!');
  })    
})

With that script in the <head> as well, the HTML on our page will look like this:

<div class=:"audioplayer">
  <audio id="audioplayer" name="audioplayer" controls loop>
    <source src="http://cdn.softlayer.com/innerlayer/Interrante-PopBounce.ogg" type="audio/ogg">
    <source src="http://cdn.softlayer.com/innerlayer/Interrante-PopBounce.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
  </audio>
 
  <a id="play-button" href="#">Play!</a>
  <a id="pause-button" href="#">Pause!</a>
</div>

Want proof that it works that simply? Boom.

You can theme it any way you like; you can add icons instead of the text … The world is your oyster. The bonus is that you’re using one of the lightest media players on the Internet! If you decide to get brave (or just more awesome), you can explore additional features. You’re using jQuery, so your possibilities are nearly limitless. If you want to implement a “Stop” feature (which returns the audio back to the beginning when “Stop” is pressed), you can get creative:

$("#stop-button").click(function(){
    $("#audioplayer")[0].currentTime = 0; // return the audio file back to the beginning
}

If you want to include some volume controls, those can be added in a snap as well:

$("#volumeUp").click(function(){
    $("#audioplayer")[0].volume +=0.1;
}
 
$("#volumeDown").click(function(){
    $("#audioplayer")[0].volume -=0.1;
}

Try it out and let me know what you think. Your homework is to come up with some unique audio player functionality and share it here!

-Cassandra

January 15, 2013

Startup Series: Moqups

By in SoftLayer, Startup Series, Tips and Tricks

Every member on the Catalyst team is given one simple goal: Find the most innovative and creative startups on the planet and get them on the SoftLayer network. We meet entrepreneurs at conferences and events around the world, we team up with the most influential startup accelerators and incubators, and we hunt for businesses who are making waves online. With the momentum Catalyst built in 2012, our message has started spreading exponentially faster than what the community development team could be doing on our own, and now it seems like we’ve earned a few evangelists in the startup community. We have those evangelists to thank for bringing Moqups to our door.

In a Hacker News thread, a user posted about needing hosting for a server/startup, and a recommendation for the Catalyst program was one of the top-rated results. The founders of Moqups saw that recommendation, researched SoftLayer’s hosting platform and submitted an application to become a Catalyst partner. As soon as we saw the unbelievable HTML5 app the Moqups team created to streamline and simplify the process of creating wireframes and mockups for website and application design, we knew they were a perfect fit to join the program.

If you’ve ever had to create a site prototype or UI mockup, you know how unwieldy the process can be. You want to sketch a layout and present it clearly and cleanly, but there aren’t many viable resources between “marker on a whiteboard” and “rendering in Photoshop” to accomplish that goal. That’s the problem the Moqups team set out to solve … Can a web app provide the functionality and flexibility you’d need to fill that gap?

We put their answer to that question to the test. I told Kevin about Moqups and asked him to spend a few minutes wireframing the SoftLayer Blog … About ten minutes later, he sent me this (Click for the full Moqups version):

SoftLayer Blog Moqup

Obviously, wireframing an existing design is easier than creating a new design from scratch, but Kevin said he was floored by how intuitive the Moqups platform made the process. In fact, the “instructions” for how to use Moqups are actually provided in an example “Quick Introduction to Moqups” project on the home page. That example project allows you to tweak, add and adjust content to understand how the platform works, and because it’s all done in HTML5, the user experience is seamless.

Moqups

Put it to the test for yourself: How long will it take you to create a wireframe of your existing website (similar to what Kevin did with the SoftLayer Blog)? You have down-to-the-pixel precision, you can group objects together, Moqups helps you line up or center all of the different pieces of your site. Their extensive library of stencils supplements any custom images you upload, so you can go through the whole process of creating a site mockup without “drawing” anything by hand!

I’m actually surprised that the Moqups team heard about SoftLayer before our community development team heard about them … In November, I was in Bucharest, Romania, for HowtoWeb, so I was right in their back yard! Central and Eastern European startups are blowing up right now, and Moqups is a perfect example of what we’re seeing from that region in EMEA.

Oh, and if you know of a crazy cool startup like Moqups that could use a little hosting help from SoftLayer, tell them about Catalyst!

-@EmilyBlitz

August 2, 2012

Meet Memcached: A Developer’s Best Friend

By in Development, Tips and Tricks

Whether you’re new to software development or you’ve been a coder since the punchcard days, at some point, you’ve probably come across horrendous performance problems with your website or scripts. From the most advanced users — creating scripts so complex that their databases flooded with complex JOINs — to the novice users — putting SQL calls in loops — database queries can be your worst nightmare as a developer. I hate to admit it, but I’ve experienced some these nightmares first-hand as a result of some less-than-optimal coding practices when writing some of my own scripts. Luckily, I’ve learned how to use memcached to make life a little easier.

What is Memcached?

Memcached is a free and open source distributed memory object caching system that allows the developer to store any sort of data in a temporary cache for later use, so they don’t have to re-query it. By using memcached, a tremendous performance load can be decreased to almost nil. One of the most noteworthy features of the system is that it doesn’t cache EVERYTHING on your site/script; it only caches data that is sure to be queried often. Originally developed in 2003 by Brad Fitzpatrick to improve the site performance of LiveJournal.com, memcached has grown tremendously in popularity, with some of the worlds biggest sites — Wikipedia, Flickr, Twitter, YouTube and Craigslist — taking advantage of the functionality.

How Do I Use Memcache?

After installing the memcached library on your server (available at http://memcached.org/), it’s relatively simple to get started:

<?php
  // Set up connection to Memcached
  $memcache = new Memcached();
  $memcache->connect('host', 11211) or die("Could not connect");
 
  // Connect to database here
 
  // Check the cache for your query
  $key = md5("SELECT * FROM memcached_test WHERE id=1");
  $results = $memcache->get($key);
 
  // if the data exists in the cache, get it!
  if ($results) {
      echo $results['id'];
      echo 'Got it from the cache!';
  } else {
    // data didn't exist in the cache
    $query = "SELECT * FROM memcached_test WHERE id=1");
  $results = mysql_query($query);
  $row = mysql_fetch_array($results);
  print_r($row);
 
  // though we didn't find the data this time, cache it for next time!
  $memcache->set($key, $row, TRUE, 30); 
  // Stores the result of the query for 30 seconds
  echo 'In the cache now!';
 
  }
 
?>

Querying the cache is very similar to querying any table in your database, and if that data isn’t cached, you’ll run a database query to get the information you’re looking for, and you can add that information to the cache for the next query. If another query for the data doesn’t come within 30 seconds (or whatever window you specify), memcached will clear it from the cache, and the data will be pulled from the database.

So come on developers! Support memcached and faster load times! What other tools and tricks do you use to make your applications run more efficiently?

-Cassandra

May 23, 2012

Web Development – JavaScript – Creating a Sticky Menu

By in Development, SoftLayer, Technology, Tips and Tricks

When designing websites, I like to focus on ease of use and accessibility for the end user. While creating your site to be friendly to screen readers and text-based browsers is a must, the accessibility I’m referring to is making it easy for your audience to navigate your site and perform certain common actions. By providing an easy interface for your users, you are immediately increasing your chances that they’ll return for more of your site’s goodness.

Thus far in our “Web Development” blog series, we’ve looked at JavaScript Optimization, HTML5 Custom Data Attributes, HTML5 Web Fonts and using CSS to style the Highlight Selection. In this post, we’re going to create a “sticky” menu at the top of a page. As a user scrolls down, the menu will “stick” to the top and always be visible (think of Facebook’s Timeline view), allowing the user quicker access to clicking common links. With some simple HTML, CSS and JavaScript, you can have a sticky menu in no time.

Let’s start with our HTML. We’re going to have a simple header, menu and content section that we’ll throw in our <body> tag.

<header>
    <h1>My Header</h1>
</header>
<nav id="menu">
    <ul id="menu-list">
        <li>Items</li>
    </ul>
</nav>
<div id="content">
    Some content
</div>

For brevity, I’ve shortened the content I show here, but the working example will have all the information. Now we can throw in some CSS to style our elements. The important part here is how the <nav> is styled.

nav#menu {
    background: #FFF;
    clear: both;
    margin: 40px 0 80px 0;
    width: 99.8%;
    z-index: 2;
}
ul#menu-list li {
    border: solid 1px blue;
    list-style-type: none;
    display: inline-block;
    margin: 0 -3px;
    padding: 4px 10px;
    width: auto;
}

We have set the menu’s background to white (#FFF) and given it a z-index of 2 so that when the user scrolls, the menu will stay on top and not be see-through. We’ve also set the list items to be styled inline-block, but you can style your items however you desire.

Now we get to the fun part – the JavaScript. I’ve created a class using Mootools, but similar functionality could be achieved using your favorite JavaScript framework. Let’s examine our initialize method (our constructor) in our Stickit class.

var Stickit = this.Stickit = new Class({
    initialize: function(item, options) {
        // 'item' is our nav#menu in this case
        this.item = document.id(item);
 
        // The element we're scrolling will be the window
        this.scrollTarget = document.id(options.scrollTarget || document.window);
 
        // The 'anchor' is an empty element that will always keep the same location
        // when the user scrolls. This is needed because this.item will change and
        // we cannot rely on it for accurate calculations.
        this.anchor = new Element('div').inject(this.item, 'top');
 
        // The 'filler' is an empty element that we'll use as a space filler for when
        // the 'item' is being manipulated - this will prevent the content below from
        // jumping around when we scroll.
        this.filler = new Element('div').inject(this.item, 'after');
 
        // Set the styles of our 'filler' to match the styles of the 'item'
        this.setFillerStyles();
 
        // Initialize our scroll events – see the next code section for details
        this.initEvents();
    }
});

What we’re doing here is grabbing our element to stick to the top – in this case, nav#menu – and initializing our other important elements. I’ll review these in the next code section.

var Stickit = this.Stickit = new Class({
    ...
    initEvents: function() {
        var that = this,
            // Grab the position of the anchor to be used for comparison during vertical scroll
            anchorOffsetY = this.anchor.getPosition().y,
            // Grab our original styles of our 'item' so that we can reset them later
            originalStyles = this.item.getStyles('margin-top', 'position', 'top');
 
        // This is the function we'll provide as our scroll event handler
        var stickit = function(e) {
            // Determine if we have scrolled beyond our threshold - in this case, our
            // anchor which is located as the first element of our 'item'
            var targetScrollY = that.scrollTarget.getScroll().y,
                fixit = targetScrollY > anchorOffsetY;
 
            if (fixit && that.cache != 'fixed') {
                // If we have scrolled beyond the threshold, fix the 'item' to the top
                // of the window with the following styles: margin-top, position and top
                that.item.setStyles({
                    'margin-top': 0,
                    position: 'fixed',
                    top: 0
                });
                // Show our (empty) filler so that the content below the 'item' does not
                // jump - this would otherwise be distracting to the user
                that.filler.setStyle('display', 'block');
                // Cache our value so that we only set the styles when we need to
                that.cache = 'fixed';
            }
            else if (!fixit && that.cache != 'default') {
                // We have not scrolled beyond the threshold.
                // Hide our filler
                that.filler.setStyle('display', 'none');
                // Reset the styles to our 'item'
                that.item.setStyles(originalStyles);
                // Cache our values so we don't keep resetting the styles
                that.cache = 'default';
            }
        };
 
        // Add our scroll event to the target - the 'window' in this case
        this.scrollTarget.addEvent('scroll', stickit);
        // Fire our scroll event so that all the elements and styles are initialized
        this.scrollTarget.fireEvent('scroll');
    }
});

This method contains the meat of our functionality. The logic includes that we test how far the user has scrolled down on the page. If s/he scrolls past the threshold – in this case, the anchor which is located at the very top of the “stuck” item – then we set the menu to be fixed to the top of the page by setting the CSS values for margin-top, position and top. We also display a filler so that the content below the menu doesn’t jump when we set the menu’s position to fixed. When the user scrolls back to the top, the styles are reset to their original values and the filler is hidden.

To see a full working example, check out this fiddle. The Stickit class I created is flexible enough so that you can “stick” any element to the top of the page, and you can specify a different scrollTarget, which will allow you to scroll another element (besides the window) and allow the item to stick to the top of that element instead of the window. If you want to give that a try, you can specify different options in Stickit and modify your CSS as needed to get it working as you’d like.

Happy coding,

-Philip

April 12, 2012

HTML5 – Compatibility for All?

By in Development, Technology

Many of us remember when Flash was the “only” way to enhance user experience and create rich media interactivity. It was a bittersweet integration, though … Many users didn’t have the browser compatibility to use it, so some portion of your visitors were left in the dark. Until recently, that user base was relatively small — the purists who didn’t want Flash or the people whose hardware/software couldn’t support it. When Apple decided it wouldn’t enable Flash on the iPhone/iPad, web developers around the world groaned. A HUGE user base (that’s growing exponentially) couldn’t access the rich media and interactive content.

In the last year or so, Adobe released Flash Media Server to circumvent the Apple-imposed restrictions, but the larger web community has responded with a platform that will be both compatible and phenomenally functional: HTML5.

HTML5 allows us to do things we’ve never been able to do before (at least without the hassle of plugins, installations and frustration). Gone are the limitations that resigned HTML to serving as a simple framework for webpages … Now developers can push the limits of what they thought possible. As the platform has matured, some developers have even taken it upon themselves to prototype exactly where this generation of scripting is heading by creating Flash-free browser games.

Yes, you read that right: Games you can actually play on your browser, WITHOUT plugins.

From simple Pong clones that use browser windows as the paddles and ball to adventure-based Zelda-like massively multiplayer online role playing games (MMORPGs) like BrowserQuest, it’s pretty unbelievable to see the tip of the iceberg of possibilities enabled by HTML5 … Though it does seem a bit ironic to say that a Pong clone is such a great example of the potential of the HTML5 platform. Click on the screenshot below to check out BrowserQuest and tell me it doesn’t amaze you:

Browser Quest

With an ingenious combination of CSS, JavaScript and HTML5, developers of BrowserQuest have been able to accomplish something that no one has ever seen (nor would ever even have thought possible). Developers are now able to generate dynamic content by injecting JavaScript into their HTML5 canvasses:

<code>
function handleKeyDown(evt){
	keys[evt.keyCode] = true;
}
 
function handleKeyUp(evt){
	keys[evt.keyCode] = false;
}
 
// disable vertical scrolling from arrows :)
document.onkeydown=function(){return event.keyCode!=38 && event.keyCode!=40}
</code>

Look familiar? The game-making process (not syntax!) appears eerily similar to that of any other popular language. The only difference: You don’t need to install this game … You just open your browser and enjoy.

Using a popular port of Box2D, a physics simulator, making pure browser-based games is as simple as “Make. Include. Create.” Here’s a snippit:

<code>
//Make your canvas
<canvas id="game" width="600" height="400"></canvas>  
 
//include your js physics files
 
// create your world
function createWorld() {
	// here we create our world settings for collisions
	var worldAABB = new b2AABB();
	worldAABB.minVertex.Set(-1000, -1000);
	worldAABB.maxVertex.Set(1000, 1000);
	// set gravity vector
	var gravity = new b2Vec2(0, 300);
	var doSleep = true;
	// init our world and return its value
	var world = new b2World(worldAABB, gravity, doSleep);
	return world;
}
</code>

We may be a few years away from building full-scale WoW-level MMORPGs with HTML5, but I think seeing this functionality in native HTML will be a sigh of relief to those that’ve missed out on so much Flash goodness. While developers are building out the next generation of games and apps that will use HTML5, you can keep yourself entertained (and waste hours of time) with the HTML5 port of Angry Birds!

Angry Birds

HTML5 is not immune to some browser compatibility issues with older versions, but as it matures and becomes the standard platform for web development, we’re going to see what’s to come in our technology’s immediate future: Pure and simple compatibility for all.

-Cassandra

January 17, 2012

Web Development – HTML5 – Web Fonts

By in Development, SoftLayer, Technology, Tips and Tricks

All but gone are the days of plain, static webpages flowered with horrible repeating neon backgrounds and covered with nauseating animated GIFs created by amateur designers that would make your mother cry and induce seizures in your grandpa. Needless to say, we have come a long way since Al Gore first “created the intarwebs” in the early ’90′s. For those of you born in this century, that’s the 1990′s … Yes, the World Wide Web is still very new. Luckily for the seven billion people on this lovely planet, many advancements have been introduced into our web browsers that make our lives as designers and developers just a little bit more tolerable.

Welcome to the third installment in Web Development series. If you’re just joining us, the first posts in the series covered JavaScript Optimization and HTML5 Custom Data Attributes … If you haven’t read those yet, take a few minutes to catch up and head back to this blog where we’ll be looking at how custom web fonts can add a little spice to your already-fantastic website.

If you’re like me, you’ve probably used the same three or four fonts on most sites you’ve designed in the past: Arial, Courier New, Trebuchet MS and Verdana. You know that pretty much all browsers will have support for these “core” fonts, so you never ventured beyond them because you wanted the experience to remain the same for everyone, no matter what browser a user was using to surf. If you were adventurous and wanted to throw in a little typographical deviation, you might have created a custom image of the text in whatever font Photoshop would allow, but those days are in the past (or at least they should be).

Why is using an image instead of plain text unfriendly?

  1. Lack of Flexibility – Creating an image is time-consuming. Even if you have really fast fingers and know your way around Photoshop, it will never be as fast as simply typing that text into your favorite editor. Also, you can’t change the styles (font-size, color, text-decoration, etc.) of an image using CSS like you can with text.
  2. Lack of Accessibility – Not everyone is alike. Some of your readers or clients may have impairments that require screen readers or a really large font. Using an image – especially one that doesn’t contain a good long description – prevents those users from getting the full experience. Also, some people use text-only browsers that don’t display any images. Think about your whole audience!
  3. More to Download – Plain text doesn’t require the same number of bytes as an image of that same text. By not having another image, you are saving on the amount of time it takes to load your page.

Now that we’re on the same page about the downsides of the “old way” of doing things, let’s look at some cool HTML5-powered methods for displaying custom fonts. Before we get started, we need to have some custom fonts to use. Google has a nice interface for downloading custom fonts (http://www.google.com/webfonts), and there are plenty of other sites that provide free and non-free fonts that can suit your taste/needs. You can pick and choose which ones you’d like to use (remembering to always follow copyright guidelines), and once you’ve created and downloaded your collection of fonts, you’ll need to setup your CSS to read them.

For simplicity, my file structure will be setup with the HTML and CSS files in the same root directory. I will have a fonts directory where I will keep all my custom fonts.

/fonts.html
/fonts.css
/styles.css
/fonts/MyCustomFont/MyCustomFont-Regular.ttf
/fonts/MyCustomFont/MyCustomFont-Bold.ttf
/fonts/...

My fonts.html file will include the two CSS files in the head section. The order in which you include the CSS files does not matter.

<link rel="stylesheet" type="text/css" href="fonts.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />

The fonts.css file will include the definitions for all of our custom fonts. The styles.css file will be our main CSS file for our website. Defining our custom fonts (in fonts.css) is really simple:

@font-face {
    font-family: 'MyCustomFont';
    src: url('fonts/MyCustomFont/MyCustomFont-Regular.ttf') format('truetype');
}

It’s almost too easy thanks to HTML5!

Let’s break this down into its components to better understand what’s going on here. The @font-face declaration will be ignored by older browsers that don’t understand it, so this standards-compliant definition degrades nicely. The font-family descriptor is the name that you’ll use to reference this font family in your other CSS file(s). The src descriptor contains the location of where your font is stored and the format of the font.

There are several things to note here. The quotes around MyCustomFont in the font-family descriptor are optional. If it were My Custom Font instead (in fonts.css and styles.css), it would still be successfully read. The quotes around the url portion are also optional. However, the quotes around the format portion are not optional. To keep things consistent, I have a habit of adding quotes around all of these items.

An alternative way to define the same font would be to leave off the format portion of the src descriptor. Browsers don’t need the format portion if it’s a standard font format (described below).

@font-face {
    font-family: 'MyCustomFont';
    src: url('fonts/MyCustomFont/MyCustomFont-Regular.ttf');
}

Like standard url inclusions in other CSS definitions, the URL item is relative to the location of the definition file (fonts.css). The URL may also be an absolute location or point to a different website altogether. If using the Google web fonts site mentioned earlier (or similar site), you may simply point the URL to the location suggested instead of downloading the actual font.

If you’ve dealt with web fonts before, you may already be familiar with the multiple formats: WOFF (Web Open Font Format, .woff), TrueType (.ttf), OpenType (.ttf, .otf), Embedded Open Type (.eot) and SVG Font (.svg, .svgz). I won’t go into great detail here about these, but if you’re interested in learning more, Google and W3C are great resources.

It should be noted that all browsers are not alike (no shock there) and some may not render some font formats correctly or at all. You can get around this by including multiple src descriptors in your @font-face declaration to try and support all the browsers.

@font-face {
    font-family: 'MyCustomFont';
    src: url('fonts/MyCustomFont/MyCustomFont-Regular.eot'); /* Old IE */
    src: url('fonts/MyCustomFont/MyCustomFont-Regular.ttf'); /* Cool browsers */
}

Now that we have our font definition setup, we have to include our new custom font in our styles.css. You’ve done this plenty of times:

h1, p {
    font-family: MyCustomFont, Arial;
}

There you go! For some reason if MyCustomFont is not understood, the browser will default to Arial. This degrades gracefully and is really simple to use. One thing to note is that even though your fonts.css file may define twenty custom fonts, only the fonts that are included and used in your styles.css file will be downloaded. This is very smart of the browser – it only downloads what it’s going to use.

So now you have one more tool to add to your development box. As more users adopt newer, standards-compliant browsers, it’s easier to give your site some spice without the headaches of creating unnecessary images. Go forth and impress your friends with your new web font knowledge!

Happy Coding!

-Philip

P.S. As a bonus, you can check out the in-line style declaration in the source of this post to see how “Happy Coding!” is coded to use the Monofett font family.

January 10, 2012

Web Development – HTML5 – Custom Data Attributes

By in Development, SoftLayer, Technology, Tips and Tricks

I recently worked on a project that involved creating promotion codes for our clients. I wanted to make this tool as simple as possible to use and because this involved dealing with thousands of our products in dozens of categories with custom pricing for each of these products, I had to find a generic way to deal with client-side form validation. I didn’t want to write custom JavaScript functions for each of the required inputs, so I decided to use custom data attributes.

Last month, we started a series focusing on web development tips and tricks with a post about JavaScript optimization. In this installment, we’re cover how to use HTML5 custom data attributes to assist you in validating forms.

Custom data attributes for elements are “[attributes] in no namespace whose name starts with the string ‘data-’, has at least one character after the hyphen, is XML-compatible, and contains no characters in the range U+0041 to U+005A (LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z).” Thanks W3C. That definition is bookish, so let’s break it down and look at some examples.

Valid:

<div data-name="Philip">Mr. Thompson is an okay guy.</div>
<a href="softlayer.com" data-company-name="SoftLayer" data-company-state="TX">SoftLayer</a>
<li data-color="blue">Smurfs</li>

Invalid:

// This attribute is not prefixed with 'data-'
    <h2 database-id="244">Food</h2>
 
// These 2 attributes contain capital letters in the attribute names
    <p data-firstName="Ashley" data-lastName="Thompson">...</p>
 
// This attribute does not have any valid characters following 'data-'
    <img src="/images/pizza.png" data-="Sausage" />

Now that you know what custom data attributes are, why would we use them? Custom attributes allow us to relate specific information to particular elements. This information is hidden to the end user, so we don’t have to worry about the data cluttering screen space and we don’t have to create separate hidden elements whose purpose is to hold custom data (which is just bad practice). This data can be used by a JavaScript programmer to many different ends. Among the most common use cases are to manipulate elements, provide custom styles (using CSS) and perform form validation. In this post, we’ll focus on form validation.

Click through for a detailed, step-by-step example. »

June 24, 2010

HTML 5 Video

By in Development, Technology

If you haven’t heard the buzz about HTML5, you should check out the many features and improvements. It has support for cool stuff like SVG and MathML, but one of the most impressive things it can accomplish is embedding streaming videos with no required flash player or java applet. The old way of video streaming usually involves first converting your video into the proprietary flash “.flv” format. Then you add many lines of ugly code, filled with frequently redundant information, like this example courtesy of YouTube:

<object width="480" height="385">
<param name="movie" value="http://www.youtube.com/v/mPpUiXDUASk&amp;hl=en_US&amp;fs=1&amp;"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/mPpUiXDUASk&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed>
</object>

In HTML5, all this can be replaced by something as clean and simple as the tag. Here is an example of what it looks like in action:

<video width="640"  height="360" src="./movies/movie1.mp4"  controls autobuffer>

Much cleaner, right?

Sadly, this is not without its caveats. First of all HTML5 is not yet a finalized standard, so the various browsers will handle it differently. Secondly, Internet Explorer does not yet support HTML5 (surprise, surprise!), although the upcoming IE9 will provide support for it. This brings me to the first major hurdle:

Currently, there is no universal codec/container combination that will satisfy all HTML5 browsers.

This means that if you desire to use HTML5 video, you will need to encode your video at least twice. The two “official” combinations are Ogg/Theora/Vorbis and MP4/H.264/AAC. The Ogg combo works on Firefox and Opera, whereas the MP4 combo works with Safari, iPhone, Android, and the upcoming IE9.

Check out http://diveintohtml5.org/video.html for more detailed information.

Once you have your videos encoded and uploaded, you’ll need to set it up in your code. The diveintohtml5.org guide recommends having 3 codecs (with webm, which is a soon-to-be standard) and Flash fallback, but in the future various browsers should have a more uniform codec support:

<video id="movie" width="320" height="240" preload controls>
<source src="pr6.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="pr6.webm" type='video/webm; codecs="vp8, vorbis"' />
<source src="pr6.ogv" type='video/ogg; codecs="theora, vorbis"' />
<object width="320" height="240" type="application/x-shockwave-flash"
data="flowplayer-3.2.1.swf">
<param name="movie" value="flowplayer-3.2.1.swf" />
<param name="allowfullscreen" value="true" />
<param name="flashvars" value='config={"clip": {"url": "http://wearehugh.com/dih5/good/bbb_480p.mp4", "autoPlay":false, "autoBuffering":true}}' />
<p>Download video as <a href="pr6.mp4">MP4</a>, <a href="pr6.webm">WebM</a>, or <a href="pr6.ogv">Ogg</a>.</p>
</object>
</video>

You’ll notice the optional mime types and codecs as additional attributes. This is really just error proofing your code. It will make sure that it will have browser interoperability, and browsers won’t have to download the videos to tell what codecs they are using (which saves you bandwidth—and when you are serving up videos, your bandwidth is a precious commodity!).

So much for the clean and simple solution, eh? So what is the upshot here? Well, first and foremost, it’s an open standard. You no longer have to rely on the proprietary Flash plugin to do something that the browser should be able to natively support. Secondly, Flash is not universally supported, and with the growing prominence of iPhone video streaming, you’ll be missing out on a huge demographic. Thirdly, HTML5 video is friendlier with overhead resources. So while it’s not perfectly simple yet, it’s still worthwhile to start adopting.

-Mark