Looking for remote work in tech?
Download our app Apple App Store Google Play Store
Looking for remote work in tech? Download our mobile app now! Apple App Store Google Play Store

jQuery Development: Your own Plugins Part II


 

December 8, 2009 | By: Adrian

Extending on my previous post jQuery development: Your own plugins, we now have to take a look into a more complex plugin as well as making greater use of both JavaScript’s built in Regular Expression objects and jQuery provided functionality.

For the purposes of this post, I’ll be extending on the previous plugin to readily handle more video services: Dailymotion, Megavideo & Vimeo as well as the already supported YouTube. Also, we’ll be adding an option to leave the link but make the video pop up in a modal box using ColorBox.

Okay enough intro…let’s code!

First, we’re going to start off with the basic structure of every jQuery plugin:

(function($){
    $.fn.videa = function(){
    }
})(jQuery)

Note: We use this format for the purpose of ease and using the familiar $ variable, however we can just do this.

jQuery.fn.videa = function(){
   //How ever, within here we can only use the jQuery object,
   // $ is undefined.
}

First we’re going to need the embed code for each service. This is readily
available on their websites as well as the format for their actual flv’s.
I’ve already done this below.

Note: I’ve made use of JSON. If you don’t know about this, read up here.

(function($){

    $.fn.videa= function(){

        var supportedSites = {
            'youtube' : '<object width="560" height="340"><param name="movie" value="[URL]&hl=en&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="[URL]&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>',
            'dailymotion': '<object width="480" height="275"><param name="movie" value="[URL]"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="[URL]" type="application/x-shockwave-flash" width="480" height="275" allowfullscreen="true" allowscriptaccess="always"></object>',
            'megavideo': '<object width="640" height="467"><param name="movie" value="[URL]"></param><param name="allowFullScreen" value="true"></param><embed src="[URL]" type="application/x-shockwave-flash" allowfullscreen="true" width="640" height="467"></embed></object>',
            'vimeo'    : '<object width="400" height="225"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="[URL]" /><embed src="[URL]" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="225"></embed></object>'
        }

        var handle = {
            'youtube'    : ['watch?v=', 'v/'],
            'dailymotion': [/.*dailymotion.*/video/(.*?)_.*/, 'http://dailymotion.com/swf/$1'],
            'megavideo'  : ['?v=', 'v/'],
            'vimeo'      : [/.*vimeo.*/(.*[0-9])/, 'http://vimeo.com/moogaloop.swf?clip_id=$1&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00adef&fullscreen=1']
        }

Next, we’ll need to make use of each utility; this is something that will be used in nearly ALL your plugins. The reason why is because you want the plugin to affect more than one HTML element.

(function($){
    $.fn.videa= function(){
        // We're of course assuming the aforementioned json is here
        // ommited for the purposes of readability
      this.each(function(){
      })
})(jQuery)

Now, for our purposes we don’t actually need to instantiate a jQuery object per <a> element – yet. All we need is the href and class attributes which are easily available via JavaScript’s native getAttribute function.

(function($){
    $.fn.videa= function(){
        // We're of course assuming the aforementioned json is here
        // ommited for the purposes of readability
      this.each(function(){
           var href    = this.getAttribute('href');
           var aClass  = this.getAttribute('class');
           var key     = href.match(/(http://www.|http://|www.|)(.*?).(.com|.*)/)[2];

          // we now have the base such as 'youtube' and 'vimeo' in key
          // check if we support it
          if( supportedSites[key] )
          {
          }
      })
})(jQuery)

Now I’ll explain the regex

The first bit:

This matches the http protocol with or without the www or just the www

  • ‘(http://www.|http://|www.|)’

The second bit:
Simply grabs everything AFTER the http://www.

  • ‘(.*?)’

The third bit:

This matches against any .com or .* extension

  • ‘.(.com|.*)’

The rest is rather straight forward and can be explained in code comments.

// Check if the site is supported
if( supportedSites[key] )
            {
               // Construct properly url to the flv
               if( href.indexOf('http://www.') == -1 )
                        href = 'http://www.' + href.replace('www.', '');

                // Check if we want a modal box
                if( aClass.indexOf('modal') > -1 )
                {
                    // Bind to the click and fire off colorbox
                    $(this).click(function(){
                        $.fn.colorbox({
                            html: supportedSites[key].replace(/[URL]/ig, href.replace(handle[key][0], handle[key][1])) ,
                            open:true
                        });
                                return false;
                     })
                }else{
                    // We don't want a modal box so just do the html
                    $(this).before(supportedSites[key].replace(/[URL]/ig, href.replace(handle[key][0], handle[key][1]))).remove();
                }

Note: jQuery is a jackhammer, sometimes all we have is nails.

That’s the plugin broken down into the important sections. The end result is as expected. Everything which has a videa class is converted. The modal class is optional (it creates a link that opens a modal box with your video).

As for plugin development, once you understand  DOM and the entire jQuery API, you can pretty much make anything you can come up with. JavaScript support is strong and growing.

The Entire plugin below:

(function($){

    $.fn.embeddedables = function(){

        var supportedSites = {
            'youtube' : '<object width="560" height="340"><param name="movie" value="[URL]&hl=en&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="[URL]&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>',
            'dailymotion': '<object width="480" height="275"><param name="movie" value="[URL]"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="[URL]" type="application/x-shockwave-flash" width="480" height="275" allowfullscreen="true" allowscriptaccess="always"></object>',
            'megavideo': '<object width="640" height="467"><param name="movie" value="[URL]"></param><param name="allowFullScreen" value="true"></param><embed src="[URL]" type="application/x-shockwave-flash" allowfullscreen="true" width="640" height="467"></embed></object>',
            'vimeo'    : '<object width="400" height="225"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="[URL]" /><embed src="[URL]" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="225"></embed></object>'
        }

        var handle = {
            'youtube'    : ['watch?v=', 'v/'],
            'dailymotion': [/.*dailymotion.*/video/(.*?)_.*/, 'http://dailymotion.com/swf/$1'],
            'megavideo'  : ['?v=', 'v/'],
            'vimeo'      : [/.*vimeo.*/(.*[0-9])/, 'http://vimeo.com/moogaloop.swf?clip_id=$1&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00adef&fullscreen=1']
        }

        // Looad in this element for all a tags
        this.each(function(){

            var href   = this.getAttribute('href');
            var aClass = this.getAttribute('class');
            var key = href.match(/(http://www.|http://|www.|)(.*?).(.com|.*)/)[2];

            if( supportedSites[key] )
            {
               if( href.indexOf('http://www.') == -1 )
                        href = 'http://www.' + href.replace('www.', '');

                if( aClass.indexOf('modal') > -1 )
                {
                    $(this).click(function(){
                        $.fn.colorbox({
                            html: supportedSites[key].replace(/[URL]/ig, href.replace(handle[key][0], handle[key][1])) ,
                            open:true
                        });
                                return false;
                     })
                }else{
                    $(this).before(supportedSites[key].replace(/[URL]/ig, href.replace(handle[key][0], handle[key][1]))).remove();
                }
            }

        });

    }

})(jQuery)