Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SunnyBoy's avatar

Upload an image using drag & drop over a placeholder image.

I have been tying to work it out since last couple of days... and finally hope i would get some answers from the lavarel community.

While working my Laravel project where I am trying to upload an image (single image) using either drag & drop or select.

NOTE: I have a placeholder image which i want to use it as a dropzone, and also the size may vary depending on where i want to use. Now I should be able to drop an image on this placeholder image. On drop or select the new image replaces the placeholder image (this part i am able to achieve) but when i am trying to submit the form if I have drop a file it won't get to the controller. But when i select the file i am good.

Here is what i have done so far... Can any one let me know what is wrong with the drag & drop method for submitting... the only issue i can think of is the <input type="file"> is not able to set the value when when file is dropped.

Here is my blade form

<form class="form" action="{{ route('categories.store') }}" method="post" enctype="multipart/form-data">
                    @csrf
                    <div class="form-group row">
                        <label for="category" class="col-sm-4 col-form-label">Category</label>
                        <div class="col-sm-8">
                            <input id="category" type="text" class="form-control @error('category') is-invalid @enderror" name="category" value="{{ old('category') }}">
                            @error('category')
                                <span class="invalid-feedback" role="alert">
                                    <strong>{{ $message }}</strong>
                                </span>
                            @enderror
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="slug" class="col-sm-4 col-form-label">Slug</label>
                        <div class="col-sm-8">
                            <input id="slug" type="text" class="form-control @error('slug') is-invalid @enderror" name="slug" value="{{ old('slug') }}">
                            @error('slug')
                                <span class="invalid-feedback" role="alert">
                                    <strong>{{ $message }}</strong>
                                </span>
                            @enderror
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="order" class="col-sm-4 col-form-label">Display Order</label>
                        <div class="col-sm-8">
                            <input id="order" type="number" class="form-control" name="order" value="{{ old('order') }}">
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="status" class="col-sm-4 col-form-label">Status</label>
                        <div class="col-sm-8">
                            <select id="status" class="form-control form__select" name="status">
                                <option value="1">Active</option>
                                <option value="0">Inactive</option>
                            </select>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="file" class="col-sm-4 col-form-label">Upload Image</label>
                        <div class="col-sm-8">
                            <div class="upload-area" id="uploadfile">
                                {{-- <h1>Drag and Drop file here<br/>Or<br/>Click to select file</h1> --}}
                                <img class="img-fluid" src="{{ asset('img/640x480.png') }}" height="200px" id="file_preview" alt="img" />
                            </div>
                            <input type="file" name="file" id="file">
                            @error('file')
                                <span class="invalid-feedback" role="alert">
                                    <strong>{{ $message }}</strong>
                                </span>
                            @enderror
                        </div>
                    </div>
                    <div class="form-group row">
                        <div class="col-sm-12">
                            <button type="submit" class="form__submit">Save</button>
                        </div>
                    </div>
                </form>

style.css

.upload-area{
    width: 42%;
    border: 2px solid lightgray;
    border-radius: 3px;
    text-align: left;
    overflow: auto;
}

.upload-area:hover{
    cursor: pointer;
}

.upload-area h1{
    text-align: center;
    font-weight: normal;
    font-family: sans-serif;
    line-height: 50px;
    color: darkslategray;
}

#file{
    opacity: 0;
}

and finally my JavaScript

 // On File Drop
        $('.upload-area').on('drop', function (e) {
            e.stopPropagation();
            e.preventDefault();
            $(this).removeClass("dragover");
   
            var file = e.originalEvent.dataTransfer.files[0];
            readFile(file);

            var fd = new FormData();
            fd.append('file', file[0]);
            // uploadData(fd);
        });

        // Open file selector on div click
        $("#uploadfile").click(function () {
            $("#file").click();
        });

        // file selected
        $("#file").change(function () {
            var file = $('#file')[0].files[0];
            readFile(file);
        });


    function readFile(file) {

        var reader = new FileReader();
        reader.onload = function (e) {
            $('#file_preview').attr('src', e.target.result);
        };
        reader.readAsDataURL(file);
    }
0 likes
4 replies
kkhicher1's avatar

okay.... now to need to know about base64_decode() php function....

You can use below method for upload a base64 image in your controller

Ex..

$url = $this->uploadImageFromBase64($request->your_image, 'path/to/store/image_name');

$url you can store this to your database

decode image and store url to database

protected function uploadImageFromBase64($image, $filename)
    {
        $exploded = explode (',', $image);
        $decodedImage = base64_decode($exploded[1]);

        if (\str_contains($exploded[0], 'jpg'))
            $extension = 'jpg';
        else
            $extension = 'png';

        if ($decodedImage) {
            $profile = $path. '.' . $extension;
            \file_put_contents($profile, $decodedImage);
        } else {
            $profile = 'default.png';
        }
        return $profile;
    }

base64 validation

protected function base64Check($image){
        try {
            $image = explode('/', $image);
            return $image[0] === 'data:image';
        }catch(\Exception $e ){
            return false;
        }
    }

ex. use of base64 image validation

if ($this->base64Check($request->image)) {
            $category->image()->create([
                'url'       => $this->uploadImageFromBase64($request->your_image, 'path/to/store/image_name');
            ]);
  }
SunnyBoy's avatar

Thanks @kkhicher1, this is all good only if i get the file in my request then into the controller. Bigger issue is I am not able to get the file itself.

Inside Controller i'm getting false when the upload is done using drag and drop. While this returns tru when i use select. So the issue is on drag and drop the input field "image_file" is is not getting set. <input type="file" name="image_file" id="file" accept="image/*"> OR is it something that i 'm missing???

dd(request()->hasFile('image_file'));
kkhicher1's avatar

sure, you will get false because you haven't a image type like png, jpg for any other file type. its send a base64 string data that's why we need to convert that string data into image file

if you dd($request->image_file) you will get a big random string of base64... that why yo need to convert or decode your file from base64.

you can try and reply

SunnyBoy's avatar
SunnyBoy
OP
Best Answer
Level 5

@kkhicher1 thanks again for the prompt response, but what you are suggesting regarding the base64 is equivalent to what i already did using event.target.result

$('#file_preview').attr('src', e.target.result); 

Anyways... what i "was" seeking was how to set our input's 'files' property on drop event which i have figured out.

Here is the missing piece of the puzzle:

$('.upload-area').on('drop', function (e) {
    e.stopPropagation();
    e.preventDefault();
    $(this).removeClass("dragover");

    var files = e.originalEvent.dataTransfer.files;

    if (files && files.length) {

        // we set our input's 'files' property
        $('#file')[0].files = files;

    }

    readFile(files[0]);

});

THANKS ALL

Please or to participate in this conversation.