Onclick event, print divs. how to Exclude class name - javascript

This question is a little add for this Stackoverflow question Here I ended up with this code.
<script type="text/javascript">
//Simple wrapper to pass a jQuery object to your new window
function PrintElement(elem){
var data = '';
$(elem).each(function() {
data = data + $(this).html();
});
Popup(data);
}
//Creates a new window and populates it with your content
function Popup(data) {
//Create your new window
var w = window.open('', 'Print', 'height=400,width=600');
w.document.write('<html><head><title>Print</title>');
//Include your stylesheet (optional)
w.document.write('<link rel="stylesheet" href="add/css/layout.css" type="text/css" />');
w.document.write('<link rel="stylesheet" href="add/css/main.css" type="text/css" />');
w.document.write('</head><body>');
//Write your content
w.document.write(data);
w.document.write('</body></html>');
w.print();
w.close();
return true;
}
</script>
that when i tricker the
onclick="PrintElement('.PrintElement')">Print
I can print out some divs with the class="PrintElement" my question is now...
If i have some elements inside the DIV that i dont want to print out, how can i then add a class="NOprintelement" so the code know that the elements with this class, need to be excluded in the print event ?

Without knowing more details, you should probably try to hide DOM elements using css media queries. For example, if you have a div with class = 'hideWhenPrinting', your CSS could include:
#media print {
.hideWhenPrinting { display: none }
}
See this related question:
How do I hide an element when printing a web page?

Related

Css not working in javascript print function

I have a javascript function to print a especific div called by a button.It works like i want but without styling.The problem is when i try to add the div style to the function,the print preview show a blank page in Chrome(Firefox works well).My function code is:
function printDiv(event) {
var DocumentContainer = document.getElementById("page-wrap");
var html = '<html><head>'+
'<link href="./css/style.css" rel="stylesheet" type="text/css"/>'+
'</head><body style="background:#ffffff;">'+
DocumentContainer.innerHTML+'</body></html>';
var WindowObject = window.open("", "PrintWindow",
"width=750,height=650,top=50,left=50,toolbars=no,scrollbars=yes,status=no,resizable=yes");
WindowObject.document.writeln(html);
WindowObject.document.close();
WindowObject.print();
WindowObject.close();
}
Anyone can help me?
Use the css media query
#media print
And apply styles you want in print
setTimeout(function() { objWin.print(); objWin.close(); }, 100);

Dreamweaver CS5.5 and Fancybox 1.3.4

I'm using Dreamweaver CS5.5 and Fancybox 1.3.4.
I've placed 4 images in a main div (2 in each row) and they fitted perfectly together (I don't want gaps as together the 4 images form one pic) till I applied fancybox to them.
Now there's a horizontal margin of about 20px between the 2 rows and I can't find where it's coming from. Any ideas? Do I need to paste the code here?
Be gentle – I'm primarily a print designer, so I'm learning dev as I go along. Thanks.
I have this in the head tag:
<script type="text/javascript" src="code.jquery.com/jquery-latest.min.js"></script>; <link href="jquery.fancybox-1.3.4/fancybox/jquery.fancybox-1.3.4.css" rel="stylesheet" type="text/css"> <link href="jquery.fancybox-1.3.4/style.css" rel="stylesheet" type="text/css">
And this before the closing body tag:
<script type="text/javascript">
$(function($){
var addToAll = false;
var gallery = false;
var titlePosition = 'inside';
$(addToAll ? 'img' : 'img.fancybox').each(function(){
var $this = $(this);
var title = $this.attr('title');
var src = $this.attr('data-big') || $this.attr('src');
var a = $('').attr('href', src).attr('title', title);
$this.wrap(a);
});
if (gallery)
$('a.fancybox').attr('rel', 'fancyboxgallery');
$('a.fancybox').fancybox({
titlePosition: titlePosition
});
});
$.noConflict();
In the code you posted, you are not closing your javascript. This might be the problem. So after $.noConflict(); add
</script>
You could also override the CSS property by setting the margin and padding to the parent elements depending on the markup of the site.
Is there any way you could show us the HTML of that section?

Call to window.print firing before documents style is applied

