Javascript Print Multiple Webpages iFrame Content (Print All Button) - javascript

Using JavaScript, how do I create a print all button?
The 'Print All' button whenever clicked would iterate through an iFrame's different src's and print the content.
As a note, the iFrame is currently setup on a main webpage. There are navigation buttons to change the content src of the iFrame. This main webpage is set up to resemble navigating through slide content with navigation buttons. The navigation buttons are really navigating to different webpages.
So, I'm guessing that the content would need to be appended to a document or arrayed so that the content could then be printed all at once with the 'Print All' button.
I was successful at printing a 'Current Slide' (or iFrame content) with the following code:
function PrintCurrentSlide()
{
var el = document.getElementById('ifMain');
el.contentWindow.focus();
el.contentWindow.print();
return;
}
Now, I'm searching for an answer to navigate through the iFrame src's to print content with just one click.

Try this in your script
window.onload=function() {
window.frames["printf"].focus();
window.frames["printf"].print();
}
function print() {
var newWin = window.frames['printf'];
newWin.document.write('<body onload=window.print()>This is a new page I inserted</body>');
newWin.document.close();
}
function change(){
var url="http://www.apple.com/";
var $iframe = $('#ifrm');
if ( $iframe.length ) {
$iframe.attr('src',url);
return false;
}
return true;
}
and in HTML
<input type="button" onclick="print()" value="Test print"/>
<button onclick="change()">next</button>
<iframe id="printf" name="printf" src="dfgdf.html"></iframe>
here put your pages dynamically and get printed. use your logic to get print automatically or in single click or whatever

I came up with a way around it.
With this you get only one print dialogue box.
The aim is to get the contents of all the iframes into the parent window by manipulating the DOM using javascript.
Here is the code:
<script>
pages =[] // initiate an empty list here
function printPage() {
var frames = document.getElementsByTagName('iframe');
// get all the iframes and loop over them
// then push their innerHTML into the list
for (var i = 0; i < frames.length; i++){
pages.push(frames[i].contentWindow.document.body.innerHTML);
;
}
if (pages && pages.length) {
// this if statement, just checks to ensure our list is not empty before running the code.
// here is the magic, we now set the parent window to be equal to all the concatenated iframes innerHTML
window.content.document.body.innerHTML = pages;
// then we print this new window that contains all the iframes
window.print();
}
else {
// do nothing
}
}
with this solution you even avoid the problem of the iframe being cut off if it exceeds one page.
Remember that in your parent page HTML you will have the code below to call the printPage function.
<input type="submit" value="Print All"
onclick="javascript:printPage()"
/>

Related

Adjusting the height of multiple iframes on the same page

I have multiple textboxes on a seperate page, which I intend to display on another page, together, each with an iframe.
I found a script in an older post, which made that possible.
However: Only the first iframe on a page is targeted by my script. Which means I have 3 more iframes with scrollbars. Once I reload the page, I can see the other iframes for a split second in their inteded height, before the site is fully loaded and they change back to those ugly scrollbars.
On the source page I use this script next to my textblock:
window.addEventListener('load', function() { let message = { height: document.body.scrollHeight, width: document.body.scrollWidth };
// window.top refers to parent window
window.top.postMessage(message, "*");
});
On the final page I inserted the script in the same HTML box as the iframe:
<iframe src="https://whateverpage.com/" id="someid"></iframe>
<script>
let iframe = document.querySelector("#someid");
window.addEventListener('message', function(e) {
// message that was passed from iframe page
let message = e.data;
iframe.style.height = message.height + 'px';
iframe.style.width = message.width + 'px';
} , false);
</script>
I'm not the brightest when it comes to javascript. That's why I use Elementor for most of the stuff I do ;)
So I have changed the ID in each iframe to be unique. Still, there is always only the first iframe element which displays as intended. I swapped the iframes around and played with different layouts of columns, but it is alway the first element which is affected by the scripts.
I'm thinking about having the two scripts appear only once on my pages, but I don't know how to do that. I'd appreciate other ideas to make that work...

How to trigger iframe load event more than once when changing iframe source

I have an iframe that links to another internal web application.
There's a side panel with a list of links that changes the src of the iframe. Sometimes if there's a lot of data, the iframe site takes a while to load. I want to put a spinner icon when a link is clicked and hide it when the frame is loaded.
I change the src using $('#myiframe').attr('src', urlVar) in a click function for the links. I can show the spinner on click.
The problem is, how do I hide it? How do I find out that the iframe has finished loading?
I tried using $('#myiframe').load(function() { }) but that only works on the initial load (i.e. for the first link I click), not for subsequent loads (if I click on another link).
This javascript works for me :
function loadNewUrl (url){
if(url === undefined) url = 'http://example.com?v=' + Math.random();
var ifr = document.getElementById('myiframe');
ifr.setAttribute('src',url);
ifr.onload = function() {
alert('loaded');
};
}

