Skip to content

Instantly share code, notes, and snippets.

@sprobejames
Forked from zahidhasanemon/Controller.php
Last active September 24, 2024 00:51
Show Gist options
  • Select an option

  • Save sprobejames/3163ef41293caf9a3ba3d6b5a7f59b55 to your computer and use it in GitHub Desktop.

Select an option

Save sprobejames/3163ef41293caf9a3ba3d6b5a7f59b55 to your computer and use it in GitHub Desktop.
Multiple file upload asynchronously using Laravel and Dropzone JS. Works perfectly with multiple files dragged and dropped or selected at a time. Images are uploaded via ajax request.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AttachmentController extends Controller
{
public function store(Request $request)
{
$files = [];
$directory = 'app/tmp/uploads';
if (!file_exists(storage_path($directory))) {
mkdir(storage_path($directory), 0777, true);
}
foreach ($request->file('file') as $key => $value) {
$filename = uniqid() . time() . '.' . $value->getClientOriginalExtension();
$value->move(storage_path($directory), $filename);
$fullPath = $directory . '/' . $filename;
$files[] = [
'name' => $value->getClientOriginalName(),
'path' => $fullPath,
];
}
return response()->json($files);
}
}
//add image to the storage disk.
public function uploadImageViaAjax(Request $request)
{
$name = [];
$original_name = [];
foreach ($request->file('file') as $key => $value) {
$image = uniqid() . time() . '.' . $value->getClientOriginalExtension();
$destinationPath = public_path().'/images/';
$value->move($destinationPath, $image);
$name[] = $image;
$original_name[] = $value->getClientOriginalName();
}
return response()->json([
'name' => $name,
'original_name' => $original_name
]);
}
//add form data to database
public function store(Request $request)
{
$messages = array(
'images.required' => 'Image is Required.'
);
$this->validate($request, array(
'images' => 'required|array|min:1',
),$messages);
foreach ($request->images as $image) {
Image::create([
'name' => $image,
'created_by' => Auth::id()
]);
}
return redirect()
->route('home')
->with('success', 'Images Added Successfully');
}
//dropzone css
<link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/dropzone.min.css" rel="stylesheet" />
//form
<form class="" method="POST" action="{{ route('image.store') }}" enctype="multipart/form-data">
@csrf
<div class="form-row">
<div class="col-md-12">
<div class="position-relative form-group">
<label for="details" class="">Images</label>
<div class="needsclick dropzone" id="document-dropzone"></div>
</div>
</div>
</div>
<button class="mt-2 btn btn-primary">Submit</button>
</form>
//script
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/dropzone.min.js"></script>
<script>
window.addEventListener('DOMContentLoaded', () => {
let uploadedDocumentMap = {};
let { Dropzone } = window;
Dropzone.autoDiscover = false;
let form = document.getElementById('dropzone-form');
let myDropzone = new Dropzone("div#document-dropzone",{
url: '{{ route('attachments.store') }}',
autoProcessQueue: true,
uploadMultiple: true,
addRemoveLinks: true,
parallelUploads: 10,
headers: {
'X-CSRF-TOKEN': "{{ csrf_token() }}"
},
successmultiple: function(data, response) {
response.map(function ({ name, path }, key) {
form.insertAdjacentHTML('beforeend', '<input type="hidden" name="images[]" value="' + path + '">');
uploadedDocumentMap[name] = path;
});
},
removedfile: function (file) {
file.previewElement.remove()
const name = typeof file.file_name !== 'undefined' ? file.file_name : uploadedDocumentMap[file.name];
const input = form.querySelector('input[name="images[]"][value="' + name + '"]');
form.removeChild(input);
}
});
});
</script>
Route::post('upload-image-via-ajax', [AttachmentController::class, 'store'])->name('attachments.store');
Route::post('store-image', 'Controller@store')->name('image.store');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment