Using javascript -- in an iPad html5 web app, is it possible to print a pdf which is loaded in an iframe?
I have tried numerous things without success such as:
var iframe = document.getElementsByTagName('iframe')[0]
if (iframe.attachEvent) {
iframe.attachEvent("onload", function(){
console.log("Local iframe is now loaded.");
iframe.contentWindow.print()
});
}
else {
iframe.onload = function(){
console.log("sLocal iframe is now loaded.");
iframe.contentWindow.print()
};
}
The iframe's url is '/data/xyz.pdf';
The goal is for the airprint dialog to open. This is a major issue for me, please help!!!
I think you are nearly get the solution. The only left is just how you print the iframe. Try to use this.
window.frames["iframe"].focus();
window.frames["iframe"].print();
Hope it helps
:)
A different way to the other two answers is to use CSS to print only the iframe:
#media print {
* {
display: none;
}
iframe {
display: block;
width: 100%;
height: 100%;
}
}
This basically makes the iframe the full width and height of the page, and hides other elements, so that the iframe is the only thing in view when the user clicks print. The advantage over the other options is that it will work with JavaScript turned off, which some users may have done for security reasons.
I'm pretty confident about safari supporting PDFObject. It's just an object to declare, pretty easy to use.
Even if not exactly an iframe, you can use a div this way :
<div id="pdfIframe"></div>
var pdf = new PDFObject({
url: "/data/xyz.pdf",
id: "pdfRendered",
pdfOpenParams: {
view: "FitH"
}
}).embed("pdfIframe");
Source : http://pdfobject.com/
EDIT : I did not see it was a printing issue, so my answer isn't really one. BTW, i remember a friend using it, he had no problem to print it, so maybe there is an included printing support function.
Related
I know this question won't be well received but I searched far and long and can't find anything, probably not using the right keywords.
I own an online radio station and I want to create a js player that once added to a website will stay in the header on all the domains of the site. I first saw this thing on a tumblr music player(http://scmplayer.net/) , you would add their code to your page and once opened the player will stay as a header even if you browse to other sub-pages of your blog.
I'm searching for this to use in forums, where you change your page so often you can't listen to anything using a built-in radio player.
I found a similar solution by using a button that opens a really small pop-up with the player, but I'd like to know if it's possible to do what I want, and how.
Even a right link, query or term to search for would help me greatly, I don't want someone to do this for me, just point me in the right way.
Edit::
Here's some stuff I forgot to mention. I'm trying to build a code users can just copy paste into their website and have it work.
If it was only for me, I wouldn't be here, since I went trough iframes and jquery to load content too(see www.r4ge.ro).
I can't expect other people to tamper with their website only to embed my radio there, and I can't iframe their site content and add my radio as an index because that would ruin google ranking and indexing.
There are multiple ways of doing this, here goes one!
First thing, I'd personally use backbone.js - backbone.js allows you to create 'partial' views that can be updated independently of another. For your scenario, it seems ideal to create a header view and then a content view.
Both the header and the content could have their own logic, and update at separate times that you specify and under your control.
Take a look at http://backbonetutorials.com/why-would-you-use-backbone/ to get started. prepare yourself ample time to do a lot of reading and following tutorials. Backbone takes time to ramp up on, but once you get it, you'll be making some awesome apps!
You basically have three options:
The one you found, opening a really small pop-up (perhaps with just the media controls visible), so that when the user navigates, it isn't affected by the page being torn down.
The same thing using frames.
The same thing using ajax to load content when navigating instead of actually navigating.
As you didn't like #1 much, let's look at #2, then come back to #3.
When the use opens the player, you'd really be going to a page with the player and a very large iframe with the rest of the content:
<!doctype html>
<html>
<head>
<!-- ... -->
</head>
<body>
<!-- player here -->
<iframe class="main" src="main.html"></iframe>
</body>
</html>
You'd use CSS to make that as seamless as you could. To make it linkable, you could use a large fragment in the URL which is the URL of the page that should go in the frame, e.g.:
http://example.com/#forum.html§ion=23
When your main page loads, you grab the fragment, and use it as the src on the iframe.
You can listen for navigation events on the iframe and update the hash fragment on the main window, so that bookmarks work, and/or have JavaScript on each page of your site that might be navigated to that tells the container page (parent) what its URL is.
#3 is similar to #2 except that rather than letting navigation happen the normal way, you load everything via ajax as the user clicks around, loading it into (say) a main content div rather than an iframe. This can also use hash fragments to ensure that it's fully linkable/bookmarkable, etc., but requires that all links in the pages loaded get rewritten so they update the hash fragment rather than the main URL instead.
#2 and #3 (and #1) all have their advantages and disadvantages. #1 is probably the least work. #2 probably comes in second, then #3, but I could have those backward.
Here's a quick and dirty version of #2 that polls for hash updates so that the pages loaded in the frame don't have to know anything about this at all. Note that all you'd have to give to the other people is the page; their pages remain the same. If they're concerned about page rank, they'll want to include the canonical URL of their pages in the markup.
withplayer.html:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Example</title>
<style>
html, body {
padding: 0;
margin: 0;
}
html {
height: 100%;
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
height: 100%;
position: relative;
}
div.player {
height: 30px;
padding: 2px;
}
iframe.content {
border: none;
position: absolute;
top:30px;
width: 100%;
/*bottom: 0px; Sigh, this works on elements other than iframe, see 'resize' JavaScript below */
}
</style>
</head>
<body>
<div class="player"></div>
<iframe class="content"></iframe>
<script>
(function() {
// Fill in our "player"
var dt = new Date().toISOString();
document.querySelector(".player").innerHTML =
"This div is our pretend player: The div was loaded on " +
dt.substring(0, 10) + " at " + dt.substring(11, 19) + ".";
// Get the iframe
var content = document.querySelector(".content");
// Listen for hash changes
window.onhashchange = loadContent;
// Load any initial hash we have
loadContent();
// Get our current hash, without the leading #
function getHash() {
return location.hash.replace(/^#/, '');
}
// Get the hash equivalent of the current content in the content iframe
function getContentHash() {
var loc, hash;
loc = content && content.contentWindow && content.contentWindow.location;
hash = loc && loc != "about:blank" ? loc.pathname + loc.search + loc.hash : undefined;
return hash;
}
// Load the content for the current hash
function loadContent() {
// If we have an initial hash, apply to the iframe
var hash = getHash();
if (hash) {
content.src = hash;
}
}
// Poll for changes to the frame's location, update our hash if
// it doesn't match
setInterval(pollContent, 100);
function pollContent() {
var newHash;
newHash = getContentHash();
if (newHash !== undefined && newHash !== getHash()) {
location.hash = "#" + newHash;
}
}
// Stoopid iframes won't stick to the bottom, have to resize their height
resize();
window.onresize = resize;
function resize() {
content.style.height = (window.innerHeight - 30) + "px";
}
})();
</script>
</body>
</html>
I have this js code I searched on auto-resizing iframe height with its content. It does what the user who posted this says it does. However, I now have this problem with dynamic content within the iframe.
The js code I have works only with the regular content of the page but not when there are dynamic changes going on within. For example, displaying texts through ajax call.
I've tried searching for other solutions to this but others did not work as well as what this code can do.
I'm hoping that there's someone who could help me update the code to meet what I currently need. I'm not very familiar with jquery/javascript to do this on my own. Thank you in advance! :)
This is the JS code:
function setIframeHeight(iframeId) {
var ifDoc, ifRef = document.getElementById(iframeId);
try {
ifDoc = ifRef.contentWindow.document.documentElement;
} catch (e) {
try {
ifDoc = ifRef.contentDocument.documentElement;
} catch (ee) {}
}
if (ifDoc) {
ifRef.height = 1;
ifRef.height = ifDoc.scrollHeight;
/* For width resize, enable below. */
//ifRef.width = 1;
//ifRef.width = ifDoc.scrollWidth;
}
}
I found this other code which enables iframe adapting to its dynamic content but I do not know how to make the code above and this work together. Please help me.
var iframe = document.getElementById("ifr").contentWindow;
iframe.$(".toggle_div").bind("change", function () {
$("#ifr").css({
height: iframe.$("body").outerHeight()
});
});
To summarize, I need a code that autoresizes iframe with its content and will autoresize again if there are changes on the size of the content.
The problem is that your page doesn't have any trigger indicating to resize when the iframe body resizes.
There also (as far as I know) isn't anything built into javascript that lets you watch for changes in an elements height.
You have two options.
If you are the owner of the iframe content, you can put a script in that page which can call to it's parent window telling the parent to run your resize script, or you can run a function which checks for changes say every second or so.
For the first method, you can follow the answer from here Can events fired from an iframe be handled by elements in its parent?
Otherwise just do a
setTimeout(function(){
$("#ifr").css({
height: iframe.$("body").outerHeight()
});
},1000);
function adjustMyFrameHeight()
{
var frame = getElement("myFrame");
var frameDoc = getIFrameDocument("myFrame");
frame.height = frameDoc.body.offsetHeight;
}
call this method on your iframe onload event and replace mtFrame to your iframe Id
Photo sets in Tumblr are served up as iFrames.
I want to manipulate that iframe via jQuery to look the way i want it too, which I'm able to do, but it doesn't always finish what it's doing.
I think it's because there is a lot of things happening concurrently as the page loads. I need a way to check that this iFrame, which I have no control over, loads 100% before i do the fun stuff.
There are various techniques suggested in other questions about this, but I don't think they are right for this situation. Here's one example from the Stack Overflow question "jQuery .ready in a dynamically inserted iframe"
function callIframe(url, callback) {
$(document.body).append('<IFRAME id="myId" ...>');
$('iframe#myId').attr('src', url);
$('iframe#myId').load(function()
{
callback(this);
});
}
But that makes no sense to me whatsoever to me, even though it got ticked and had 100 upvotes.
In this 'answer' the iframe is being appended by the function. That to me is not a dynamically loaded iframe!
Here is my code with the 'dumb' iframe load checker. The code works, but only sometimes. You can see it in action here http://syndex.me (third post is a photoset)
$(".post_relative").each(function () {
var post_relative = $(this);
var photoset = post_relative.find('.html_photoset');
if(photoset.length){
var myFrame = photoset.find("iframe");
myFrame.load(function(){
var newCover=myFrame.contents().find('.photoset').children(':first-child').children(':first-child').attr("href")+ '?'+(Math.random()*10000);
post_relative.append("<img src='"+ newCover +"' alt='Cover Page' />");
var psHeight = post_relative.find('img');
psHeight.load(function(){
if (psHeight.height()>heightRef){
psHeight.height(heightRef);
}
myFrame.hide();
})
})
}
});
So the question is: How do you execute a script based on the 100% loading and readiness of an iframe?
You have write data outside the context of each frame using the onload event. You have two options:
cookies
localStorage
The second is a vastly superior solution, but it is not supported on IE7. If it is in the same schema, domain, and port then you can access these items from both frames.
If your using jquery have you tried
$("#iFrameId").load(function (){
// do something once the iframe is loaded
});
I want to show the user that the document which he wants to access
is loading and not ready yet.
I want to show the web-page when it is fully loaded.
I use
$(document).ready(function(){});
for document ready. What should I do for my approach?
The first thing to do is ask why the page is so slow to load that you feel you need a loading banner, and to do whatever you can to fix that.
If you can't fix that because of the nature of the page in question, the next consideration is making sure that the "Loading" banner only appears for people who have JavaScript enabled (because we're going to remove it later with JavaScript, so it would be a bit mean to put it there and then not remove it if they don't have JavaScript). This may be one of the few valid remaining uses of the document.write statement (and only if you're not using XHTML, because it's not valid in XHTML):
<body>
<script>
document.write("<p id='loading'>Loading...</p>");
</script>
...which you'd style with CSS, presumably:
#loading {
position: absolute;
left: 0px;
top: 0px;
background-color: #ddd;
/* ... */
}
And then in your ready handler, remove it:
$('#loading').remove();
If you're using XHTML (or you just don't want to use document.write on principle), you can do something similar without document.write, along the lines of:
<body>
<script>
(function() {
var p = document.createElement('p');
p.id = 'loading';
p.innerHTML = "Loading...";
document.body.appendChild(p);
})();
</script>
Live example (Tested on IE6/7/8 on Windows; Safari on Windows; and Chrome, Opera, and Firefox on Linux and Windows.)
Write some element with the loading text/animation at the start of the code, then remove or hide that element with javascript on document ready. Some output buffering might be needed to get the loading-message to show up right away.
$(function() {
$("#loading_element").hide();
});
I am trying to create a bookmarklet, so that when you click on it, it will load example.com/yourdata.php in a div box.
How can I make it get the data from example.com?
IFRAME? or is there a better solution?
You may have issues with creating a bookmarklet within another page that grabs data from a different domain (to load into a <div /> using Ajax).
Your best option is probably to insert an IFrame with the content as the source of the page.
If you want to do this as a very basic lightbox, you could do something like this:
(function() {
var iFrame = document.createElement('IFRAME');
iFrame.src = 'http://google.com';
iFrame.style.cssText = 'display: block; position:absolute; '
+ 'top: 10%; left: 25%; width: 50%; height: 50%';
document.body.insertBefore(iFrame, document.body.firstChild);
})();
And here is the same code in bookmarklet format:
javascript: (function() { var iFrame = document.createElement('IFRAME'); iFrame.src = 'http://google.com'; iFrame.style.cssText = 'display: block; position:absolute; top: 10%; left: 25%; width: 50%; height: 50%'; document.body.insertBefore(iFrame, document.body.firstChild); })();
You could also style this a lot more if you wanted something pretty. This is just a basic example of what is possible. As another person said, it would be easiest to make it pretty by loading jQuery using an Ajax request, but that is a little more involved.
Do an AJAX call directly in your bookmarklet, and then set the innerHTML of your div to the returned content. Not sure if there are security restrictions on this or not.
Edit: You don't want to use JQuery, as you can't easily load a javascript library from a bookmarklet. (Although maybe you could get it via AJAX and then eval it...)
You need to do a classic XMLHttpRequest.
Some more info here.
With The Dojo Toolkit you can use dijit.layout.ContentPane or dojox.layout.ContentPane to do exactly what you want in one single div.
The difference between dijit.layout.ContentPane and dojox.layout.ContentPane is that you can run inline javascript inside the dojox.layout.ContentPane.
I got around the domain restriction by making a php function on my server that outputs a page on another domain. that way, javascript thinks it is in the same domain when I do an ajax.updater call.
$sSrcPage = $_REQUEST['SrcPage'];
echo file_get_contents($sSrcPage, 0);