window.focus doesn't work within http promise then - javascript

I try to make a focus on a new tab window , within callback (then function) of a http request and it doesn't work . i.e -
$http.get('').then(function () {
that.myWin.focus(); // isn't focusing
})
I did a demo for that , press "Open" to open the tab and then press "Focus" to focus in this tab which doesn't work .
Here is another demo which isn't within then that works fine .
How to make the focus function to work well ?
EDIT :
I'm testing on Google Chrome.

I know this is kind of wiered issue, on which spent my couple of hours and actually I found something working.
While debugging I found that if, we tries to focus tab for than 1 sec of time, It doesn't focus the tab. So I assumed that in one second I should access that.myWin object, otherwise after 1sec nothing happens with tab focusing.
$scope.focus = function() {
//maintained flag for checking promise completed or not.
var promiseResolved = false; //by default false
// on each second I'm checking promise has resolved or not.
var interval = setInterval(function() {
if (promiseResolved) {
console.log('Going to focus tab')
clearInterval(interval); //clearing interval
that.myWin.focus(); //focusing tab
}
}, 1000); // 1sec interval because of above assumption
//ajax call using $http
$http.get('').then(function() {
//set flag to true when promise resolved
promiseResolved = true;
console.log("I'm here");
});
};
I know I partially figured out what may be happening, but anyone can point out, if they find anything right/wrong in my answer. I'd appreciate that help. Thanks.
Demo Fiddle

Related

Whitelist / Blocking with chrome.webRequest