I have a form with a print function. Inside the function I open a window, build the document, add the head with style sheets, add the form HTML and make the call to print the last part of the body. The problem is the initial print preview/print doesn't reflect the style. If I cancel the print and attempt to print manually, the style shows up.
I've tried quite a few ways of doing this with no luck. It seems like a timing issue. Any ideas?
Browser is Chrome. Below is the JS function. (This is injected with a faces context).
function printForm(windowTitle, path){
var printWindow = window.open();
var printDocument = printWindow.document;
var headHtml = "<link href='" + path + "/css/style.css' rel='stylesheet' type='text/css'/>";
printDocument.getElementsByTagName('head')[0].innerHTML = headHtml;
var printDiv = printDocument.createElement("DIV");
var formDiv = document.getElementById("formDiv");
printDiv.innerHTML = formDiv.innerHTML // Styling here is the issue
printDocument.body.appendChild(printDiv);
var scriptTag = printDocument.createElement("script");
var script = printDocument.createTextNode("print();");
scriptTag.appendChild(script);
printDocument.body.appendChild(scriptTag);
}
I think you need a setTimeout to delay printing for a second or two so the style can be applied. You'll need to tinker to find the right length.
Instead of trying to guessing with a timer, it might be more precise to use the load event on the <link ...> to know exactly when it has completed loading.
Below is a function I use which illustrates this technique. It uses an off-screen <iframe> to print a portion of a page. It's jQuery based, but the principles are the same in vanilla JS. Note the setting of the <link>'s onload function with an anonymous function which invokes print() on the <iframe>'s window object.
/*
* expects:
* <tag id="whatever">...goop...</tag>
* <input type="button" class="printit" data-target="whatever" value="Print">
*/
$(function() {
$( '.printit' ).click(function() {
var goop = $( '#' + this.dataset.target ).prop('outerHTML');
var ifr = $('<iframe>');
var bas = $('<base href="' + document.baseURI + '">');
var lnk = $('<link rel="stylesheet" href="/css/print.css">');
lnk.on('load', function() { /* CSS is ready! */
ifr[0].contentWindow.print();
});
ifr.css( { position: 'absolute', top: '-10000px' } )
.appendTo('body')
.contents().find('body').append(goop);
ifr.contents().find('head').append(bas).append(lnk);
return false;
});
});

Set entire page's css on click?

Does anyone know how I can change the entire document's CSS file on click? I've searched around but only found a few results on setting a class/ID's CSS, not the entire document. My website has two themes, light/dark, and I want to load up "light.css" or "dark.css" from two links.
Thanks.
You need to change the src of the the link tag, which controls the styles. For example, you probably have this in your head tag:
<link rel="stylesheet" href="light.css">
You need to change the href attribute of the link tag to "dark.css" when you click something. You can do that like this:
document.getElementById('id-of-element').addEventListener('click',function(){
document.getElementsByTagName('link')[0].setAttribute('href',isDark?'light.css':'dark.css');
isDark=isDark?false:true;
}
IMPORTANT: you need to set isDark to false or true before this code, depending on whether the page is supposed to be dark or light in the beginning. You also need to change id-of-element to the id of the element that should be clicked to toggle the state of the page.
I think this is better than the other answers because it is simpler and uses no jquery.
EDIT: I accidentally had the src attribute instead of the href one before. I now updated it to be correct.
Yeah, you can do using theming. But the changing of CSS is limited to the <body> tag.
$("a.theme").click(function(){
$("body").addClass("dark");
});
I have used jQuery library to make the coding easier. And it is not a good idea to switch CSS rather, you can change the classes.
Demo
You can check out the working demo in jsBin.
Check out this answer for more details: Selecting a web page look and feel without reloading, with one CSS.
Try something like this:
Light
Dark
<script type="text/javascript" charset="utf-8">
$('a#light, a#dark').click(function(){
$('style').remove();
$.ajax({
url:'http://www.example.com/' + $this.attr('id') + '.css',
success:function(data){
$('<style></style>').appendTo('head').html(data);
}
})
})
</script>
Of course, you need to load jQuery first.
There's 2 ways that come immediately to mind.
1) Add a style tag to the page's head, ensuring that the style tag has a unique id. You can then set the innerHTML of that element. (somewhat messy)
2) Add a link tag to the page's head, also ensuring that it has a unique id. You set the type='text/css' and the rel='stylesheet' attributes. You the set the src of this link element to the appropriate css file.
Here's an example of each type. Just supply css files for theme3() and theme4() functions.
Example:
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function toggleClass(element, newStr)
{
index=element.className.indexOf(newStr);
if ( index == -1)
element.className += ' '+newStr;
else
{
if (index != 0)
newStr = ' '+newStr;
element.className = element.className.replace(newStr, '');
}
}
function forEachNode(nodeList, func)
{
var i, n = nodeList.length;
for (i=0; i<n; i++)
{
func(nodeList[i], i, nodeList);
}
}
window.addEventListener('load', mInit, false);
function mInit()
{
var style = newEl('style');
style.setAttribute('id', 'dynCss');
document.head.appendChild(style);
var style2 = newEl('link');
style2.setAttribute('type', 'text/css');
style2.setAttribute('rel', 'stylesheet');
style2.setAttribute('id', 'dynCss2');
document.head.appendChild(style2);
}
function theme1()
{
var style = byId('dynCss');
style.innerHTML = "h1{color: red;}";
var style2 = byId('dynCss2');
style2.setAttribute('href', '');
}
function theme2()
{
var style = byId('dynCss');
style.innerHTML = "h1{color: blue;}";
var style2 = byId('dynCss2');
style2.setAttribute('href', '');
}
function theme3()
{
var style = byId('dynCss');
style.innerHTML = "";
var style2 = byId('dynCss2');
style2.setAttribute('href', 'style3.css');
}
function theme4()
{
var style = byId('dynCss');
style.innerHTML = "";
var style2 = byId('dynCss2');
style2.setAttribute('href', 'style4.css');
}
</script>
<style>
</style>
</head>
<body>
<h1>This is the heading</h1>
<input type='button' onclick='theme1();' value='Theme 1'/>
<input type='button' onclick='theme2();' value='Theme 2'/>
<input type='button' onclick='theme3();' value='Theme 3'/>
<input type='button' onclick='theme4();' value='Theme 4'/>
</body>
</html>

