etimbo / jquery-print-preview-plugin

jQuery plugin for print preview (modal window)
jquery-print-preview-plugin
382 stars 128 forks source link

Printing Elements, Event Triggers & Formatting issues #6

Open derickdsouza opened 12 years ago

derickdsouza commented 12 years ago

Hi,

Thank you for this awesome plugin! I faced a few issues getting it to work on my page. Had to make a few changes, have included them here.


//Print specific elements (with class=printpreview) or the whole page
print_content = $('.printpreview').length > 0 
                ? $('.printpreview') 
                : $('body > *:not(#print-modal):not(script)'); 
//Used it here
var $iframe_body = print_content.clone();
//and here
print_content.clone().each(function() {
                    $('body', print_frame_ref).append(this.outerHTML);
                });
// Added Event triggers to allow container page to carry out actions
print_content.trigger('printPreview.loading'); //first line after print_content is assigned
print_content.trigger('printPreview.ready'); //end of loadPrintPreview
print_content.trigger('printPreview.unloading'); //first line of distroyPrintPreview
print_content.trigger('printPreview.complete'); //last line of distroyPrintPreview

// Replaced the loop by this statement as the addThis plugin in FF was throwing a permission error
// used contentWindow instead of contentDocument for older browsers
print_frame_ref = print_frame[0].contentWindow.document;

// Stored the css values of body before changing them
bodyCSS = { overflowY: $('body').css('overflowY'), height: $('body').css('height') }
$('body').css({ overflowY: 'hidden', height: '100%' });

// Restored it later - this used to mess up my page
$('body').css(bodyCSS);

// Print the iframe instead of the page
if ($(this).hasClass('print')) { print_frame[0].contentWindow.print(); }

Regards,

Derick

LDigital84 commented 12 years ago

@derickdsouza - You said "...the addThis plugin in FF was throwing a permission error" - How do you correct this error from happening? (Note: It is happening in at least FF and Chrome.) I do not know enough about JS to follow you.

I tried changing the:

var print_frame_ref = window.frames[i].document

to

print_frame_ref = print_frame[0].contentWindow.document;

Or am I missing something here? Thanks for any help.

derickdsouza commented 12 years ago

@Lynda333, don't know if this still useful

I replaced

// The frame lives
            for (var i=0; i < window.frames.length; i++) {
                if (window.frames[i].name == "print-frame") {
                    var print_frame_ref = window.frames[i].document;
                    break;
                }
            }

with

print_frame_ref = print_frame[0].contentWindow.document;

LDigital84 commented 12 years ago

@derickdsouza - It was very useful. Thanks for the help!

alex84G commented 11 years ago

@derickdsouza

To print the iframe instead of the page was very useful for me. Thak you!!!!

jurgen-74 commented 11 years ago

@derickdsouza

Could you please post the whole script for me? I am starting to get a bit lost.

Jurgen

derickdsouza commented 11 years ago

@jurgen-74 here's the complete script, I have not added comments for the changes, a diff will show them up anyway.

/*!
* jQuery Print Previw Plugin v1.0.1
*
* Copyright 2011, Tim Connell
* Licensed under the GPL Version 2 license
* http://www.gnu.org/licenses/gpl-2.0.html
*
* Date: Wed Jan 25 00:00:00 2012 -000
*/

