An Intro to App.js – Mobile Webapps Made Easy

JavaScript has become increasingly popular for mobile application development. It has enabled web application developers to develop mobile web applications without learning any native language skills.

In this tutorial, we’ll discuss a lightweight JavaScript UI library called App.js. Using App.js one can create mobile web apps without compromising performance or looks.

Getting Started

During the course of this tutorial, we’ll be creating a simple user registration app using App.js. We’ll be using Firebase as a backend. To get started, download App.js and unzip it. Inside we have 4 files.

  • app.min.css : Default stylesheet containing all android/iOS styles
  • app.min.js : The library
  • index.html : Basic template file to get started
  • zepto.js : A mobile friendly jQuery like library

Use of zepto.js is optional. In this tutorial, we’ll be using jQuery.

Creating Home Screen

Below shown is the standard format for app.js web apps.

<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
    <meta name="viewport" content="width=device-width,
                                   initial-scale=1.0,
                                   maximum-scale=1.0,
                                   user-scalable=no,
                                   minimal-ui">
    <link rel="stylesheet" href="//cdn.kik.com/app/2.0.1/app.min.css">
    <style>
      /* put your styles here */
    </style>
  </head>
  <body>
    <!-- put your pages here -->
    <script src="//zeptojs.com/zepto.min.js"></script>
    <script src="//cdn.kik.com/app/2.0.1/app.min.js"></script>
    <script>
      /* put your javascript here */
    </script>
  </body>
</html>

Let’s start from scratch. Open up index.html and remove everything from the body except the app.min.css,app.min.js and add the script below.

 try {
     App.restore(); // it loads/restores the app
 } catch (err) {
     App.load('home'); // in case of error it loads the default page
 }

Download jQuery and include it in your page or refer to the jQuery CDN version.

<script src="http://code.jquery.com/jquery-1.9.0.js"></script>

Create a div, add class app-page and you have your first page ready. Class app-page is used to define a page.

<div class="app-page"></div>

The app-page must always have a data-page attribute. data-page is used to access the page from JavaScript.

Now let’s add a top bar and title to it.

<div class="app-page" data-page="home">
    <div class="app-topbar">
        <div class="app-title">My Web App</div>
    </div>
</div>

Next we need to add a SignIn and SignUp button on the home page. All contents need to be defined inside an app-content div, hence create the app-content div and place the buttons inside it.

<div class="app-page" data-page="home">
    <div class="app-topbar">
        <div class="app-title">Simple Web App</div>
    </div>
    <div class="app-content">
        <br />
        <div class="app-button green">SignIn</div>
        <br />
        <div class="app-button blue">SignUp</div>
    </div>
</div>

Browseindex.html and you should see the home page with a SignIn and SignUp button.

Creating SignUp Screen

App.js is built to serve makers of static single-page apps. This means that it keeps all page navigation within the session of the webpage, defining “pages” as DOM nodes that can be instantiated

From the App.js documentation

We’ll be creating all our pages in the same index.html. Let’s create the SignUp screen and hook it up to the home screen button. Here is how it looks:

<div class="app-page" data-page="SignUp">
    <div class="app-topbar">
        <div class="app-button left blue" data-target="home">back</div>
    </div>
    <br />
    <div class="app-content">
        <input id="btnEmail" class="app-input" placeholder="Email">
        <input id="btnPassword" " class="app-input " placeholder="Password" type="password">
        <div id="btnSignUp" class="app-button green ">SignUp</div>
    </div>
</div>

The data-target attribute is used to link screens together. Add data-target to the SignUp button on the home page to link to this screen. If you browse the index.html file and click on the SignUp button on the home page it will redirect to the SignUp screen.

Hook your app up to Firebase

Firebase is a powerful api to store and sync data in realtime. To get started with Firebase, you’ll need to register for a free account. Simply login, create an app and click the link to manage the app. You’ll get a unique url to store data. In my case its:

https://burning-fire–1723.firebaseio.com/

From the firebase dashboard, click on Simple login from the left hand side menu. Click on the Email and Password authentication providers tab and check enabled.

Create a controller script called controller.js and include it in index.html. Every app-page has controller logic. In controller.js, we’ll define the controller logic to read email and password and store it in firebase.

To get started, download and include the firebase client or reference the CDN version.

<script type='text/javascript' src='https://cdn.firebase.com/js/client/1.0.17/firebase.js'></script>

We’ll also require the firebase simple login script.

<script type='text/javascript' src='https://cdn.firebase.com/js/simple-login/1.6.1/firebase-simple-login.js'></script>

