Extjs panel loadmask not working on chrome - extjs

I have a panel and on click on a button I am calling a Ajax call. on firefox I could see the loadmask on panel but on chrome it is not working. Even I create a separate mask object before Ajax call but it only shows after Ajax call complete. I could show/hide mask using browser javascript console but somehow it is not working when Ajax call running my Ajax call is sync. and issue with chrome only.
jsfiddle.net/naveen_ramawat/6d7pyohL/2/

Use a mask for the whole body
Ext.getBody().mask('your message');
before ajax call and use,
Ext.getBody().unmask();
inside ajax success
Updated jsfiddle- http://jsfiddle.net/yq8e7na8/3/
(set a timeout before asynchronos ajax call)

Try this code instead:
panel = Ext.getCmp('panel');
var myMask = new Ext.LoadMask(panel , {msg:"Loading..."});
myMask.show();
Then you can hide in the success callback function:
myMask.hide();

This is the thing:
my Ajax call is sync. and issue with chrome only
Sync AJAX has been deprecated and Chrome actually does not process it anymore, showing this warning in console:
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check http://xhr.spec.whatwg.org/.
Use async AJAX.
UPDATE:
Chrome actually seems to process the sync AJAX request, however, showing the load mask falls through. It looks like, unlike Firefox, Chrome does not wait for the interface to actually render the mask before moving onto the next bit of JavaScript code. And because the next bit is a sync AJAX call which is freezing everything, followed by myMask.hide() — we never see the mask.
To see the mask in Chrome, you can put a small delay (1 millisecond was enough on my machine) after myMask.show();:
handler(){
var myMask = new Ext.LoadMask(mypanel , {msg:"Loading..."});
myMask.show();
setTimeout(function(){
Ext.Ajax.request({
url: '/echo/js/?delay=5&js=',
method: 'GET',
async: false
});
console.log('hiding mask');
myMask.hide();
}, 1);
}
During the delay, the mask is rendered before the browser freezes making sync AJAX call.
Working fiddle: http://jsfiddle.net/6d7pyohL/4/

var myMask = new Ext.LoadMask(Ext.getBody(),{msg:"please wait..."});
$(document).ajaxStart(function(){
myMask.show();
});
$(document).ajaxComplete(function(){
myMask.hide();
});
jQuery.ajax({
url:"abc.php",
async:true,
type:"POST",
success:function(data){
}
});
instead of async:false, use async:true

Related

How to prevent browser window from closing in AngularJS until the promise is resolved

I have the following code:
$window.onbeforeunload = function (event) {
event.preventDefault();
// some asynchronous code
};
I want the onbeforeunload event to wait until the asynchronous code is executed. Not sure if this can be achieved across all browsers supporting AngularJS.
Regardless of whether you are using AngularJS, or any other framework, delaying window unload until an async action completes is not something that modern browsers support anymore, as it creates a bad user experience.
However, assuming that the async thing you want to do is make an API request, then the modern solution is to use the navigator.sendBeacon() method instead. It is guaranteed to be sent in a non-blocking fashion by the browser, even after the window has been unloaded. It is a nicer solution for everyone.
Note that beacon requests have to be sent as POST requests, so your API needs to support this method for any endpoints you wish to use in an unload handler.
One can create a handler that looks at a spinner flag:
var spinnerFlag = false;
$window.addEventListener('beforeunload',unloadHandler);
$scope.$on("$destroy", function() {
$window.removeEventListener('beforeunload',unloadHandler);
});
function unLoadHandler(e) {
if (spinnerFlag) {
// Cancel the event
e.preventDefault();
// Chrome requires returnValue to be set
e.returnValue = '';
};
});
Then one can set and clear the flag:
spinnerFlag = true;
var promise = promiseBasedAPI(arguments).finally(function() {spinnerFlag = false;});
This will set the flag before starting the asynchronous operation and clear the flag when the promise either succeeds or rejects.
The user will be prompted to confirm the page unload if the promise has not resolved.
For more information, see
MDN Web API Reference - onbeforeunload
Prevent a webpage from navigating away using JavaScript — this answer
How to show the "Are you sure you want to navigate away from this page?" when changes committed?
Can beforeunload/unload be used to send XmlHttpRequests reliably

angularjs fire promise and redirect to external URL before it resolves [duplicate]

I'm writing a small script to capture link clicks and save the link's URL into a database table in order to track how many times each link on a particular page is clicked. The links are to external sites.
So, I capture the click event in my JavaScript function, use jQuery to post to a PHP page that saves the data in MySQL, and then the JavaScript function redirects the user to the URL of the link they clicked on.
The problem I'm running into is that it seems like the post never completes because the of redirect. I've worked around this by calling the redirect inside the post callback, but that adds a few second delay because it doesn't get called until after the post completes. I'm looking for a way to just post the data and redirect the user immediately, regardless of whether or not the post succeeds or fails.
This is the current code with the workaround. It works fine, but adds the delay:
function trackClicks(event)
{
var clicked = $(this).attr('href');
$.post
(
$('#track-click-post-url').attr('value'),
{
action: 'track_landing_page_clicks',
clicked_url: clicked,
nonce: $('#track-click-nonce').attr('value')
},
function( response )
{
window.location = clicked;
}
);
event.preventDefault();
}
And this is what I'd like to do, but when I try it never completes:
function trackClicks(event)
{
var clicked = $(this).attr('href');
$.post
(
$('#track-click-post-url').attr('value'),
{
action: 'track_landing_page_clicks',
clicked_url: clicked,
nonce: $('#track-click-nonce').attr('value')
}
);
window.location = clicked;
event.preventDefault();
}
jQuery doesn't provide a callback for what you're looking for. Here are the available ready states:
Value State Description
0 UNSENT open()has not been called yet.
1 OPENED send()has not been called yet.
2 HEADERS_RECEIVED send() has been called, and headers and status are available.
3 LOADING Downloading; responseText holds partial data.
4 DONE The operation is complete.
You're looking for readystate 2, as that's the earliest you're aware of the fact that the server received the message.
This should get you off the ground:
var xhr = new XMLHttpRequest();
xhr.open("POST", clicked);
xhr.onreadystatechange = function() {
if (xhr.readyState >= 2) window.location = clicked;
};
xhr.send($('#track-click-post-url').attr('value'));
https://developer.mozilla.org/en/XMLHttpRequest for further reading.
Why do you post using Javascript when you are going to load a page any way?
Just update the db with the link clicked on the new page.
Perhaps using the referrer URL to track on what page the click was.
Or some other solution to get on what page the click was (e.g. url param) or some other way.
When you leave a page, all pending requests are killed, and the new page loads. The 1st way is the correct way. Yes, there will be a delay when a link is clicked, that's because the POST request is running.
You can't run a request in the background of a page, if the user is not on that page.
Maybe you can save the link URL in a cookie, and put it into the DB when the next page loads.

Angular Error In FireFox When Changing Urls

I have a function in an angular factory that gets invoked when my page is loaded. There's a controller which invokes this factory method.
Looks something that looks like this.
factory.getData = $http.post('/LocationOfData/Here').
then(function(response) {
// stuff happens here when successful
}, function (response) {
console.log('an error has occurred');
});
I noticed that my page works correctly as in //stuff happens here when successful gets hit... but only when the page fully loads.
If I load my page and then very quickly click on a link taking me to a different page within my app, an error occurs. (as in the console.log.)
This only seems to happen in FireFox. everything works ok in Chrome.
Any suggestions on what I should change or look out for?
EDIT: The response Object is
Object { data: null, status: 0, headers: headersGetter/<(), config: Object, statusText: "" }
Normally in JavaScript while when the page is loading if you are injecting any scripts it will consider it as one of the parallel process,if you disabled the cache of the browser it will not consider the parallel process and it will kill the process,in your case while the page load you are doing a service call and the call will be treated as a separate thread or process in chrome if you are not disabled the cache,you may get the service to fail in Chrome as well if you disabled the cache
Its an assumption only,may help:)

Scroll AngularJS ngRepeat with Ajax loading data

First of all a plunk: http://embed.plnkr.co/C866y3LHCE7QfBGuFQPQ/preview
So here I'm getting a set of posts via Ajax and displaying them using ngRepeat. Then (when the posts are done rendering) I want to scroll the page to a specific post (let's say post №18). Seems simple, but I can't get it working.
The problem seems to be that angular can't find that post after it receives the data from Ajax, so the position() and scrollTop() functions are not working.
You have to wait until after the view has been updated with your new model, use $timeout waiting 0 milliseconds to scroll immediately after the DOM is ready
plunkr
$scope.getPosts = function() {
$http.get(data_url).success(function(data){
$scope.posts = data;
$timeout(function() {
var post = $('#pid_18');
console.log('pid_18', post);
$('body').scrollTop(post[0].offsetTop);
}, 0);
});
I think the problem is that the render is not finish then if you have 2 element it's could be work but not with 1000.
So the best way is to know when the rendering is finish, a related post :
Calling a function when ng-repeat has finished

Testing an event while an ajax call is in progress using Protractor + Angular

I am using protractor 1.7.0 and angular 1.2.
I have a functionality that when i click a button say 'Load Results' an ajax request is fired, meanwhile the results are coming back I see a button say 'Cancel Request' (to cancel the ongoing ajax request, this button gets hidden when ajax response is received).
Now to test it in protractor I am wirting something like this
//to load the results
element(by.css('#load-results')).click();
//to cancel ongoing ajax request to load results
element(by.css('.search-cancelled')).then(function(){
element(by.css('.search-cancelled')).click();
});
it gives me an error saying that element is not visible.
As far as i know protractor waits for angular to resolve its promises before executing the next statement. So till the time it reaches this code
element(by.css('.search-cancelled')).then(function(){
element(by.css('.search-cancelled')).click();
});
the ajax call has returned and thats why the element gets hidden.
Is there a way i can make protractor not wait for the angular promise and execute my code when the ajax request is going on?
Looks like you could do it this way:
$('#load-results').click();
waitElementToBeShown($('.search-cancelled'));
$('.search-cancelled').click();
Here is the code for help function:
var waitElementToBeShown = function (elm) {
browser.wait(function () {
return elm.isPresent();
},15000);
browser.wait(function () {
return elm.isDisplayed();
},15000);
};

Resources