Creating a Simple Upload File with AngularJS Progress Bar and PHP/MySQLi

This tutorial tackles how to create a progress bar in Angular JS. Angular JS is a javascript framework maintained by Google and is capable of creating Single-Page Applications. In the case of this tutorial, we show our progress bar on file upload to track its progress. Increase your upload size by editing your php.ini for uploads.

Getting Started

I've used Bootstrap and Angular JS in this tutorial so you need an internet connection for them to work. Angular JS version = 1.5.7.

Creating our Database

First, we're going to create our database. "Apache" and "MySQL" Servers are required too in this tutorial. In my case I am using XAMPP as my virtual server.

  1. Open PHPMyAdmin.
  2. Click databases, create a database and name it as angular.
  3. After creating a database, click the SQL and copy/paste the below codes. See the image below for detailed instructions.
  1. CREATE TABLE `upload` (
  2.   `uploadid` int(11) NOT NULL AUTO_INCREMENT,
  3.   `original` varchar(150) NOT NULL,
  4.   `new` varchar(150) NOT NULL,
  5.   `type` varchar(10) NOT NULL,
  6. PRIMARY KEY(`uploadid`)
database sql

Creating the Interface

Next, this is our index which contains our upload form and our uploaded files table. Create a new file and copy/paste the script below and save it as index.php.

  1. <!DOCTYPE html>
  2. <html >
  3.     <title>AngularJS Progress Bar with PHP/MySQLi</title>
  4.     <meta charset="utf-8">
  5.     <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  6.     <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>  
  7. </head>
  8.     td{
  9.         word-break: break-all;
  10.     }
  11. <body ng-app="app" ng-controller="uploader" ng-init="fetch()">
  12. <div class="container">
  13.     <h1 class="page-header text-center">AngularJS Progress Bar with PHP/MySQLi</h1>
  14.     <div class="row">
  15.         <div class="col-md-3">
  16.             <h3 class="text-center">Upload File/s</h3>
  17.             <hr>
  18.             <label>File:</label>
  19.             <input type="file" file-input="files" multiple>
  20.             <hr>
  21.             <button class="btn btn-primary" ng-click="upload()"><span class="glyphicon glyphicon-download-alt"></span> Upload</button>
  22.             <progress id="progress" max="100" value="{{progressBar}}" ng-show="showProgress" style="height:30px; width:100%; margin-top:30px;"></progress>
  23.             <div class="text-center">{{progressCounter}}</div>
  24.             <div ng-show="error" class="alert alert-danger text-center" style="margin-top:30px;">
  25.                 <button type="button" class="close" ng-click="clearMessage()"><span aria-hidden="true">&times;</span></button>
  26.                 <span class="glyphicon glyphicon-remove"></span> {{ errorMessage }}
  27.             </div>
  28.             <div ng-show="success" class="alert alert-success text-center" style="margin-top:30px;">
  29.                 <button type="button" class="close" ng-click="clearMessage()"><span aria-hidden="true">&times;</span></button>
  30.                 <span class="glyphicon glyphicon-check"></span> {{ successMessage }}
  31.             </div>
  32.         </div>
  33.         <div class="col-md-9">
  34.             <table class="table table-bordered table-striped">
  35.                 <thead>
  36.                     <th width="25%">Original FileName</th>
  37.                     <th width="25%">New FileName</th>
  38.                     <th width="25%">Type</th>
  39.                     <th width="25%">File Location</th>
  40.                 </thead>
  41.                 <tbody>
  42.                     <tr ng-repeat="upload in uploads">
  43.                         <td>{{ upload.original }}</td>
  44.                         <td>{{ upload.new }}</td>
  45.                         <td>{{ upload.type }}</td>
  46.                         <td>upload/{{ upload.new }}</td>
  47.                     </tr>
  48.                 </tbody>
  49.             </table>
  50.             <!-- <div class="col-md-4" ng-repeat="image in images">
  51.                <img ng-src="upload/{{ image.filename }}" width="100%" height="250px" class="thumbnail">
  52.            </div> -->
  53.         </div>
  54.     </div>
  55. </div>
  56. <script src="angular.js"></script>
  57. </body>
  58. </html>

Creating the Script

This contains our angular.js codes.

  1. var app = angular.module('app', []);
  2. app.directive('fileInput', ['$parse', function ($parse) {
  3.     return {
  4.         restrict: 'A',
  5.         link: function($scope, elm, attrs){
  6.             elm.bind('change', function(){
  7.                 $parse(attrs.fileInput).assign($scope, elm[0].files);
  8.                 $scope.$apply();
  9.             });
  10.         }
  11.     }
  12. }]);
  13. app.controller('uploader', function($scope, $http){
  14.     $scope.showProgress = false;
  15.     $scope.error = false;
  16.     $scope.errorMessage = "";
  17.     $scope.success = false;
  18.     $scope.successMessage = "";
  19.     $scope.upload = function(){
  20.  
  21.         var uploadForm = new FormData();
  22.         angular.forEach($scope.files, function(file){
  23.             uploadForm.append('file[]', file);
  24.         });
  25.         $http.post('upload.php', uploadForm, {
  26.             transformRequest:angular.identity,
  27.             headers: {'Content-Type':undefined, 'Process-Data': false},
  28.             uploadEventHandlers: {
  29.                 progress: function (e) {
  30.                           if (e.lengthComputable) {
  31.                                 $scope.showProgress = true;
  32.                                 $scope.progressBar = (e.loaded / e.total) * 100;
  33.                                 $scope.progressCounter = $scope.progressBar.toFixed(2) + ' %';
  34.                           }
  35.                 }
  36.             }
  37.         })
  38.         .success(function(response){
  39.             console.log(response);
  40.             if(response.error){
  41.                 $scope.error = true;
  42.                 $scope.errorMessage = response.message;
  43.             }
  44.             else{
  45.                 $scope.success = true;
  46.                 $scope.successMessage = response.message;
  47.                 $scope.fetch();
  48.             }
  49.         })
  50.     }
  51.  
  52.     $scope.fetch = function(){
  53.         $http.get('fetch.php')
  54.         .success(function(data){
  55.             $scope.uploads = data;
  56.         });
  57.  
  58.     }
  59.  
  60.     $scope.clearMessage = function(){
  61.         $scope.error = false;
  62.         $scope.errorMessage = "";
  63.         $scope.success = false;
  64.         $scope.successMessage = "";
  65.     }  
  66. });

Creating a Fetch API and Saving Process

This is our PHP API/code that fetches our uploaded files.

fetch.php
  1. <?php
  2.     $conn = new mysqli('localhost', 'root', '', 'angular');
  3.     $output = array();
  4.     $sql = "SELECT * FROM upload";
  5.     $query=$conn->query($sql);
  6.     while($row=$query->fetch_array()){
  7.         $output[] = $row;
  8.     }
  9.  
  10.     echo json_encode($output);
  11. ?>

Lastly, this is our PHP code/API in uploading our files.

upload.php
  1. <?php
  2.  
  3.     $conn = new mysqli('localhost', 'root', '', 'angular');
  4.     $out = array('error' => false);
  5.  
  6.     if(!empty($_FILES['file']['name'])){
  7.         $count = count($_FILES['file']['name']);
  8.         foreach ($_FILES['file']['name'] as $key => $filename){
  9.             $newFilename = time() . "_" . $filename;
  10.  
  11.             $ext = strtoupper(pathinfo($filename, PATHINFO_EXTENSION));
  12.  
  13.             $path = 'upload/' . $newFilename;
  14.  
  15.             if(move_uploaded_file($_FILES['file']['tmp_name'][$key], $path)){
  16.                 $sql = "INSERT INTO upload (original, new, type) VALUES ('$filename', '$newFilename', '$ext')";
  17.                 $query=$conn->query($sql);
  18.             }
  19.                
  20.             if($query){
  21.                 if($count > 1){
  22.                     $out['message'] = 'Files Uploaded Successfully';
  23.                 }
  24.                 else{
  25.                     $out['message'] = 'File Uploaded Successfully';
  26.                 }
  27.                
  28.             }
  29.             else{
  30.                 $out['error'] = true;
  31.                 $out['message'] = 'File Uploaded but not Saved';
  32.             }
  33.        
  34.         }
  35.     }
  36.     else{
  37.         $out['error'] = true;
  38.         $out['message'] = 'Upload Failed. File empty!';
  39.     }
  40.  
  41.     echo json_encode($out);
  42. ?>

Note: You can increase upload size of your localhost by setting the value of upload_max_filesize and post_max_size in your php.ini. Then, restart your localhost server to save your changes.

That ends this tutorial. I hope this will help you with what you are looking for and will be useful for your future projects.

Happy Coding :)

Add new comment