0

I've setup a javascript window.open bit of script to print one div.

Is it possible to style the div with css that gets printed, no matter what styling i put around the div, they disappear when i press the print button and it opens this new window with the div in it...

Any advice,

Thanks

2
Contributors
1
Reply
4
Views
7 Years
Discussion Span
Last Post by fxm
0

print one div

Well, there's good news and mediocre news.

The good news is that this page http://home.comcast.net/~judysgames/directory.htm shows code I wrote for this very purpose in action. It works in Firefox/Chrome/Safari(pc)/Opera and IE8/7/6.

The mediocre news is that I haven't finished making a context-free version that can be posted here as a code snippet.

The pieces that you need [all found in that page] are:
1. the call

<form>
          <button onclick="printNodeById('players')">Pop<br />
          Print</button>
        </form>

2. the 'window' function

function printNodeById(sId) {
    var oPrt = document.getElementById(sId);

    if (window.opera && oPrt.offsetHeight > 800) { // opera screws up on 'very tall' windows
        _oPrp = window.open('', "printpreview", 
		"location=no,height=" + (32 + 800) + ", width=" + (32 + oPrt.offsetWidth));
    } else {
        _oPrp = window.open('', "printpreview", 
		"location=no,height=" + (32 + oPrt.offsetHeight) + ", width=" + (32 + oPrt.offsetWidth));
    }

    if (!document.importNode) {

        _oPrp.document.body.style.cursor = "wait";

        // import CSS
/* process STYLE elements approach */

        var oPrH = _oPrp.document.getElementsByTagName("head")[0];
        var cStyls = document.getElementsByTagName('style')
        //	if cStyls.length > limit there will be a problem when StyleSheet is created

        for (var j = cStyls.length, i = 0; i < j; ++i) {
            oPrH.appendChild(_importNode(cStyls[i], true));
        }

/* process existing StyleSheets approach 
	this code absolutely works (in IE8, at least) but since I thought it would be
	necessary to process 'excess' STYLE elements [>31 or >26 or whatever] it
	seemed to make more sense to do it all this way; now, however, it begins
	to look as though 'over the limit' STYLE elements may not be possible

			var oPrH = _oPrp.document.getElementsByTagName("head")[0];

			for (var j=document.styleSheets.length,i=0;i<j;i++) { 
//				var oStyl = _oPrp.document.createStyleSheet(); // number limited [?31 or ?26] so why bother

 				var oStyl = _oPrp.document.createElement('STYLE');  // needed after limit anyway
				oPrH.appendChild(oStyl);
// appending oStyl to 'head' here makes
// oStyl.styleSheet available immediately

				with(document.styleSheets[i]) {

				    oStyl.href = href; 
				    oStyl.media = media; 
				    oStyl.title = title; 
				    oStyl.disabled = disabled; 
				    oStyl.type = type; 	// [evidently read-only in StyleSheet]
//					    			// ?? what about link, rel
				    for (var k=rules.length,ii=0;ii<k;ii++) {

//   I gave up on this approach (in favor of the STYLE-element approach, above) becuase IE6 locks up 
//   ('invalid pointer' error) when attempting to copy a [probably 'empty'] rule based on CSS like
//			tr.idx {page-break-after: avoid}
//   [which IE6 evidently thinks is not 'legal']

					if (!rules[ii].selectorText) oStyl.styleSheet.addRule("*",rules[ii].style.cssText);
					else oStyl.styleSheet.addRule(rules[ii].selectorText,rules[ii].style.cssText);

				    } // for k
				}  // with
			}; // for j

//			appendChild() NOT here - either already done above [STYLE] or not needed at all [createStyleSheet]

*/

        _oPrp.document.body.appendChild(_importNode(oPrt, true));

        _oPrp.document.body.style.cursor = "default";

    } else {

        _oPrp.document.body.appendChild(_oPrp.document.importNode(oPrt, true));

        // import CSS 
/* process STYLE elements approach */

        var oPrH = _oPrp.document.getElementsByTagName("head")[0]
        var cStyls = document.getElementsByTagName('style')
        for (var j = cStyls.length, i = 0; i < j; ++i) {
            oPrH.appendChild(_oPrp.document.importNode(cStyls[i], true));
        }

        if (window.opera) { // apparently opera doesn't act on imported classes automatically
            var cEls = _oPrp.document.getElementsByTagName('*');
            for (var j = cEls.length, i = 0; i < j; i++) cEls[i].setAttribute('class', cEls[i].getAttribute('class'));
        }

        //  copy item not imported by at least one browser
        var cTAs = document.getElementsByTagName('textarea');
        for (var j = cTAs.length, i = 0; i < j; ++i) {
            _oPrp.document.getElementById(cTAs[i].getAttribute('id')).value = cTAs[i].value;
        }

        //  copy item not imported by at least one browser
        var cSels = document.getElementsByTagName('select');
        for (var j = cSels.length, i = 0; i < j; ++i) {
            _oPrp.document.getElementById(cSels[i].getAttribute('id')).selectedIndex = cSels[i].selectedIndex;
        }

        // Safari(pc) radio: actual 'checked' is lost depending 
        // on position relative to default 'checked' in group
        var cInps = document.getElementsByTagName('input');
        for (var j = cInps.length, i = 0; i < j; ++i) {
            if (cInps[i].type == 'radio') _oPrp.document.getElementById(cInps[i].getAttribute('id')).checked = cInps[i].checked;
        }
    }

    _oPrp.focus();
    _oPrp.print();
    _oPrp.close();
}

