Javascript OpenWindow not loading stylesheet not working - javascript

I have a document with a table and Print button. The print button calls a javascript function to generate a printable version in a new window. The printable version should load a stylesheet from the site. However the stylesheet does not load. And when I open the source from the newly opened window, although the stylesheet href -appears- correct, clicking on it does nothing. So clearly my browser doesn't recognise it as a proper href.
SO: Why is the link tag not being recognised as an href?
Here is the javascript function:
jQuery("div.jch-noise_records span.print_button a").on('click', function(e) {
e.preventDefault();
var getpanel = document.getElementById("jch-noise_records");
var MainWindow = window.open('', '', 'height=500,width=800');
MainWindow.document.write('<!DOCTYPE html>\r\n');
MainWindow.document.write( '<html lang="en-US">\r\n<head>\r\n');
MainWindow.document.write( '<title>Noise Records Report</title>\r\n');
MainWindow.document.write( '<link rel="stylesheet" href="http://example.com/wp-content/plugins/jchwebdev-noise_by_hour/jchwebdev-noise_by_hour.css" type="text/css" media="all" />\r\n');
MainWindow.document.write( '</head>\r\n');
MainWindow.document.write( '<body>\r\n');
MainWindow.document.write( getpanel.innerHTML);
MainWindow.document.write( '\r\n</body>\r\n</html>\r\n');
MainWindow.document.close();
MainWindow.document.focus();
// MainWindow.print();
return true;
});
And here is a bit of the html generated in the print window:
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Noise Records Report</title>
<link rel='stylesheet' href='http://example.com/wp-content/plugins/jchwebdev-noise_by_hour/jchwebdev-noise_by_hour.css' type='text/css' media='all' />
</head>
<body>
<span class="close"><a title="Close" href="#">X</a></span><div class="jch_table_wrapper"><p class="header"><span class="report_date">2018-06-12 18:00</span><span class="report_title">Noise By The Hour (Checkbox Detail)</span><span class="report_ip">71.231.25.83</span></p><p class="header"><span class="report_query">For date >= 2018-01-01 AND date <= 2018-05-31</span></p><table id="jch-noise_by_hour" class="jch-noise"><tbody><tr class="total"><td colspan="5">Total of <span>151 </span> days tracked for <span></span> at <span> 12AM</span> from <span>01/01/2018</span> to <span>05/31/2018</span><br>
Average noise: <span>82.8dbA</span><br>
Total # of events detected: <span>12,153</span><br>
Average number of events/hour: <span>6</span></td></tr>
</tbody></table></div>
</body>
</html>