How to set the title for the new browser tab?

I have a question about the new tab for the link.
Is there anyway I can set the browser tab title before user clicks a link? It seems like there is no way to debate the title for the new tab if the html contained in the new tab doesn't have title attribute. Am I right? How do I set the title?
//the href is dynamic so I can't set them one by one because I have 100+ html file here
<a href="test.html" target="_blank">open me<a>
As you have it, this is not possible because your links are just normal HTML links. When the new page opens in a new tab, the current page will not have any reference to it and so cannot change it in any way. You will need to open the page using javascript and set the title that way.
You can dynamically set this up in window onload to find all a tags and add a click event whihc opens the window and sets the title.
If you want different titles for each page, you can store this in a data- attribute in the a tag.
Note tho that this will only work with pages in the same domain (for security), and that it does not handle people right clicking and pressing "Open in New Window". Middle click in Windows does seem to work however.
HTML
open me
JavaScript
window.addEventListener("load", function() {
// does the actual opening
function openWindow(event) {
event = event || window.event;
// find the url and title to set
var href = this.getAttribute("href");
var newTitle = this.getAttribute("data-title");
// or if you work the title out some other way...
// var newTitle = "Some constant string";
// open the window
var newWin = window.open(href, "_blank");
// add a load listener to the window so that the title gets changed on page load
newWin.addEventListener("load", function() {
newWin.document.title = newTitle;
});
// stop the default `a` link or you will get 2 new windows!
event.returnValue = false;
}
// find all a tags opening in a new window
var links = document.querySelectorAll("a[target=_blank][data-title]");
// or this if you don't want to store custom titles with each link
//var links = document.querySelectorAll("a[target=_blank]");
// add a click event for each so we can do our own thing
for(var i = 0; i < links.length; i++) {
links[i].addEventListener("click", openWindow.bind(links[i]));
}
});
Sample JsFiddle
You can pass the title with hash and get it on another page, if this another page is yours and you can modify its code.
1st page:
...
<a href="test.html#the_title_you_want" target="_blank">open me<a>
...
2nd page - modify the body opening tag like this:
<body onload="document.title=window.location.hash.replace('#','');">
If the page you are linking to isn't yours, you can use window.open method:
open me
I have not seen addEventListener work reliably, especially when opening a new page using javascript. The best way to change the tab title and have it work reliably is to set a timeout until the page loads. You may have to play with the timeout value, but it works.
var newWindow = window.open(url, '_blank');
setTimeout(function () {
newWindow.document.title = "My Tab Name";
}, 100);
You have two options. Using pure HTML, you can let the user open up links, then later on change the title. Or you can change the title with inline JavaScript. Here's how you do both:
Method 1
Change your links by assigning a target attribute, and then later on use that window name to control the document. For instance in your links it would be: <a href="whatever" target="theNewWindow">. Whenever you want to change the title for this page, you'd use JavaScript as such: window.open("", "theNewWindow").document.title = "New Page Title!"; The problem with this method however is that all links with that target/window name will open in that same window. In addition, after the first time the link is clicked, your browser won't automatically switch to the new tab/window.
Method 2
Change your links by assigning an onclick attribute, which would open the link manually and change the title of the page immediately. Basically it would come down to look like: <a href="whatever" onclick="var w=window.open(this.href, '_blank'); (w.onload=function(){w.document.title='New Page Title!';})(); return false;">. This opens the window based on the href attribute, immediately changes the title, and sets the window to change the title to that when it finishes loading (just in case there really was a title tag).
The problem with both of these methods (as mentioned by others) is your html files have to be on the same domain.
The simplest way is a follows:
var winTab = window.open("", "_blank")
//Open URL by writing iframe with given URL
winTab.document.write("write iframe with your url in src here")
//Set Title for the new tab
winTab.document.title = "Form Title"
You could make your own Page 2 that opens up the other pages (the ones you can't edit), in a frameset. You can then either change the title dynamically when loading your page 2, or as others have suggested if you use window.open you can control the title from the parent page.
If you are in page 1, and opening page 2 in a new tab, you can't set title for page 2 from page 1.
If you have access to page 2 then it's possible, otherwise not.

Printing a web page using just url and without opening new window?

<html>
<head>
<script type="text/javascript">
var URL = "http://localhost:8000/foobar/";
var W = window.open(URL); **Note1**
W.window.print();
</script>
</head>
<p> Print ME...............</p>
</html>
I am using this script to print a webpage.
My views render this page and The JS take care all other things.
But I dont want to open new window for that. So, What should I use instead of window.open(URL) so no new window opens. Similarly, I don't want to open new window for print function.So, Whenever I render this page it do all stuff on the same page. No new window, No new tab. How can I achieve this. I google but nothing seems working.
You can do this using a hidden iFrame (I'm using jquery for the example):
function loadOtherPage() {
$("<iframe>") // create a new iframe element
.hide() // make it invisible
.attr("src", "/url/to/page/to/print") // point the iframe to the page you want to print
.appendTo("body"); // add iframe to the DOM to cause it to load the page
}
This will load the page you want to print. To print, you can add javascript code to the print page so that it gets printed after loading:
$(document).ready(function () {
window.print();
});
This will print the page without showing a new window. I've tested this in IE8,9 and Google Chrome, so I'm not sure if this works for Safari or Firefox, though.
There's a nice example on MDN how to do that with a hidden iframe https://developer.mozilla.org/en-US/docs/Printing#Print_an_external_page_without_opening_it
In reference to #andragon's answer. updated on top of it.
You can do this using an iFrame(Not hidden because hidden iFrame prints the blank page in latest versions of browsers. You can hide after the print is triggered)
function loadOtherPage(link) {
$("<iframe class='printpage'>") // create a new iframe element
.attr("src", link) // point the iframe to the page link you want to print
.appendTo("body");
}
This will load the page link you want to print.
On loading the print page link you can call javascript.
$(document).ready(function () {
window.print();
});
window.onafterprint = function () {
$('.printpage', window.parent.document).hide();
}
This will print the page from the same window and onafterprint Event is triggered when a page has started printing, or if the print dialog box has been closed
window.parent.document is to hide the iFrame block on the parent page.
I'm using Asp .net core with razor html as view, in this case I have used window.print() to print the page then used window.onafterprint to back to the page where used want to be redirected.
You can use ViewBag to replace the "/NewSales" URL.
NOTE: window.onafterprint will be called whenever user clicks Cancel/Submit/Print button in that pop-up.
$(document).ready(function () {
window.print();
window.onafterprint = function () {
window.location.href = "/NewSales";
}
});
function CallPrint() {
var prtContent = document.getElementById('main');
var WinPrint = window.open('', '', 'width=800,height=650,scrollbars=1,menuBar=1');
var str = prtContent.innerHTML;
WinPrint.document.write(str);
WinPrint.document.close();
WinPrint.focus();
}
Call this javascript function on Print button click."main" is the id of the div which we have to print without opening into new window.I want to notify that this will print the current page div.
Try and rever in case of any issue.
Thanks,
Gourav

javascript- how to determine if text has been selected within an iframe or main window- error when i run my code

I am trying to run the following code, to assign user selected text in web page to a variable.
The code works fine if the web page(in which text has been selected) is within the main window, however if the text is in an iframe, then the code is unable to detect the iframe at all.
Javascript code--
var iframe_or_main= 'main';
var selection;
selection = document.getSelection();
if (!selection) //this means that user has selected text within an iframe (and not within main window)...
{
//this variable tells us that the user has selected text within an iframe...
//this is required when adding an element with translated text to web page...
iframe_or_main='iframe';
var id_of_iframe;
id_of_iframe= getIframeWithSelection(window);
console.log(" Content selected within an iframe- iframe id=" + id_of_iframe);
selection = getIFrameDocument(document.getElementById(id_of_iframe)).getSelection();
}
// return; // selection is probably in an iframe;
console.log(" Indicator - iframe or main? --" + iframe_or_main)";
console.log(" Iframe id (if applicable)=" + id_of_iframe);
Also, output when I select text in an iframe, is shown below--
Indicator - iframe or main? --main
Iframe id (if applicable)=undefined
Note that I have tried selecting text in a web page (open in iframe) that belongs to same domain as main web page. I also tried doing this with same origin policy disabled in Google Chrome- using start parameters to disable it. In both cases I am getting the same output as above.
Is there something wrong with my code? How do I fix it?
Please note that I want the code to work in Google Chrome, although if it works across other browsers that would be a plus.
You cannot access the DOM of a document by using the IFrame as the root. Use the .contentWindow property to access the window of an iframe. Also, about "ID of frame, if applicable". Your code will break when the IFrame doesn't have an ID. See the code proposal at the bottom of this answer.
if (!selection){
iframe_or_main = 'iframe';
var iframes = document.getElementsByTagName("iframe");
var test_selection;
for(var i=0; i<iframes.length; i++){
try{ //Try-catch to prevent the same-origin policy from breaking the code
if(test_selection = iframes[i].contentWindow.document.getSelection()){
id_of_frame = iframes[i].id;
selection = test_selection;
break;
}
}catch(e){}
}
console.log(" Content selected within an iframe- iframe id=" + id_of_iframe);
}
If the ID of the frame doesn't matter, use the following code:
if (!selection){
iframe_or_main = 'iframe';
var test_selection;
for(var i=0; i<frames.length; i++){
try{ //Try-catch to prevent the same-origin policy from breaking the code
if(test_selection = frames[i].document.getSelection()){
selection = test_selection;
break;
}
}catch(e){}
}
}
See also: determine the frame id/name when a user has selected text in that frame- the page has multiple frames

Categories