3

My goal is to show a different first page depending on whether the user is logged in or not. The login check happens using a synchronous Ajax call, the outcome of which decides whether to show a login dialog or the first user page.

The normal way to do this would be to set $.mobile.autoInitialize = false and then later on initialize programmatically, as described in the answer to this question. For some reason this won't work, instead another page gets loaded every single time.

I decided to give up on this way and try out a different parcour. I now use a placeholder, empty startup page that should be shown for as long as the login check takes. After the login check it should automatically change. This is done by calling a function that performs the ajax call needed for authentication on the pagechange event that introduces this startup page. The function takes care of changing to the outcome page as well.

The trick is that it doesn't quite do that.. Instead it shows the correct page for just a short time, then changes back to the placeholder. Calling preventDefault in pagechange didn't prevent this, as described in the tutorial on dynamic pages. Adding a timer fixed this, leading me to think that the placeholder wasn't quite finished when pageshow got fired (as per this page on page events), or some side-effect of the initial page load still lingered.

I'm really clueless as to how to fix this seemingly trivial, yet burdensome problem. What causes this extra change back to the initial page? Also, if my approach to intercepting the initial page load is wrong, what would be the correct approach instead?

I use jQuery Mobile 1.4.0 and jQuery 1.10.2 (1.8.3 before).

EDIT: Below is the code to my last try before I posted the question here. It does not work: preventDefault does not prevent the transition to the placeholder page.

$(document).on("pagebeforechange", function(e, data) {
    if (typeof(data.options.fromPage) === "undefined" && data.toPage[0].id === "startup") {
        e.preventDefault();
        initLogin();
    }
});

function initLogin() {
    // ... Login logic
    if (!loggedIn) // Pseudo
        $('body').pagecontainer("change", "#login", {});
}
Community
  • 1
  • 1
Ruben
  • 541
  • 6
  • 14
  • use `pagebeforechange`, and as of jQM 1.4, you can use `pagebeforetransition`. `pagechange` is the last event that fires on a page, that's why you see a page for a sec. – Omar Feb 01 '14 at 23:22
  • @Omar You understood wrong. The page I see for a short time is the one I want to see, not the placeholder. It just gets overridden by the original page again. – Ruben Feb 08 '14 at 15:14
  • Is the first page a dialog? – Omar Feb 08 '14 at 16:09
  • @Omar, the placeholder isn't, but the target first page is, yes. – Ruben Feb 10 '14 at 09:10

2 Answers2

0

If you're using a Multi-page model, you can prevent showing any page on pagebeforechange event. This event fires twice for each page, once for the page which is about to be hidden and once for the page which is about to be shown; however, no changes is commenced in this stage.

It collects data from both pages and pass them to change page function. The collected data is represented as a second argument object, that can be retrieved once the event is triggered.

What you need from this object is two properties, .toPage and .options.fromPage. Based on these properties values, you decide whether to show first page or immediately move to another one.

var logged = false; /* for demo */

$(document).on("pagebeforechange", function (e, data) {

    if (!logged && data.toPage[0].id == "homePage" && typeof data.options.fromPage == "undefined") {
        /* immediately show login dialig */
        $.mobile.pageContainer.pagecontainer("change", "#loginDialog", {
            transition: "flip"
        });

        e.preventDefault(); /* this will stop showing first page */
    }
});
  • data.toPage[0].id value is first page in DOM id.

  • data.options.fromPage should be undefined as it shouldn't be redirected from another page within the same webapp.

Demo

Omar
  • 32,302
  • 9
  • 69
  • 112
  • I have edited my post and included the last code I've tried, which is essentially what you suggest. `initLogin` initiates the login and performs a `change` like in your example, so I've got basically the same. The `preventDefault` still doesn't work. – Ruben Feb 03 '14 at 13:29
  • @RubenVereecken try `retrun false;` but after changePage function. – Omar Feb 03 '14 at 15:50
  • thanks for the kind advice, yet still the same behaviour persists. The intended page shows, then is replaced by the original page again (the placeholder). – Ruben Feb 08 '14 at 14:24
  • I have this same behaviour as well. But I am using multi html pages... Have you found a solution for this issue? – rdon Sep 09 '15 at 18:50
0

I'm undergoing the same problem as the one described by @RubenVereecken, that is, a coming back to the initial page once the cange to my second page has completed. In fact, he posed the question "What causes this extra change back to the initial page?" and it hasn't been replied yet. Unfortunately, I don't know the reason since I haven't found how the page-event order works in JQM-1.4.2 yet, but fortunately, the workaround suggested by @Omar is working for me.

It's not exactly the same code but the general idea works at the time of preventing a coming back to the initial page. My code is as follows:

$(document).on("pagebeforechange", function(event, data) {
if ( typeof (data.toPage) == "string") {
       if (data.toPage.indexOf("#") == -1 && typeof (data.options.fromPage[0].id) == string") {
          event.preventDefault();         
       }      
}});

The condition data.toPage.indexOf("#") == -1 is because I checked that all the undesired coming-backs to the initial page were happening when the property '.toPage' was set to something like [http://localhost/.../index.html].

Yakiv Mospan
  • 8,174
  • 3
  • 31
  • 35
txapeldot
  • 71
  • 2
  • 10
  • And I'd also suggest the use of the 'change' method with the property 'changeHash' set to false, in order to prevent unexpected page-changes to happen, specially if you're developing for a mobile-oriented project. – txapeldot Mar 19 '14 at 17:34