Codeigniter 3 and AngularJS CRUD with Search and Pagination Tutorial.

In this tutorial, I’ll show you how to use AngularJS to create CRUD (Create, Read, Update, Delete) forms in Codeigniter. I added a few steps to your Codeigniter framework to create, edit, delete, lists, search, and pagination application. In this tutorial, you will learn how to create a simple crud, search, and pagination module for use in your codeigniter project. I’ll show a preview of the items module that we’ll create with angularJS and Codeigniter 3.

Preview:

Codeigniter 3 and AngularJS CRUD with Search and Pagination Tutorial

Table of Contents

  • Step 1: Create items table.
  • Step 2: Route file.
  • Step 3: Create controller.
  • Step 4: Use AngularJS.
  • Step 5: Create View.

Create items table

In this first step, we must configure our Codeigniter 3 project, so navigate to application/config/database.php and enter your database name, username, and password. Next, we must create the items table using the following sql query:

CREATE TABLE IF NOT EXISTS `items` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `description` text COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=16 ;

Route file

In this step, you must include a route in your route file. So, first, we will create a templates route, through which we will obtain an html template for our application. Next, we will create another route for items modules for lists, which will allow us to create, edit, update, and delete items. Put the following content in the route file:

application/config/routes.php

defined('BASEPATH') OR exit('No direct script access allowed');
$route['default_controller'] = 'welcome';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
$route['templates/(:any)'] = "templates/view/$1";
$route['items'] = "items/index";
$route['itemsCreate']['post'] = "items/store";
$route['itemsEdit/(:any)'] = "items/edit/$1";
$route['itemsUpdate/(:any)']['put'] = "items/update/$1";
$route['itemsDelete/(:any)']['delete'] = "items/delete/$1";

Create controller

Ok, now we need to create two new controllers, one for the templates route and another for the items route, so first create a new templates controller in this path application/controllers/Templates.php with the following content:

application/controllers/Templates.php

defined('BASEPATH') OR exit('No direct script access allowed');
class Templates extends CI_Controller {
	public function view($view)
	{
		$this->load->view('templates/'.$view);
	}
}

Create a second controller for the items modules, and include functions for listing, creating, editing, updating, and deleting. Create an Items.php file in the path application/controllers/Items.php and paste the following code into it:

application/controllers/Items.php

defined('BASEPATH') OR exit('No direct script access allowed');
class Items extends CI_Controller {
	public function index()
	{
		$this->load->database();
		if(!empty($this->input->get("search"))){
			$this->db->like('title', $this->input->get("search"));
			$this->db->or_like('description', $this->input->get("search")); 
		}
		$this->db->limit(5, ($this->input->get("page",1) - 1) * 5);
		$query = $this->db->get("items");
		$data['data'] = $query->result();
		$data['total'] = $this->db->count_all("items");
		echo json_encode($data);
	}
	public function store()
    {
    	$this->load->database();
    	$_POST = json_decode(file_get_contents('php://input'), true);
    	$insert = $this->input->post();
		$this->db->insert('items', $insert);
		$id = $this->db->insert_id();
		$q = $this->db->get_where('items', array('id' => $id));
		echo json_encode($q->row());
    }
    public function edit($id)
    {
    	$this->load->database();
		$q = $this->db->get_where('items', array('id' => $id));
		echo json_encode($q->row());
    }
    public function update($id)
    {
    	$this->load->database();
    	$_POST = json_decode(file_get_contents('php://input'), true);
    	$insert = $this->input->post();
    	$this->db->where('id', $id);
    	$this->db->update('items', $insert);
        $q = $this->db->get_where('items', array('id' => $id));
		echo json_encode($q->row());
    }
    public function delete($id)
    {
    	$this->load->database();
        $this->db->where('id', $id);
		$this->db->delete('items');
		echo json_encode(['success'=>true]);
    }
}

Use AngularJS

