How to print webpages with iframe and css - javascript

I have to print the contents of a dialog. I'm adding a empty iframe then i add contents to it in javascript.
this is my js code where i add html and css as children of iframe
var layoutCSS = new String('<link href="css/ReportPageOne.css" rel="stylesheet" type="text/css">');
var pageOneCSS = new String('<link href="css/ReportLayout.css" rel="stylesheet" type="text/css">');
var pageTwoCSS = new String('<link href="css/ReportPageTwo.css" rel="stylesheet" type="text/css">');
var materialityCSS = new String('<link href="css/MaterialityMatrix.css" rel="stylesheet" type="text/css">');
window.frames.print_frame.document.head.innerHTML = layoutCSS + pageOneCSS + pageTwoCSS + materialityCSS;
window.frames.print_frame.document.body.innerHTML = $('#__dialog1-cont').html();
window.frames.print_frame.window.focus();
window.frames.print_frame.window.print();
opens the print dialog properly but css is not applied quite well.
On print page in options i checked in 'Background graphichs' and i am using google chrome.

You are calling frame.print() before the styles have loaded.
"The load event fires once the stylesheet and all of its imported content has been loaded and parsed, and immediately before the styles start being applied to the content."
Try this:
head.lastChild.addEventListener("load", function (event) {
// In IE, you have to focus() the Iframe prior to printing
// or else the top-level page will print instead
frame.focus();
frame.print();
}, 0);
References
https://github.com/abbotto/teleprint/blob/master/src/components/print.js
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#Stylesheet_load_events

Related

Window.print not working for print graph

I have one page where I use java script and css to show graph.When I try to print graph using div content and opening new window it does not work.
Below is screenshot of graph page and print window
I have tried to put css before printing and also added bootstrap js but stil not work.
Below is code that I copy form stackoverflow and modify as I require.Thanks.
function printDiv() {
debugger;
var printContents = $('body').clone().find('script').remove().end().html();
// get all <links> and remove all the <script>'s from the header that could run on the new window
var allLinks = $('head').clone().find('script').remove().end().html();
var js = "";
js += "#Html.Raw(string.Format("<script src='/SkillsAssessmentModule/Scripts/bootbox.min.js'/>"))";
// open a new window
var popupWin = window.open('', '_blank');
// ready for writing
popupWin.document.open();
// -webkit-print-color-adjust to keep colors for the printing version
var keepColors = '<style>body {-webkit-print-color-adjust: exact !important; }</style>';
// writing
// onload="window.print()" to print straigthaway
popupWin.document.write('<html><head>' + keepColors + allLinks + '</head><body>' + document.getElementById("lProgress").innerHTML + js + '</body></html>');
popupWin.print();
// close for writing
popupWin.document.close();
setTimeout(function () { popupWin.close(); }, 1);
}
</script>
}

Print html page with internet explorer

