Twitter: raymondcamden


Address: Lafayette, LA, USA

Some thoughts on organizing a large jQuery Mobile project

05-16-2012 9,721 views Mobile, Development, jQuery, JavaScript, HTML5 7 Comments

Ben Forta pinged me with an interesting question (and when the Forta pings you, you respond) that I thought I'd share here. It's one of those "best practices" questions that really has no best answer, so as always, I'm very eager to hear what my readers have to say. Don't feel afraid to tell me I'm completely off my rocker - that makes for fun conversation. Ok, so the question:

I have a JQ+jQM=PG app. It started off as 2 small pages and 50 lines of code, and is now 10 pages and over 1000 lines of code (excluding lots of .js libraries, some my own and some downloaded, that are all included).

My question simply is how would you go about organizing the code? Each "page" in its own HTML file? Would you put page supporting event handlers with those pages? What about handlers that use JQ to manipulate other pages? Separate all JavaScript in included files? And actually, how the heck do you even use JQ to manipulate controls in another page?

I know there is no right or wrong answer, but I am about to start refactoring this entire mess, so ... any thoughts you'd like to share?

That's quite a bit there and covers a few different aspects. I'd separate this into:

  • jQuery Mobile HTML architecture (in other words, how to organize your views)
  • jQuery Mobile JavaScript architecture (how to organize JavaScript code)
  • Handling UI changes in a jQuery Mobile page for non-visible pages.

To be clear, I do not believe I have the best answers here (especially in terms of JavaScript architecture), but here are the general guidelines I'm using now.

Let's discuss pages first. In jQuery Mobile, a "page" is a div element with a data-role of page. It does not need to be one particule HTML file. jQuery Mobile allows you to use as many "pages" as you want within a particular HTML file. However - I think it quickly gets messy if you begin putting lots of different pages into one HTML file. At most, I may have a root index.html page that includes the initial view and possibly a simple "About" page or "Office Location" type list. Outside of that I follow the same rules I would for a non-jQuery mobile site. One page per file - using a file naming and folder system that makes sense.

JavaScript architecture is another matter. Right now I'm using one file per site (or application). Most of my logic comes down to a set of page handlers. I.e., "on page X loading, let's do these things" and "on page Y loading, start listening for a form submit and do blah". This leads to a giant file, which I am not terribly happy about. I like having my views extremely simple - just HTML - but I'm considering how best to 'break' up my JavaScript so the file is a bit easier to work with.

I think a more organized approach would be to use a JavaScript file as a controller. You can imagine your file having the page event handlers, but all of your business logic (like hit the server to get users) would be in a few various service files. I haven't actually tried this approach yet, but it is what I'm considering. I've got an application like this now, and rearchitecting out the business logic should be possible.

Now for your final aspect - how to modify the UI of other pages. This one is going to be tricky. When you load a page via jQuery Mobile, it adds the page into your DOM. Once it is "gone", it's really just hidden. You can still work with it. But if you haven't loaded it yet, you can't. That is enough for me to think that this approach may be a bad idea.

Instead - I think I'd consider an approach where when the page loads (the one you would have modified), you check your model (JavaScript variables I mean) to see what state the UI should be in. Your view then is tied to your data and handles knowing how to render itself based on current settings. This could be a good use case for something like Ember or Angular on top of jQuery Mobile, but this is not something I've done myself.

So... thoughts? I know this is all theory and no code, so if folks want to work on a proof of concept example (via Github), let me know and I'll set up a repo. Also, if folks have examples they can share, please do.

7 Comments

  • Commented on 05-16-2012 at 10:16 AM
    Interesting how something so simple to develop on Flex-based apps (like architecture and componentization) become so complicated with JS.
  • WebManWlkg #
    Commented on 05-16-2012 at 10:34 AM
    I'm of the school of thought that apps, databases, network wiring, etc, should design themselves, based on your needs.

    Example: "how the heck to you even use JQ to manipulate controls on another page?" You don't. You've just made a persuasive argument that your app needs to use a multi-page template, so that "another page" resides in the same DOM.

    Keep asking yourself honestly what you need it to do, and it will gradually organize itself, IMHO.
  • Commented on 05-16-2012 at 10:38 AM
    Sounds like you haven't discovered the awesomeness of BackboneJS yet. Picking up backbone has completely changed the way I think about architecting large JS apps. As CF devs you'll appreciate the lack of convention over configuration in backbone. It basically provides the tools to do MVC on the frontend without forcing you into any specific pattern.

    Have a look at the article below that specifically talks about using backbonejs along with jQuery mobile.
    http://coenraets.org/blog/2012/03/using-backbone-j...
  • Commented on 05-16-2012 at 2:07 PM
    If you have that many pages, you should be using a MVC architecture with something like backbone.js or knockout.js. It will dramatically organize your code and give you a project that is much easier to maintain moving forward.

    Christophe has some good "getting started" materials - http://coenraets.org/blog/?s=backbone

    Honestly, JQM is not really intended for mobile apps. It's more for mobile web sites where the pages are dynamically created using something like PHP, CF, etc. When you get to a lot of pages and/or you need to start customizing, you find yourself working "against the design" of JQM.

    Greg
  • Commented on 05-16-2012 at 7:13 PM
    Backbone is a good choice, but if think better: Backbone + jQuery + jQueryUI = ExtJS4 (Sencha).
    So, you can use a mix of js libraries or just use an unique framework.
  • Commented on 05-16-2012 at 8:48 PM
    Interesting question.

    Solution: Go back to Flex, NaN! hehe

    But, seriously, try to use some MVC js libraries out there. sproutcore is by far the best friendly mvc for JS and specially if you know cairngorm.

    Split js as Controllers and html as views.
  • Frequent #
    Commented on 05-22-2012 at 8:15 AM
    I'm trying to upgrade a fairly complex site (Coldfusion8/MySQL) I had developed for me some time ago into solely using Jquery Mobile (no Phonegap so far).

    I'm pretty much starting from scratch with MySql and Coldfusion and am still learning the ropes from the existing source code.

    Having looked at various frameworks (more closely js-backbone, cf-fw1), they all require to more or less turn off JQM-AJAX-handling (what I'm used to, what I like).

    I've eventually went with a basic page layout (about 25 pages, some using JQM-splitscreen which I developed) and am trying to do all the server-side-communication and view-loading through AJAX exclusively, as I don't want to reload the page constantly on mobile devices.

    I'm structuring the site into base-pages, templates, layouts, controllers and services, which is enough complexity for me... so I'm not really keen on dropping another framework layer and on top of this.

    The only thing I ended up using was requirejs (so I'm also having JS-controllers and JS-services). This loads all- 3rd party-plugin related stuff on demand only and seems to work so far... although still a long way to go.

Post Reply

Please refrain from posting large blocks of code as a comment. Use Pastebin or Gists instead. Text wrapped in asterisks (*) will be bold and text wrapped in underscores (_) will be italicized.

Leave this field empty