Better way to load scripts and CSS using javascript - javascript

I generate some telerik reports on a page which I would like to print when the user clicks "Print". I would like to have a popup window which has the same content as the original report with a print dialog. My current approach is to just copy over the head element using document.write. The problem is that since the head element contains script src which loads external script (and also css loads), when the print dialog appears, the pages are blank. I would like to ensure all the content is loaded first on this new page before print dialog is triggered. How can I do this? Below is my code:
function printElem(elem) {
var mywindow = window.open('', 'PRINT', 'height=600,width=800');
mywindow.document.write('<html><head>' + document.head.innerHTML + '</head><body>');
mywindow.document.write('<h1>' + document.title + '</h1>');
mywindow.document.write(document.getElementById(elem).innerHTML);
mywindow.document.write('</body></html>');
mywindow.print();
return true;
}

Unfortunately, there's no way to build up a page that you'll reveal with window.open. You have two options.
First, you could display a loading view that will be hidden once all the other elements have loaded. This is perhaps the most elegant solution if you're committed to opening another popup.
<div id="loader"><img src="loading.gif /></div>
<div id="content" style="display:none">Stuff to print</div>
<script>
<!-- I know jQuery is taboo nowadays, but you get the idea -->
$(function() {
$('#loader').hide();
$('#pagecontent').show();
});
</script>
Another trick is to write the content and close the window immediately afterward. (I'm not certain if this works on all browsers.)
var css = document.getElementById('the-stylesheet');
var content = document.getElementById('the-content');
var mywindow = window.open('', 'PRINT', 'height=600,width=800');
mywindow.document.write(content.innerHTML);
mywindow.document.close();
mywindow.document.head.appendChild(css);
css.addEventListener('load', function () {
mywindow.focus();
mywindow.print();
});
If you're willing to forgo a popup, another trick would be to use print specific styling on the page.
<style>
#media print {
/* Hide everything you don't need here */
}
</style>

You can use onload event on the new window.
function printElem(elem) {
console.log('new window')
var mywindow = window.open('', 'PRINT', 'height=600,width=800');
// Add this function here
function printWindow(){
console.log('loaded my window');
mywindow.print();
}
// call it once the new window is loaded.
mywindow.document.onload = printWindow();
mywindow.document.write('<html><head>' + document.head.innerHTML + '</head><body>');
mywindow.document.write('<h1>' + document.title + '</h1>');
mywindow.document.write(document.getElementById(elem).innerHTML);
mywindow.document.write('</body></html>');
return true;
}
It may help..

Related

window.print() gives no only selected option

When using print from Google Chrome one can select an option in the dialog to make Chrome only print the contents that is selected. But when I fire
window.print()
from the console after setting a selection on the page I don't get this option. Is there some way to make this option appear? Or is this impossible?
Thats correct as far as i'm aware you cant make the dialogue appear, you can however print specific html content, here's an example of how to do so :-
function PrintElem(elem)
{
var mywindow = window.open('', 'PRINT', 'height=400,width=600');
mywindow.document.write('<html><head><title>' + document.title + '</title>');
mywindow.document.write('</head><body >');
mywindow.document.write('<h1>' + document.title + '</h1>');
mywindow.document.write(document.getElementById(elem).innerHTML);
mywindow.document.write('</body></html>');
mywindow.document.close(); // necessary for IE >= 10
mywindow.focus(); // necessary for IE >= 10*/
mywindow.print();
mywindow.close();
return true;
}
elem being the HTML container of the content you want to print.

Window.open not displaying anything after adding iframe tag

