Opening inline div in new window with javascript - javascript

I am using a previous question in SO to help me with this "open-in-new-window" javascript function:
Copy div And his style to new window
So my goal is to open an inline div in a new window and then to be able to print the new window (the div I want to open in the new window is a coupon).
I've accomplished styling the div (to look like a coupon) and set the javascript so that the div does indeed open in a new window, but
1) ...I can't get the style sheet to link to the new window,
2) ...and, I can't get the new window to print (instead nothing happens when I click to print the new window - but when I close the new window, the print dialogue box appears.
here is the code I'm using so far, any help is greatly appreciated:
$('#printCoupon').bind('click', function () {
var printContents = new $("#coupon").clone();
var myWindow = window.open("", "popup", "width=600,height=380,scrollbars=yes,resizable=yes," +
"toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0");
var doc = myWindow.document;
doc.open();
$(printContents).find("#printCoupon").remove();
doc.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
doc.write("<html>");
doc.write("<head>");
doc.write("<link href='http://[link-to-css]/css/coupon.css' rel='stylesheet' type='text/css' />"); // your css file comes here.
doc.write("</head>");
doc.write("<body>");
doc.write($(printContents).html());
doc.write("</body>");
doc.write("</html>");
});
and my html:
<div id="couponWrap">
<div id="coupon">
<h3>Coupon Title</h3>
<p>Present this coupon and receive $10 off labor on your first service visit and 2% loyalty points on you next visit.</p>
</div>
Click to print this coupon.
</div>
Thank you,
Cindy

As far as writing, try the following (removed doc.open() and removed popup argument):
$('#printCoupon').bind('click', function () {
var printContents = new $("#coupon").clone();
var myWindow = window.open("", "", "width=600,height=380,scrollbars=yes,resizable=yes," +
"toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0");
var doc = myWindow.document;
$(printContents).find("#printCoupon").remove();
doc.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
doc.write("<html>");
doc.write("<head>");
doc.write("<link href='http://[link-to-css]/css/coupon.css' rel='stylesheet' type='text/css' />"); // your css file comes here.
doc.write("</head>");
doc.write("<body>");
doc.write($(printContents).html());
doc.write("</body>");
doc.write("</html>");
});

Did you check any issues based on whether your styles are element specific or not #media print? Go back to the reference you gave on where you based your example. Someone else commented this - maybe this is your issue:
It depends on the way the div is styled. If the styles are applied
based on the ID or class then you should be fine to just include the
same stylesheet in the new window. However if any of the styles are
based on the element's ancestors then it becomes tricky as you would
have to copy the ancestral elements in order for the exact styles to
be applied.
It sounds like you ought to be using print-specific styles. You can
apply a stylesheet to print only by including the media="screen"
attribute on the stylesheet link. This stylesheet is then responsible
for hiding any elements in the page that you don't want to print and
positioning the ones that you do. This way you are not subject to
popup blockers and give the user one less step to print the document.

Here is my solution thus far - the javascript stripped the divs from the HTML when opening in a new window, so I simply rewrote the div's back into the new window:
(does anyone know how to write the javascript to have multiple inline DIVs open in a new window when the inline DIVs are on the same webpage? I would need to dynamically generate the IDs, I believe in the code below and in the HTML.)
$('#printCoupon').bind('click', function () {
var printContents = new $("#coupon").clone();
var myWindow = window.open("width=600,height=380");
var doc = myWindow.document;
$(printContents).find("#printCoupon").remove();
doc.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
doc.write("<html>");
doc.write("<head>");
doc.write("<link href='http://linktocssfile.css' rel='stylesheet' type='text/css' />"); // your css file comes here.
doc.write("</head>");
doc.write("<body>");
doc.write("<div id='coupon'>");
doc.write($(printContents).html());
doc.write("</div>");
doc.write("</body>");
doc.write("</html>");
});

Related

Javascript overwrites data on screen and refreshes page

