How to Upload Multiple image without page reload in PHP

This tutorial we going to implement Multiple image upload without page refresh. we use base 64 to convert into image and store. upload multiple image and store all image in single submit button click.

Here are the steps for Upload Multiple image.

  • Create index.php file
  • Add Progress bar on submit button click
  • Create JS file for image upload and progress bar
  • Store image in server

Let’s start with creating form and we use bootstrap as design.

Create index.php file

<!DOCTYPE html>
<html lang="en">
   <head>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" crossorigin="anonymous">
      <link rel="stylesheet" href="./css/style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      <script src="./js/add_post.js"></script>
   </head>
   <body>
      <div class="container">
         <div class="row">
            <div class="col-md-12">
               <div class="panel panel-card ">
                  <div class="panel-body">
                     <h2>How to upload Multiple image without page refresh using PHP,jQuery and AJAX</h2>
                     <form method="post" id="add_form">
                        <div class="form-group">
                           <span class="btn btn-success fileinput-button">
                           <span>Select Attachment</span>
                           <input type="file" name="files[]" id="files" multiple accept="image/jpeg, image/png, image/gif,"><br />
                           </span>
                           <output id="Filelist">
                              <ul class="thumb-Images" id="imgList">
                              </ul>
                           </output>
                        </div>
                        <div class="progress">
                           <div class="progress-bar"></div>
                        </div>
                        <div id="uploadStatus"></div>
                        <div id="optimize_img"></div>
                        <div class="widget-content padding">
                           <input type="button" name="save_post"  id="add_post" class="btn btn-primary md-trigger"  value="Save"></button>
                        </div>
                     </form>
                  </div>
               </div>
            </div>
         </div>
      </div>
   </body>
</html>

Create form where user can upload multiple image file on single click as we can use multiple attributes for this and if you want single upload won’t need to add multiple and array as name.

add_post.js file