so I've been trying to add whitelist ability to chrome extension, where that list can be updated via or whitelist can be totally disabled.
After checking the documentation and all possible answers here, I am still facing one weird issue, any light on it would be appreciated.
So here is the code snippet
//this list can be updated by user or other trigger
var allowed = ["example.com", "cnn.com", "domain.com"];
//this is main callback, so it can be removed from listener when needed
whiteMode = function (details) {
//checking url to array
var even = function(element) {
return details.url.indexOf(element) == -1;
}
if (allowed.some(even) == true) {
return {cancel: true }
} else {
return {cancel: false}
}
}
//setup listener
chrome.webRequest.onBeforeRequest.addListener(
whiteMode,
{urls: ["<all_urls>"]},
["blocking"]
);
so that works fine itself, if user wants to disable the mode, I just call
chrome.webRequest.onBeforeRequest.removeListener(whiteMode);
Then, if I would like to update the allowed list, I first use removeListener, then relaunch it again with new values, it does launches, however the "whiteMode" function keeps triggering twice now. By checking with console.log, I see that my new url is missing in the array on first try, then immidiately listener works again, and there is correct new array of allowed, however as it was already blocked by first trigger, it's just doing nothing.
The question, why the listener keeps doing it twice or more (if I add more items let's say), even if it was removed before added back.
Is there any way to clear up all listeners? (nothing about that in docs), been struggling with this for quite some time...
Also, tried with onHandlerBehaviorChanged, but its not helping.

SuityeCRM - jQuery Code not working On Chrome

$("#subpanel_title_documents").click(function(){
alert("clicked");
alert("loaded");
$("#documents_cases_create_button").click(function(){
alert("clicked");
setTimeout(function(){console.log("undefined");},1000);
alert("test");
setTimeout(function(){
if($("#account_id").attr("data-id-value") != ""){
alert("account");
setTimeout(function(){
var idAccount = $("#account_id").attr("data-id-value");
var nAccount = $("#account_id").text();
alert(idAccount);
alert(nAccount);
$("#account_id_c").val(idAccount);
$("#accounts_c").val(nAccount);
},500);
}else{
$("#subpanel_title_contacts").click();
alert("subpanel open");
setTimeout(function(){
var idcontact = $("*[data-module='Contacts']").data("record-id");
var nomecontact = $("*[data-module='Contacts']").data("module-name");
alert(idcontact);
alert(nomecontact);
$("#contact_id_c").val(idcontact);
$("#contacts_c").val(nomecontact);
$("#Documents_subpanel_full_form_button").click();
},1500);
};
},1000);
});
});
I'm trying to populate some fields on SuiteCRM after some actions.
This code works well on Mozilla Firefox but not on Google Chrome. After second Alert ( alert("loaded") ) stops working on Chrome.
Can anyone understand what is the issue?
You should include some more details, like in which module/detail view/edit vew/popup are you trying this.
For instance in the account module this ID documents_cases_create_button doesn't exist.
Furthermore, I haven't found evidence that this documents_cases_create_button exists in the SuiteCRM official repo.
If you are doing something custom, please specify.
also, if you are loading content using AJAX, and that AJAX is executed at the same time that $("#subpanel_title_documents").click(function(){ is Clicked, then the DOM object documents_cases_create_button might not be there quite yet.
If you don't know, the set a timeout before setting this listener
$("#subpanel_title_documents").click(function(){
console.log("Documents Clicked")
setTimeout(function(){
console.log("Just waited 3 secs for dom to finish loading AJAX content")
$("#documents_cases_create_button").click(function(){
console.log("I finally got the event I wanted");
})
},3000);
})
If that was the issue, then your option will be to set some kind of Observer. (thats what I do for AJAX loaded content when there are no native callbacks).

javascript browser timeout second timer

I am trying to set a session timeout with Javascript and looks like the alert is blocking the timer from starting. Here is my code:
var first_timer = 2 * 1000;
var second_timer = 8 * 1000;
var down = -1;
function initTimer() {
down = setTimeout(processTimeout, first_timer)
}
function processTimeout() {
down = setTimeout(logout, second_timer);
alert ("Timeout of first timer, timerid:" + down );
}
function logout() {
alert("You are logged out");
window.location = "http://www.google.com"
}
function clearTimer() {
if ( -1 != down )
clearTimeout(down);
alert("Restarting timer");
initTimer();
}
initTimer();
When I run the above, I see the second timer only starts after the first alert is dismissed. How can I make sure the second timer starts immediately after first timeout even if the alert is not dismissed?
Thx
The alert() function blocks everything else until it is dismissed. You can use whats known as a modal dialog to create your own alert style message that does not block.
jQuery UI has this feature.
It most probably depends on the browser you are using. I'm not experiencing the issue you describe with latest Firefox.
But still, the second timer alert box won't be shown until the first one is closed.
This is because JavaScript interpreters are not multi-threaded. But JavaScript itself is heavily asynchronous, especially on long delay requests such as timers, AJAX and animations. This is what sometimes gives the feeling of multi-threading.
Indeed, in your code sample, the second timer started as expected. When I dismiss the first dialog box, let's say, 10 sec after it appears, the second one is immediately shown.
Nonetheless, and it may be your question, it will never be shown before you dismiss the first alert because alert is a synchronous call. So that the main event loop won't get the control back until dismissed.
A workaround for this situation is to use "HTML" dialog boxes as those provide by Jquery-UI for example.

window.onbeforeunload in Chrome: what is the most recent fix?

Obviously, window.onbeforeunload has encountered its fair share of problems with Chrome as I've seen from all the problems I've encountered. What's the most recent work around?
The only thing I've got even close to working is this:
window.onbeforeunload = function () { return "alert" };
However, if I substitute return "alert" with something like alert("blah"), I get nothing from Chrome.
I saw in this question that Google purposefully blocks this. Good for them... but what if I want to make an AJAX call when someone closes the window? In my case, I want to know when someone has left the chatroom on my website, signalled by the window closing.
I want to know if there's a way to either
(a): fix the window.onbeforeunload call so that I can put AJAX in there
or
(b): get some other way of determining that a window has closed in Chrome
Answer:
$(window).on('beforeunload', function() {
var x =logout();
return x;
});
function logout(){
jQuery.ajax({
});
return 1+3;
}
A little mix and match, but it worked for me. The 1+3 makes sure that the logout function is being called (you'll see 4 if it's successful on the popup when you try to leave).
As of Chrome 98.0.4758.109 and Edge 100.0.1185.29, Chromium has not met the standard. There is a bug report filed, but the review is abandoned.
Test with StackBlitz!
Chrome requires returnValue to be a non-null value whether set as the return value from the handler or by reference on the event object.
The standard states that prompting can be controlled by canceling the event or setting the return value to a non-null value.
The standard states that authors should use Event.preventDefault() instead of returnValue.
The standard states that the message shown to the user is not customizable.
window.addEventListener('beforeunload', function (e) {
// Cancel the event as stated by the standard.
e.preventDefault();
// Chrome requires returnValue to be set.
e.returnValue = '';
});
window.location = 'about:blank';
Here's a more straightforward approach.
$(window).on('beforeunload', function() {
return "You should keep this page open.";
});
The returned message can be anything you want, including the empty string if you have nothing to add to the message that Chrome already shows. The result looks like this:
According to MDN,
The function should assign a string value to the returnValue property
of the Event object and return the same string.
This is the following
window.addEventListener( 'beforeunload', function(ev) {
return ev.returnValue = 'My reason';
})
This solved my problem why it wasn't working in my app:
Note that the user must interact with the page somehow (clicking somewhere) before closing its window, otherwise beforeunload is ignored in order not prevent abuse.

Annoying Popup - (or other more graceful solution)

Here's my "need" - I have a user opening a window with a document displayed, I need to log the amount of time the user has that window "in focus" or "opened"... IF the user views another window, I want to stop logging the time - and resume logging if they re-focus on that page... basically I want to "know" how long it took a user to read the page.
this is a review type scenario, where the users is a 'trusted' member who needs to log their time... I want to keep a 'running total' for reference only - so if the user says that spent 10 min, on the page, but my log shows the window was only open for 2min, I know I've got a problem...either with my code or my people.. ;)
My thought was to keep a js counter going when the page was in focus, pause on blur or on close, and Ajax the data back to my db... and add any subsequent time to that record if the user returns...
onUnload doesn't seem to work, at least when i try - plus it doesn't catch a closing of the browser... so I was thinking I could launch a NEW window, when the document window is closed (not to be annoying - but to make the logging call to the server, and then close itself).
Does anyone have a solution for this? I know this all smacks of 'poor' design, but if someone has a 'correct' way to handle this scenario - please tell me. (BTW- IE is a requirement- it's intranet based IE7 req.)
Thx
======== sample code below - that is 'not' working...kinda ============
When i say it's NOT working, this is what I mean... The "XMLHttpRequest" Is being made, i assume because the response is the message I'd expect - HOWEVER the log isn't changes (I know you'll say it's the php page, but if I call the url directly - it works fine... so it's no the logging page, IN ADDITION the 60 second setInterval() seems to fire randomly, because my response alert just pops up, sometime 10 in a row with no time between, certainly not at 'regular' 60 sec intervals... THOUGHTS?
<script type="text/javascript">
var closeMe = 0;
var logMe = 0;
//the window doesn't have focus, do nothing or something that let's them know we're not logging at the moment
function onBlur() {
//after 2 min of non focus, close it.
closeMe = setInterval('window.close()',120000); //after 2 min of non focus, close it.
};
//the window has focus... keep logging.
function onFocus(){
//stop the close counter - in the event to 'blurred' sometime
clearInterval ( closeMe );
//run the AJAX on a schedule - we're doing it every minute - bu tyou can do it as often as you like
logMe = setInterval('logTime()',60000);
};
//call a script that logs another minute...
function logTime() {
var xhReq = new XMLHttpRequest();
xhReq.open("GET", "ajax-on-time-interval.php", false);
xhReq.send(null);
var serverResponse = xhReq.responseText;
alert(serverResponse);
}
// check for Internet Explorer... IE uses 'onfocusin/out" - everything else uses "onfocus/blur"
if (/*#cc_on!#*/false) {
document.onfocusin = onFocus;
document.onfocusout = onBlur;
} else {
window.onfocus = onFocus;
window.onblur = onBlur;
}
</script>
I've have thought that a regular Ajax based "heartbeat" that updates the underlying database data every 'n' seconds (depending on the granularity you require, I'd have thought every minute would be sufficient) would be a neater solution than a pop-up and also avoid the fact that not all browsers handle onunload, etc. gracefully.
That said, I'm presuming that JavaScript will be enabled on these machines. (Seems fair based on your question.)
window.onfocus and onblur are documented in the MDC, but they're not standards. Evidently IE has document.onfocusin and .onfocusout :
if (/*#cc_on!#*/false) { // check for Internet Explorer
document.onfocusin = onFocus;
document.onfocusout = onBlur;
} else {
window.onfocus = onFocus;
window.onblur = onBlur;
}
I haven't tried it. I just read about it here.
http://www.thefutureoftheweb.com/blog/detect-browser-window-focus
One somewhat sloppy solution that partially resolves the issue with the browser closing/crashing is to have an ajax function that pings the server DB at a set interval while the document is in focus. This way, if the client crashes, you will be accurate within 30 seconds of how how long the document was open.

Categories

Resources