Thursday, April 26, 2012

Solution to Chapter 8 Exercises of Learning jQuery 3rd Edition


My solutions to Learning jQuery 3rd Edition Chapter 7 exercises:




Exercises:


Some of the exercises are requires modifications of codes from the book. You can easily locate my modifications by looking for //--------------Added sections




1. Create new plugin methods called .slideFadeIn() and .slideFadeOut(), combining the opacity animations of .fadeIn() and .fadeOut() with the height animations of .slideDown() and .slideUp().

(function ($) {
    $.fn.slideFadeIn = function() {
        return this.each(function () {
            //$(this).slideDown('slow').fadeIn('slow');
            $(this).slideDown('slow').fadeTo('slow', 1.0);
        });
    };
  
    $.fn.slideFadeOut = function() {
        return this.each(function () {
            //$(this).slideUp('slow').fadeOut('slow');
            $(this).fadeTo('slow', 0.5).slideUp('slow');
        });
    };
})(jQuery);

//------Sample code for testing excercise 1
jQuery(document).ready(function ($) {

    //Test for .slideFadeIn & .slideFadeOut
    //Click the <h1>Inventory</h1> to see the effect of these new methods
    $('#container h1').toggle(function() {
        $('#inventory').slideFadeOut();
    }, function () {
        $('#inventory').slideFadeIn();
    });
});



2. Extend the customizability of the .shadow() method so that the z-index of the cloned copies can be specified by the plugin user. Add a new sub-method called isOpen to the tooltip widget. This sub-method should return true if the tooltip is currently displayed and false otherwise.


/******************************************************************************
.shadow()
Create a shadow effect on any element by brute-force copying.
******************************************************************************/
(function ($) {
    $.fn.shadow = function (opts) {
        var options = $.extend({}, $.fn.shadow.defaults, opts);

        return this.each(function () {
            var $originalElement = $(this);
            for (var i = 0; i < options.copies; i++) {
                var offset = options.copyOffset(i);
                $originalElement
          .clone()
          .css({
              position: 'absolute',
              left: $originalElement.offset().left + offset.x,
              top: $originalElement.offset().top + offset.y,
              margin: 0,
              //------------------------------------------------------Added
              zIndex: options.zIndex,
              //-------------------------------------------------------------
              opacity: options.opacity
          })
          .appendTo('body');
            }
        });
    };

    $.fn.shadow.defaults = {
        copies: 5,
        opacity: 0.1,
        copyOffset: function (index) {
            return { x: index, y: index };
        },
        //------------------------------------------------------Added
        zIndex: -1
        //-----------------------------------------------------------
    };
})(jQuery);


/******************************************************************************
.tooltip()
A simple jQuery UI tooltip widget.
******************************************************************************/
(function ($) {
    $.widget('ljq.tooltip', {
        options: {
            offsetX: 10,
            offsetY: 10,
            content: function () {
                return $(this).data('tooltip-text');
            }
        },

        _create: function () {
            //------------------------------------------------------Added
            this.isTooltipOpen = false;
            //-----------------------------------------------------------

            this._tooltipDiv = $('<div></div>')
                .addClass('ljq-tooltip-text ui-widget ui-state-highlight ui-corner-all')
                .hide().appendTo('body');
                    this.element
                .addClass('ljq-tooltip-trigger')
                .bind('mouseenter.ljq-tooltip', $.proxy(this._open, this))
                .bind('mouseleave.ljq-tooltip', $.proxy(this._close, this));
        },

        destroy: function () {
            this._tooltipDiv.remove();
            this.element.removeClass('ljq-tooltip-trigger')
                        .unbind('.ljq-tooltip');
            $.Widget.prototype.destroy.apply(this, arguments);
        },

        open: function () {
            this._open();
        },

        close: function () {
            this._close();
        },

        _open: function () {

            //------------------------------------------------------Added
            this.isTooltipOpen = true;
            //-----------------------------------------------------------
            if (!this.options.disabled) {
                var elementOffset = this.element.offset();
                this._tooltipDiv.css({
                    left: elementOffset.left + this.options.offsetX,
                    top: elementOffset.top + this.element.height() + this.options.offsetY
                }).text(this.options.content.call(this.element[0]));
                this._tooltipDiv.show();
                this._trigger('open');
            }
        },

        _close: function () {
           
            //------------------------------------------------------Added
            this.isTooltipOpen = false;
            //-----------------------------------------------------------

            this._tooltipDiv.hide();
            this._trigger('close');
        },

        //------------------------------------------------------Added
        isOpen: function() {
            return this.isTooltipOpen;
        }
        //-----------------------------------------------------------
    });
})(jQuery);