I have to print a table with its style
So I'm using jQuery.copyCSS to clone its CSS,style into another element
(Because I'm testing it on IE 8 and seems like it doesn't preserve CSS after clicking/calling window.print())
https://github.com/moagrius/copycss
I thought to "send" the table to another page and call from there the print.
Thus I need to clone the css into another element (to pass on the second page)
$("#table_report").clone().attr({"id":"table_report_clone", "name":"clone"}).appendTo("body"); // doesn't matter if it appears on the page, I will just pass these one
$('#table_report_clone').copyCSS('#table_report'); // copy CSS from original to clone
var clone = $("#table_report_clone").html();
var w = window.open();
$(w.document.body).html(clone ); //table_report should be the table with its style
w.document.close();
So, passing .html it will parse only the HTML not including the style
How can I do that?
EDIT 1:
Now some icons are being displayed..however the table is really 'raw'
w.document.write(clone); // instead of $(w.document.body).html(clone);
EDIT 2:
Changed adding some tips by #Roljhon
En fact this does work on FF, Chrome, but in IE 8 nope..
(Anyway I'm using JQuery 1.5.1)
dumpCSSText is a function from
https://stackoverflow.com/a/15011387/7370271
since I have to get/join the styles attributes
$("#table_report").inlineStyler();
var table_report = document.getElementById("table_report");
var w = window.open();
var css = "" + dumpCSSText(table_report) //css of your table_content
var style = document.createElement('style');
style.type = "text/css";
style.appendChild(document.createTextNode(css));
w.document.head.appendChild(style);
w.document.body.innerHTML = document.getElementById("table_report").innerHTML
EDIT 3: Now it works
var table_report = $("#table_report").html();
var w = window.open();
w.document.write('<html><head><link rel="stylesheet" href="/i/css/apex.min.css?v=4.2.6.00.03" type="text/css" /><!--[if IE]><link rel="stylesheet" href="/i/css/apex_ie.min.css?v=4.2.6.00.03" type="text/css"/><![endif]--><link rel="stylesheet" href="/i/libraries/jquery-ui/1.8.22/themes/base/jquery-ui.min.css" type="text/css" /></head><body>');
$(w.document.body).html(table_report);
w.document.write('</body></html>');
w.document.close();
w.focus();
w.print();
w.close();
Finally I'm now at 90%..the only problem is CSS in IE8..
Thank you
I tried to create a solution to your problem and this could possibly solve it or give you an idea of what to do to pass your table css.
Option 1
You could create a link to the stylesheet.Create it directly from your javascript. But make sure that the stylesheet content is the exact CSS of the table_content and append this to the head section of the new window and at the same time write your table in the body part of the new window.
var link = document.createElement('link');
link.rel = "stylesheet";
link.href ="table_content_style.css"; // this will have your table_content_clone CSS
w.document.head.appendChild(link);
w.document.body.innerHTML = "<h1>test</h1>"; // your html table markup
Option 2
You could create the stylesheet as well directly from javascript and doing the same thing as above.
var css = "body{background-color: red;}"; //css of your table_content
var style = document.createElement('style');
style.type="text/css";
style.appendChild(document.createTextNode(css));
w.document.head.appendChild(style);
w.document.body.innerHTML = "<h1>test</h1>"; // your html table markup
I hope that helps. See fiddle: https://jsfiddle.net/0vzwzrpq/
The best approach to style elements you'd like to print is to use CSS media queries.
#media print {
body {
background-color: pink;
}
}
There is a very good article here about the subject: https://www.smashingmagazine.com/2011/11/how-to-set-up-a-print-style-sheet/

How to enable HTML import in other browsers using polymer?

As title, I used a HTML import link in my site:
<link rel="import" href="http://XX.XX.XX.XX/">
<script type="text/javascript">
var link = document.querySelector('link[rel="import"]');
var content = link.import;
// Grab DOM from warning.html's document.
var el = content.querySelector('body');
</script>
The variance "link" returns a document in Chrome, but returns null in Safari and other browsers. I know HTML import function is only supported by Chrome so far, so I added the following code before import link to load Polymer's webcomponents.js:
<script src="../webcomponentsjs/webcomponents-lite.js"></script>
but it still returns null in other browsers, can anybody tell me how to fix it?
It's because the <link> request is asynchonous.
Catch the HTMLImportsLoaded event, to parse the file only when it is loaded by the browser:
<script src="../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="http://XX.XX.XX.XX/XX/warning.html">
<script type="text/javascript">
window.addEventListener( "HTMLImportsLoaded", function ()
{
var link = document.querySelector('link[rel="import"]');
var content = link.import;
// Grab DOM from warning.html's document.
var el = content.querySelector('body');
} )
</script>

Modal menu issues using ratchet framework (twitter-bootstrap)