How to print only a selected HTML element?

I am trying to implement a print feature in HTML. I know I can print the whole page with window.print(), but how do I print only a specific page element? For example a particular <DIV>Some text to print</DIV>.
You could use a print specific CSS stylesheet and hide everything but what you want printed.
<div class="no-print">I won't print</div><div class="something-else">I will!</div>
Just the no-print class will be hidden, but anything with a print class will show.
<style type="text/css" media="print">
.no-print { display: none; }
</style>
If you are familiar to jQuery, you can use jQuery Print Element plugin like this:
$('SelectorToPrint').printElement();
Created something generic to use on any HTML element
HTMLElement.prototype.printMe = printMe;
function printMe(query){
var myframe = document.createElement('IFRAME');
myframe.domain = document.domain;
myframe.style.position = "absolute";
myframe.style.top = "-10000px";
document.body.appendChild(myframe);
myframe.contentDocument.write(this.innerHTML) ;
setTimeout(function(){
myframe.focus();
myframe.contentWindow.print();
myframe.parentNode.removeChild(myframe) ;// remove frame
},3000); // wait for images to load inside iframe
window.focus();
}
Usage:
document.getElementById('xyz').printMe();
document.getElementsByClassName('xyz')[0].printMe();
Hope this help
Regards
Gaurav Khurana
Simple html and pure javascript works best. Parameter "this" refers to current id, so that function is universal for all ids. By using "ref.textContent" instead of "ref.innerHTML" you can extract only textual content for printing.
html body:
<div id="monitor" onclick="idElementPrint(this)">element to print
<img src="example.jpg" width="200">
</div>
pure javascript:
/*or:
monitor.textContent = "click me to print content";
const imga = new Image(200); //width
imga.src = "./example.jpg";
monitor.appendChild(imga);
*/
const idElementPrint = ref => {
const iframe = document.createElement("iframe");
iframe.style.display = "none";
document.body.appendChild(iframe);
const pri = iframe.contentWindow;
pri.document.open();
pri.document.write(ref.innerHTML);
pri.document.close();
pri.focus();
pri.print();
pri.onafterprint = () => { document.body.removeChild(iframe); }
}
If you are using JQuery, you can use clone to do the following:
function printElement(e) {
var ifr = document.createElement('iframe');
ifr.style='height: 0px; width: 0px; position: absolute'
document.body.appendChild(ifr);
$(e).clone().appendTo(ifr.contentDocument.body);
ifr.contentWindow.print();
ifr.parentElement.removeChild(ifr);
}
and use like so:
printElement(document.getElementById('myElementToPrint'))
If I understood you well you can use CSS3 to print your selected HTML element.
#media print {
body.print-element *:not(.print) {
display: none;
}
}
Notice, that you just need a selector. This allows you to easily print an element or the entire page using CSS classes.
Here you can check a working example: https://jsfiddle.net/gengns/d50m8ztu/
If you're using bootstrap, just add classname d-print-none to the elements you don't want to display in print
I found a solution that doesn't have the problems other solutions have. It copies the printed element to the body, and is fairly elegant and general:
CSS:
#media print {
body *:not(.printable, .printable *) {
// hide everything but printable elements and their children
display: none;
}
}
JS:
function printElement(e) {
let cloned = e.cloneNode(true);
document.body.appendChild(cloned);
cloned.classList.add("printable");
window.print();
document.body.removeChild(cloned);
}
The only limitation is that the element loses styles it inherited from its previous parents. But it works on arbitrary elements in the document structure
If you need to print the HTML element with pure JS, you can open a window that contains only the element you want to print (without any HTML-markup).
For instance, you can print the image itself without wrapping it in any HTML by opening this image in a new window as a file.
Note: 'visible=none' doesn't actually make the window invisible, but it allows to open it as a separate window (not a tab).
afterprint event allows us to close the window when the printing dialog is closed. event.target points to the opened window instance.
Note: afterprint MUST be assigned before calling .print(), otherwise it would not be called.
let win = window.open('/absolute/image/path.jpg', '__blank', 'visible=none');
win.addEventListener('afterprint', event => event.target.close() );
win.print();
Printing an Html or a Selected Html is easy using Print.Js
Add Print.Js Library
http://printjs.crabbly.com/
<form method="post" action="#" id="printJS-form">
...
</form>
<button type="button" onclick="printJS('printJS-form', 'html')">
Print Form
</button>
Add this method
function printDiv(divName) {
let specific_element = document.getElementById(divName).innerHTML;
let original_elements = document.body.innerHTML;
document.body.innerHTML = specific_element;
window.print();
document.body.innerHTML = original_elements;
}
This implementation will create and apply an ad-hoc temporary style that hides all the elements on print media except the one that we want to print. After the printing the temporary style is removed, so your document will get back to its initial state.
Feel free to adjust the ad-hoc style (like papar size, margins, etc) to fit your needs.
/**
* #description Print the given element using browser built-in function
* #param {HTMLElement} element
*/
function printElement(element) {
if (!element) {
throw new Error(`Invalid print target element`);
}
const printWrapper = "print-wrapper";
const printElement = "print-element";
const css = `
body.${printWrapper} *:not(.${printElement}) {
visibility:hidden;
}
body.${printWrapper} .${printElement} {
width: 210mm;
height: 297mm;
left:0;
top:0;
position:fixed;
}
body.${printWrapper} .${printElement} * {
visibility:initial;
margin: 0;
}
`;
const head = document.getElementsByTagName("head")[0];
const style = document.createElement("style");
style.setAttribute("type", "text/css");
style.setAttribute("media", "print");
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
document.body.classList.add(printWrapper);
element.classList.add(printElement);
window.print();
document.body.classList.remove(printWrapper);
element.classList.remove(printElement);
head.removeChild(style);
}
The simplest way to do it is:
elem = document.getElementById('elem').outerHTML
orig = document.documentElement.outerHTML
document.documentElement.outerHTML=elem
print()
document.documentElement.outerHTML = orig
function printDomElement(element) {
element.classList.add("printCss");
let printId = "printSvgId";
let name = ".printCss";
let rules = "-webkit-print-color-adjust:exact;height:100%;width:100%;position:fixed;top:0;left:0;margin:0;";
var style = document.createElement('style');
style.id = printId;
style.media = "print";
document.getElementsByTagName('head')[0].appendChild(style);
if (!(style.sheet || {}).insertRule)(style.styleSheet || style.sheet).addRule(name, rules);
else style.sheet.insertRule(name + "{" + rules + "}", 0);
window.print();
setTimeout(() => {
element.classList.remove("printCss");
let elem = document.getElementById(printId);
if (elem) elem.remove();
}, 500);
}
Set the style of the element you want to print to position:fixed,then make it cover the whole page.
Here is another (perhaps a more modern?) solution:
<link rel="stylesheet" media="print" href="print.css">

Categories

Resources