Now we will manage AngularJS routes and controllers, so first create a “app” directory in your main folder (app)(I mean outside application folder) and create a route.js (app/route.js) file to write all angular js. and paste the code below into it.

app/route.js

var app =  angular.module('main-App',['ngRoute','angularUtils.directives.dirPagination']);
app.config(['$routeProvider',
    function($routeProvider) {
        $routeProvider.
            when('/', {
                templateUrl: 'templates/home.html',
                controller: 'AdminController'
            }).
            when('/items', {
                templateUrl: 'templates/items.html',
                controller: 'ItemController'
            });
}]);

Now we must create a folder “controllers” in your app folder and a file “ItemController.js” (app/controllers/ItemController.js) in that folder.

app/controllers/ItemController.js

app.controller('AdminController', function($scope,$http){
  $scope.pools = [];
});
app.controller('ItemController', function(dataFactory,$scope,$http){
  $scope.data = [];
  $scope.pageNumber = 1;
  $scope.libraryTemp = {};
  $scope.totalItemsTemp = {};
  $scope.totalItems = 0;
  $scope.pageChanged = function(newPage) {
    getResultsPage(newPage);
  };
  getResultsPage(1);
  function getResultsPage(pageNumber) {
      if(! $.isEmptyObject($scope.libraryTemp)){
          dataFactory.httpRequest('/items?search='+$scope.searchText+'&page='+pageNumber).then(function(data) {
            $scope.data = data.data;
            $scope.totalItems = data.total;
            $scope.pageNumber = pageNumber;
          });
      }else{
        dataFactory.httpRequest('/items?page='+pageNumber).then(function(data) {
          $scope.data = data.data;
          $scope.totalItems = data.total;
          $scope.pageNumber = pageNumber;
        });
      }
  }
  $scope.searchDB = function(){
      if($scope.searchText.length >= 3){
          if($.isEmptyObject($scope.libraryTemp)){
              $scope.libraryTemp = $scope.data;
              $scope.totalItemsTemp = $scope.totalItems;
              $scope.data = {};
          }
          getResultsPage(1);
      }else{
          if(! $.isEmptyObject($scope.libraryTemp)){
              $scope.data = $scope.libraryTemp ;
              $scope.totalItems = $scope.totalItemsTemp;
              $scope.libraryTemp = {};
          }
      }
  }
  $scope.saveAdd = function(){
    dataFactory.httpRequest('itemsCreate','POST',{},$scope.form).then(function(data) {
      $scope.data.push(data);
      $(".modal").modal("hide");
    });
  }
  $scope.edit = function(id){
    dataFactory.httpRequest('itemsEdit/'+id).then(function(data) {
    	console.log(data);
      	$scope.form = data;
    });
  }
  $scope.saveEdit = function(){
    dataFactory.httpRequest('itemsUpdate/'+$scope.form.id,'PUT',{},$scope.form).then(function(data) {
      	$(".modal").modal("hide");
        $scope.data = apiModifyTable($scope.data,data.id,data);
    });
  }
  $scope.remove = function(item,index){
    var result = confirm("Are you sure delete this item?");
   	if (result) {
      dataFactory.httpRequest('itemsDelete/'+item.id,'DELETE').then(function(data) {
          $scope.data.splice(index,1);
      });
    }
  }
});

We must create a new folder “helper” in the app directory for the myHelper.js (app/helper/myHelper.js) file because it will be used to define the helper function.

app/helper/myHelper.js

function apiModifyTable(originalData,id,response){
    angular.forEach(originalData, function (item,key) {
        if(item.id == id){
            originalData[key] = response;
        }
    });
    return originalData;
}

Create a new folder “packages” and a file dirPagination.js (app/packages/dirPagination.js) with the following code:

https://github.com/michaelbromley/angularUtils/blob/master/src/directives/pagination/dirPagination.js

Finally, create a new folder called “services” and a file called myServices.js (app/services/myServices.js).

app/services/myServices.js

app.factory('dataFactory', function($http) {
  var myService = {
    httpRequest: function(url,method,params,dataPost,upload) {
      var passParameters = {};
      passParameters.url = url;
      if (typeof method == 'undefined'){
        passParameters.method = 'GET';
      }else{
        passParameters.method = method;
      }
      if (typeof params != 'undefined'){
        passParameters.params = params;
        passParameters.params = params;
      }
      if (typeof dataPost != 'undefined'){
        passParameters.data = dataPost;
      }
      if (typeof upload != 'undefined'){
         passParameters.upload = upload;
      }
      var promise = $http(passParameters).then(function (response) {
        if(typeof response.data == 'string' && response.data != 1){
          if(response.data.substr('loginMark')){
              location.reload();
              return;
          }
          $.gritter.add({
            title: 'Application',
            text: response.data
          });
          return false;
        }
        if(response.data.jsMessage){
          $.gritter.add({
            title: response.data.jsTitle,
            text: response.data.jsMessage
          });
        }
        return response.data;
      },function(){
        $.gritter.add({
          title: 'Application',
          text: 'An error occured while processing your request.'
        });
      });
      return promise;
    }
  };
  return myService;
});

Create View

This is the final step, and you must first modify the welcome_message.php file for theme configuration, so let’s modify welcome_message.php (application/views/welcome_message.php) and insert the following code:

application/views/welcome_message.php

<html lang="en">
<head>
	<title>Codeigniter 3</title>
	<!-- Fonts -->
	<link href='//fonts.googleapis.com/css?family=Roboto:400,300' rel='stylesheet' type='text/css'>
	<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
	<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
	<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
	<!-- Angular JS -->
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>  
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular-route.min.js"></script>
	<!-- MY App -->
	<script src="app/packages/dirPagination.js"></script>
	<script src="app/routes.js"></script>
	<script src="app/services/myServices.js"></script>
	<script src="app/helper/myHelper.js"></script>
	<!-- App Controller -->
	<script src="app/controllers/ItemController.js"></script>
</head>
<body ng-app="main-App">
	<nav class="navbar navbar-default">
		<div class="container-fluid">
			<div class="navbar-header">
				<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
					<span class="sr-only">Toggle Navigation</span>
					<span class="icon-bar"></span>
					<span class="icon-bar"></span>
					<span class="icon-bar"></span>
				</button>
				<a class="navbar-brand" href="#">Codeigniter 3</a>
			</div>
			<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
				<ul class="nav navbar-nav">
					<li><a href="#/">Home</a></li>
					<li><a href="#/items">Item</a></li>
				</ul>
			</div>
		</div>
	</nav>
	<div class="container">
		<ng-view></ng-view>
	</div>
</body>
</html>

Ok, now we need to create a templates folder in the views folder and add three html files, which I will do, so give them proper names and add them.

  • application/views/templates/home.html
<h2>Welcome to Dashboard</h2>
  • application/views/templates/items.html
<div class="row">
    <div class="col-lg-12 margin-tb">
        <div class="pull-left">
            <h1>Item Management</h1>
        </div>
        <div class="pull-right" style="padding-top:30px">
            <div class="box-tools" style="display:inline-table">
              <div class="input-group">
                  <input type="text" class="form-control input-sm ng-valid ng-dirty" placeholder="Search" ng-change="searchDB()" ng-model="searchText" name="table_search" title="" tooltip="" data-original-title="Min character length is 3">
                  <span class="input-group-addon">Search</span>
              </div>
            </div>
            <button class="btn btn-success" data-toggle="modal" data-target="#create-user">Create New</button>
        </div>
    </div>