I am trying to open a new window using window.open with dynamic content (for print functionality I am using this dynamic content).
Below dynamic HTML is not visible on window.open page where as in view source it is available. Please help me out why it is not getting displayed there.
Below is the code.
var win = window.open('', 'title', 'toolbar=0,location=0,menubar=0,resizable=yes,width=' + (screen.width - 100) + ', height=' + (screen.height - 150));
win.document.write("<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>");
win.document.write("<html>");
win.document.write("<head><title>title</title>");
win.document.write('<script language="javascript" type="text/javascript">function printPage() { PrintDiv("defaultPrintBuffer"); }<\/script>');
win.document.write('</head>');
win.document.write('<body>');
win.document.write("<iframe width='560' height='315' id='defaultPrintBuffer2' name='defaultPrintBuffer2'>");
win.document.write(iframeContent);
win.document.write("</iframe>");
win.document.write('</body>');
win.document.write("</html>");
win.document.close();
win.focus();
win.printPage();
Since you mention that you're trying to implement printing, I'll add how I solved this problem in an answer instead of a comment, so the code is more readable.
Basically I made an empty (but valid) html page and just insert nodes into that page before printing it. This avoids the use of document.write and iframes, which are considered bad practice in alot of cases. If you really want to use an iframe, just add the iframe to the print page html and append your content to that node instead of to the body.
var data = $('myPartOfPageSelector'),
printPage;
if (!data || !data.length) alert('Nothing to print.');
else {
printPage = window.open('resources/print.html');
setTimeout(function() {
printPage.document.body.innerHTML = data.innerHTML;
printPage.print();
printPage.close();
}, 100);
}
The iframe tag doesn't show the content that you put in it, you have to load a page in the iframe.
You could use a script to put content in the iframe:
win.document.write("<iframe width='560' height='315' id='defaultPrintBuffer2' name='defaultPrintBuffer2'>");
win.document.write("</iframe>");
win.document.write("<script type='text/javascript'>var doc = document.getElementById('defaultPrintBuffer2').contentWindow.document;doc.open();doc.write('" + iframeContent.replace("'","\\'").replace("\\","\\\\") + "');doc.close();</script>");
Note that the content should be a complete HTML document in itself.

open iframe src to new page

