Member Avatar for benhowdle89

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

Member Avatar for fxm

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.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.