document.addEventListener("DOMContentLoaded", init, false);
//To save an array of attachments
var AttachmentArray = [];
//counter for attachment array
var arrCounter = 0;
//to make sure the error message for number of files will be shown only one time.
var filesCounterAlertStatus = false;
//un ordered list to keep attachments thumbnails
var ul = document.createElement("ul");
ul.className = "thumb-Images";
ul.id = "imgList";
function init() {
//add javascript handlers for the file upload event
document
.querySelector("#files")
.addEventListener("change", handleFileSelect, false);
}
//the handler for file upload event
function handleFileSelect(e) {
//to make sure the user select file/files
if (!e.target.files) return;
//To obtaine a File reference
var files = e.target.files;
// Loop through the FileList and then to render image files as thumbnails.
for (var i = 0, f; (f = files[i]); i++) {
//instantiate a FileReader object to read its contents into memory
var fileReader = new FileReader();
// Closure to capture the file information and apply validation.
fileReader.onload = (function(readerEvt) {
return function(e) {
//Apply the validation rules for attachments upload
ApplyFileValidationRules(readerEvt);
//Render attachments thumbnails.
RenderThumbnail(e, readerEvt);
//Fill the array of attachment
FillAttachmentArray(e, readerEvt);
};
})(f);
// Read in the image file as a data URL.
// readAsDataURL: The result property will contain the file/blob's data encoded as a data URL.
fileReader.readAsDataURL(f);
}
document
.getElementById("files")
.addEventListener("change", handleFileSelect, false);
}
//To remove attachment once user click on x button
jQuery(function($) {
$("div").on("click", ".img-wrap .close", function() {
var id = $(this)
.closest(".img-wrap")
.find("img")
.data("id");
//to remove the deleted item from array
var elementPos = AttachmentArray.map(function(x) {
return x.FileName;
}).indexOf(id);
if (elementPos !== -1) {
AttachmentArray.splice(elementPos, 1);
}
//to remove image tag
$(this)
.parent()
.find("img")
.not()
.remove();
//to remove div tag that contain the image
$(this)
.parent()
.find("div")
.not()
.remove();
//to remove div tag that contain caption name
$(this)
.parent()
.parent()
.find("div")
.not()
.remove();
//to remove li tag
var lis = document.querySelectorAll("#imgList li");
for (var i = 0; (li = lis[i]); i++) {
if (li.innerHTML == "") {
li.parentNode.removeChild(li);
}
}
});
});
//Apply the validation rules for attachments upload
function ApplyFileValidationRules(readerEvt) {
//To check file type according to upload conditions
if (CheckFileType(readerEvt.type) == false) {
alert(
"The file (" +
readerEvt.name +
") does not match the upload conditions, You can only upload jpg/png/gif files"
);
e.preventDefault();
return;
}
//To check file Size according to upload conditions
if (CheckFileSize(readerEvt.size) == false) {
alert(
"The file (" +
readerEvt.name +
") does not match the upload conditions, The maximum file size for uploads should not exceed 300 KB"
);
e.preventDefault();
return;
}
//To check files count according to upload conditions
if (CheckFilesCount(AttachmentArray) == false) {
if (!filesCounterAlertStatus) {
filesCounterAlertStatus = true;
alert(
"You have added more than 10 files. According to upload conditions you can upload 10 files maximum"
);
}
e.preventDefault();
return;
}
}
//To check file type according to upload conditions
function CheckFileType(fileType) {
if (fileType == "image/jpeg") {
return true;
} else if (fileType == "image/png") {
return true;
} else if (fileType == "image/gif") {
return true;
} else if (fileType == "image/jpg") {
return true;
} else {
return false;
}
return true;
}
//To check file Size according to upload conditions
function CheckFileSize(fileSize) {
if (fileSize < 3000000) {
return true;
} else {
return false;
}
return true;
}
//To check files count according to upload conditions
function CheckFilesCount(AttachmentArray) {
//Since AttachmentArray.length return the next available index in the array,
//I have used the loop to get the real length
var len = 0;
for (var i = 0; i < AttachmentArray.length; i++) {
if (AttachmentArray[i] !== undefined) {
len++;
}
}
//To check the length does not exceed 10 files maximum
if (len > 9) {
return false;
} else {
return true;
}
}
//Render attachments thumbnails.
function RenderThumbnail(e, readerEvt) {
var li = document.createElement("li");
ul.appendChild(li);
li.innerHTML = [
'
<div class="img-wrap"> <span class="close">×</span>' +
   '<img class="thumb" src="',
      e.target.result,
      '" title="',
      escape(readerEvt.name),
      '" data-id="',
      readerEvt.name,
      '"/>' + "
</div>
"
].join("");
var div = document.createElement("div");
div.className = "FileNameCaptionStyle";
li.appendChild(div);
div.innerHTML = [readerEvt.name].join("");
document.getElementById("Filelist").insertBefore(ul, null);
}
//Fill the array of attachment
function FillAttachmentArray(e, readerEvt) {
AttachmentArray[arrCounter] = {
AttachmentType: 1,
ObjectType: 1,
FileName: readerEvt.name,
FileDescription: "Attachment",
NoteText: "",
MimeType: readerEvt.type,
Content: e.target.result.split("base64,")[1],
FileSizeInBytes: readerEvt.size
};
arrCounter = arrCounter + 1;
}
$(document).on('click','#add_post',function(e) {
e.preventDefault();
//validation of form
var valid=1;
var form = $('#add_form')[0];
var formData = new FormData(form);
var paramJSON = JSON.stringify(AttachmentArray);
var main_image=$("#main_image").val();
formData.append('main_image', main_image);
formData.append('file', paramJSON);
formData.append('action', 'add');
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = ((evt.loaded / evt.total) * 100);
$(".progress-bar").width(percentComplete + '%');
$(".progress-bar").html(percentComplete+'%');
}
}, false);
return xhr;
},
type: 'POST',
url: 'upload.php',
dataType:"json",
data: formData,
contentType: false,
cache: false,
processData:false,
beforeSend: function(){
$(".progress-bar").width('0%');
$('#uploadStatus').html('<img src="images/loading.gif"/>');
$("#add_post").attr("disabled", true);
},
error:function(){
$('#uploadStatus').html('
<p style="color:#EA4335;">File upload failed, please try again.</p>
');
$("#add_post").attr("disabled", false);
$('#optimize_img').html('');
},
success: function(resp){
if(resp.success ==1){
$('#add_form')[0].reset();
$('#uploadStatus').html('
<p style="color:#28A74B;">Added successfully!</p>
');
$("#add_post").attr("disabled", false);
$('#optimize_img').html('');
}else if(resp.success ==0){
$('#uploadStatus').html('
<p style="color:#EA4335;">'+resp.error+'</p>
');
$("#add_post").attr("disabled", false);
$('#optimize_img').html('');
}
}
});
});

