New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading message is not hidden after using preventDefault in pageloadfailed event #3143

Closed
daniel-chambers opened this Issue Nov 23, 2011 · 13 comments

Comments

Projects
None yet
@daniel-chambers

daniel-chambers commented Nov 23, 2011

If you listen to the pageloadfailed event and call event.preventDefault() (and later either data.deferred.success or .reject), the loading message is not hidden and stays on the page.

I have created a reproduction on jsfiddle here: http://jsfiddle.net/3PVpj/2/

When you click "Go to next page", jQuery will try to load a page that does not exist and fire the pageloadfailed event. I handle that event and call preventDefault and then call reject. You can see in the preview pane that the loading message sticks on the page and does not close.

I have reproduced this on jQuery Mobile 1.0 Final.

Looking at the jQuery Mobile code, it seems that the $.mobile.loadPage's ajax error function deliberately skips the hiding of the loading message when preventDefault is called. Unfortunately, there doesn't seem to be a way to force close the loading message myself cleanly, because it is shown using a timer and the timer's handle is private to the loadPage function. The loadPage function uses a private function hideMsg to close the loading message, but it doesn't make that available for use by the handler of pageloadfailed. $.mobile.hidePageLoadingMsg can't be called directly as a workaround because it's possible it'll be called before the timer has actually displayed the message.

@jkane001

This comment has been minimized.

Show comment
Hide comment
@jkane001

jkane001 Nov 28, 2011

Seconding this issue. Lack of documentation on how to properly handle "pageloadfailed" isn't helping.

jkane001 commented Nov 28, 2011

Seconding this issue. Lack of documentation on how to properly handle "pageloadfailed" isn't helping.

@ghost ghost assigned johnbender and jblas Dec 12, 2011

@toddparker

This comment has been minimized.

Show comment
Hide comment
@toddparker

toddparker Dec 12, 2011

Contributor

Thanks, we'll take a look.

Contributor

toddparker commented Dec 12, 2011

Thanks, we'll take a look.

@redaemn

This comment has been minimized.

Show comment
Hide comment
@redaemn

redaemn Dec 19, 2011

Contributor

I was looking at the code: maybe the function to hide the loading message could be attached to the deferred object returned by loadPage() (using deferred.then() or something like that); in this way it will be executed when the deferred will be resolved or rejected

Contributor

redaemn commented Dec 19, 2011

I was looking at the code: maybe the function to hide the loading message could be attached to the deferred object returned by loadPage() (using deferred.then() or something like that); in this way it will be executed when the deferred will be resolved or rejected

@VitaliyMF

This comment has been minimized.

Show comment
Hide comment
@VitaliyMF

VitaliyMF Jan 6, 2012

I also reproduced the issue with handling 'pageloadfailed' + event.preventDefault() additional side effect:
the 'isPageTransitioning' flag is not released and further page transitioning is not possible at all!

I dig the code of JQueryMobile 1.0final and found the reason:
at lines 2974-2989 lock is released using deferred. But when event.preventDefault() is called the code at lines 2890-2892 just returns and deferred.reject is NEVER called:

                if( plfEvent.isDefaultPrevented() ){
                    return;
                }

I suggest this part of code should be replaced with:

                if( plfEvent.isDefaultPrevented() ){
                                            deferred.reject( absUrl, options );
                    return;
                }

VitaliyMF commented Jan 6, 2012

I also reproduced the issue with handling 'pageloadfailed' + event.preventDefault() additional side effect:
the 'isPageTransitioning' flag is not released and further page transitioning is not possible at all!

I dig the code of JQueryMobile 1.0final and found the reason:
at lines 2974-2989 lock is released using deferred. But when event.preventDefault() is called the code at lines 2890-2892 just returns and deferred.reject is NEVER called:

                if( plfEvent.isDefaultPrevented() ){
                    return;
                }

I suggest this part of code should be replaced with:

                if( plfEvent.isDefaultPrevented() ){
                                            deferred.reject( absUrl, options );
                    return;
                }
@dayu

This comment has been minimized.

Show comment
Hide comment
@dayu

dayu Feb 21, 2012

The simple solution is to put hideMsg() before triggering the pageloadfailed event.

dayu commented Feb 21, 2012

The simple solution is to put hideMsg() before triggering the pageloadfailed event.

@ghost ghost assigned gseguin Feb 22, 2012

@tomor

This comment has been minimized.

Show comment
Hide comment
@tomor

tomor Feb 29, 2012

I would also appreciate a solution for hiding the loading dialog, thanks.

tomor commented Feb 29, 2012

I would also appreciate a solution for hiding the loading dialog, thanks.

@tomor

This comment has been minimized.

Show comment
Hide comment
@tomor

tomor Feb 29, 2012

Or for me it would be enough to have configurable fadeout value for pageLoadErrorMessage.

tomor commented Feb 29, 2012

Or for me it would be enough to have configurable fadeout value for pageLoadErrorMessage.

@toddparker

This comment has been minimized.

Show comment
Hide comment
@toddparker

toddparker Mar 8, 2012

Contributor

Are these latest comments on 1.1 or 1.0.1? We have a lot more options for the loading message in 1.1:
http://jquerymobile.com/test/docs/api/globalconfig.html
http://jquerymobile.com/test/docs/config/loadingMessageTextVisible.html