My web page opens app.html first.After clicking to login i need to open index.html which i open in iframe and i dynamically create iframe in javascript.so to open that i frame im appending to document.body.But it appends to the body of the app.html.But I need to open in new page
var el = document.createElement("iframe");
el.setAttribute('id', 'ifrm');
el.setAttribute('name', 'ifrm');
el.setAttribute('src', '/index/index.html');
el.setAttribute('width', '100%');
el.setAttribute('height', '100%');
el.setAttribute('scrolling', 'no');
document.body.appendChild(el);
You could use this to open in a new window:
var myWindow = window.open("/index/index.html");
You would have to layer the iframe over the current page
el.style.position = 'absolute';
el.style.top = 0;
el.style.left = 0;
You question is a bit unclear as to what you are trying to do. The answer all depends on things like:
Are you trying to open index.html in addition to app.html or instead of it?
If you want both open, then do you want to open in a new window?
If so, do you want a regular window (i.e. same size as the original, without modification). Yes, then use JavaScript:
newWin = window.open("index.html", "My App's Main Window", winOptions);
or a specific size window, with other modifications (no Navigation bar, No address bar, etc) - in other words do you want a Popup Window
<html>
<head>
<title>JavaScript Popup Example</title>
<script type="text/javascript">
function loginCheck(){
//isLoggedIn is a boolean variable you've set to check login
if (isLoggedIn) {
popup();
}
}
function popon(){
var winOptions = "";
winOptions += "location=1, ";
winOptions += "status=0, ";
winOptions += "scrollbars=0, ";
winOptions += "width=100, ";
winOptions += "height=100";
newWin = window.open(
"index.html",
"My App's Main Window",
winOptions
);
newWin.moveTo(400, 300); //300 pixels down,
//400 pixels to the right
}
</script>
</head>
<body onload="javascript: loginCheck()">
<h1>JavaScript Popup Example</h1>
</body>
</html>
Or do you want to open index.html in a new tab?
simply use the target attribute in your anchor tag with the value set to new, e.g. <a target="new"...
If you are trying to replace index.html/open in the same tab... you don't need to do anything with your href
If you want to open the content of app.html WITHIN the app.html page somehow... then you either:
Need to use an iframe (that can already be tagged in the app.html (you don't need to create it dynamically with JavaScript) and load index.html into it OR...
Use AJAX to load the page behind the scenes while app.html is STILL loaded, in the window/tab... without reloading or replacing it. Once the AJAX request completes, youi would then do something with the HTML from index.html... like:
use plain vanilla JavaScript to dynamically create a div (or show a hidden div) and fill it once index.html is loaded.
use a (jQuery) widget such as a tab/tab set or accordion and fill it when app.html is loaded

Adding parent window's CSS to child window using javascript

I'm trying to generate a pop-up window with a printable version of a small portion of the main window. I'm using Meteor, so the HTML and CSS files are all programmatically generated.
What I'd like to do is use Javascript to read all the linked CSS files in the parent window and append them to the child window.
var childWindow = window.open("", "_blank", "width=350,height=150");
var childDoc = childWindow.document;
var childHead = childDoc.getElementsByTagName("head")[0];
$('link').each(function(index,element){
childLink = childDoc.createElement("link");
childLink.rel = "stylesheet";
childLink.href = element.href;
childHead.appendChild(childLink);
});
childDoc.write(myHtml);
But its not working. It appears that childHead is referring to the head of the parent document, not the child. I'm not sure if this is a security thing I'm running afoul of or just have a mistake in the code.
Any ideas what I'm doing wrong?
I'm doing a very similar thing on one of my pages. I just use the 'parent' page to write everything and it works fine. Here is how it works for me. See this fiddle in action.
You'll notice that it only prints the stuff from the printMe div. Also, the printed page has all the same exact scripts and styles that the parent page does.
some stuff NOT to print
<div id="printMe" class="ui-selectable-helper">
I should be printed, but not the other stuff.
</div>
more stuff NOT to print
$(function(){
var printWindow = window.open('', 'printWin', 'height=600, width=900, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, directories=no, status=no');
//create a new HEAD with the exact same content as the main page
var writeMe = ('<body><head>' + $('head').html() + '</head><html>');
//grab the content of the printMe div and use it on the print page
writeMe += ("<div>" + $('#printMe')[0].outerHTML + "</div>");
writeMe += ('</html></body>');
printWindow.document.write(writeMe);
printWindow.document.close();
printWindow.focus();
printWindow.print();
//you might even use this next line if you want the 'popup' window to go away as soon as they have finished printing.
//printWindow.close();
});
Note: I am just using the class="ui-selectable-helper" to show you that indeed the CSS pages are transferring properly to the new popup window.
What ended up working for me was appending something to the body with childDoc.write(myHtml);
Previous to this, the CSS would not load, but once I actually passed in a few divs, the CSS showed up without any other modifications.

Print in the background with javascript i.e. without document pop up

Found this code to print from javascript. But it opens a window with the document to be printed. Is there a way to hide that document?
var element=document.getElementById(element_id);
var newWin=window.open('','Print-Window','width=400,height=400,top=100,left=100');
newWin.document.open();
/* newWin.document.title = "Readings on PageLinks"; */
newWin.document.write('<html><head><title>Readings on PageLinks</title></head><body onload="window.print()">'+element.innerHTML+'</body></html>');
newWin.document.close();
setTimeout(function(){ newWin.close(); },10);
The print is done onload() for that document, so I guess printing could not be done without it. But can it be hidden?
You can accomplish this using a print-specific stylesheet as described in How to print only a selected HTML element? Don't use window.open() at all; use CSS classes (dynamically applied if need be) to specify which elements should/shouldn't be printed.
Add this to your markup:
<iframe id="ifrOutput" style="display:none;"></iframe>
Add the following javascript function:
function printContainer(content, styleSheet) {
var output = document.getElementById("ifrOutput").contentWindow;
output.document.open();
if (styleSheet !== undefined) {
output.document.write('<link href="' + styleSheet + '" rel="stylesheet" type="text/css" />');
}
output.document.write(content);
output.document.close();
output.focus();
output.print();
}
And call it like so:
// with stylesheet
printHtml('<div>Styled markup</div>', 'printStyles.css');
// without stylesheet
printHtml('<div>Unstyled markup</div>');

Categories

Resources