First we need to create an instance of firebase using our firebase url. Using this firebase instance, create a FirebaseSimpleLogin instance.

var firebaseRef = new Firebase('https://burning-fire-1723.firebaseio.com'); 
var wishRef = new Firebase('https://burning-fire-1723.firebaseio.com/WishList');
var auth = new FirebaseSimpleLogin(firebaseRef, function (error, user) {
    if (!error) {
        if (user) {
            App.load('LoginHome',user);
        }
    }
});

When we try to authenticate the user login, if there is no error, LoginHome will be loaded.

Next we’ll add the controller logic for the SignUp page. Here is how it will look:

App.controller('SignUp', function (page) {

    $(page)
        .find('#btnSignUp')
        .on('click', function () {
            var email = $('#btnEmail').val();
            var password = $('#btnPassword').val();
            if (email &amp;&amp; password) {
            // on successful validation create the user
                auth.createUser(email, password, function (error, user) {
                    if (!error) {
                        // App.load('SignIn'); 
                    }
                });
            } else {
            // on validation failure show the validation message
                App.dialog({
                    title: 'Validation Error',
                    text: 'Please enter username and password.',
                    okButton: 'Try Again',
                    cancelButton: 'Cancel'
                }, function (tryAgain) {
                    if (tryAgain) {
                        App.load('SignUp');
                    }
                });
            }

        });

});

Clicking the btnSignUp button on the SignUp page, will create a user by calling auth.createUser.

Add the LoginHome html page that we are loading on a successful login as shown below:

<div class="app-page" data-page="LoginHome">
    <div class="app-topbar">
        <div class="app-title">Welcome Home!! <span class="user"></span>
        </div>
        <div class="app-button right">Logout</div>
    </div>
    <div class="app-content">
    </div>
</div>

Browse the index.html page and click on the SignUp button. Enter an email and password and click SignUp. If all goes well, the newly added user will show up in the firebase user list.

Creating Sign In screen

What we have so far is a Home page with a link to SignUp and SignIn screens. We have created the SignUp screen and also linked it to home page. Let’s add a SignIn screen.

<div class="app-page" data-page="SignIn">
    <div class="app-topbar">
        <div class="app-button left blue" data-target="home">back</div>
    </div>
    <br />
    <div class="app-content">
        <input id="btnUsername" class="app-input" placeholder="Username">
        <input id="btnPass" class="app-input" placeholder="Password" type="password">
        <div id="btnSignIn" class="app-button green">SignIn</div>
    </div>
</div>

The above html code is similar to the SignUp screen. Now let’s attach a controller to this data-page.

App.controller('SignIn', function (page) {

    $(page)
        .find('#btnSignIn')
        .on('click', function () {
            var email = $('#btnUsername').val();
            var password = $('#btnPass').val();
            if (email &amp;&amp; password) {
                auth.login('password', {
                    email: email,
                    password: password
                });
            } else {
                App.dialog({
                    title: 'Validation Error',
                    text: 'Please enter username and password.',
                    okButton: 'Try Again',
                    cancelButton: 'Cancel'
                }, function (tryAgain) {
                    if (tryAgain) {
                        App.load('SignIn');
                    }
                });
            }
        });
});

The above code calls the auth.login function to authenticate against firebase data. If a user is found, it will redirect to LoginHome.

Let’s add the controller method for the LoginHome page and define the logout functionality.

App.controller('LoginHome', function (page,user) {
    $(page)
        .find('.user').text(user.email); //setting the email in welcome message 

    $(page)
        .find('.app-button')
        .on('click', function () {
            auth.logout();  //logs out the user session
            App.load('SignIn'); // loads the Sign In page
        });
});

Since we have added the SignIn page, uncomment the App.load('SignIn') in SignUp success callback. Link the home page to the SignIn page using the data-target attribute. Browse to index.html and if is well, both sign-in and sign up functionality should be working fine.

Adding a List in Login Home

Next let’s create an interface for the logged in user to add an item to a list. We modified the existing LoginHome html to include a textbox and a button. We have also added a welcome message and a link in the top bar. Here is the modified html code:

<div class="app-page" data-page="LoginHome">
    <div class="app-topbar">
        <div id="btnShowList" class="app-button red left">Wish List</div>
        <div class="app-title">Welcome Home!! <span class="user"></span>
        </div>
        <div id="btnLogout" class="app-button red right ">Logout</div>
    </div>
    <div class="app-content">


        <input id="txtWish" class="app-input" placeholder="wish">
        <br />
        <div id="btnAdd" class="app-button green">Add Wish</div>

    </div>