//------Sample code for testing excercise 2
jQuery(document).ready(function ($) {

    $.fn.shadow.defaults.copies = 10;
    //$.fn.shadow.defaults.zIndex = 2; //if you uncomment this, Clicking <h1>Inventory</h1> will have no effect
    $('h1').shadow({
        copyOffset: function (index) {
            return { x: -index, y: index };
        }
    });   

    //$('a').tooltip();
    $('a').tooltip().hover(function () {
        //alert($(this).tooltip('isOpen').toString());       
        console.log('Is tooltip open? -> ' + $(this).tooltip('isOpen').toString());
    });
});



3. Add code that listens for the tooltipopen event that our widget fires, and logs a message to the console.


jQuery(document).ready(function ($) {
    $('a').bind('tooltipopen', function () {
        console.log('tooltip open event fires');
    });
});



4. Challenge: Provide an alternative content option for the tooltip widget that fetches the content of the page and anchor's href points to via Ajax, and displays that content as the tooltip text.


jQuery(document).ready(function ($) {
    $('a').tooltip({ content: function () {
        var url = $(this).attr('href');
        var result = null;
        $.ajax({
            url: url,
            type: 'get',
            dataType: 'html',
            async: false,
            success: function (data) {
                result = data;
            }
        });

        return result;
    }});
});



5. Challenge: Provide a new effect option for the tooltip widget that, if specified, applies the named jQuery UI effect (such as explode) to the showing and hiding of the tooltip.



/******************************************************************************
.tooltip()
A simple jQuery UI tooltip widget.
******************************************************************************/
(function ($) {
    $.widget('ljq.tooltip', {
        options: {
            offsetX: 10,
            offsetY: 10,
            content: function () {
                return $(this).data('tooltip-text');
            }
        },

        _create: function () {
            //------------------------------------------------------Added
            this.isTooltipOpen = false;
            //-----------------------------------------------------------

            this._tooltipDiv = $('<div></div>')
                .addClass('ljq-tooltip-text ui-widget ui-state-highlight ui-corner-all')
                .hide().appendTo('body');
            this.element
                .addClass('ljq-tooltip-trigger')
                .bind('mouseenter.ljq-tooltip', $.proxy(this._open, this))
                .bind('mouseleave.ljq-tooltip', $.proxy(this._close, this));
        },

        destroy: function () {
            this._tooltipDiv.remove();
            this.element.removeClass('ljq-tooltip-trigger')
                        .unbind('.ljq-tooltip');
            $.Widget.prototype.destroy.apply(this, arguments);
        },

        open: function () {
            this._open();
        },

        close: function () {
            this._close();
        },

        _open: function () {

            //------------------------------------------------------Added
            this.isTooltipOpen = true;
            //-----------------------------------------------------------

            if (!this.options.disabled) {
                var elementOffset = this.element.offset();
                this._tooltipDiv.css({
                    left: elementOffset.left + this.options.offsetX,
                    top: elementOffset.top + this.element.height() + this.options.offsetY
                }).text(this.options.content.call(this.element[0]));
                this._tooltipDiv.show();
                this._trigger('open');

                //------------------------------------------------------Added
                if(this.options.effect) {
                    this._tooltipDiv.effect(this.options.effect, {distance: 10, duration: 80});
                }
                //-----------------------------------------------------------
            }
        },

        _close: function () {

            //------------------------------------------------------Added
            this.isTooltipOpen = false;
            //-----------------------------------------------------------

            this._tooltipDiv.hide();
            this._trigger('close');
        },

        //------------------------------------------------------Added
        isOpen: function () {
            return this.isTooltipOpen;
        }
        //-----------------------------------------------------------
    });
})(jQuery);

//------Sample code for testing excercise 5
jQuery(document).ready(function ($) {
    $('a').tooltip({effect: 'shake'});
});




 


  
Free Lessons for Chruch Pianists:
Free lessons, tips and downloads for church pianists

DVD Courses (Reharmonization, Play by Ear!, Arranging, Accompanying, Theory for Church Pianists, etc.):
Over 30 hours of DVD instruction for church pianists
 


Visit Vitabase for Quality Health Supplements