1. #1
    Ext User
    Join Date
    Jul 2008
    Posts
    41
    Vote Rating
    0
    nerdydude81 is on a distinguished road

      0  

    Lightbulb Print Element

    Print Element


    This is my first post. For my site I needed to print specific elements without using popup windows. I solved this by creating an iframe and inserting the html, then printing the hidden iframe. Here's my code, please make suggestions.

    PHP Code:
    /**
     * @version 0.4
     * @author nerdydude81
     */
    Ext.override(Ext.Element, {
        
    /**
         * @cfg {string} printCSS The file path of a CSS file for printout.
         */
        
    printCSSnull
        
    /**
         * @cfg {Boolean} printStyle Copy the style attribute of this element to the print iframe.
         */
        
    printStylefalse
        
    /**
         * @property {string} printTitle Page Title for printout. 
         */
        
    printTitledocument.title
        
    /**
         * Prints this element.
         * 
         * @param config {object} (optional)
         */
        
    , print: function(config) {
            
    Ext.apply(thisconfig);
            
            var 
    el Ext.get(this.id).dom;
            var 
    document.getElementById('printcontainer');
            var 
    iFrame document.getElementById('printframe');
            
            var 
    strTemplate '<HTML><HEAD>{0}<TITLE>{1}</TITLE></HEAD><BODY onload="{2}"><DIV {3}>{4}</DIV></BODY></HTML>';
            var 
    strLinkTpl '<link rel="stylesheet" type="text/css" href="{0}"/>'
            
    var strAttr '';
            var 
    strFormat;
            var 
    strHTML;
            
            
    //Get rid of the old crap so we don't copy it
            //to our iframe
            
    if (iFrame != nullc.removeChild(iFrame);
            if (
    != nullel.removeChild(c);
            
            
    //Copy attributes from this element.
            
    for (var 0el.attributes.lengthi++) {
                if (
    Ext.isEmpty(el.attributes[i].value) || el.attributes[i].value.toLowerCase() != 'null') {
                    
    strFormat Ext.isEmpty(el.attributes[i].value)? '{0}="true" ''{0}="{1}" ';
                    if (
    this.printStylethis.printStyleel.attributes[i].name.toLowerCase() != 'style')
                        
    strAttr += String.format(strFormatel.attributes[i].nameel.attributes[i].value);
                }
            }
            
            var 
    strLink ='';
            if(
    this.printCSS){
                if(!
    Ext.isArray(this.printCSS))
                    
    this.printCSS = [this.printCSS];
                
                for(var 
    i=0i<this.printCSS.lengthi++) {
                    
    strLink += String.format(strLinkTplthis.printCSS[i]);
                }
            }
            
            
    //Build our HTML document for the iframe
            
    strHTML String.format(
                    
    strTemplate
                    
    strLink
                    
    this.printTitle
                    
    Ext.isIE'document.execCommand(\'print\');''window.print();'
                    
    strAttr
                    
    el.innerHTML
            
    );
            
            
    //I coun't get FF to print a hidden iframe,
            //so I encapsulated it in a hidden div.
            
    document.createElement('div');
            
    c.setAttribute('style','width:0px;height:0px;' + (Ext.isSafari'display:none;''visibility:hidden;'));
            
    c.setAttribute('id''printcontainer');
            
    el.appendChild(c);
            
            
    //IE doesn't like style attributes anymore?
            
    if (Ext.isIE)
                
    c.style.display 'none';
            
            
    iFrame document.createElement('iframe');
            
    iFrame.setAttribute('id''printframe');
            
    iFrame.setAttribute('name''printframe');
            
    c.appendChild(iFrame);
            
            
    //Write our new document to the iframe
            
    iFrame.contentWindow.document.open();        
            
    iFrame.contentWindow.document.write(strHTML);
            
    iFrame.contentWindow.document.close();
        }
    });

    Ext.override(Ext.Component, {
        
    printEl: function(config) {
            
    this.el.print(Ext.isEmpty(config)? this.initialConfigconfig);
        }
        , 
    printBody: function(config) {
            
    this.body.print(Ext.isEmpty(config)? this.initialConfigconfig);
        }
    }); 
    Last edited by nerdydude81; 24 Nov 2008 at 2:54 PM. Reason: Added printCSS array support provided by vtswingkid

  2. #2
    Ext User
    Join Date
    Apr 2008
    Posts
    14
    Vote Rating
    0
    kekoav is on a distinguished road

      0  

    Talking It Works Beautifully!

    It Works Beautifully!


    Thanks for that great piece of code it worked flawlessly, without any goofy setup either!

    It does exactly what it needs to do, I was going to do something similar, but glad I found you beat me to it!

    NO issues yet.

  3. #3
    Ext User
    Join Date
    Sep 2008
    Posts
    1
    Vote Rating
    0
    vasan_sr@yahoo.com is on a distinguished road

      0  

    Default


    Iam new to Ext JS. I saw your code but uanable to execute it

    Can you please explain me with an Example.

    Thanks
    VasanS

  4. #4
    Sencha User galdaka's Avatar
    Join Date
    Mar 2007
    Location
    Spain
    Posts
    1,166
    Vote Rating
    -1
    galdaka is an unknown quantity at this point

      0  

    Default


    Live example or screenshot please!!


    Greetngs,

  5. #5
    Ext User
    Join Date
    Jul 2008
    Posts
    41
    Vote Rating
    0
    nerdydude81 is on a distinguished road

      0  

    Question Usage

    Usage


    I'll see if I can get an example setup. It's usage it fairly simple

    /**
    * Prints an element on the page. Copies all attributes except
    * style, unless specified.
    * @param {node} el Element to print out
    * @param {string} style CSS Style file for printing
    * @param {number} pageWidth Page width in inches
    * @param {number} pageHeight Page height in inches
    * @param {boolean} elStyle Copy the Elements style attribute
    */

    @param {node} el Element to print out
    This is the parent container that you want printed. Everything within this node will be printed. Populate this parameter using the actual DOM node.

    Like:
    PHP Code:
      var myElement document.getElementByID('MyDiv');

      
    SS.printElement(myElement, .... 
    @param {string} style CSS Style file for printing
    Because this function copies the node to a hidden iframe, your CSS file won't be applied. To solve this I'm adding a link tag to the html in the iframe. This can also be useful if you have a different style sheet for printing. Populate this parameter with the path for your css file or make it a null string (' ' or "").

    Like
    PHP Code:
      var myElement document.getElementByID('MyDiv');
      var 
    cssPath '/css/gridprint.css';

      
    SS.printElement(myElementcssPath, .... 
    @param {number} pageWidth Page width in inches
    @param {number} pageHeight Page height in inches
    The page size is self explainitory

    Like
    PHP Code:
      var myElement document.getElementByID('MyDiv');
      var 
    cssPath '/css/gridprint.css';
      var 
    pageWidth 8.5;
      var 
    pageHeight 11;

      
    SS.printElement(myElementcssPathpageWidthpageHeight, .... 
    @param {boolean} elStyle Copy the Elements style attribute
    Because this function copies all the attributes on the Element node, I chose to exclude the style attribute; however if it's needed set this parameter to true.

    Like
    PHP Code:
      var myElement document.getElementByID('MyDiv');
      var 
    cssPath '/css/gridprint.css';
      var 
    pageWidth 8.5;
      var 
    pageHeight 11;

      
    SS.printElement(myElementcssPathpageWidthpageHeighttrue); 
    For Extjs you could do something like
    PHP Code:
      var myPanel = new Ext.Panel({some stuff here});

      
    SS.printElement(myPanel.getEl().dom'/css/gridprint.css'8.511true); 
    Hope this helps out.

  6. #6
    Sencha User TopKatz's Avatar
    Join Date
    Mar 2007
    Posts
    337
    Vote Rating
    1
    TopKatz is on a distinguished road

      0  

    Default


    Is there another part to configuring this for use? Im getting a "SS is not defined" error with it.

  7. #7
    Ext User
    Join Date
    Jul 2008
    Posts
    41
    Vote Rating
    0
    nerdydude81 is on a distinguished road

      0  

    Cool SS is not defined

    SS is not defined


    You can take the SS off, change it, declare it or add it's namespace to Ext via Ext.namespace("SS"). Some people here are using the Ext.ux namespace, I'll update the code to make it easier. SS is just the initials for my company.

  8. #8
    Sencha User TopKatz's Avatar
    Join Date
    Mar 2007
    Posts
    337
    Vote Rating
    1
    TopKatz is on a distinguished road

      0  

    Default


    I actualy had tried that with more success, but I was still getting errors. I figured out the problem. You have what looks like a type-O in the code.

    Code:
    for (var I = 0; I < el.attributes.length; I++) {
            if (elStyle? elStyle: el.attributes[i].name.toLowerCase() != 'style') {
                strAttr += String.format('{0}="{1}" ', el.attributes[i].name, el.attributes[i].value);
            }
        }
    should be:

    Code:
    for (var i = 0; i < el.attributes.length; i++) {
            if (elStyle? elStyle: el.attributes[i].name.toLowerCase() != 'style') {
                strAttr += String.format('{0}="{1}" ', el.attributes[i].name, el.attributes[i].value);
            }
        }
    the upper case "I" should be "i"

    BTW: this only seams to work once per page load. Any reason in particular for that?

  9. #9
    Sencha User Tasm's Avatar
    Join Date
    Nov 2007
    Location
    Kazakhstan, Almaty
    Posts
    10
    Vote Rating
    0
    Tasm is on a distinguished road

      0  

    Default


    Hi sorry for my english, i dont test this extension yet, but i think will be cool to override Ext.Element for add method print:
    Code:
    Ext.override(Ext.Element, {
       print: function(style, pageWidth, pageHeight, elStyle) {
          var el = this.dom;
          ...
       }
    });
    And use so:
    Code:
    var myEl = Ext.Element({...})
    myEl.print(style, pageWidth, pageHeight, elStyle);

  10. #10
    Ext User
    Join Date
    Jul 2007
    Posts
    3,128
    Vote Rating
    0
    devnull has a little shameless behaviour in the past

      0  

    Default


    Pretty cool stuff
    I would highly recommend using a config object rather than params though since everything else in Ext uses this pattern wherever possible.
    Code:
    SS.printElement({
      element: myElement, //having this accept an Ext.element reference or a string id might be nice too
      pageWidth: 200,
      pageHeight: 400,
      //etc
    })