I have been working on a project that I just need to print the contents of a hidden div. The below solution works fine, but replaces the page contents with the div then calls the print of the window and then replaces the page with the original contents. This is fine, but when I click on the page after this or try to print again, the page refreshes.
Is there a way, without opening a new window to print the contents of a div and the page still be functional?
$scope.printDiv = function(printable) {
var restorePage = document.body.innerHTML;
var printContent = document.getElementById(printable).innerHTML;
document.body.innerHTML = "<html><head><title></title></head><body>" + printContent + "</body>";
window.print();
document.body.innerHTML = restorePage;
};
I had created a directive that did something much like this. It involves creating a new window, populating it with the HTML you want printed, printing that window, and then finally closing.
The code looks like the following:
$scope.printPage = function() {
var pageToPrint = $window.open('', 'Print Page', 'width=800, height=600');
pageToPrint.document.write(angular.element(pageHtml).html());
pageToPrint.document.close();
pageToPrint.focus();
pageToPrint.print();
pageToPrint.close();
}
This works in all of the browsers and cleanly closes everything out once the user finishes with the print dialog window.
You can do it with CSS: https://stackoverflow.com/a/356123/1516112
When the user click on your button, wrap your entire page inside a div using the .no-print class. Next add your content in another div next to the previous div. Call print() and restore your page. It should works.
See a similar question that I found: AJAX - Print Page Content
It seems the answer of Matt Razza is what You are looking for.
If you're trying to print invisible content you could use two
different css files for the different media (screen vs print) where
you hide/unhide the required content via display: none; and then
spawn the print dialog via window.print().
<link rel="stylesheet" type="text/css" href="theme1.css" media="screen" />
<link rel="stylesheet" type="text/css" href="theme2.css" media="print" />
<div class="hidden_on_page">YOU CAN'T SEE ME BUT YOU CAN PRINT ME!</div>
<div class="on_page">YOU CAN SEE ME BUT YOU CAN'T PRINT ME</div>
Then in theme1.css:
.hidden_on_page { display: none; }
theme 2.css:
.on_page { display: none; }
And you would trigger the print dialog to spawn when required via:
window.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

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>');

javascript nullifies when setting the document.body.innerHTML

Good day.
I am currently working on a project that prints a desired <div> to a printer.
Here is the code:
var printContents = document.getElementById(id).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
document.body.style.display = "none";
window.print();
document.body.innerHTML = originalContents;
document.body.style.display = "block";
This code works and prints the desired <div>, but after that I need to put back the previous page again so I used this statement:
document.body.innerHTML = originalContents;
document.body.style.display = "block";
This displays the previous page but the functionalities of my buttons are gone?! Can someone explain to me what happened and is there a solution to this problem? Thanks in advance!
This is happening because you've wiped out the old DOM which had events wired up to it, and replaced it with a totally new, different DOM that just happens to have the same HTML.
Presumably you're taking this approach because the printable zone is determined at runtime. A less-destructive solution might be to create a new <iframe> and copy the desired markup into that; then invoke print() on the iframe. Something like:
var printElement = function(element) {
var frame = document.createElement('iframe');
document.appendChild(frame);
frame.contentDocument.innerHTML = element.innerHTML;
frame.contentWindow.print();
document.removeChild(frame);
};
You'll also need to copy over any CSS references into the <iframe>.
(note this is pseudo-code and not tested)
Your code clears the document and then puts back the HTML stored in originalContents, but this variable stores only a string, so all previously registered event handlers are gone.
Why don't you create a print stylesheet and hide everything except the content that you want to print?
<link rel="stylesheet" type="text/css" href="print.css" media="print">
When you reset the innerHTML, you don't get all your event handlers back. They are wiped out when you create entirely new DOM elements.
One idea would be to have two master divs in the body, one that is your normal display and one that is what you want to print. You can then hide whichever one you don't want to display like this:
<body>
<div id="mainContent">main screen content goes here</div>
<div id="printContent">generated print content goes here</div>
</body>
// hide main content
var mainDiv = document.getElementById("mainContent");
mainDiv.style.display = "none";
// put content to print in the print div and show it
var printDiv = document.getElementById("printContent");
printDiv.innerHTML = document.getElementById(id).innerHTML;
printDiv.style.display = "block";
// print
window.print();
// restore visibility
mainDiv.style.display = "block";
printDiv.style.display = "none;
You could also just use the whole body for printing and use a stylesheet with media="print" to control the visibility of the things you do/don't want to print.
You can add a click event to all dives inside your page so that user can click the div.
after that add a class to that div which the class is defined within the print CSS file.
inside css print file use the following code:
`*{display:none}
.printableDiv{display:block}`
to define a print css file use this code :
<link rel="stylesheet" type="text/css" href="print.css" media="print"> (which Rafael has told you ).
good luck

Categories

Resources