Contributor

toddparker commented Mar 8, 2012

Are these latest comments on 1.1 or 1.0.1? We have a lot more options for the loading message in 1.1:
http://jquerymobile.com/test/docs/api/globalconfig.html
http://jquerymobile.com/test/docs/config/loadingMessageTextVisible.html

@tomor

This comment has been minimized.

Show comment
Hide comment
@tomor

tomor Mar 8, 2012

My issue was for 1.0.1, great to hear your comment about 1.1

tomor commented Mar 8, 2012

My issue was for 1.0.1, great to hear your comment about 1.1

@gharirao

This comment has been minimized.

Show comment
Hide comment
@gharirao

gharirao Jul 12, 2012

Is there a workaround for hiding the loading message when calling preventDefault on the pageloadfailed event? We are using jQM 1.1 and implemented a custom error handler attached to pageloadfailed, but the loading indicator doesn't hide even after hidePageLoadingMsg() is invoked.

Thanks in advance!

gharirao commented Jul 12, 2012

Is there a workaround for hiding the loading message when calling preventDefault on the pageloadfailed event? We are using jQM 1.1 and implemented a custom error handler attached to pageloadfailed, but the loading indicator doesn't hide even after hidePageLoadingMsg() is invoked.

Thanks in advance!

@joshringer

This comment has been minimized.

Show comment
Hide comment
@joshringer

joshringer Jul 24, 2012

still the case, even in 1.2 dev currently.
best "workaround" I've found is to put the hide in an equal delay, assuming defaults:

$(document).on('pageloadfailed', function (event, data) {
    // Let the framework know we're going to handle things.
    event.preventDefault();
    // Remove loading message.
    setTimeout(function() {
            $.mobile.hidePageLoadingMsg();
        }, $.mobile.loadPage.defaults.loadMsgDelay);
    // Response page is already crafted as a jqm dialog, so load it straight up.
    var page = $(data.xhr.responseText).appendTo('body');
    $.mobile.changePage(page);
    // Resolve the deferred object.
    data.deferred.resolve(data.absUrl, data.options, page);
});

Given that a new loader http://jquerymobile.com/test/docs/pages/loader.html is being developed anyway, would it not make more sense to add the delay functionality into that? say as $.mobile.loader.prototype.options.delay, then the show timer could be automatically cancelled when calling $.mobile.loading('hide');

joshringer commented Jul 24, 2012

still the case, even in 1.2 dev currently.
best "workaround" I've found is to put the hide in an equal delay, assuming defaults:

$(document).on('pageloadfailed', function (event, data) {
    // Let the framework know we're going to handle things.
    event.preventDefault();
    // Remove loading message.
    setTimeout(function() {
            $.mobile.hidePageLoadingMsg();
        }, $.mobile.loadPage.defaults.loadMsgDelay);
    // Response page is already crafted as a jqm dialog, so load it straight up.
    var page = $(data.xhr.responseText).appendTo('body');
    $.mobile.changePage(page);
    // Resolve the deferred object.
    data.deferred.resolve(data.absUrl, data.options, page);
});

Given that a new loader http://jquerymobile.com/test/docs/pages/loader.html is being developed anyway, would it not make more sense to add the delay functionality into that? say as $.mobile.loader.prototype.options.delay, then the show timer could be automatically cancelled when calling $.mobile.loading('hide');

@thenewguy

This comment has been minimized.

Show comment
Hide comment
@thenewguy

thenewguy Jun 17, 2014

I am still running into this issue on jqm 1.4.2

I cannot find a way to reliably close the loading spinner from within my "pagecontainerloadfailed" handler after calling event.preventDefault() and data.deferred.reject(data.absUrl, data.options).

Calling $.mobile.loading("hide") seems to work sometimes but not every time. And when it doesn't work, the loading spinner is left open permanently.

Is there a way to ensure the spinner is closed yet?

thenewguy commented Jun 17, 2014

I am still running into this issue on jqm 1.4.2

I cannot find a way to reliably close the loading spinner from within my "pagecontainerloadfailed" handler after calling event.preventDefault() and data.deferred.reject(data.absUrl, data.options).

Calling $.mobile.loading("hide") seems to work sometimes but not every time. And when it doesn't work, the loading spinner is left open permanently.

Is there a way to ensure the spinner is closed yet?

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Jan 14, 2015

Contributor

The problem is that the pagecontainer shows the loader after a 50ms delay, so that fast page loads do not necessitate the loader at all. If you call $.mobile.loading( "hide" ) before the timeout for that delay fires, then you end up hiding the loader before the timeout starts showing it. The solution is for the pagecontainer to hide the loader, because the pagecontainer's method also clears the 50ms timeout.

Contributor

gabrielschulhof commented Jan 14, 2015

The problem is that the pagecontainer shows the loader after a 50ms delay, so that fast page loads do not necessitate the loader at all. If you call $.mobile.loading( "hide" ) before the timeout for that delay fires, then you end up hiding the loader before the timeout starts showing it. The solution is for the pagecontainer to hide the loader, because the pagecontainer's method also clears the 50ms timeout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment