Easy Tutorial
❮ Ionic Ion Tabs Ionic Ion Header Bar ❯

Creating an Ionic App

In the previous chapters, we have learned how to import the Ionic framework into our project.

Next, we will introduce how to create an Ionic app.

Creating an Ionic app uses HTML, CSS, and JavaScript. So, we can create a www directory and an index.html file within it, with the following code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Todo</title>
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">

    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- File included in apps created with Cordova/PhoneGap, provided by Cordova/PhoneGap (shows 404 during development) -->
    <script src="cordova.js"></script>
  </head>
  <body>
  </body>
</html>

In the above code, we have included the Ionic CSS file, Ionic JS file, and the Ionic AngularJS extension ionic.bundle.js.

The ionic.bundle.js file already includes the Ionic core JS, AngularJS, and Ionic's AngularJS extensions. If you need to include other Angular modules, you can call them from the lib/js/angular directory.

The cordova.js file is generated when using Cordova/PhoneGap to create an app and does not need to be manually included. You can find this file in your Cordova/PhoneGap project, so it is normal to show a 404 during development.


Creating the App

Next, we will implement an app that includes a title, sidebar, list, etc., as shown in the design below:

Creating the Sidebar

The sidebar is created using the ion-side-menus controller.

Edit the previously created index.html file and modify the content inside the <body> tag as follows:

<body>
  <ion-side-menus>
    <ion-side-menu-content>
    </ion-side-menu-content>
    &lt;ion-side-menu side="left">
    </ion-side-menu>
  </ion-side-menus>
</body>

Controller explanation:

Initializing the App

Next, we create a new AngularJS module and initialize it. The code is located in www/js/app.js:

angular.module('todo', ['ionic'])
<body ng-app="todo">

Include the app.js file above the <script src="cordova.js"></script> in the index.html file:

<script src="js/app.js"></script>

Modify the content of the body tag in the index.html file as follows:

<body ng-app="todo">
  <ion-side-menus>

    <!-- Center content -->
    <ion-side-menu-content>
      &lt;ion-header-bar class="bar-dark">
        <h1 class="title">Todo</h1>
      </ion-header-bar>
      <ion-content>
      </ion-content>
    </ion-side-menu-content>

    <!-- Left menu -->
    &lt;ion-side-menu side="left">
      &lt;ion-header-bar class="bar-dark">
        <h1 class="title">Projects</h1>
      </ion-header-bar>
      <ion-content>
      </ion-content>
    </ion-side-menu>

  </ion-side-menus>
</body>
</ion-header-bar>
    </ion-side-menu>

  </ion-side-menus>
</body>

Try it out »

Following the steps above, we have completed the basic setup of an Ionic app.


Creating a List

First, create a controller TodoCtrl:

<body ng-app="todo" ng-controller="TodoCtrl">

In the app.js file, define the list data using the controller:

angular.module('todo', ['ionic'])

.controller('TodoCtrl', function($scope) {
  $scope.tasks = [
    { title: 'tutorialpro.org' },
    { title: 'www.tutorialpro.org' },
    { title: 'tutorialpro.org' },
    { title: 'www.tutorialpro.org' }
  ];
});

In the index.html page, use Angular ng-repeat to iterate over the data for the list:

<!-- Center content -->
<ion-side-menu-content>
  &lt;ion-header-bar class="bar-dark">
    <h1 class="title">Todo</h1>
  </ion-header-bar>
  <ion-content>
    <!-- List -->
    <ion-list>
      &lt;ion-item ng-repeat="task in tasks">
        {{task.title}}
      </ion-item>
    </ion-list>
  </ion-content>
</ion-side-menu-content>

The modified code within the body tag of index.html is as follows:

<body ng-app="todo" ng-controller="TodoCtrl">
    <ion-side-menus>

    <!-- Center content -->
    <ion-side-menu-content>
      &lt;ion-header-bar class="bar-dark">
        <h1 class="title">Todo</h1>
      </ion-header-bar>
      <ion-content>
        <!-- List -->
        <ion-list>
          &lt;ion-item ng-repeat="task in tasks">
            {{task.title}}
          </ion-item>
        </ion-list>
      </ion-content>
    </ion-side-menu-content>

    <!-- Left menu -->
    &lt;ion-side-menu side="left">
      &lt;ion-header-bar class="bar-dark">
        <h1 class="title">Projects</h1>
      </ion-header-bar>
    </ion-side-menu>

    </ion-side-menus>
    <script src="http://www.tutorialpro.org/static/ionic/js/app.js"></script>
    <script src="cordova.js"></script>
</body>

Try it out »


Creating an Add Page

Modify index.html by adding the following code after </ion-side-menus>:

<script id="new-task.html" type="text/ng-template">

  <div class="modal">

    <!-- Modal header bar -->
    &lt;ion-header-bar class="bar-secondary">
      <h1 class="title">New Task</h1>
<button class="button button-clear button-positive" ng-click="closeNewTask()">Cancel</button>
</ion-header-bar>

<!-- Modal content area -->
<ion-content>

  <form ng-submit="createTask(task)">
    <div class="list">
      <label class="item item-input">
        <input type="text" placeholder="What do you need to do?" ng-model="task.title">
      </label>
    </div>
    <div class="padding">
      <button type="submit" class="button button-block button-positive">Create Task</button>
    </div>
  </form>

</ion-content>

</div>

</script>

In the above code, we define a new template page using <script id="new-task.html" type="text/ng-template">.

The form submission triggers the createTask(task) function.

ng-model="task.title" assigns the form input data to the title property of the task object.

Modify the content within <ion-side-menu-content> as follows:

<!-- Center content -->
<ion-side-menu-content>
&lt;ion-header-bar class="bar-dark">
  <h1 class="title">Todo</h1>
  <!-- New button -->
  <button class="button button-icon" ng-click="newTask()">
    <i class="icon ion-compose"></i>
  </button>
</ion-header-bar>
<ion-content>
  <!-- List -->
  <ion-list>
    &lt;ion-item ng-repeat="task in tasks">
      {{task.title}}
    </ion-item>
  </ion-list>
</ion-content>
</ion-side-menu-content>

In the app.js file, the controller code is as follows:

angular.module('todo', ['ionic'])

.controller('TodoCtrl', function($scope, $ionicModal) {
  $scope.tasks = [
    { title: 'tutorialpro.org' },
    { title: 'www.tutorialpro.org' },
    { title: 'tutorialpro.org' },
    { title: 'www.tutorialpro.org' }
  ];

  // Create and load the modal
  $ionicModal.fromTemplateUrl('new-task.html', function(modal) {
    $scope.taskModal = modal;
  }, {
    scope: $scope,
    animation: 'slide-in-up'
  });

  // Call on form submission
  $scope.createTask = function(task) {
    $scope.tasks.push({
      title: task.title
    });
    $scope.taskModal.hide();
    task.title = "";
  };

  // Open the new modal
  $scope.newTask = function() {
    $scope.taskModal.show();
  };

  // Close the new modal
  $scope.closeNewTask = function() {
    $scope.taskModal.hide();
  };
});

Creating a Sidebar

With the above steps, we have implemented the new task feature. Now, we will add a sidebar functionality to the app.


<!-- Main Content -->
<ion-side-menu-content>
  &lt;ion-header-bar class="bar-dark">
    <button class="button button-icon" ng-click="toggleProjects()">
      <i class="icon ion-navicon"></i>
    </button>
    <h1 class="title">{{activeProject.title}}</h1>
    <!-- Add Button -->
    <button class="button button-icon" ng-click="newTask()">
      <i class="icon ion-compose"></i>
    </button>
  </ion-header-bar>
  &lt;ion-content scroll="false">
    <ion-list>
      &lt;ion-item ng-repeat="task in activeProject.tasks">
        {{task.title}}
      </ion-item>
    </ion-list>
  </ion-content>
</ion-side-menu-content>

Add Sidebar:

<!-- Left Sidebar -->
&lt;ion-side-menu side="left">
&lt;ion-header-bar class="bar-dark">
  <h1 class="title">Projects</h1>
  <button class="button button-icon ion-plus" ng-click="newProject()">
  </button>
</ion-header-bar>
&lt;ion-content scroll="false">
  <ion-list>
    &lt;ion-item ng-repeat="project in projects" ng-click="selectProject(project, $index)" ng-class="{active: activeProject == project}">
      {{project.title}}
    </ion-item>
  </ion-list>
</ion-content>
</ion-side-menu>

The ng-class directive in <ion-item> sets the active menu style.

Here we create a new JS file app2.js (to avoid confusion with the previous one), with the following code:

angular.module('todo', ['ionic'])
/**
 * The Projects factory handles saving and loading projects
 * from local storage, and also lets us save and load the
 * last active project index.
 */
.factory('Projects', function() {
  return {
    all: function() {
      var projectString = window.localStorage['projects'];
      if(projectString) {
        return angular.fromJson(projectString);
      }
      return [];
    },
    save: function(projects) {
      window.localStorage['projects'] = angular.toJson(projects);
    },
    newProject: function(projectTitle) {
      // Add a new project
      return {
        title: projectTitle,
        tasks: []
      };
    },
    getLastActiveIndex: function() {
      return parseInt(window.localStorage['lastActiveProject']) || 0;
    },
    setLastActiveIndex: function(index) {
      window.localStorage['lastActiveProject'] = index;
    }
  }
})
.controller('TodoCtrl', function($scope, $timeout, $ionicModal, Projects, $ionicSideMenuDelegate) {

  // A utility function for creating a new project
  // with the given projectTitle
  var createProject = function(projectTitle) {
    var newProject = Projects.newProject(projectTitle);
    $scope.projects.push(newProject);
    Projects.save($scope.projects);
    $scope.selectProject(newProject, $scope.projects.length-1);
  }

  // Load or initialize projects
  $scope.projects = Projects.all();

  // Grab the last active, or the first project
  $scope.activeProject = $scope.projects[Projects.getLastActiveIndex()];

  // Called to create a new project
  $scope.newProject = function() {
    var projectTitle = prompt('Project name');
    if(projectTitle) {
      createProject(projectTitle);
    }
  };

  // Called to select the given project
  $scope.selectProject = function(project, index) {
    $scope.activeProject = project;
    Projects.setLastActiveIndex(index);
    $ionicSideMenuDelegate.toggleLeft(false);
  };

  // Create our modal
  $ionicModal.fromTemplateUrl('new-task.html', function(modal) {
    $scope.taskModal = modal;
  }, {
    scope: $scope
  });

  $scope.createTask = function(task) {
    if(!$scope.activeProject || !task) {
      return;
    }
    $scope.activeProject.tasks.push({
      title: task.title
    });
    $scope.taskModal.hide();

    // Inefficient, but save all the projects
    Projects.save($scope.projects);

    task.title = "";
  };

  $scope.newTask = function() {
    $scope.taskModal.show();
  };

  $scope.closeNewTask = function() {
    $scope.taskModal.hide();
  }

  $scope.toggleProjects = function() {
    $ionicSideMenuDelegate.toggleLeft();
  };

  // Try to create the first project, make sure to defer
  // this by using $timeout so everything is initialized
  // properly
  $timeout(function() {
    if($scope.projects.length == 0) {
      while(true) {
        var projectTitle = prompt('Your first project title:');
        if(projectTitle) {
          createProject(projectTitle);
          break;
        }
      }
    }
  });
});
<ion-side-menus>

<!-- Center Content -->
<ion-side-menu-content>
  &lt;ion-header-bar class="bar-dark">
    <button class="button button-icon" ng-click="toggleProjects()">
      <i class="icon ion-navicon"></i>
    </button>
    <h1 class="title">{{activeProject.title}}</h1>
    <!-- New Button -->
    <button class="button button-icon" ng-click="newTask()">
      <i class="icon ion-compose"></i>
    </button>
  </ion-header-bar>
  &lt;ion-content scroll="false">
    <ion-list>
      &lt;ion-item ng-repeat="task in activeProject.tasks">
        {{task.title}}
      </ion-item>
    </ion-list>
  </ion-content>
</ion-side-menu-content>

<!-- Left Sidebar -->
&lt;ion-side-menu side="left">
&lt;ion-header-bar class="bar-dark">
  <h1 class="title">Projects</h1>
  <button class="button button-icon ion-plus" ng-click="newProject()">
  </button>
</ion-header-bar>
&lt;ion-content scroll="false">
  <ion-list>
    &lt;ion-item ng-repeat="project in projects" ng-click="selectProject(project, $index)" ng-class="{active: activeProject == project}">
      {{project.title}}
    </ion-item>
  </ion-list>
</ion-content>
</ion-side-menu>

</ion-side-menus>

Try it »

❮ Ionic Ion Tabs Ionic Ion Header Bar ❯