Codeigniter 3 and AngularJS CRUD with Search and Pagination Example.
In This tutorial i want to show you how to create CRUD(Create, Read, Update, Delete) using AngularJS in Codeigniter. I added few step to create create, edit, delete, lists, search and pagination application in your Codeigniter framework. In this tutorial through you can make simple crud, search and pagination module and easily use in your codeigniter project. I am going to show preview of items module that we will do using angularJS and Codeigniter 3.
Preview:
Step 1: Create items table
In this first step we have to configration of our Codeigniter 3 project, so first go on application/config/database.php, In this file you have to add your database name, username and password, then we have to create items table in 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 ;
Step 2: Route file
In this step you have to add some route in your route file.So first we will create templates route, templates route through we will get html template for our application, Then we will create other route for items modules for lists, create, edit, update and delete.so put the bellow content in 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";
Step 3: Create controller
Ok, now first we have to create two new controller one for templates route and another for items route, so first create new templates controller in this path application/controllers/Templates.php and put bellow content in that file:
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);
}
}
Now create second controller for items modules, in this controller we will add function for listing, create, edit, update and delete. so create Items.php file in this path application/controllers/Items.php and put bellow code in this file:
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]);
}
}
Step 4: use AngularJS
Now we will manage AngularJS route and controller, so first cretae "app" directory in your main folder (app)(I mean out side application folder) and create route.js(app/route.js) file for write all angular js. and put the bellow code in that file.
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 have to create one folder in your app folder "controllers" and create one file "ItemController.js"(app/controllers/ItemController.js) file 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 have to create another folder "helper" in app directory for myHelper.js(app/helper/myHelper.js) file because that file will help to define 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 one another folder "packages" and create file dirPagination.js(app/packages/dirPagination.js) and put code of following link:
Ok, at last you have create another one folder call "services" and create file 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;
});
Step 5: Create View
This is a last step and you have to modify first welcome_message.php file for theme setting, so let's modify welcome_message.php(application/views/welcome_message.php) and put 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 templates folder in views folder and need to add three html file, i am going to create that so give name properly and add that.
1.application/views/templates/home.html
<h2>Welcome to Dashboard</h2>
2.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>
3.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>
Ok, now we are ready to run our web application with crud, search and pagination, open your laravel application in browser and check pls,
IF you want to download this from git then you can download from here GitHub
Hardik Savani
I'm a full-stack developer, entrepreneur and owner of ItSolutionstuff.com. I live in India and I love to write tutorials and tips that can help to other artisan. I am a big fan of PHP, Laravel, Angular, Vue, Node, Javascript, JQuery, Codeigniter and Bootstrap from the early stage. I believe in Hardworking and Consistency.