Bayesean Blog - Desktop, Mobile and IOT Developer Blog


Javascript Image-File Uploader with ThumbViewer

Posted on 28th Feb 2017 in Ajax


uploadheader.png

Background

Uploading a file is relatively easy. However to create a seamless user experience can be difficult. So I went ahead and created a visual single file uploader with same page thumbnail editor.

Project Scope

Develop a uploader that gas an input with dynamic status with an integrated button (file open browser). It must be able to upload all normal formats such as "jpg", "png", "gif", "bmp", "jpeg", "GIF", "JPG", "PNG"   and auto change file format to a standard “.png” format to reduce unnecessary overhead without reducing image quality limiting size to 2 MB. Add an image name before uploadingand preview a selected thumbnail image before uploading with an image uploading progress shown on uploading the image

Provide an integrated thumbnail viewer which also auto updates on uploaded completion which allows thumbnail name edit and thumbnail deleting.

 upload.gif

 

Coding Difficulty

Medium. Good knowledge of Javascript/Ajax and PHP required would help.

Libaries

Bootstrap 3 Framework –download here or visit the website at http://getbootstrap.com.

Bootstrap Filestyle – download the bootstrap-filestyle.min.js from here or visit the website at www. markusslima.github.10/bootstrap-Filestyle.

This improves on the poorly styled Bootstrap input implementation. The Bootstrap Filestyle JQuery based plugin is simple and efficient and is a nicely styled input/button. Check the site out to view all the options offered. This plugin requires JQuery to create the styling and function.

JQuery – download from here or visit the website http://jquery.com.

Structure

The file structure is as follows. The folder uploads holds no script but is the folder where all the uploaded images are stored.

uploadstructure.PNG

 

 The index.php file holds the Visual element of the Uploader and alsomakes use of the file reader script that opens the file explorer.

     <script>
       This script opens  the computors’ file explorer.
        function readURL(input) {
        if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
        $('#img_prev')
        .attr('src', e.target.result)
        };
        reader.readAsDataURL(input.files[0]);
        }
        }
        function clearimage(){
        $('#img_prev')
        .attr('src', "img/preview.png")
        }

 

This is the AJAX code to POST (send) the file information to the server as all the action has taken place directly on the web-browser. It also communicates to the progress bar. The eventlistener is attached to the upload and any changes of the XMLHttpRequest() of data sent in the background to the uploadscript.php will communicate the loaded information which will continually recalculate the percentage complete. The progressbar is then refreshed.

$.ajax({
        url: 'uploadscript.php',
        data: formData,
        processData: false,
        contentType: false,
        type: 'POST',
        // this part is progress bar
        xhr: function () {
        var xhr = new window.XMLHttpRequest();
        xhr.upload.addEventListener("progress", function (evt) {
        if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        percentComplete = parseInt(percentComplete * 100);
        $('.myprogress').text(percentComplete + '%');
        $('.myprogress').css('width', percentComplete + '%');
        }
        }, false);
        return xhr;
        },
        success: function (data) {
        $('.msg').text(data);
        $('#btn').removeAttr('disabled');
        
        setTimeout(resettimer, 3000);
        }
        });
        });
        });
        </script>

 