All JS logic we implement add_post.js file. it provide all image to display preview with delete option as well. Render file thumbnails, image size validation and maximum image upload limit. We use ajax call to send image data in upload.php. var formData = new FormData(form); that can handle all form data.

Create style.css

.btn {
  display: inline-block;
  padding: 6px 12px;
  margin-bottom: 0;
  font-size: 14px;
  font-weight: normal;
  line-height: 1.42857143;
  text-align: center;
  white-space: nowrap;
  vertical-align: middle;
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  background-image: none;
  border: 1px solid transparent;
  border-radius: 4px;
}
/*Also */
.btn-success {
  border: 1px solid #c5dbec;
  background: #d0e5f5;
  font-weight: bold;
  color: #2e6e9e;
}

.fileinput-button {
  position: relative;
  overflow: hidden;
}

.fileinput-button input {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  opacity: 0;
  -ms-filter: "alpha(opacity=0)";
  font-size: 200px;
  direction: ltr;
  cursor: pointer;
}

.thumb {
  height: 80px;
  width: 100px;
  border: 1px solid #000;
  border-radius: 10px;
}
.thumb-Images{padding-left: 0px;}
ul.thumb-Images li {
  width: 120px;
  float: left;
  display: inline-block;
  vertical-align: top;
  height: 120px;
}

.img-wrap {
  position: relative;
  display: inline-block;
  font-size: 0;
  margin: 10px;
}

.img-wrap .close {
  position: absolute;
  top: 2px;
  right: 2px;
  z-index: 100;
  background-color: #d0e5f5;
  padding: 5px 2px 2px;
  color: #000;
  font-weight: bolder;
  cursor: pointer;
  opacity: 0.5;
  font-size: 23px;
  line-height: 10px;
  border-radius: 50%;
}

.img-wrap:hover .close {
  opacity: 1;
  background-color: #ff0000;
}

.FileNameCaptionStyle {
  font-size: 12px;
}

.progress {
    display: -ms-flexbox;
    display: flex;
    height: 20px;
    overflow: hidden;
    font-size: .75rem;
    background-color: #e9ecef;
    border-radius: .25rem;
    margin-top: 10px;
	box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
}
.progress-bar {
     display: flex;
     flex-direction: column;
     justify-content: center;
    overflow: hidden;
    color: #fff;
    text-align: center;
    white-space: nowrap;
    background-color: #28a745;
    transition: width .6s ease;
    font-size: 16px;
    text-align: center;
}
ul#imgList {
    margin: 0px;
}
ul.thumb-Images li.active{
	background:red;
}

Add some design for progress bar, delete icon and file display to looks awesome.

Create uploads folder in working directory and create upload.php file in to store all image in uploads folder.

Create upload.php file

File data are pass inside upload.php. We are using base64_encode function so at the end receiver site we are decode it . file_put_contents can write file inside directory.

<?php

$target_dir = "./uploads/"; // Upload directory

$data = json_decode($_POST["file"]);

if($_POST['action']=='add'){
		
	for($i=0; $i<count($data); $i++){
		if(!empty($data[$i]->FileName))	{
			$image_base64 = base64_decode($data[$i]->Content);
			$temp = explode(".", $data[$i]->FileName);
			$file_name_cl=time();
			$newfilename =$file_name_cl.'.'. end($temp);
		
			$file = $target_dir . $newfilename;
			file_put_contents($file, $image_base64);
		}
	}
	
	$response = array('error'=>'','success'=>1);
	
	echo json_encode($response);
}

Final Output

How to Upload Multiple image without page reload using PHP and jQuery

Conclusion

upload multiple image tutorial implementations helps to add this on your project just require to change CSS. you can take all JS, PHP from here.

Comments

No comments yet. Why don’t you start the discussion?

    Leave a Reply