(function ($) {

    // Initialization
    $.fn.printPreview = function () {
        this.each(function () {
            $(this).bind('click', function (e) {
                e.preventDefault();
                if (!$('#print-modal').length) {
                    $.printPreview.loadPrintPreview();
                }
            });
        });
        return this;
    };

    // Private functions
    var mask, size, print_modal, print_controls, print_content, bodyCSS, print_frame_ref;
    $.printPreview = {
        loadPrintPreview: function () {
            // Declare DOM objects
            print_content = $('.printpreview').length > 0 ? $('.printpreview') : $('body > *:not(#print-modal):not(script)'); //Added by Derick D'souza on June 27, 2012 to allow filtered printing
            print_content.trigger('printPreview.loading');
            print_modal = $('<div id="print-modal"></div>');
            print_controls = $('<div id="print-modal-controls">' +
                                    '<a href="#" class="print" title="Print page">Print page</a>' +
                                    '<a href="#" class="close" title="Close print preview">Close</a>').hide();
            var print_frame = $('<iframe id="print-modal-content" scrolling="no" border="0" frameborder="0" name="print-frame" />');

            // Raise print preview window from the dead, zooooooombies
            print_modal
                .hide()
                .append(print_controls)
                .append(print_frame)
                .appendTo('body');

            print_frame_ref = print_frame[0].contentWindow.document; //Added by Derick D'souza on June 27, 2012 to access iframe directly, the loop above was throwing up errors becuase of inaccessible frames
            print_frame_ref.open();
            print_frame_ref.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' +
                '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">' +
                '<head><title>' + document.title + '</title></head>' +
                '<body></body>' +
                '</html>');
            print_frame_ref.close();

            // Grab contents and apply stylesheet
            var $iframe_head = $('head link[media*=print], head link[media=all]').clone(), 
            $iframe_body = print_content.clone();
            $iframe_head.each(function () {
                $(this).attr('media', 'all');
            });
            if (!$.browser.msie && !($.browser.version < 7)) {
                $('head', print_frame_ref).append($iframe_head);
                $('body', print_frame_ref).append($iframe_body);
            }
            else {
                print_content.clone().each(function () {
                    $('body', print_frame_ref).append(this.outerHTML);
                });
                $('head link[media*=print], head link[media=all]').each(function () {
                    $('head', print_frame_ref).append($(this).clone().attr('media', 'all')[0].outerHTML);
                });
            }

            // Disable all links
            $('a', print_frame_ref).bind('click.printPreview', function (e) {
                e.preventDefault();
            });

            // Introduce print styles
            $('head').append('<style type="text/css">' +
                '@media print {' +
                    '/* -- Print Preview --*/' +
                    '#print-modal-mask,' +
                    '#print-modal {' +
                        'display: none !important;' +
                    '}' +
                '}' +
                '</style>'
            );

            // Load mask
            $.printPreview.loadMask();

            // Disable scrolling
            bodyCSS = { overflowY: $('body').css('overflowY'), height: $('body').css('height') }
            $('body').css({ overflowY: 'hidden', height: '100%' });
            $('img', print_frame_ref).load(function () {
                print_frame.height($('body', print_frame.contents())[0].scrollHeight);
            });

            // Position modal            
            var starting_position = $(window).height() + $(window).scrollTop();
            var css = {
                top: starting_position,
                height: '100%',
                overflowY: 'auto',
                zIndex: 10000,
                display: 'block'
            }
            print_modal
                .css(css)
                .animate({ top: $(window).scrollTop() }, 400, 'linear', function () {
                    print_controls.fadeIn('slow').focus();
                });
            print_frame.height($('body', print_frame.contents())[0].scrollHeight);

            // Bind closure
            $('a', print_controls).bind('click', function (e) {
                e.preventDefault();
                if ($(this).hasClass('print')) { print_frame[0].contentWindow.print(); }
                else { $.printPreview.distroyPrintPreview(); }
            });
            print_content.trigger('printPreview.ready');
        },

        distroyPrintPreview: function () {
            print_content.trigger('printPreview.unloading');
            print_controls.fadeOut(100);
            print_modal.animate({ top: $(window).scrollTop() - $(window).height(), opacity: 1 }, 400, 'linear', function () {
                print_modal.remove();
                $('body').css(bodyCSS);
                print_content.trigger('printPreview.content.removed');
            });
            mask.fadeOut('slow', function () {
                mask.remove();
                print_content.trigger('printPreview.mask.removed');
            });

            $(document).unbind("keydown.printPreview.mask");
            mask.unbind("click.printPreview.mask");
            $(window).unbind("resize.printPreview.mask");
            print_content.trigger('printPreview.complete');
        },

        /* -- Mask Functions --*/
        loadMask: function () {
            size = $.printPreview.sizeUpMask();
            mask = $('<div id="print-modal-mask" />').appendTo($('body'));
            mask.css({
                position: 'absolute',
                top: 0,
                left: 0,
                width: size[0],
                height: size[1],
                display: 'none',
                opacity: 0,
                zIndex: 9999,
                backgroundColor: '#000'
            });

            mask.css({ display: 'block' }).fadeTo('400', 0.75);

            $(window).bind("resize..printPreview.mask", function () {
                $.printPreview.updateMaskSize();
            });

            mask.bind("click.printPreview.mask", function (e) {
                $.printPreview.distroyPrintPreview();
            });

            $(document).bind("keydown.printPreview.mask", function (e) {
                if (e.keyCode == 27) { $.printPreview.distroyPrintPreview(); }
            });
        },

        sizeUpMask: function () {
            if ($.browser.msie) {
                // if there are no scrollbars then use window.height
                var d = $(document).height(), w = $(window).height();
                return [
                    window.innerWidth ||                        // ie7+
                    document.documentElement.clientWidth ||     // ie6  
                    document.body.clientWidth,                  // ie6 quirks mode
                    d - w < 20 ? w : d
                ];
            } else { return [$(document).width(), $(document).height()]; }
        },

        updateMaskSize: function () {
            var size = $.printPreview.sizeUpMask();
            mask.css({ width: size[0], height: size[1] });
        }
    }
})(jQuery);
jurgen-74 commented 11 years ago

Brilliant! Thanks

sethArrow commented 10 years ago

Excellent Thnks