</div>
<table class="table table-bordered pagin-table">
    <thead>
        <tr>
            <th>No</th>
            <th>Title</th>
            <th>Description</th>
            <th width="220px">Action</th>
        </tr>
    </thead>
    <tbody>
        <tr dir-paginate="value in data | itemsPerPage:5" total-items="totalItems">
            <td>{{ $index + 1 }}</td>
            <td>{{ value.title }}</td>
            <td>{{ value.description }}</td>
            <td>
            <button data-toggle="modal" ng-click="edit(value.id)" data-target="#edit-data" class="btn btn-primary">Edit</button>
            <button ng-click="remove(value,$index)" class="btn btn-danger">Delete</button>
            </td>
        </tr>
    </tbody>
</table>
<dir-pagination-controls class="pull-right" on-page-change="pageChanged(newPageNumber)" template-url="templates/dirPagination.html" ></dir-pagination-controls>
<!-- Create Modal -->
<div class="modal fade" id="create-user" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <form method="POST" name="addItem" role="form" ng-submit="saveAdd()">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                <h4 class="modal-title" id="myModalLabel">Create Item</h4>
            </div>
            <div class="modal-body">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-6 col-md-6">
                            <strong>Title : </strong>
                            <div class="form-group">
                                <input ng-model="form.title" type="text" placeholder="Name" name="title" class="form-control" required />
                            </div>
                        </div>
                        <div class="col-xs-12 col-sm-6 col-md-6">
                            <strong>Description : </strong>
                            <div class="form-group" >
                                <textarea ng-model="form.description" class="form-control" required>
                                </textarea>
                            </div>
                        </div>
                    </div>
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                    <button type="submit" ng-disabled="addItem.$invalid" class="btn btn-primary">Submit</button>
                </div>
            </div>
            </form>
        </div>
    </div>
</div>
</div>
<!-- Edit Modal -->
<div class="modal fade" id="edit-data" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <form method="POST" name="editItem" role="form" ng-submit="saveEdit()">
                <input ng-model="form.id" type="hidden" placeholder="Name" name="name" class="form-control" />
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                <h4 class="modal-title" id="myModalLabel">Edit Item</h4>
            </div>
            <div class="modal-body">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-6 col-md-6">
                            <div class="form-group">
                               <input ng-model="form.title" type="text" placeholder="Name" name="title" class="form-control" required />
                            </div>
                        </div>
                        <div class="col-xs-12 col-sm-6 col-md-6">
                            <div class="form-group">
                               <textarea ng-model="form.description" class="form-control" required>
                                </textarea>
                            </div>
                        </div>
                    </div>
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                    <button type="submit" ng-disabled="editItem.$invalid" class="btn btn-primary create-crud">Submit</button>
                </div>
            </div>
            </form>
        </div>
    </div>
</div>
</div>
  • application/views/templates/dirPagination.html
<ul class="pagination pull-right" ng-if="1 < pages.length">
    <li ng-if="boundaryLinks" ng-class="{ disabled : pagination.current == 1 }">
        <a href="" ng-click="setCurrent(1)">«</a>
    </li>
    <li ng-if="directionLinks" ng-class="{ disabled : pagination.current == 1 }">
        <a href="" ng-click="setCurrent(pagination.current - 1)">‹</a>
    </li>
    <li ng-repeat="pageNumber in pages track by $index" ng-class="{ active : pagination.current == pageNumber, disabled : pageNumber == '...' }">
        <a href="" ng-click="setCurrent(pageNumber)">{{ pageNumber }}</a>
    </li>
    <li ng-if="directionLinks" ng-class="{ disabled : pagination.current == pagination.last }">
        <a href="" ng-click="setCurrent(pagination.current + 1)">›</a>
    </li>
    <li ng-if="boundaryLinks"  ng-class="{ disabled : pagination.current == pagination.last }">
        <a href="" ng-click="setCurrent(pagination.last)">»</a>
    </li>
</ul>

Now that we’re ready to run our web application with crud, search, and pagination, launch your Codeigniter 3 application in a browser.

Leave a Reply