views:

82

answers:

3

Easy All

As I've been learning jQuery lately, I decided to write my own modal window to play videos in, when the video thumbnail is clicked. It all works fine, but I'm just wondering how could I turn it into a plugin, so I could use it on different pages with different parameters etc. I read the documentation, and a few tutorials, but I can't seem to get it working. My basic code is as follows:

<script type="text/javascript">
var $j = jQuery.noConflict();
$j(document).ready(function(){

    // Add our click OPEN event
    $j("a.video_link").click(function (e) {
        e.preventDefault();
        // Add our overlay div
        $j('body').append('<div id="overlay" />');
        // Fade in overlay
        $j('#overlay').css({"display":"block","opacity":"0"}).animate({"opacity":"0.2"}, 300),
        // Animate our modal window into view
        $j('#video').css({"top":"43%"}).css({"opacity":"0"}).show().animate({"top": "50%", "opacity": "1"}, 550),
        // Add our close image
        $j('#video').append('<div id="modal-vid-close" title="Close window" />');
        // Add our click CLOSE event
        $j('#overlay, #modal-vid-close').click(function () {
            //Animate our modal window out of view
            $j('#video').animate({"top": "55%", "opacity": "0"}, 350).fadeOut(200),
            // Fade out and remove our overlay
            $j('#overlay').fadeOut(200, function () { $j(this).remove(); $j('#modal-vid-close').remove()} )
        });
    });
});

I'd like to turn this into a plugin so I can use it on different pages, and just specify the 'trigger' link, and the div id to show in the window (it will already be loaded on the page, but hidden). Something like this, added to doc load on each page:

var trigger = $j('.video_container a');
var modalcontent = $j('#video');

Any help, or pointers to good tutorials, much appreciated!

+3  A: 

Here's a good template, which I found on a tutorial site, Queness:

(function($){
    $.fn.extend({
        // change 'pluginname' to your plugin name (duh)
        pluginname: function(options) {

            // options for the plugin
            var defaults = {
                width: 500,
                height: 300
            }

            var options =  $.extend(defaults, options);

            return this.each(function() {
                // main code goes here, will apply to each element of $(this)
                // e.g. `$(this).click( function() {} )`
                // also have access to `options` i.e. `options.width`
            });
        }
    });
})(jQuery);

Then put this in your HTML:

<script type="text/javascript">
$(document).ready( function() {
    // use default options
    $('.selector').pluginname();
    // custom options
    $('.selector').pluginname({width:300, height:200});
});
</script>
DisgruntledGoat
I just asked a question as to whether it was more efficient to use `$.extend(pluginName: function())` or `$.fn.pluginName = function()`...with the ::overwhelming:: (haha) response I got, I determined `$.fn.pluginName` would probably be a bit faster - http://stackoverflow.com/questions/2145320/is-there-any-performance-difference-in-the-ways-of-writing-a-jquery-plugin
munch
You may be right, though `$.fn.extend` just "feels" like a better and more official way to do it. Speed difference would be tiny.
DisgruntledGoat
Indeed, to each his own
munch
+2  A: 

I found the official jQuery plugin authoring guide very good, and there's also this article at Learning jQuery which helps you to understand what's going on a bit better.

Mark B
A: 

OK, thanks to the Queness tutorial, I'm 99% there! Cheers Disgruntled for the link. Everything is fine except that now my modal window won't close. Should that be in a separate "close" function or something? Here's the new code:

<script type="text/javascript">
(function($){
$.fn.extend({
    mynewmodal: function(options) {

   var defaults = {
                   container: "#modalcontainer"
          };
        var options = $.extend(defaults, options);
        return this.each(function() {
            var o =options;
            // Add our click OPEN event
            $(this).click(function (e) {
                e.preventDefault();
                // Add our overlay div
                $('body').append('<div id="overlay" />');
                // Fade in overlay
                $('#overlay').css({"display":"block","opacity":"0"}).animate({"opacity":"0.2"}, 300),
                // Animate our modal window into view
                $(o.container).css({"top":"43%", "opacity":"0"}).show().animate({"top": "50%", "opacity": "1"}, 550),
                // Add our close image
                $(o.container).append('<div id="modal-vid-close" title="Close window" />');
                // Add our click CLOSE event
                $('#overlay', '#modal-vid-close').click(function () {
                    //Animate our modal window out of view
                    $(o.container).animate({"top": "55%", "opacity": "0"}, 350).fadeOut(200),
                    // Fade out and remove our overlay 
                    $('#overlay').fadeOut(200, function () { $(this).remove(); $('#modal-vid-close').remove()} )
                });
            });
        });
    }
});
})(jQuery);
</script>

and then to initiate it:

<script type="text/javascript">
var $j = jQuery.noConflict();
$j(document).ready( function() {
$j('.video_container a').mynewmodal({ container: "#video" });
});
</script>
Sam
I think the problem is this line in the close link `click()` handler: `$(o.container).animate({"top": "55%", "opacity": "0"}, 350).fadeOut(200),` - `o.container` will be out of scope when the plugin code finishes executing. Try replacing `o.container` with `'#overlay'` as you do in the line below.
Mark B
Nope, doesn't do it. Anymore ideas?
Sam
OK, I uploaded a jsbin example. You can see that it all works fine up til the 'close window' part - http://jsbin.com/adere
Sam
Bah, was me writing the selectors wrong - should be written as $('#modal-vid-close, #video')...
Sam