How to refresh the parent page on closing the rad window - javascript

I have a opened a rad window using below java-script code given below. Now I want to refresh my parent page on closing the rad window. To achieve this i have linked a jquery method, OnSendInviteClose with onclose event. Now this code refreshes my parent page but some time it gives me error described as "can't execute code from a freed script". How to fix this issue or reload my parent page on close (any other way).
Thanks
var e_showaddresslist = function (sender, args) {
var url = $page.url.create("Pages/CalendarInvites.aspx?parentScreen=sendInviteWnd");
var win = $window.createPopup(url,
{
size: "750, 500", behaviors: Telerik.Web.UI.WindowBehaviors.Close | Telerik.Web.UI.WindowBehaviors.Maximize | Telerik.Web.UI.WindowBehaviors.Move | Telerik.Web.UI.WindowBehaviors.Reload | Telerik.Web.UI.WindowBehaviors.Modal, name: "sendInviteWnd", onclose: onSendInviteClose
},
function () {
//$page.get_window().set_destroyOnClose(true);
});
}
function onSendInviteClose() {
window.location.reload(true);
}
Note: All the code is place in the calendar.js file which has references in both parent and radwindow page.

Have a read of this What causes the error "Can't execute code from a freed script"
The try / catch solution may help in your case.

You can hook the OnClientColose to the RadWindow and refresh the page using document.location.reload().
function RefreshParentPage()//function in parent page
{
document.location.reload();
}
Thanks,
Saritha

Make sure the code is executed in the correct context, i.e., in the main page and not in the CalendarInvites page.
Then, if this is ok, try adding a timeout like this:
function onSendInviteClose() {
setTimeout(function() {
window.location.reload(true);
}, 0); //you can also try increasing the timeout.
}
Usually, the cannot execute code from freed script means that the content page that is being disposed is still trying to run some code but it is orphaned (e.g., other pieces of code it depends on are disposed, or its context is gone - the window object). Most often this would be the page in the iframe (i.e., inside the RadWindow), but it may also be your main page.

Attached the 'onSendInviteClose' method on close event.
var win = $window.createPopup(url,
{
size: "750, 500", behaviors: Telerik.Web.UI.WindowBehaviors.Close |Telerik.Web.UI.WindowBehaviors.Move, onclose: onSendInviteClose
}
Now create that method in the page from which the popup is opened. This function will automatically fired when popup window is closed.
function onSendInviteClose() {
//get a reference to the current RadWindow
var wndow = GetRadWindow();
wndow .Close();
// and as this method is present in parent page
// we can refresh the page controls easily.
}
function GetRadWindow() {
var oWindow = null;
if (window.radWindow) oWindow = window.radWindow;
else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
return oWindow;
}

Related

JavaScript Event function runs one every page load

I put an event javascript function inside the HTML body section of the page.
<script type="text/javascript">
function CookiebotCallback_OnAccept() {
window.location.reload(true);
if (Cookiebot.consent.statistics)
{
}
}
</script>
This script causes an infinite refresh because the function run every time the page is loaded. What can I do to make this function only run when it is called and not automatically every page load?
No need to deal with manipulating cookies, or any other hacky solutions. JavaScript offers a few native event listeners for verifying that the document has been successfully loaded. Essentially your three options are:
Inline HTML example
1. <body onload='fooBar()'>
Native DOM events that can be invoked within an HTML snippet,
or more preferably, within there own parent function to offer
more fine grained control over invocation.
2. document.onload = ()=>
3. window.onload = ()=>
i.e:
const foo = () => document.onload
const bar = () => window.onload
Invoking them anywhere within you code base as necesary without
rigidly coupling your JavaScript code within your HTML
The preferred method is window.onload as the document isn't completely honest about when it's been loaded.
Following the logic you have above using the inline approach, here's a working alternative:
// Add the following HTML immediately after your opening `body` tag.
// This ensures no competing JS scripts can run before the one we have
// here.
<script type="text/javascript">
(() => {
const runMeAfterPageLoad = () =>
Cookiebot.consent.statistics ? // If true logic here : null
if (window.addEventListener) {
window.addEventListener('load', runMeAfterPageLoad, false)
}
else if (window.attachEvent) {
window.attachEvent('onload', runMeAfterPageLoad)
}
else window.onload = runMeAfterPageLoad
})()
</script>
my solution is creating a flag variable in localStorage or sessionStorage, then check if has the variable already, skip calling reload.
<script type="text/javascript">
function CookiebotCallback_OnAccept() {
if(!sessionStorage.getItem('isReloaded')) {
sessionStorage.setItem('isReloaded', true);
window.location.reload(true);
if (Cookiebot.consent.statistics)
{
}
}
}
</script>
// you can also clear the variable to trigger the reload again.
// By: sessionStorage.removeItem('isReloaded');
// Note: the sessionStorage will be cleared each time you close the browser,
// while localStorage is only by uninstalled the browser or manually.

Window.document not updated

I open a new tab in the browser with const w = window.open('www.example.com'); and I get the DOM with let d = w.document; Then I go to another webpage with an click-event: d.querySelector('a').click(); The new webpage opens, in the same window, and I want to grap the DOM of the just openend page by running d = w.document again. And this is the point where I get stuck.
I aspect the DOM of the currently openend window, but instead I get the DOM of the previous window back. When console.log(w) (in the .js itself not in the console), with the new webpage open, I get the window object of the current page and the window.document matches the DOM of the openend page. But as I said in reality I get the DOM of the previous page back when I run d = w.document on the new page.
The following code is the whole function I use. Sidenote: I didn't(/couldn't) use window.document.onload fom I reason I don't understand, but It seems I can't attach an function to the window onload event. Also to make things clear my code is inside of a ES6 Class so I didn't use the constas in the example.
The Problem:
When I run the getDOM method on the new openend webpage it returns the DOM of the previous page.
async foo() {
await this.getDOM()
.then(w => this.d = w.document);
const x = this.d.querySelector('button.x');
console.log(send); //null
}
getDOM () {
return new Promise(resolve => {
const interval = setInterval(() => {
if (this.w.document.readyState === 'complete') {
clearInterval(interval);
resolve(this.w);
}
}, 500);
});
}
I hope someone can help, thanks in advance!