Although I'm guessing at why this is the issue, I wanted to put this answer here for visibility as it seems to have worked based on the comments on the question.
I believe the new popup window (or new tab depending on the user's settings) is not loading and rendering the linked CSS due to some sort of security/context issue.
Since the window.open(url, name, params); call you are making is passing in an empty string for the url and the name parameters I believe this is setting your new window to be in a different "protocol" or "domain" context than your opening page, AND the linked CSS file.
Someone like #EricLaw might be able to confirm this suspicion but I believe that "" (empty string), "about:blank", and "javascript:" trigger some special ~sandboxing~ when used for popups/iframes.
That all said, it appears that if you set the URL of your initial window.open() call to be an actual HTML page (it can be a dummy/stub) from your server... and then afterwards inject the CSS link you want and content to render in the body... it overcomes this issue.

Related

printing contents in a new tab prints a blank page

I am trying to print the contents of a div to a new tab, however, it print a blank page only for the first time. When i manually print the page, it works fine. I am loading 2 tables wrapped in a div.
HTML structure:
<div class="receipt_bg" id="print_receipt">
<div id="div1">
table1
</div>
<div id="div2">
table2
</div>
</div>
<button type="button" id="print_btn">Print</button>
Javascript:
$('#print_btn').click(printClick);
function printClick(receipt_bg) {
var DocumentContainer = $('.receipt_bg').html();
var WindowObject = window.open("PrintWindow","_blank");
WindowObject.document.writeln('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">'+ '<html><head><title>test print receipt</title> <link href="../css/style.defaultprint.css" rel="stylesheet" type="text/css" /></head><body>' + DocumentContainer + '</body></html>')
setTimeout(WindowObject.print(), 5);
WindowObject.close();
}
I even tried using
WindowObject.onload = WindowObject.print();
instead of
setTimeout(WindowObject.print(), 5);
still it doesn't seem to work. I saw a similar post, but its solutions did not work for me.
Check this url.
It contain few example for printing content from page.It has all you need.
I had use jQuery Print Element 1.2 for print, in this, if you have large content to print then you need to increases time out from 50 to 500,other wise it will show blank page as you face issue, but for me it is only happend in Chrome browser, other then that i haven't face this issue.
check printElement js. below url contain nice example with demo and source.
Check this : jQuery Print Page Options
Here is the code , which will help you.
function printClick(receipt_bg) {
var DocumentContainer = $('.receipt_bg').html();
var WindowObject = window.open("", "printElementWindow", "width=650,height=440,scrollbars=yes");
WindowObject.document.writeln('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">'+ '<html><head><title>test print receipt</title> <link href="../css/style.defaultprint.css" rel="stylesheet" type="text/css" /></head><body>' + DocumentContainer + '</body><script type="text/javascript">setTimeout(printPage(),1000); function printPage(){focus();print();}<\/script></html>')
WindowObject.close();
}
This will work for you, here i added one javascript function to your window code, which will executed after timeout. try it, and let me know , is it work for you or not. you can extend or decrees timeout as per your content.

Javascript print div not working in Safari

I have a Javascript function that prints the contents of two elements in a webpage. It works in Chrome, Firefox and IE but Safari just brings up an empty window and if I select print, it simply prints a blank page.
Here's my code:
var content = "<!doctype html><html><head>";
content += '<link rel="stylesheet" href="/css/normalise.css" type="text/css" />';
content += '<link rel="stylesheet" href="/App_Themes/CS2011/StyleSheet.css" type="text/css" />';
content += "</head><body>";
//Find the div to insert the rest of the html after
var contractToFind = $(divElement).parent().find("div").get(0);
//Insert rest of code
content += contractToFind.innerHTML;
content += "</body></html>";
//Set up print window and print
var printWindow = window.open('', '', params);
printWindow.document.write(content);
printWindow.document.close();
printWindow.focus();
printWindow.print();
//Close the window
printWindow.close();
Is there a way I can modify my code to allow it to render the page properly in Safari so I can print it? Preferably without using additional plugins.
Edit: Thanks Eric but that didn't work for me. Adding a time delay to the print seems to work well although it's not ideal, even a 10ms delay solves the issue. The line I used was:
setTimeout(this.print, 100);
I found a solution to this problem. The problem resides in the fact that window.print() is not standard for all browser and Safari probably takes a different approach on when triggering it.
I changed a little your code so maybe this solution can't fit your possibility but it works for all browser (tested on Safari, FF, Chrome, IE8).
Note that you need to have a different page for the popup content (I changed the code to retrieve the contract to make a sample for myself, hope you will figure out how to get contract content).
The code:
HTML for the page that opens the popup
<body>
<input type="button" id="popup" value="Open Popup" />
<div id="yourContract">
<div>blablabla</div>
<div>blablabla2</div>
<div>blablabla3</div>
<table>
<tr>
<td>blablabla td1</td>
<td>blablabla td2</td>
</tr>
<tr>
<td>blablabla td3</td>
<td>blablabla td4</td>
</tr>
</table>
</div>
</body>
<script>
$("#popup").click(function(){
var win = window.open("static.html");
});
</script>
HTML for the popup (static.html):
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
$.holdReady(true);
$.getScript("print.js", function() {
$.holdReady(false);
});
</script>
</head>
<body>
<script>
var contract = window.opener.$("#yourContract").html(); //change to fit your needs
$("body").html(contract);
</script>
</body>
</html>
JS file (print.js) called by static.html
$(document).ready(function(){
window.print();
window.close();
});
How does it works:
static.html consists of two script section. The section in the body loads via javascript the content in the page.
The section in the head prevent the document to trigger ready status by setting holdReady to true. Then it loads print.js which waits for document to be ready, but we will decide the exact moment because we are preventing it.
After the script is included in the page holdReady is set again to false, triggering the ready status to document and calling the print() and close() functions on the window.
This however occurs after the browser has loaded all the page content, so you will see the preview in the popup page and the print dialog.
Hope this solution is what you need.

jquery: replace the link to style.css to game.css?

Trying to replace the conents of a whole page ( works ) + also replace the link to a style.css to game.css, with query
$.get('/games/14', function(data){ var $page = $(data);
$('head').append('<link rel="stylesheet" href="style2.css" type="text/css" />');
//$('#layout').empty().append($page);
$('body').empty().append($page);
})
I seem to be unable to change the "style.css" to "game.css" no matter what I try, wich Jquery Guru knows how to accomplish this? thx !
UPDATE:
tried the suggestions below still have issues, this is what I'm using now ( no replacement of the .css file )
$.get('/games/14', function(data){
$("link[href='style.css']").attr({href: 'game.css'});
var $page = $(data);
$('body').empty().append($page);
})
Here ya go, just tested this out and it worked.
<!DOCTYPE HTML>
<html>
<head>
<script src="jquery-1.7.2.min.js"></script>
<link href="/assets/frontend.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<script>
$("link[href='/assets/frontend.css']").attr('href', '/assets/game.css');
</script>
</body>
</html>
To anwer your comment below, I tested it using Firebug.
Using the Console tab, I can see that it first attempted to load up assets/frontend.css, ran the JS, then attempted to load up assets/game.css.
I then checked the DOM in the HTML tab of firebug, and saw that the link elements href attribute was updated.
Target the link element with href attribute 'style.css' and replace the href attribute of that element with 'game.css':
$("link[href='style.css']").attr({href: 'game.css'});
You can use jQuery's attr() function to change the href.
$("link[href=style.css]").attr('href', 'game.css');
There's probably a more rock-solid selector you'll want to use, but that'll do it.
href attribute substitution as suggested in other answers is inconsistently handled by different browsers (i.e. may not trigger re-flow/re-render). Instead, the original style element has to be removed and a new element with the desired href has to be inserted in its place. An intuitive way to do so with jQuery:
$('link[href$="style.css"]').replaceWith('<link href="game.css" ... ></link>');

No-Javascript Detection Script + Redirect

I would like to write a script that detects whether the user has javascript disabled, and if yes, redirect them to another page (let's say mysite.com/enablejavascript)
However, I have no idea where to start! Thanks SO.
Gdoron mentioned noscript already. Together with meta refresh¹ you can redirect users if they have JavaScript disabled.
A JavaScript redirect can be done with location.replace(URL).
<head>
<noscript>
<meta http-equiv="refresh" content="0; url=http://example.com/without-js" />
</noscript>
<script>
location.replace('http://example.com/with-js');
</script>
</head>
Example of noscript+meta refresh: http://pastehtml.com/view/bsrxxl7cw.html
1) Mind the drawbacks section of the Wikipedia article!
Meta refresh tags have some drawbacks:
If a page redirects too quickly (less than 2-3 seconds), using the "Back" button on the next page may cause some browsers to move back to the redirecting page, whereupon the redirect will occur again. This is bad for usability, as this may cause a reader to be "stuck" on the last website.
A reader may or may not want to be redirected to a different page, which can lead to user dissatisfaction or raise concerns about security.
How do you want to write a script when java-script is disabled... ?
It's can not be done. You can show a message when javascript is disabled with <noscript>.
<noscript> tag on MDN:
The HTML NoScript Element () defines a section of html to be inserted if a script type on the page is unsupported or if scripting is currently turned off in the browser.
You should combine HTML redirect in a noscript element. I found this JavaScript redirection generator. Here is your sample code:
<!-- Pleace this snippet right after opening the head tag to make it work properly -->
<!-- This code is licensed under GNU GPL v3 -->
<!-- You are allowed to freely copy, distribute and use this code, but removing author credit is strictly prohibited -->
<!-- Generated by http://insider.zone/tools/client-side-url-redirect-generator/ -->
<!-- REDIRECTING STARTS -->
<link rel="canonical" href="https://yourdomain.com/"/>
<noscript>
<meta http-equiv="refresh" content="0;URL=https://yourdomain.com/">
</noscript>
<!--[if lt IE 9]><script type="text/javascript">var IE_fix=true;</script><![endif]-->
<script type="text/javascript">
var url = "https://yourdomain.com/";
if(typeof IE_fix != "undefined") // IE8 and lower fix to pass the http referer
{
document.write("redirecting..."); // Don't remove this line or appendChild() will fail because it is called before document.onload to make the redirect as fast as possible. Nobody will see this text, it is only a tech fix.
var referLink = document.createElement("a");
referLink.href = url;
document.body.appendChild(referLink);
referLink.click();
}
else { window.location.replace(url); } // All other browsers
</script>
<!-- Credit goes to http://insider.zone/ -->
<!-- REDIRECTING ENDS -->
Try this: If java script is disabled then display a php link
<script type="text/javascript">
document.write("<button type='button' onclick='somefunction()' >Some Text</button>");
</script>
<noscript>
<?php echo "<a href='redirectfile.php'>Some Text</a>"; ?>
</noscript>

JQuery to Select and Swap Stylesheet href values

I wondering how I can select the two stylesheet links I have below in the resize function below. I need to modify the two links href value based on the orientation value, but I'm unsure how to select and populate those inside the conditional statement below, any ideas?
<head>
<link rel="stylesheet" href="css/style.css" type='text/css' media='all' />
<link rel="stylesheet" href="css/iphone.css" type='text/css' media='all' />
<script type="text/javascript">
$ = jQuery
$(document).ready(function() {
$(window).resize(function() {
var orientation = window.orientation;
if(orientation == 90 || orientation == -90) {
//populate href of stylesheet link here
} else {
//populate href of stylesheet link here
}
});
});
</script>
</head>
Just give your stylesheet and id and change it like so:
$("#id").attr("href", "/somecss.css");
If you use CSS3 you can use css3 Media Queries to change your styles based on the Orientation of the users browser.
<link rel="stylesheet" media="all and (orientation:landscape)"href="landscape.css">
This will only include this stylesheet if the orientation of the users browser is landscape.
Remember this will only work on CSS3 compatible browsers.
Look at this link :
http://www.1stwebdesigner.com/tutorials/how-to-use-css3-orientation-media-queries/
another SO question:
CSS3: Detecting device orientation for iPhone
Its better to put both the css in one file and not to change the css later on.
Css Gets loaded first . and only then your javascript gets executed. So first your default css will be loadeed. then you would change the href tag (using other answer) then next file would be loaded. making an extra call to server. The better idea it to have both(landscape & potrait) css defined in one file.
IMHO 80% of the css for both landscape & potrait would be the same the rest 20% can be configured using the naive css fomr the first link.

Categories

Resources