2

I'm running a dynamic page generator in JQM and am struggling to get it to work correctly.

When a user clicks on a link, I intercept the changePage call like this:

  ...
  .on("pagebeforechange", function (e, data) {
    if (typeof data.toPage === "string") {
      init.parsePage(util.parseLink(data.toPage), true);
      e.preventDefault();
    }
  })

which will call my parsePage method, which generates a new page, initializes and appends it to the DOM like so:

  $(document).enhanceWithin();
  $.mobile.initializePage();
  // go to the new page
  $.mobile.changePage("#" + config.id);

My problem is, using e.preventDefault() and a new changePage call will get caught in my pagebeforechange listener again and loop forever. I also tried to not preventing the initial changepage call and just modifying the data.toPage parameters, but assembly of my page takes "too long" and there is no way to delay JQM until the page is assembled.

Question:
How do I trigger a new transition that is not being "caught" by my listener or better, how do I delay the JQM transition until everything is ready (promises would be nice to have here :-)

Thanks!

frequent
  • 27,643
  • 59
  • 181
  • 333
  • I was doing something similar with jQM. I grabbed the pagebeforechange event in order to create a custom way of handling URL variables. I turned it into a fairly self-contained plug-in but it would override any pagebeforechange event handling you already had. – Cameron Askew Oct 24 '13 at 08:21
  • I have my own "plugin" handling, so that is fine. What I would like to know is, if you generate a new page you will trigger a new? JQM changepage to it. If so, how do you prevent this new changepage call of being caught by your pagebeforechange handler? – frequent Oct 24 '13 at 08:23
  • pagebeforechange will get fired, but you could pass something through the url anywhere after the hash to behave differently within the handler – Cameron Askew Oct 24 '13 at 08:28
  • Does this help? http://stackoverflow.com/questions/19520101/stop-showing-page/19522643#19522643 – Omar Oct 24 '13 at 09:10
  • @Omar: not really. I'm more or less doing the same, but it must be fully generic so without specific conditions and page-ids. To add intrigue, I also need to skip generating a new page if going back to the first page which may be `/` only. – frequent Oct 24 '13 at 09:53

1 Answers1

0

My current working (not satisfiable) solution:

  // generate dynamic pages
  .on("pagebeforechange", function (e, data) {
    var page;

    if (typeof data.toPage === "string") {
      page = document.getElementById(data.toPage.replace("#",""));

      if (page || data.toPage === $.mobile.getDocumentUrl()) {
        return;
      }
      init.parsePage(util.parseLink(data.toPage), true);
      e.preventDefault();
    }
  })

So I'm checking if the page is in the DOM, because as I'm generating a page dynamically, it will be injected into the DOM before changepaging to it. This way, on first pagebeforechange, the page does not exist, so it will be generated, while on the 2nd turn it will be in the DOM so I return.

Problems with this:

  • Going back to the first page will always find a page in the DOM (stop transition when it should not) or trigger generating a new page, when the first page URL is /. Can be solved by comparing data.toPage (e.g. localhost/app/) to $.mobile.getDocumentUrl() (url of the document - remember you always stay in the first DOM you load, hence a documentUrl). This allows to identify the first page.
  • pagebeforechange will also trigger on popups being opened, so this must also not trigger a transition. Checking for options.role
  • What if data.toPage is a full URL not #foo?
frequent
  • 27,643
  • 59
  • 181
  • 333