Home / Cordova

Cordova

Handlebars Templates Using Cordova

Writing HTML fragments in JavaScript and programmatically inserting them into the DOM is tedious. It makes your application harder to write and harder to maintain. HTML templates address this issue by decoupling the UI definition (HTML markup) from your code. There are a number of great HTML template solutions, including Mustache.js, Handlebars.js, and Underscore.js to name a few.
In this module, we create two templates to streamline the code of the Employee Directory application. We use Handlebars.js but the same result can be achieved using the other HTML template solutions.

Step 1: Define the templates
Modify index.html as follows:

1.0 Add a script tag to include the handlebars.js library:

<script src="lib/handlebars.js"></script>

1.1 Add ratchet.css and styles.css to the head of index.html

<link href="assets/ratchet/css/ratchet.css" rel="stylesheet">
<link href="assets/css/styles.css" rel="stylesheet">

1.2 Create an HTML template to render the Home View. Add this script tag as the first child of the body tag:

<script id="home-tpl" type="text/template">
    <header class="bar bar-nav">
        <h1 class="title">Directory</h1>
    </header>
    <div class="bar bar-standard bar-header-secondary">
        <input class='search-key' type="search"/>
    </div>
    <div class="content"></div>
</script>

1.3 Create an HTML template to render the employee list. Add this script tag immediately after the previous one:

<script id="employee-list-tpl" type="text/template">
    <ul class="table-view">
        {{#each this}}
        <li class="table-view-cell media">
          <a href="#employees/{{ id }}">
              <img class="media-object pull-left" src="assets/pics/{{pic}}">
              <div class="media-body">
                  {{firstName}} {{lastName}}
                  <p>{{title}}</p>
              </div>
          </a>
        </li>
        {{/each}}
    </ul>
</script>

Step 2: Use the Templates

Modify the immediate function in app.js as follows:

2.0 Immediately before the service variable declaration, declare two variables that hold the compiled version of the templates defined above:

    var homeTpl = Handlebars.compile($("#home-tpl").html());
    var employeeListTpl = Handlebars.compile($("#employee-list-tpl").html());

2.1 Modify renderHomeView() to use the homeTpl template instead of the inline HTML:

function renderHomeView() {
    $('body').html(homeTpl());
    $('.search-key').on('keyup', findByName);
}

2.2 Modify findByName() to use the employeeListTpl template instead of the inline HTML:

function findByName() {
    service.findByName($('.search-key').val()).done(function (employees) {
        $('.content').html(employeeListTpl(employees));
    });
}

2.3 Test the application.

Step 3: Fixing the Status Bar Issue on iOS7

In iOS7, the status bar overlaps the application views. As a result, the status bar text may collide with the application’s header text as shown in the screenshot above. You can fix this issue using the statusbar plugin.
3.0 Add the status bar plugin:

cordova plugins add org.apache.cordova.statusbar

3.1 In app.js, add the following code at the top of the deviceready handler:

StatusBar.overlaysWebView( false );
StatusBar.backgroundColorByHexString('#ffffff');
StatusBar.styleDefault();

3.2 Finally, Build the application again and test your application in the iOS emulator or on an iOS device.

Camera API Using Cordova

You use the Cordova Camera API to provide the user with the ability to take a picture of an employee, and use that picture as the employee’s picture in the application. We do not persist that picture in this sample application.
The code below only works when running the application on your device as a Cordova app. In other words, you can’t test it in a browser on the desktop.

1. Add the camera plugin to your project:

cordova plugin add org.apache.cordova.camera

2. In index.html, add the following list item to the employee template: See this Template Tutorial


<li class="table-view-cell media">
  <a hre="#" class="push-right change-pic-btn">
      <span class="media-object pull-left"></span>
      <div class="media-body">
          Change Picture
      </div>
  </a>
</li>

3. In the initialize() function of EmployeeView, register an event listener for the click event of the Change Picture list item:

this.$el.on('click', '.change-pic-btn', this.changePicture);

4. In EmployeeView, define the changePicture event handler as follows:

this.changePicture = function(event) {
  event.preventDefault();
  if (!navigator.camera) {
      alert("Camera API not supported", "Error");
      return;
  }
  var options =   {   quality: 50,
                      destinationType: Camera.DestinationType.DATA_URL,
                      sourceType: 1,      // 0:Photo Library, 1=Camera, 2=Saved Album
                      encodingType: 0     // 0=JPG 1=PNG
                  };

  navigator.camera.getPicture(
      function(imgData) {
          $('.media-object', this.$el).attr('src', "data:image/jpeg;base64,"+imgData);
      },
      function() {
          alert('Error taking picture', 'Error');
      },
      options);

  return false;
};

5. Finally Test the Application 🙂