</div>

We need to check the textbox for valid data and save the data into firebase. If the data is invalid, we’ll show the validation pop up using Dialogs. For saving data into firebase, we’ll be using push(). Below is the code for the btnAdd click:

$(page)
    .find('#btnAdd')
    .on('click', function () {
        var wish = $('#txtWish').val();
        if (wish) { // checking if valid data

            // if valid data insert into firebase
            wishRef.push({
                'user_id': user.email,
                'text': wish
            });
            App.load('WishList',user); // load the page to show all wishes
        } 
        else{
            // got invalid data, show validation message
            App.dialog({
                title: 'Validation Error',
                text: 'Looks like you forgot to enter the wish.',
                okButton: 'Try Again',
                cancelButton: 'Cancel'
            }, function (tryAgain) {
                if (tryAgain) {
                    App.load('LoginHome', user);
                }
            });
        }

    });

Next, we need to provide an interface to show the data entered by users. Let’s create another page, WishList as shown below:

<div class="app-page" data-page="WishList">
    <div class="app-topbar">
        <div class="app-title">Wish List</div>
        <div class="app-button left blue">Back</div>
    </div>
    <div class="app-content">
        <ul class="app-list">

        </ul>
    </div>
</div>

Note the ul with class app-list. We’ll be populating our items into this list. On the LoginHome page, we have a link in the top bar called Wish List. Let’s attach an event to that link to load the WishList page when clicked.

$(page)
    .find('#btnShowList')
    .on('click', function () {
        App.load('WishList', user);
    });

Now we need to declare the controller method for the WishList page. Inside the controller, we need to define a click event to load LoginHome when clicked on the button in the top bar. We also need to fetch data from firebase and bind it to the ul with class app-list. Here is the controller code:

App.controller('WishList', function (page, user) {
    $(page)
        .find('.app-button')
        .on('click', function () {
            App.load('LoginHome', user); //Loading LoginHome page
        });

    // Fetching data from Firebase and passing it to show function
    new Firebase('https://burning-fire-1723.firebaseio.com/WishList')
        .once('value', show);

    function show(snap) {
        $.each(snap.val(), function (i, value) {
            var spanText = $('<span/>').css('font-weight', 'bold').text(value.text);
            var spanUser = $('<span/>').text(' by:: ' + value.user_id);
            $(page).find('.app-list').append($('<li/>').append(spanText, spanUser));
        });
    }
});

Try browsing to index.htmland everything should be working.

Conclusion

In this tutorial, we used some features of app.js to create a small app. We only focused on a limited number of features like app-page,app-list and app.dialog. All the features and functionality provided by app.js can found in the App.js docs.

Source code from this tutorial is available on GitHub.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Bruno Seixas

    Thanks for the tutorial.
    There´s a lot of Front-end HTML5 frameworks to develop Mobile Hybrid Apps…it´s like JavaScript MVC frameworks… more and more appear…kinda like pokemons ;p

    After looking into App.js it seems that is very lightweight comparing to others like Ionic.

    • http://www.techillumination.in Jay

      Thnks for the feedback @disqus_iN6qlRgNbk:disqus . Ya this one seems to quite lightweight :)

  • http://www.i-visionblog.com s.shivasurya

    nice one!

    • http://www.techillumination.in Jay

      Thnks @shivasurya:disqus

  • Aankhen

    App.js is built to serve makers of static single-page apps. This means
    that it keeps all page navigation within the session of the webpage,
    defining “pages” as DOM nodes that can be instantiated

    Oy vey. *facepalms*

  • http://www.techillumination.in Jay

    I tried to include some codepen demo’s but the CDN was throwing some wierd errors. Anywaz u can simply clone it from github and browse :)

  • http://www.techillumination.in Jay

    It off course seems quite light compared to IONIC @Maurice

  • http://ricardozea.me/ Ricardo Zea

    Any specific reason why you are using jQuery 1.9.0 and not 1.11.1 (the latest version at the moment of this post)?

    • http://www.techillumination.in Jay

      No specific reasons @ricardozea:disqus :)

  • http://www.techillumination.in Jay

    @zeno I think the last updates was just a month ago …. here is the github link https://github.com/kikinteractive/app

  • matthew murfitt

    Thank you for the crash course!

  • codenchips

    I tried a roll my own approach then moved to app.js which I foundto be a great lightweight solution. For me though, it’s too light and I’ve ended up with JQM which has some nice features – also you don’t have to use the JQM themes at all, they are designed to be overridden.