Javascript function call across HTML windows - javascript

According to this page I should be able to call parameters and functions of child windows, but it is not working for me.
var w = window.open("index.html");
console.log(w);
console.log(w.foo);
console.log(w) shows that there is a function named foo but console.log(w.foo) outputs undefined. Is this a security issue?
EDIT Here is some more functionality:
child.html (omitting the body):
<head>
<script type="text/javascript">
test = 123 ;
function foo(arg){
//do something
}
</script>
</head>
parent.html:
var w = window.open("child.html");
console.log(w);
//outputs all the methods and parameters
console.log(w.foo);
//outputs 'undefined'
console.log(w.test);
//outputs 'undefined'
EDIT 2 Also I should explain why I need to pass arguments as someone will inevitably ask me why I can't 'just hard code it'. I have an HTML canvas element, and every time the user right clicks, there is a right click menu with the option 'list shapes underneath'.
When the user clicks this menu item, I want to pass a list of all the shapes underneath that click and to display it in a new window. Here are the problems I am facing:
I can't pass it as an argument b/c I don't know whether the window has been loaded (I can't seem to change the onload function either)
I can't have the child window query the parent window b/c the right click menu disappears after clicking it.

The problem is that you are not giving the DOM of the child window a chance to load before trying to inspect its contents.
console.log(w) appeared to work by displaying Window or similar immediately, but in fact it's just that by the time your human fingers got around to expanding the item details in the console, the properties and methods were present.
When I inject a delay with help from a Firebug breakpoint, I can see the child window's properties like this just fine.
This question talks about adding onLoad event listeners for children. Using its accepted answer, how about:
<script type="text/javascript">
// parent.html
var w;
function lol() {
console.log(w.foo);
console.log(w.test);
}
w = window.open("child.html");
console.log(w);
w.addEventListener('load', lol, true);
</script>
(I was also able to achieve success with a 1s setTimeout delay.)

The answer is rather simple if you look at your code logically
The following two calls will only work inside the window you open.
console.log(w.foo);
//outputs 'undefined'
console.log(w.test);
//outputs 'undefined'
i.e.
console.log(foo);
in the parent window javascript, and
console.log(window.parent.foo);
in the child window javascript.

Related

JQwidgets scroll doesn't work on chrome when i close opened window

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/

Call JavaScript of parent window from child window

I have a calendar and when I click on a <td>, a pop-up window appears so you can create your evenement for the date you selected. I want to add a feature.
When the user finishes creating the event, I want to send a JavaScript request to the parent page so I can refresh the calendar using AJAX. Basically, I want to call a function from the child, but the function is on the parent page.
On Google, I only found a script that can refresh the parent window – nothing about a “parent callback”. ☹ Is it even possible?
P.S. The answer can be pure JS or jQuery, it doesn’t matter. I’ll keep looking in the meanwhile.
What you're looking for is a reference to the window that opened the popup window. Once you have that, you can call functions in that window, read and write variables in that window, or even manipulate its DOM.
That reference is called opener. It gives you the window object for the window that opened the current window. For example, if you have a function in the original window like this:
function updateMe( data ) {
alert( data );
}
then in the popup window you could call it like this:
opener.updateMe( 'Hello!' );
Naturally, you need to make sure that updateMe() is a global function in the original page. Or if you have some object in the original page and updateMe() is a method of that object, you can still do it, as long as the object is global. e.g. in the host page:
var myObject = {
updateMe: function( data ) {
alert( data );
}
};
then in the popup you could do:
opener.myObject.updateMe( 'Hello!' );
Basically, as long as you could get to the object or function in the original page with window.whatever, then in the popup you can simply change that to opener.whatever.

window.close(); not working when page changed or refreshed

I have this little function to open/close a popup player:
function popuponclick(popup)
{
my_window = window.open("folder/player-itself.htm", popup, "width=350,height=150");
}
function closepopup()
{
my_window.close();
}
I call the functions from HTML anchors that are on each page of the site (idea is to have the player stopped/started whenever you want)...now...
it works well until i change the page, or refresh the existing one - and from then the window can't be closed anymore. Any idea where i'm wrong? Tested in FF and IE8, same behavior.
Thanks for your help.
When you reload the original window (or tab), everything about the old one is gone, blasted into the digital void, never to be seen or heard from again. The bits literally disintegrate into nothingness.
Thus, the "my_window" reference you so lovingly saved when the second window was opened is gone for good, and the "my_window" variable in the newly-loaded window contains nothing. It's name is but a mockery of the variable in the now-dead page.
The only way to deal with this situation is for the popup window to periodically check back via "window.opener" to see if its parent page has been rudely replaced by some interloper. If that happens (and the new page is from the same domain), then the popup page can restore the reference to itself in the new page's "my_window" variable.
edit — OK here's a sample. You'd put something like this in the popup page, not the launching pages:
<script>
var checkParent = setInterval(function() {
try {
if (window.opener && ('my_window' in window.opener))
window.opener.my_window = window;
}
catch (_) {
// clear the timer, since we probably won't be able to fix it now
clearInterval(checkParent);
}
}, 100);
</script>
That's probably pretty close.

Using JQuery to open a popup window and print

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.

destroy cfwindow in javascript 'is not a function'

Having an issue here that I have tried everything I can think of but cant get it to work. I have a page with a link that creates a cfwindow like so
function create_window(ID){
var config = new Object();
config.modal=true;
config.center=true;
config.height=775;
config.width=700;
config.resizable=false;
config.closable=false;
config.draggable=false;
config.refreshonshow=true;
ColdFusion.Window.create('newWindow','Window Title', '/source/url'+ID, config)
The window is created and the URL has the ID parsed to it that is used for displaying the correct item in the window. This all works fine.
The problem is when I try and close the window and open a new window with a different item being displayed, the URL is not changed. I realise that this is because the window is being hidden, and not destroyed, and therefore it is the same window being opened. So I have created an onHide event handler to destroy the window like so.
function showItemDetails(){
var ID=document.getElementById("sList").value
create_window(ID);
ColdFusion.Window.onHide('newWindow', refreshList);
}
function refreshList(){
ColdFusion.bindHandlerCache['sList'].call();
ColdFusion.Window.destroy('newWindow',true);
}
Now when I close the window Firebug is returning the error "ColdFusion.Window.destroy is not a function" (In IE the error is "Object doesn't support this property or method"). I have made sure we are running the latest version of ColdFusion 8.01 on the server (as I know that .destroy wasnt added until 8.01) and have applied the latest hotfixes to the server as well.
Any ideas?
Unfortunately, ColdFusion.Window.destroy() doesn't really destroy is a known bug. I'm not sure they've fixed it in CF9 or not, but it was definitely left unfixed in CF8.
Use ColdFusion.navigate() as a workaround. Instead of destroying the window, reuse the same window and navigate it to some other URL.
EDIT: Try this instead:
function refreshList(){
ColdFusion.bindHandlerCache['sList'].call();
var newWindow = ColdFusion.Window.getWindowObject('newWindow');
newWindow.close();
}
I think this is closer, per Adobe's docs...

Categories