I'm building a mobile app using ratchet, and I love the toolset so far, but I'm running into an issue using a modal as a menu.
Here's the live index page.
This is the only custom js I'm using:
$(document).ready(function() {
if ((navigator.userAgent.match(/Android/i))) {
$('head').append('<link rel="stylesheet" href="css/ratchet-theme-android.min.css" type="text/css" />');
var plainAddress = $("#appAddress").text().replace(/\s+/g, "+");
var paramAddress = encodeURI(plainAddress);
var urlAddress = ('geo:0,0+?q=' + paramAddress);
$('#appLink').attr('href', urlAddress);
} else {
$('head').append('<link rel="stylesheet" href="css/ratchet-theme-ios.min.css" type="text/css" />');
var plainAddress = $("#appAddress").text().replace(/\s+/g, "+");
var paramAddress = encodeURI(plainAddress);
var urlAddress = ('http://maps.apple.com/?q=' + paramAddress);
$('#appLink').attr('href', urlAddress);
};
});
$.get('modal/qrModal.html', function(qr) {
$("#loadedModals").append(qr);
});
$.get('modal/menuModal.html', function(qr) {
$("#loadedModals").append(qr);
});
The rest is ratchet.js from goratchet.com. I'm pulling in the menu and the qr code via js because they're not unique to every page. The menu though when launched works fine, and when a selection is made the first time, it follows through, loads the page, and closes the modal.
After that it get's finicky.
Sometimes the modal won't load, sometimes it's unresponsive, sometimes it loads, loads a newpage but doesn't exit the modal.
Is this because I've exported it to external pages? Or is something else the matter?
It looks like your loadedModals container is being cleared out, and not repopulated after a new page is loaded via push.js.
<div id="loadedModals">
...
</div>
You can reload the modals after each push event by firing a callback.
var loadModal = function(){
$.get('modal/qrModal.html', function(qr) {
$("#loadedModals").append(qr);
});
$.get('modal/menuModal.html', function(qr) {
$("#loadedModals").append(qr);
});
};
loadModal();
window.addEventListener('push', loadModal);

Javascript document.title doesn't work in Safari

I'm using Safari 6.0.5.
I open a new empty window, try to change the title to 'debug window', nothing happens. With a check function checking every 10 milliseconds, it says the window.document.title is 'Debug Window', still the new Window title bar says it is 'untitled'.
var debug_window = window.open('', 'debug_window', 'height=200');
debug_window.document.title = 'Debug Window';
function check()
{
debugLog(1, 'title:' + debug_window.document.title);
if(debug_window.document) { // if loaded
debug_window.document.title = "debug_window"; // set title
} else { // if not loaded yet
setTimeout(check, 10); // check in another 10ms
}
}
check();
The output in the debugLog is:
17:35:04.558: title:
17:35:04.584: title:debug_window
What is going wrong here that the new window is still called 'untitled'?
Thanks!
Now the second argument to window.open() is a frame/window-name and serves also as the default title. This is eventually overridden by the document loaded into this window. Opening the document-stream and inserting a basic html-document should serve the purpose:
var debug_window = window.open('', 'debug_window', 'height=200');
debug_window.document.open();
debug_window.document.write('<!DOCTYPE html>\n<html lang="en">\n<head>\n<title>Debug Window</title>\n</head>\n<body></body>\n</html>');
debug_window.document.close();
var debug_body = debug_window.document.getElementsByTagName('body')[0];
// write to debug_window
debug_body.innerHTML = '<p>Message</p>';
So you would be setting up a basic document inside the window, just as it would be loaded by the server (by writing to the "document stream"). Then you would start to manipulate this document like any other.
Edit: Does not work in Safari either.
Other suggestion: set up a basic document (including the title) on the server and inject the content into its body on load. As a bonus, you may setup CSS via stylesheets.
var debug_window = window.open('debug_template.html', 'debug_window', 'height=200');
debug_window.onload = function() {
var debug_body = debug_window.document.getElementsByTagName('body')[0];
debug_body.innerHTML = '...';
// or
// var el = document.createElement('p');
// p.innerHTML = '...';
// debug_body.appendChild(p);
debug_window.onload=null; // clean up cross-reference
};
And on the server side something like
<!DOCTYPE html>
<html lang="en">
<head>
<title>Debug Window</title>
<link rel="stylesheet" href="debug_styles.css" type="text/css" />
</head>
<body></body>
</html>
If this still should not work (e.g.: writing to the debug-window's document is without effect), you could call your app from inside the debug-window by something like:
<body onload="if (window.opener && !window.opener.closed) window.opener.debugCallback(window, window.document);">
</body>
(So you would check if the opener – your App – exists and hasn't been closed in the meantime and then call a callback-function "debugCallback()" in your app with the debug-window and its document as arguments.)
Try:
var debug_window = window.open('about:blank', 'debug_window', 'height=200');

Categories