3. my _importNode() [which fills in for the importNode() method missing from IE]

// _importNode() needed for IE 
if (!document.importNode) {
    function _importNode(oNode, bImportChildren) {
        var oNew;
        with(oNode) {

            switch (nodeType) {
                // HTML 
                //   TEXT_NODE          = 3;
                //   ELEMENT_NODE       = 1;
                //   ATTRIBUTE_NODE     = 2;  [not accessed as a node]
                //   COMMENT_NODE       = 8;  [ignored; not printable]
            default:
                alert('nodeType ' + nodeType + ' not handled');
                break;
            case 3:
                oNew = _oPrp.document.createTextNode(nodeValue);
                break;
            case 1:
                oNew = _oPrp.document.createElement(nodeName);

                if (nodeName != "TEXTAREA") {
                    if (nodeName == 'INPUT') {
                        oNew.type = type;
                        if (type == 'radio' || type == 'checkbox') {
                            oNew.setAttribute('defaultChecked', checked)
                        } // ?? IE8 only
                    }
                    if (nodeName == 'STYLE') {
                            // in this approach oNew hasn't been 
                            // appended to 'head' at this stage
                            // so oNew.styleSheet isn't available
                        var oStyl = _oPrp.document.createStyleSheet(); // limit [?31 or ?26]
                        var rls = innerHTML.match(/.+{.+}/g);
                        for (var j = rls.length, i = 0; i < j; i++) {
                            var k = rls[i].indexOf('{');
                            oStyl.addRule(rls[i].substring(0, k), rls[i].substring(k)) // ?? 4095 limit [counting , splits]
                        }
                    }
                    for (var j = attributes.length, i = 0; i < j; i++) {
                        if (attributes[i].nodeValue != null && attributes[i].nodeValue != '') {
                            // _classIE is set globally to 'class' [IE 8] or 'className' [lt IE 8]
                            if (attributes[i].name == 'class') oNew.setAttribute(_classIE, attributes[i].value);
                            else oNew.setAttribute(attributes[i].name, attributes[i].value);
                        }
                    }
                } // !TEXTAREA
                if (style && style.cssText) oNew.style.cssText = style.cssText;

                if (bImportChildren && hasChildNodes()) {
                    for (var oChild = firstChild; oChild; oChild = oChild.nextSibling) {
                        oNew.appendChild(_importNode(oChild, true));
                    }
                }
            } // switch
        } // with
        return oNew;
    } // function
} // (!document.importNode

4. a couple of essential bits of overheard

<script language="JavaScript" type="text/javascript">
//<![CDATA[
_classIE='class';  // default to IE8
    //]]>
    </script>

<!--[if lt IE 8]>
    <script language="JavaScript" type="text/javascript">
//<![CDATA[
_classIE='className';
    //]]>
    </script>
<![endif]-->

Put #4, #3, and #2 (in that order) as <script> in the HEAD of your page.
Put #1 in the BODY [changing the parameter in the onclick= function call to use the id of your desired node].

You should be good to go on the first click.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.