Ajax .load() won't work when triggered initially

So I have a simple tab system which I handle with the .load function to load the desired content. The problem is that the page itself which contains this tab system is a ajax loaded content. And for some reason the initial call of the tab function to display the initial tab content won't work. But after manually choosing a tab, the load function loads the content properly.
her some code to look at:
The tab handler:
function loadTab(tab) {
$(".tab_a:eq("+otab+")").removeClass("tab_slc");
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
at the end I call loadTab(tab); and the thing should be initialized. but for some reason the content remains empty. As soon as you manually click on a tab (I have an on click function which calls loadTab(tab) everything starts working)
Because the code by itself works, I think the problem is caused by the other script which handles the page itself. It is also a .load function which loads the page, which loads this tab system.
So do multiple .loads don't like each other? and if so, what can I change?
Thanks in advance ;)
EDIT: I could't post the entire code for some reason, but if you go here you can see the site in action with all the scripts:
n.ethz.ch/student/lukal/paint.net
The tab system is on the download page.
EDIT:-----------------------------------------------------------------------------------------------------------------------------
Big Update
So this is still the same issue but with a slight twist: I did what was recommended in the comments and put my secondary .load() call inside the success call of the first one.
$("#content").load("pages/contact #contentInside", function() {
$("#OtherContent").load("include/info #OtherContentInside");
});
So this works.
But now I had the great idea to make a giant load function. It is a slightly better function than just the plain load, cause it does some fading and stuff. But now I have the same problem, but even more complicated. I created the load function as a "plugin" so the function itself is in a different script file and therefore I can't access the inside of the success function. I solved this problem with a return $.ajax(); and a .done() call. The problem here is that there is some rare case where it just skips the secondary load function. So I am searching for a guaranteed way of controlling the order of the .load calls. Any idea?
The mock-up website is up to date with the new scripts if you wish to take a look. And people were complaining about potential virus spread from my link. For some reason I can't post long code snippets so the site is the best source I got to show everything. If you know a more trustworthy way to share my code please let me know.
We cannot see the rest of your code to tell where the initial call is being invoked from. A set up like the following should work:
$(function() {
var tab = 0;
loadTab( tab );
});
function loadTab(tab) {
//WHAT IS otab???
$(".tab_a:eq("+otab+")").removeClass("tab_slc"); //<<<==== otab
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
Update
The reason it does not work initial is because otab is not defined the first time the function is called. You have initialized otab at the end of the function but you are using it at the beginning of the function.
UPDATE 2
I have had a chance to look at your code and I just found out what the issues are:
You do not have DOM ready
You are not calling the function on page load.
The following version of your code should work -- try not to use global variable as you're doing with otab. Since you're loading this script at the end of the page (an you are using event delegation) you may get away with DOM ready. Adding .trigger('click') or click() as indicated below should resolve the issue.
//Tab-loader
//Haeri Studios
var tab = 0;
var otab = tab;
var counter = 0;
//click detect
$(document).on('click', '.tab_a', function() {
tab = counter == 0 ? tab : ($(this).attr('id'));
loadTab(tab);
counter++;
return false;
})
.trigger('click'); //<<<<<===== This will call the function when the page loads
//Tab setup
function loadTab(tab) {
//Content Setup
$(".tab_a:eq("+otab+")").removeClass("tab_slc");
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
//Initialize << WHAT ARE YOUR INTENTIONS HERE .. DO YOU REALLY NEED THIS PIECE?
$.ajax({success: function() {
loadTab(tab);
}});
A partial answer to this problem was to call the loadTab function inside the success call of the page load function, like charlietfl pointed out. But the problem is that there is no need to call the tabloader every time a new page gets called. So I would rather not have a rare call in every page setup function.
I am a bit disappointed by the system on stackoverflow. It seems like if you have not a high reputation level, no one gives a "S" about your questions. Well but at least some input was give, for which I am very thankful.
So by digging deeper into google I found out that the callback can be manually placed in the function where ever you like.
so if we have a function:
foo(lol, function() {
//This after
});
this does stuff after foo() is done. But what if we have another function inside foo() which we also need to wait for:
function foo(lol) {
bar(troll, function() {
//This first
});
}
The bar function is not relevant to the success call of foo. This causes the unpredictable outcome of calls.
The trick is to control when the success function of foo gets called.
If we add a parameter(callback) inside foo and call this "parameter" (callback();) inside the success call of bar, we can make sure the order is guaranteed.
And that's it:
function foo(lol, callback) {
bar(troll, function() {
//This first
callback(); //<-This callback placement defines when it should be triggered
});
}
foo(lol, function() {
//This after
});
We get:
//this first
//this after

jQuery function not invoked from window variable

I need to show a primefaces dialog when my applet is closed, because there is a thread doing some stuff once it's finished i would like to hide the dialog from the page.
In order to do this i have used the liveConnect using netscape.javascript.JSObject.
this is working like a charm everything is alright.
The problem is the javascript functions are well invoked, but the dialog.show() function is not invoked.
Here is the code :
function doit1() {
$(window).ready(function() {
statusDialog.show();
});
}
;
function doit2() {
$(window).ready(function() {
statusDialog.hide();
});
};
window.callJS = function() {
console.log("we're here 1");
doit1();
console.log("its here1");
};
window.callJS1 = function() {
console.log("we're here 2");
doit2();
console.log("its here2");
};
these methods are called from the applet like this :
JSObject window = JSObject.getWindow(this);
window.call("callJS", null);
//do_some_thread_stuff();
window.call("callJS1", null);
And here is what's happening in the console :
we're here 1
its here1
we're here 2
its here2
So, what i'm really missing and what's preventing the dialog from showing.
Note : when i use chrome DevTools console to execute the doit() methods they're working fine but i get the undefined aftermath.
The problem was with threads, i was invoking JS methods before thread.start().
I've put the window.call("callJS", null); inside the thread and it's working fine.

Checking for unsaved changes when switching views in backbone.js

I am new to Javascript and backbone.js, so hopefully I am missing something simple here. I am experimenting with some sample code I found which is supposed to check for unsaved changes before allowing a user to navigate away to another page. I have created a JSfiddle here:
http://jsfiddle.net/U43T5/4/
The code subscribes to the hashchange event like this:
$(window).on("hashchange", router.hashChange);
And the router.hashChange function checks a "dirty" flag to determine whether or not to allow the navigation, like this:
hashChange: function (evt) {
if (this.cancelNavigate) { // cancel out if just reverting the URL
evt.stopImmediatePropagation();
this.cancelNavigate = false;
return;
}
if (this.view && this.view.dirty) {
var dialog = confirm("You have unsaved changes. To stay on the page, press cancel. To discard changes and leave the page, press OK");
if (dialog == true) return;
else {
evt.stopImmediatePropagation();
this.cancelNavigate = true;
window.location.href = evt.originalEvent.oldURL;
}
}
},
The problem is that the code is not working because this.view is undefined, so the 2nd if block is never entered.
I would like the sample program to always ask for confirmation before navigating away from the page (in my sample program, I have set this.view.dirty to always be true, which is why it should always ask for confirmation). Or if there is a better approach, I am open to alternatives.
The main issue is the this context in the methods , this corresponds to the Window Object and not the Router. So it always remains undefined as you are defining view on the router. Declare a initialize method which binds the context inside the methods to router.
initialize: function() {
_.bindAll(this, 'loadView', 'hashChange');
},
Check Fiddle
I spent a lot of time to make at least something decent.
I ended up writing a wrapper for Backbone function:
var ignore = false;
Backbone.history.checkUrl = function() {
if (ignore) {
ignore = false;
return;
}
app.dirtyModelHandler.confirm(this, function () {
Backbone.History.prototype.checkUrl.call(Backbone.history);
},
function() {
ignore = true;
window.history.forward();
});
};
app.dirtyModelHandler.confirm is a function which shows confirmation (Ok, Cancel) view and takes success and cancel functions as arguments.

Categories

Resources