Skip to content

App and View Structure

kerrishotts edited this page Apr 2, 2013 · 3 revisions

While views can be put together in various methods (one file, two files, three files, etc.), they should all follow the same pattern.

View HTML

<div class="viewBackground">
    <div class="navigationBar">
        <div id="view_title">Title</div>
        <button class="barButton backButton"
                   id="view_backButton">Back</button>
    </div>
    <div class="content avoidNavigationBar avoidToolBar" id="view_scroller">
        <div id="view_contentArea">
        </div>
    </div>
    <div class="toolBar">
    </div>
</div>

The view, at the minimum, should be contained within a DIV classed with viewBackground. The remaining content can be variable, but the above is a good example that includes a navigation bar with a title and back button, a content area (with a scroller DIV), and a toolbar.

The avoidNavigationBar and avoidToolBar classes help the content scroller know if it should avoid a navigation bar and/or toolbar in the view.

Where elements have IDs, the view prefix should be replaced with the name of the view so that there are no conflicts when multiple views are loaded into the DOM. For example, if the view is named documentView, the prefix should be documentView_. Therefore, a back button would be named documentView_backButton.

Although text can be included within the HTML, if it is to be localized, it is best to either leave it blank or understand that it will be replaced later with JavaScript code (typically in the view's initializeView).

Views are almost always placed in their own HTML file. The HTML file can have the styling and scripting inline or referenced externally.

View Styles

Styles that can be applied to multiple views should be placed in /style/style.css. Styles that are specific to the view should either be placed in /style/viewName.css and referenced externally or in a `STYLE tag within the view's HTML file.

Common styles in views are as follows:

.ios .backButton { left: 10px; }
.android .backButton, .wince .backButton { display: none; }
#view_title { text-overflow: ellipsis; overflow: hidden; }
.ios #view_title { left: 80px; right: 10px; }
#view_scroller { overflow: scroll; }
.ios #view_scroller { -webkit-overflow-scrolling: touch; }
#view_contentArea { height: auto; }

If you want to reference styles externally, you can use

<link rel="stylesheet" href="./style/view.css">

or, if you want the styles to be in the /views directory:

<link rel="stylesheet" href="./views/view.css">

View JavaScript

View-related JavaScript can be in the HTML file or referenced externally. The following is a good template:

var view = $ge("view") || {};

// define any view properties
view.myScroll = null;
view.viewTitle = null;
view.backButton = null;
view.lastScrollLeft = -1;
view.lastScrollTop = -1;

view.initializeView = function()
{
    view.viewTitle = $ge("view_title");
    view.viewTitle.innerHTML = __T("VIEW_TITLE");

    view.backButton = $ge("view_backButton");
    view.backButton.innerHTML = __T("BACK");
    PKUI.CORE.addTouchListener( view.backButton, "touchend", view.backButtonPressed );

    if (PKDEVICE.platform() === "android")
    {
        if (android version <= 2)
        {
            view.myScroll = new SCROLLER.GenericScroller('view_contentArea');
        }
    }
}

view.viewWillAppear = function ()
{
    if (view.myScroll.scrollTo)
    {
        PKUTIL.delay(50, function() { view.myScroll.scrollTo ( view.lastScrollLeft, view.lastScrollTop ); } );
    }
}

view.viewWillHide = function ()
{
    if (view.myScroll.getScrollLeft)
    {
        view.lastScrollLeft = view.myScroll.getScrollLeft();
        view.lastScrollTop = view.myScroll.getScrollTop();
    }
}

view.backButtonPressed = function ()
{
    PKUI.CORE.popView();
}

view.viewDidAppear = function ()
{
}

view.viewDidHide = function ()
{
}

view.initializeView();

The script can be contained within a SCRIPT tag within the HTML document, or it can be referenced externally like so:

<script type="application/javascript" charset="utf-8" src = "./views/view.js"></script>

Initializing the view

Technically none of the methods above are required, but it is highly suggested each view have an initializeView method that can be called when the HTML, styling, and script are all loaded.

The view is usually initiated at the last line of the view's JavaScript so that it is always executed after everything has been loaded. You can also execute it as part of the success method in PKUTIL.loadHTML, but only if the JavaScript is part of the HTML file and not referenced externally.

Loading a view

Views are usually loaded in app.js using the following code:

PKUTIL.loadHTML ( "./views/view.html",
                  {
                    id: "view", className: "container",
                    attachTo: $ge("rootContainer"), aSync: true
                  },
                  function ( success) {
                    if (!success) { console.log ( "Failed to load view." ); }
                  } );

App Structure

Apps typically consist of several index files that are platform specific in the root of the www directory. They typically look like this:

<html>
    <head>
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="viewport" content="width=device-width, maximum-scale=1.0" />
        <meta name="format-detection" content="telephone=no" />
        <link rel="stylesheet" href="./framework/base.css" type="text/css" />
        <link rel="stylesheet" href="./style/style.css" type="text/css" />
        <script type="application/javascript" charset="utf-8" src="./cordova/cordova-2.2.0-ios.js"></script>
        <script type="application/javascript" charset="utf-8" src="./framework/scroller.js"></script>
        <script type="application/javascript" charset="utf-8" src="./framework/utility.js"></script>
        <script type="application/javascript" charset="utf-8" src="./app.js"></script> 
    </head>
    <body>
        <div class="container" id="rootContainer"></div>
        <div class="preventClicks"></div>
    </body>
</html>

For Android, the following meta tag is suggested:

    <meta name="viewport" content="width=device-width, maximum-scale=1.0, target-densityDpi=160" />

Of course, the Android-specific cordova library should also be loaded.

Application bootstrapping is usually accomplished in app.js. The following is a good template:

var APP = APP || {};

document.addEventListener ( "deviceready", onDeviceReady, false );

function onDeviceReady() { APP.start(); }

APP.start = function ()
{
    // load any libraries we need
    PKUTIL.include (["./framework/fileutil.js",
                     "./framework/ui-gestures.js",
                     "./framework/ui-msg.js",
                     "./framework/ui-core.js",
                     "./framework/device.js",
                     "./framework/localization.js"],
                    function() { APP.initLocalization(); } );
}

APP.initLocalization = function ()
{
    PKLOC.initializeGlobalization(function ()
    { PKLOC.loadLocales(["en-US"], function() { APP.init(); }); });
}

APP.init = function ()
{
    PKLOC.addTranslation ("en", "BACK", "Back");
    PKUI.CORE.initializeApplication();
    // load views
    ...
}

The app begins by registering for the deviceready event -- something that Phonegap itself will generate when the device is ready for our code. Once that event is called, APP.start loads a lot of libraries that we might need (and this list can be trimmed if certain libraries are not used), and when the libraries are loaded, APP.initLocalization is called.

APP.initLocalization initializes the globalization functions using PKLOC.initializeGlobalization, which then loads the "en-US" locale using PKLOC.loadLocales. Once the locale is loaded, APP.init is called.

APP.init creates any translations necessary, sets any PKUI.CORE properties (such as PKUI.CORE.viewHandlingMethod) and then calls PKUI.CORE.initializeApplication. After all this, the models and views are loaded.

Starting the Application

The first view that should be displayed on screen should contain the following line at the end of the JavaScript:

PKUI.CORE.showView ( view ); // where view is the name of the view

The first view should generally be the last loaded, as well.

Clone this wiki locally