The fileuploadscript.php - This file receives the AJAX POST call and receives the data  so long as the data is not empty  -“if (isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST") “

We first check if the file is less than 2 MB and if it is then changes the name by using a count in date seconds which is added to the existing name i.e. box will become box03 . This ensures that no similar file name is overwritten.

We also resize the image to a max width of 800px and create a temporary  copy which becomes a PNG file. The old file is deleted.

The file is now saved to the correct folder in the server. Here is a snippit of the code.

error_reporting(0);
if (isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST") {
    $path = "uploads/"; //set your folder path
    //set the valid file extensions 
    $valid_formats = array("jpg", "png", "gif", "bmp", "jpeg", "GIF", "JPG", "PNG");//add the formats you want to upload add if needed "doc", "txt", "docx", "pdf", "xls", "xlsx") 
    $name = $_FILES['myfile']['name']; //get the name of the file
    $size = $_FILES['myfile']['size']; //get the size of the file

    if (strlen($name)) { //check if the file is selected or cancelled after pressing the browse button.
        list($txt, $ext) = explode(".", $name); //extract the name and extension of the file
        if (in_array(strtolower($ext), $valid_formats)) { //if the file is valid go on.
            if ($size < 2098888) { // check if the file size is more than 2 mb
                $file_name = $_POST['filename']; //get the file name
               /* changename add int seconds to name  to create unique name*/
                    $tmpint =idate('s'); 
                    $file_name = $file_name.''.$tmpint;

                $tmp = $_FILES['myfile']['tmp_name'];

 

Create a file imageadjust.php - This file allows the thumbnails to be deleted and also allows the filename to be changed. If deleted, the thumbnail will immediately be removed in the Index.php file. This file will open with an input with the existing filename. Changing the input name and posting the data results in the filename being changed. Here is a snippit...

 

<?php 
  $path = "uploads/"; //set your folder path

//delete file and edit file folder

//error_reporting(0);

$id = null;
	if ( !empty($_GET['id'])) {
		$oldname = $_REQUEST['id'];

		
	//echo $oldname;
	
	}
	if ( $id==null) {
	//	header("Location: index.php");
	}

	if(isset($_POST['submit'])){
       $newname = $_POST['name'];
     //	echo $newname;
     	echo $path.''.$newname;

rename ($path.''.$oldname , $path.''.$newname);

	header("Location: index.php");
//	$oldname =$newname;
}
?>
           <h3>Edit Selected Image </h3>
             <hr>
           <form method="post" enctype="multipart/form-data" >
              <div class="form-group">
 <input class="form-control input"  name = "name" type="text" id="filename" placeholder = "Enter New filename for image" value="<?php echo $oldname;?>">
          </div>

                 <div class="form-actions">
    <button inputtype="submit" class= "btn btn-success"  name="submit" value="submit"><i class="glyphicon glyphicon-check "></i></button>
    
</div>
</form>
  </div>
<?php

?>
</body>
</html>

 

Licence MIT

Happy Coding....

 

Download Code

 


Reg      Commented   3 years ago Reply

I found in Stack Overflow that they use a foreach statement to pull the data. Your method is different. Which is the best method?

Admin      Replied    Moderator   3 years agoReply


Yes I am aware of the Stack Overflow method suggested. The problem is that we are dealing with server side and client side script. The foreach method updates the Client on every call. So if you has 500 rows of data, then you will be persistently updating the client 500 times and as it is a single threaded call, the client will simply stop working until the process is complete. Loading the data into Json in the Server creates a lightweight data object. This is only sent once to the client and the Json object (string) is quickly unpacked in the client allowing a quicker response. I hope that this clears up your concerns.

Add a Comment

9+5

Recent News

Delphi Delimited String to Fields
Delphi A Professional VCL DBGrid Part Four
Delphi A Professional VCL DBGrid Part Three
Delphi A Professional VCL DBGrid Part Two
Delphi A Professional VCL DBGrid Part One
Delphi VCL Buttons in DBGrid
Two Helper Apps for Delphi LibUSB
Delphi Libusb Library Introduction

Categories

Bootstrap 4
Delphi VCL
Delphi FMX
Ajax
Bootstrap 3
CSS
XE4>Delphi > XE4
Delphi < XE4
PHP

Archives

August 2019

Delphi Delimited String to Fields

June 2019

Delphi A Professional VCL DBGrid Part Four

May 2019

Delphi A Professional VCL DBGrid Part Three

April 2019

Delphi A Professional VCL DBGrid Part Two

March 2019

Delphi A Professional VCL DBGrid Part One

November 2018

Delphi VCL Buttons in DBGrid

October 2018

Two Helper Apps for Delphi LibUSB

September 2018

Delphi Libusb Library Introduction

August 2018

Delphi Object directly to a Json string in a REST Client
Delphi using Environment Variables in your App

July 2018

Delphi FMX Leaflet Plotter using OSM Maps

June 2018

C2PAS32 Convertor Application
C to Delphi Open Source Convertors Shootout
Delphi command-line programs with DOSCommand

May 2018

Delphi PDF Embedded viewer with PDF.js

March 2018

Delphi FMX - Changing TCharacter to TCharHelper
Make Your Delphi App POP using Javascript!

January 2018

Delphi FMX Dashboard using Chart.JS
Delphi FMX Form Docking

December 2017

PHP Slim REST Server & Delphi Auth Part 5

November 2017

Delphi FMX REST Client App Part 4

October 2017

Delphi VCL REST Pricing Client App Part 3

September 2017

Delphi REST VCL Client Basic Auth Part 2B

August 2017

Delphi REST Client Part 2A
PHP PDO REST Server Part 1

July 2017

PHP REST Server and Delphi Client Intro

June 2017

Delphi SQLite Encryptor-Decryptor Tool
Updating Applications Manifest using Delphi

May 2017

Create a Visual IP Address Geolocation with PHP

March 2017

PHP Downloader using Countdown timer
PHP File Downloader from a Inbox Selection

February 2017

Javascript Image-File Uploader with ThumbViewer

January 2017

Morris Charts and PHP-PDO

December 2016

CSS to create a functional Toggle Button