Nay mình chia sẻ với mọi người cách Multiple Image upload using ajax with Laravel 5.8, thường có nhiều project ta phải upload nhiều hình ảnh, ví dụ: upload hình ảnh minh họa của một sản phẩm, ta có thể dùng cách này
Đoạn code minh dưới đây mình viết code có thể không theo logic lắm, chỉ làm theo cái suy nghĩ làm vậy thôi, để mọi người có thể hinh dung và tùy biến theo ý thích.
Tạo file upload.blade.php trong thư mục views/pages/upload.blade.php của ta.
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-10"> <form action="" enctype="multipart/form-data" method="post" id="upload"> <h2>Upload image multiple in Laravel 5.8</h2> <div class="form-group"> <label for="image 1">Image 1</label> <input type="file" name="files" class="selectImage" id="images"/> <div class="show-progress"> </div> </div> <div class="form-group"> <button type="submit" class="btn btn-primary" id="uploadImage">Upload</button> </div> </form> </div> </div> <div class="row justify-content-center" id="showImage"> </div> </div> @endsection
Đoạn code bên trên mọi người chắc quá quen thuộc rồi hehe, các bạn nhớ thêm enctype="multipart/form-data" vào form nhé
<div id="showImage">: thẻ div này mình dùng show hình ảnh ra, khi ta chọn hình ảnh, nó sẽ append đến thẻ div này
<div class="show-progress">: thẻ div này mình append các progress-bar để xử lý tiến trình, nó sẽ thêm append đến thẻ này
Code Jquery xử lý của mình như sau:
$(document).ready(function(){ var i=0; var dataImage = new Array(); var dataPosition = new Array(); $("#images").change(function(){ var checkImage = this.value; var ext = checkImage.substring(checkImage.lastIndexOf('.') + 1).toLowerCase(); if (ext == "gif" || ext == "png" || ext == "jpg" || ext == "jpeg") { change(this); var file = document.getElementById('images').files[0]; dataImage[i]=file; //add push to array dataImage dataPosition[i]=i; //add push position to dataPosition //created html progress var html_progress = '<div class="progress" style="margin-bottom:5px;"><div class="progress-bar" id="progress-'+i+'" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div></div>'; $(".show-progress").append(html_progress); i++; } else alert("Chọn image (jpg, jpeg, png).") ; }); var change = function(input){ if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function (e) { var addImage = '<div class="col-md-3"><img src='+e.target.result+'></div>'; //add image to div="showImage" $("#showImage").append(addImage); } reader.readAsDataURL(input.files[0]); } } });
Đoạn code bên trên mình có tạo một vài biến toàn cục và mảng(array), bên cạnh đó mình cài đặt sự kiện khi click chọn hình
var upload = function(data,position){ var formData = new FormData(); //append data to formdata formData.append('image',data); var id = position; $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $.ajax({ type:'POST', url:'http://localhost:8000/form/upload', data:formData, contentType: false, dataType:'json', processData: false, cache:false, xhr: function () { console.log(id); var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function (evt) { if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total; percentComplete = parseInt(percentComplete * 100); if(percentComplete==100){ dataImage.splice(id, 1); dataPosition.splice(id, 1); } $("#progress-"+id).text(percentComplete + '%'); $("#progress-"+id).css('width', percentComplete + '%'); } }, false); return xhr; }, success:function(data){ console.log(data); } }); } $("form#upload").submit(function( event ) { event.preventDefault(); var k=0; for(k=0; k<dataImage.length;k++){ /** * Function Upload * params 1: data image * params 2: position[ progressbar-1 or progressbar-2,...] **/ upload(dataImage[k],dataPosition[k]); } });
Đoạn code này mình cài đặt các sự kiện khi upload một tấm hình hoặc nhiều tấm hình, mỗi lần upload xong 1 tấm sẽ xóa tấm hình đó ra khỏi vị trí mảng
Full Code Jquery
$(document).ready(function(){ var i=0; var dataImage = new Array(); var dataPosition = new Array(); $("#images").change(function(){ var checkImage = this.value; var ext = checkImage.substring(checkImage.lastIndexOf('.') + 1).toLowerCase(); if (ext == "gif" || ext == "png" || ext == "jpg" || ext == "jpeg") { change(this); var file = document.getElementById('images').files[0]; dataImage[i]=file; //add push to array dataImage dataPosition[i]=i; //add push position to dataPosition //created html progress var html_progress = '<div class="progress" style="margin-bottom:5px;"><div class="progress-bar" id="progress-'+i+'" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div></div>'; $(".show-progress").append(html_progress); i++; } else alert("Please select image file (jpg, jpeg, png).") }); var change = function(input){ if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function (e) { var addImage = '<div class="col-md-3"><img src='+e.target.result+'></div>'; //add image to div="showImage" $("#showImage").append(addImage); } reader.readAsDataURL(input.files[0]); } } var upload = function(data,position){ var formData = new FormData(); //append data to formdata formData.append('image',data); var id = position; $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $.ajax({ type:'POST', url:'http://localhost:8000/form/upload', data:formData, contentType: false, dataType:'json', processData: false, cache:false, xhr: function () { console.log(id); var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function (evt) { if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total; percentComplete = parseInt(percentComplete * 100); if(percentComplete==100){ dataImage.splice(id, 1); dataPosition.splice(id, 1); } $("#progress-"+id).text(percentComplete + '%'); $("#progress-"+id).css('width', percentComplete + '%'); } }, false); return xhr; }, success:function(data){ console.log(data); } }); } $("form#upload").submit(function( event ) { event.preventDefault(); var k=0; for(k=0; k<dataImage.length;k++){ /** * Function Upload * params 1: data image * params 2: position[ progressbar-1 or progressbar-2,...] */ upload(dataImage[k],dataPosition[k]); } }); });
Để xử lý upload hình ảnh bên phí Controller trong Laravel ta sẽ làm như sau:
namespace App\Http\Controllers; use Illuminate\Http\Request; class FormController extends Controller { public function index(){ return View('pages.upload'); } /** * UPLOAD IMAGES */ public function store(Request $request){ if($request->hasFile('image')){ $file = $request->file('image'); $name = $file->getClientOriginalName(); $exection = $file->getClientOriginalExtension(); $file->move(public_path().'/uploads/', $name); //echo public_path().'/uploads/'; return Response()->json(array('success'=>1,'message'=>'Upload success!')); }else{ return Response()->json(array('success'=>0,'message'=>'Upload error!')); } } }
Mở file web.php trong thư mục routes/web.php chỉnh sửa lại như sau:
Route::prefix('form')->group(function () { Route::get('/','FormController@index')->name('form.index'); Route::post('/upload','FormController@store')->name('form.store'); });
Giờ mọi người có thể test thử xem, trong nội dung chia sẻ này, mình chỉ dựa theo ý tưởng làm thử, có gì sai bạn có thể comment và đóng góp ý kiến thêm cho hoàn chỉnh.