A while back I created a lightbox plugin using jQuery that would load a url specified in a link into a lightbox. The code is really simple:
$('.readmore').each(function(i){
$(this).popup();
});
and the link would look like this:
<a class='readmore' href='view-details.php?Id=11'>TJ Kirchner</a>
The plugin could also accept arguments for width, height, a different url, and more data to pass through.
The problem I'm facing right now is printing the lightbox. I set it up so that the lightbox has a print button at the top of the box. That link would open up a new window and print that window. This is all being controlled by the lightbox plugin. Here's what that code looks like:
$('.printBtn').bind('click',function() {
var url = options.url + ( ( options.url.indexOf('?') < 0 && options.data != "" ) ? '?' : '&' ) + options.data;
var thePopup = window.open( url, "Member Listing", "menubar=0,location=0,height=700,width=700" );
thePopup.print();
});
The problem is the script doesn't seem to be waiting until the window loads. It wants to print the moment the window appears. As a result, if I click "cancel" to the print dialog box, it'll popup again and again until the window loads. The first time I tried printing I got a blank page. That might be because the window didn't finish load.
I need to find a way to alter the previous code block to wait until the window loads and then print. I feel like there should be an easy way to do this, but I haven't found it yet. Either that, or I need to find a better way to open a popup window and print from the lightbox script in the parent window, without alternating the webpage code in the popup window.
You should put the print function in your view-details.php file and call it once the file is loaded, by either using
<body onload="window.print()">
or
$(document).ready(function () {
window.print();
});
Got it! I found an idea here
http://www.mail-archive.com/discuss#jquery.com/msg18410.html
In this example, they loaded a blank popup window into an object, cloned the contents of the element to be displayed, and appended it to the body of the object. Since I already knew what the contents of view-details (or any page I load in the lightbox), I just had to clone that content instead and load it into an object. Then, I just needed to print that object. The final outcome looks like this:
$('.printBtn').bind('click',function() {
var thePopup = window.open( '', "Customer Listing", "menubar=0,location=0,height=700,width=700" );
$('#popup-content').clone().appendTo( thePopup.document.body );
thePopup.print();
});
I had one small drawback in that the style sheet I was using in view-details.php was using a relative link. I had to change it to an absolute link. The reason being that the window didn't have a URL associated with it, so it had no relative position to draw on.
Works in Firefox. I need to test it in some other major browsers too.
I don't know how well this solution works when you're dealing with images, videos, or other process intensive solutions. Although, it works pretty well in my case, since I'm just loading tables and text values.
Thanks for the input! You gave me some ideas of how to get around this.
Are you sure you can't alter the HTML in the popup window?
If you can, add a <script> tag at the end of the popup's HTML, and call window.print() inside it. Then it won't be called until the HTML has loaded.
Related
I use JQwidgets ,, I use to print data onclick print-button
as code :
$("#print").click(function () {
var gridContent = $("#jqxgrid").jqxGrid('exportdata', 'html');
var newWindow = window.open('', '', 'width=800, height=500'),
document = newWindow.document.open(),
pageContent =
'<!DOCTYPE html>\n' +
'<html>\n' +
'<head>\n' +
'<meta charset="utf-8" />\n' +
'<title>jQWidgets Grid</title>\n' +
'</head>\n' +
'<body>\n' + gridContent + '\n</body>\n</html>';
document.write(pageContent);
document.close();
newWindow.print();
});
When I close printing-widow(not continue printing), I can't use the grid-scroll (on chrome)..
google-chrome Version 34.0.1847.131 m
This worked fine on Firefox and IE..
How to fix the scroll after closing printing-window on chrome
Fiddle-Demo
It looks like you're not the only one with this issue.
I understand that your code is already setup and you want to run with what you have, but unless someone comes up with a hack or Google decided to fix what is clearly a bug, I think you need to re-think how you are approaching this issue.
If chromeless windows were an option, or if the print dialogue were a modal then you could pull this off with the current strategy, but neither of those options are possible in Chrome. Even if you were able to get around this scrolling issue somehow you're still left with a less than desirable UX problem in that if the user hits "cancel" in the print dialogue then they are left with a still open blank window.
Here is a JS fiddle to demonstrate that you need to change your approach: DEMO
You can see from this demonstration that even if we run a completely separate script from within the new window by passing it as plain text in the content object, it still causes the same issue. This means to me that this is a parent/child type of a relationship that is not easily circumvented with JS.
I recommend 2 alternative possible solutions:
Option1:
<input type="button" value="Print" onclick="window.print(); return false;" />
This triggers a full screen print dialogue that can't be closed from the "Windows Close Button." That way you can avoid the issue all together. Then you can use a combination of JS and Print Styles to target and isolate the information you want to print. I know it's more work but I think may be the better cross-platform solution.
This option is more brute force and simplistic in nature (and you have already commented that you know this but I'm leaving it up because it's still an option).
DEMO
Option2:
User clicks on a link/button that opens a new tab/window
In the same function the data from your table gets loaded into a JSON Object
The JSON object is loaded into a print template in the new tab/window
the template initiates the print function
By taking these actions, I think you will have disassociated the JS instance enough that the new tab will not affect the initiating script.
This is a browser bug - you'd have to find some sort of hack to fix it.
Doesn't sound like you want to put the print dialog code elsewhere thus not affecting your scroll bar. That is the obvious solution but it sounds like you can't do that.
Here's what I would do: Wait until someone has triggered the problematic condition, then put an event listener on the scroll event. when it happens... go ahead and reload the page.
Simple, easy, fun.
var needToReload = false;
$("#print").click(function () {
... as you have
needToReload = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
}
$('#contentjqxgrid').scroll(function () {
if (needToReload) {
window.location.reload();
}
});
$("#jqxscrollbar").jqxScrollBar({
width: 5,
height:180,
theme:'energyblue',
vertical:true
});
$("#jqxscrollbar1").jqxScrollBar({
width: 300,
height:5,
theme:'energyblue'
});
Look at jsfiddle: http://jsfiddle.net/8PtUX/6/
i'm currently working on a function (started after Buttonclick) to print a document in Lotus Notes (IBM Domino Designer 9.0 Social Edition Release 9.0). I have a custom control which creates a new document to the database. After saving the document its opened in read-only-Mode. There you have a button which will redirect you to a new window where the same contents are displayed without any layouts and something else (just the Text). Now its possible to print the page with Ctrl+P. There are two differen xPages for that.
Distribution.xsp
DistributionPrint.xsp
First of all i'm using
path = facesContext.getExternalContext().getRequest().getRequestURL();
to get the current page URL. After that there is an option to replace the current Page of the path (Distribution.xsp) into DistributionPrint.xsp.
var replacePage = #RightBack(path, "/");
path = #ReplaceSubstring(path, replacePage, "DistributionPrint.xsp");
When im testing it the replacement successfully worked. After that i'm bulding a new URL for the specific document to open with the new path. Finally everything is placed into the view.postScript method:
var docid = docApplication.getDocument().getUniversalID();
view.postScript("window.open('"+path.toString() + "?documentId=" + docid + "&action=openDocument"+"')")
Now my Problem starts. At 99% of my trys the new window is opened like i said the programm to do. But there are some kind of documents where i click on the button and he doesn't open a new window and trys to open the old Distribution.xsp url. I already tested out the path he wants to open at these kind of documents by using the debugtoolbar. The result of the button click returns the completly correct URL which should be opened. I can also copy that url and paste it manually into my browser => it works! But if i want to open that URL by a buttonclick and viewPostScript nothing happens.
Has anybody expierenced the same problem like me? Maybe one of you can help me through that problem. Its really annoying that everything works finde at 99% of my documents but at some documents it doesn't work although the given url is 100 percent correct.
Thanks for everyones help!
Try adding you code into a javascript function on the page and call that function from your view.postscript code
Or as Panu suggested add it to onCompete code
If the URL is correct then it sounds like a problem with view.postScript. Try with <xp:this.onComplete>.
Other things to try:
Use var w = window.open(... Plain window.open may change the URL of
current window.
Double check the URL with an alert();
You might be barking up the completely wrong tree. Did you try, instead of creating a second page for printing, create a second CSS stylesheet?
Using #Media Print you can tell the browser to use that stylesheet for printing. There you set all navigational elements to display : none and they won't print.
Removes the need to maintain a separate XPage for the printing stuff.
Thank you everyone for your suggestions. The solution of Fredrik Norling worked for me. I placed the Code into a function and called it at the buttonclick. Now every page is opened as expected. Thank you very much for the help!
I was developing a struts web application, in one of my JSP I created a button to open a new window. The way I did it is:
window.open(location,'_blank');
everything works fine except the new window is always scrolled down to the bottom itself. How to show the top part instead?
I am using Chrome.
Include place this JS at the bottom of the page just before the closing body tag.
<script>window.scrollTo(0,0);</script>
Or you could simply use jQuery if your page is already including it:
<script>$(document).ready(function(){$(window).scrollTop(0);});</script>
Try something like this:
var newWindow = window.open(someUrl, '_blank');
newWindow.onload = function(){
newWindow.scrollTo(0, 0);
}
newWindow.onload();
Try this
window.open(location,'_blank','top=50');
I have an iframe setup within a page and basically want to know whether it's possible to have a button in this iframe and when pressed, opens the iframe into a new browser window, showing the contents of the iframe.
I am planning on using either JavaScript or jQuery to achieve this. I am using IE6.
$('.button').click( function(){
window.open($('iframe').attr('src'),'mywindow','width=400,height=200');
});
For what you need (to open the same page where this button), no matter if it's an iframe or if in the home page.
The only difference is if you want that data to open in new window, are a reflection of the same page, such as data that can be an input.
If you care about who are the same data:
$("#mybuttonOpenWin").click(function(){
window.open(window.location.href);
});
If you are interested, you can try this code:
$("#mybuttonOpenWin").click(function(){
var mref = window.open(window.location.href);
(function = onReadyRef(xref){
if(xref.window.document.readyState=="complete"){
$(xref.window.document).find("body").html($("body").html());
}
else{
onReadyRef.call(this, xref);
}
})(mref);
});
1- OPEN FIREBUG, on the console tab
2- OPEN YOUR GMAIL ACCOUNT,
3- when gmail is loaded, click on one of your label (at the left under the draft box)
4- WITH FIREBUG YOU SEE THAT THE PAGE DOES NOT COMLETLY RELAOD SINCE ALL PREVIOUS ACTION STILL THERE FOR THE CURRENT DOCUMENT, BUT THE BROWSER COMPLETLY ACT LIKE THE PAGE HAVE BEEN RELOADED, stop button browser own loading effect, etc...)
5- !!!!! this is it..!!!!
Does some on have a clue on how site like Gmail can make the browser load on ajax call ( I mean show the loading icon and all, history, etc)
I already know what to check for the history navigation but how in the world they can make the browser to act like this was a simple link that load a complete new page.
from what I see with things like firebug Gmail basically retrieve mail information in JSON and than use some Javascript to render it to the user. But how they make the browser load in the while.
In gmail once it is loaded, obviously they ain't load all the data, from all your folder in background, so when you click on some of your folder and the data is not already loaded they make the browser 'load' like if it were loading a complete new page, while they retrieve the information from their server with some ajax call ( in Firefox you see the browser act like when you click on a normal link, loading icon, stop (x) button activated, and all).
Is it clear?
I came up with some 'ugly' code to achieve my goal that work quite nice in FireFox and IE (sadly it seems to not work in Chrome/WebKit and Opera).
I tell the browser to go to a url that it will not be able to reach before the ajax call end, with window.location=. The browser start to load and than when the ajax call sucess I call window.stop() (window.document.execCommand('Stop') for IE) than innerHTML the ajax data in the document
To me its look ugly and since it not work properly in Chrome/Webkit, this is apparently not the way to go.
There are many ways to utilize AJAX.
Gmail needs to load a lot of files/data before something meaningful can be displayed for the users.
E.g. showing the folder tree first doesn't make sense if it's not clickable or not ready for any interactive use.
Hence, what they do is show something lightweight like a loading graphic/progress bar while asynchronously (behind the scene), pull more data from the server until they can populate the page with a full interface for usage.
I don't know how to explain further. Maybe wiki can help: http://en.wikipedia.org/wiki/Ajax_%28programming%29
http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/
Use one of the methods shown as triggering a browser busy state in the table on the page above.
document.getElementById('iframe').src = "http://www.exemple.com/browser_load.html";
They are using iFrame. By changing the source of the iFrame.
Sitepoint has a book "Build Your Own AJAX Applications" and they show some content (all?) in this tutorial:
http://articles.sitepoint.com/article/build-your-own-ajax-web-apps
They will guide you with your AJAX coding.
Think this is your answer:
http://www.obviously.com/tech_tips/slow_load_technique
Looks like gmail and facebook method (browser is showing page as "loading" with loading icons etc. - it is just simulating, because there is a background ajax request) :)
$(function($){
$('a').attr('onclick','return false;').click(function(){
var title = $(this).attr('title');
var href = $(this).attr('href');
$('title').html(title);
$('#content').load(href+' #content', function(){
history.pushState(null, null, href);
}, function(responseText) {
var title = responseText.match(/<title>([^<]*)/)[1];
document.title = title;
});
});
});
window.onpopstate = function( e ) {
var returnLocation = history.location || document.location;
var returnTitle = history.propertyName || document.title;
$('title').html(returnLocation.title)
$('#content').load(returnLocation.href+ ' #content', function(){
history.pushState(null, null, href);
}, function(responseText) {
var title = responseText.match(/<title>([^<]*)/)[1];
document.title = title;
});
}