Laravel and AngularJS CRUD with Search & Pagination Example

Share Me
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Today now in this blog i show you how to create CRUD(Create, Read, Update, Delete) operation by using AngularJS and Laravel . Now in following step by step we can create a web application of create, edit, delete, lists, search . Also with pagination of items modules. Now In this post through we can make a simple crud, search and pagination module and easily use in our laravel project.

Step 1: Create items table and module

At in first step we need to create a migration for items table by using Laravel php artisan command. So now first need to fire bellow command:

php artisan make:migration create_items_table

So after this command we will find one file in following path database/migrations  and we need to put bellow code in our migration file for create items table.

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateItemsTable extends Migration
{
    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('description');
            $table->timestamps();
        });
    }
    public function down()
    {
        Schema::drop("items");
    }
}

So after the create “items” table we need to create Item model for items, so at first create file in this path app/Models/Item.php and now need to put bellow content in item.php file:

app/Models/Item.php
namespace App;
use Illuminate\Database\Eloquent\Model;
use DB;
class Item extends Model
{
    public $fillable = ['title','description'];
}
Step 2: Create controller

Ok good, now we should create a new controller as name ItemController in this on this path app/Http/Controllers/ItemController.php. Now in this controller i will manage all lists, create, edit, delete ,search and pagination request and it return json response, so need to put bellow content in controller file:

app/Http/Controllers/ItemController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Item;
class ItemController extends Controller
{
    public function index(Request $request)
    {
        $input = $request->all();
        if($request->get('search')){
            $items = Item::where("title", "LIKE", "%{$request->get('search')}%")
                ->paginate(5);      
        }else{
		  $items = Item::paginate(5);
        }
        return response($items);
    }
    public function store(Request $request)
    {
    	$input = $request->all();
        $create = Item::create($input);
        return response($create);
    }
    public function edit($id)
    {
        $item = Item::find($id);
        return response($item);
    }
    public function update(Request $request,$id)
    {
    	$input = $request->all();
        Item::where("id",$id)->update($input);
        $item = Item::find($id);
        return response($item);
    }
    public function destroy($id)
    {
        return Item::where('id',$id)->delete();
    }
}
Step 3: Route file

So now in this step we need to add some route in our route file. So at first we will add a resource route for items module and the another one for templates route. So this templates route through we will get html template for our application, So it put the bellow content in route file:

app/Http/routes.php
Route::get('/', function () {
    return view('app');
});
Route::group(['middleware' => ['web']], function () {
    Route::resource('items', 'ItemController');
});
// Templates
Route::group(array('prefix'=>'/templates/'),function(){
    Route::get('{template}', array( function($template)
    {
        $template = str_replace(".html","",$template);
        View::addExtension('html','php');
        return View::make('templates.'.$template);
    }));
});
Step 4: use AngularJS

So now we will manage a AngularJS route and controller, so at first create a “app” directory in our public folder(public/app) and then need to create a route.js(public/app/route.js) file for write the all angular js. and then need put the bellow code in that file.

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'
            });
}]);

So now we have to create one folder in our app folder as name “controllers” and then need to create one file “ItemController.js”(public/app/controllers/ItemController.js) file in that folder.

ItemController.js
app.controller('AdminController', function($scope,$http){
  $scope.pools = [];
});
app.controller('ItemController', function(dataFactory,$scope,$http){
  $scope.data = [];
  $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;
          });
      }else{
        dataFactory.httpRequest('/items?page='+pageNumber).then(function(data) {
          $scope.data = data.data;
          $scope.totalItems = data.total;
        });
      }
  }
  $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('items','POST',{},$scope.form).then(function(data) {
      $scope.data.push(data);
      $(".modal").modal("hide");
    });
  }
  $scope.edit = function(id){
    dataFactory.httpRequest('items/'+id+'/edit').then(function(data) {
    	console.log(data);
      	$scope.form = data;
    });
  }
  $scope.saveEdit = function(){
    dataFactory.httpRequest('items/'+$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('items/'+item.id,'DELETE').then(function(data) {
          $scope.data.splice(index,1);
      });
    }
  }
});

So we need to create a another folder as name “helper” in app directory for myHelper.js(public/app/helper/myHelper.js) file because that the file will help to define helper function.

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

So now need to create one another folder as name “packages” and create file dirPagination.js(public/app/packages/dirPagination.js) and then need to put code of following link:

dirPagination.js

Ok, now at last we need to create another one folder call as “services” and create file myServices.js(public/app/services/myServices.js).

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;
      }
      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

So now this is a last step and we need to create first app.blade.php file for the theme setting, so let’s create a app.blade.php(resources/views/app.blade.php) and then need to put following code :

app.blade.php
<html lang="en">
<head>
	<title>Laravel </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="{{ asset('/app/packages/dirPagination.js') }}"></script>
	<script src="{{ asset('/app/routes.js') }}"></script>
	<script src="{{ asset('/app/services/myServices.js') }}"></script>
	<script src="{{ asset('/app/helper/myHelper.js') }}"></script>
	<!-- App Controller -->
	<script src="{{ asset('/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="#">Laravel 5.2</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>

Okay food, so now we need to create a templates folder in the views folder and then need to add three html file, now i am going to create that so give name properly and add that.

1.resources/views/templates/home.html
<h2>Welcome to Dashboard</h2>
2.resources/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.resources/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>

Read Also : How to push item to 0 index or first of $scope object in AngularJS?

Thanks for read. I hope it help you. For more you can follow us on facebook.

About code chef

My name is Shahriar sagor. I'm a developer. I live in Bangladesh and I love to write tutorials and tips that will help to other Developer's. I am a big fan of PHP, Javascript, JQuery, Laravel, Codeigniter, VueJS, AngularJS and Bootstrap from the early stage.

View all posts by code chef →