How to easily upload multiple images with AJAX and jQuery in Laravel

I have an issue with uploading multiple images using Ajax and jQuery. When passing the images from the view to the controller in the request, I receive all the images in the form of an array. However, only a single image is being uploaded and only a single image is being previewed. My goal is to upload and preview all the images.

Route:

Route::match(['post','get'],'/webadmin/uploadbanner','Webadmin\Banners@upload_banner_image');

Controller:

public function upload_banner_image(Request $request){
      if ($request->isMethod('get'))
          return view('/webadmin/uploadbanner');
      else {
          $validator = Validator::make($request->all(),
              [
                  'file' => 'image',
              ],
              [
                  'file.image' => 'The file must be an image (jpeg, png, bmp, gif, or svg)'
              ]);
          if ($validator->fails())
              return array(
                  'fail' => true,
                  'errors' => $validator->errors()
              );
              $files = $request->file('files');
             $total = $request->TotalImages;
             foreach($files as $file) {
                  for ($i = 0; $i < $total; $i++) {
                    $dir = 'public/assets/uploads/Banners/';
                    $imagename = $file->getClientOriginalName();
                    $filename = uniqid() . '_' . time() . '.' . $imagename;
                    $file->move($dir, $filename);
                    return $filename;
                  }

       }

      }

   }

View :

<div class="form-group">
                                <label for="field-ta" class="col-sm-2 control-label"> Featured Image</label>
                                <div class="col-sm-4">
                        <div class="full editp">
                        <label for="name" ></label>
                        <div id="image">

                             <img width="100%" height="100%" id="preview_image" src="https://projects.caresortsolutions.com/Elearn/public/assets/Webadmin/images/attach-1.png"/>
                       <i id="loading" class="fa fa-spinner fa-spin fa-3x fa-fw" style="position: absolute;left: 40%;top: 40%;display: none"></i>
                        </div>
                        <p>
                            <div class="form-group">
                                <div class="col-sm-offset-1 col-sm-10">
                                    <div class="checkbox">
                                        <label>
                            <a href="javascript:upload_banner()" style="text-decoration: none;" class="btn btn-success">
                                <i class="glyphicon glyphicon-edit "></i> upload image
                            </a>&nbsp;&nbsp;
                            <a href="javascript:removeFile()" style="color: white;text-decoration: none;" class="btn btn-red">
                                <i class="glyphicon glyphicon-trash "></i>
                                Remove
                            </a>
                                </div>
                                </div>
                            </div>
                        </p>
                        <input type="file" id="file" style="display: none" multiple/>
                        <input type="hidden" name="file_name[]" id="file_name" />
                        </div> </div>
                            </div>

Ajax :

var j = jQuery.noConflict();
    function upload_banner(){
        j('#file').click();
    }
     j('#file').change(function () {
         if (j(this).val() != '') {
            upload(this);
      }
    });
    function upload(img) {
        let image_upload = new FormData();
        image_upload.append('_token', '{{csrf_token()}}');
        j('#loading').css('display', 'block');
        let TotalImages = j('#file')[0].files.length; 
         let images = j('#file')[0]; 
         for (let i = 0; i < TotalImages; i++) {
            image_upload.append('files[]', images.files[i]);
        }
        image_upload.append('TotalImages', TotalImages);
        j.ajax({
            url: "{{url('/webadmin/uploadbanner')}}",
            data: image_upload,
            type: 'POST',
            contentType: false,
            processData: false,
            success: function (data) {
                alert(data);
                if (data.fail) {
                  j('#preview_image').attr('src', '{{URL::to('/public/assets/Webadmin/images/attach-1.png')}}');
                    alert(data.errors['file']);
                }
                else {
                    j('#file_name').val(data);
                    j('#preview_image').attr('src', '{{URL::to('/public/assets/uploads/Banners/')}}/' + data);
                }
                j('#loading').css('display', 'none');
            },
            error: function (xhr, status, error) {
                alert(xhr.responseText);
                j('#preview_image').attr('src', '{{URL::to('/public/assets/Webadmin/images/attach-1.png')}}');

            }
        });
    }

Answer №1

Your controller should resemble the following code:

First, upload all images and then retrieve the image file name with its path.

public function upload_banner_image(Request $request){
      if ($request->isMethod('get'))
          return view('/webadmin/uploadbanner');
      else {
          $validator = Validator::make($request->all(),
              [
                  'file' => 'image',
              ],
              [
                  'file.image' => 'The file must be an image (jpeg, png, bmp, gif, or svg)'
              ]);
          if ($validator->fails())
              return array(
                  'fail' => true,
                  'errors' => $validator->errors()
              );
             $files = [];  //store filename in this array.
            // $total = $request->TotalImages;  no need to check total images.
           if($request->files) {
             foreach($request->file('files') as $file) {
                    $dir = 'public/assets/uploads/Banners/';
                    $imagename = $file->getClientOriginalName();
                    $filename = uniqid() . '_' . time() . '.' . $imagename;
                    $file->move($dir, $filename);
                    $files[] = $dir.$filename;
            } //foreach
         } //if
                 //return all the filename with path ...
           return response()->json(['files' => $files]);
     } //else
 } //function 

Your JavaScript code should look similar to this:

var j = jQuery.noConflict();
    function upload_banner(){
        j('#file').click();
    }
     j('#file').change(function () {
         if (j(this).val() != '') {
            upload(this);
      }
    });
    function upload(img) {
        let image_upload = new FormData();
        image_upload.append('_token', '{{csrf_token()}}');
        j('#loading').css('display', 'block');
        let TotalImages = j('#file')[0].files.length; 
         let images = j('#file')[0]; 
         for (let i = 0; i < TotalImages; i++) {
            image_upload.append('files[]', images.files[i]);
        }
        image_upload.append('TotalImages', TotalImages);
        j.ajax({
            url: "{{url('/webadmin/uploadbanner')}}",
            data: image_upload,
            type: 'POST',
            contentType: false,
            processData: false,
            success: function (data) {
                alert(data);
                if (data.fail) {
                  j('#preview_image').attr('src', '{{URL::to('/public/assets/Webadmin/images/attach-1.png')}}');
                    alert(data.errors['file']);
                }
                else {
                    if(data.files) {
                      data.files.forEach(function(item,key) {
                       //j('#file_name').val(item); //file with path
                          j('#preview_image').attr('src',item); //file with path
                       });    
                    } //if files get
                } //else
                j('#loading').css('display', 'none');
            },
            error: function (xhr, status, error) {
                alert(xhr.responseText);
                j('#preview_image').attr('src', '{{URL::to('/public/assets/Webadmin/images/attach-1.png')}}');

            }
        });
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on implementing a progress bar for file uploads with JavaScript and AJAX request

I am looking to implement a progress bar in my file uploader. Below is the ajax call I have set up for both file upload and progress tracking. $(function() { $('button[type=button]').click(function(e) { e.preventDefault(); ...

Is it feasible to grant Ajax authorization to a website that is not within the same origin?

I am attempting to extract a particular p element from one of my websites hosted on Server 1 and place it within a <div id="insert"></div> element located on a website hosted on Server 2 I'm striving to achieve this through the use of t ...

Unable to obtain the accurate response from a jQuery Ajax request

I'm trying to retrieve a JSON object with a list of picture filenames, but there seems to be an issue. When I use alert(getPicsInFolder("testfolder"));, it returns "error" instead of the expected data. function getPicsInFolder(folder) { return_data ...

Tips for managing Ajax JSON response in a PhoneGap application

Although there are a few posts on this topic, I am struggling to piece together the necessary components to make it work. I am in the process of converting a web application into an app using phonegap and I am attempting to create a search form that retri ...

The differential treatment of arrays' values in comparison to manually inputted values

Here is a function that I have: public function getReward($formattedArray, $key){ $id = $formattedArray[$key][0]; //dd($id); //Returns 1 $reward = Item::find($id); return $reward; } The problem arises when executing this part of the code ...

Saving the subtracted value from a span into a cookie until the checkbox is unchecked - here's how to

I am working on a piece of code that includes numeric values within a span. When the checkbox is clicked, it subtracts 1 from the main value, essentially reducing the total value. How can I achieve this so that even after the form is submitted, the deducte ...

Navigating with Rails and Devise: How to send the user back to the original page after logging in successfully?

I have implemented the idiom described in this resource # /app/controllers/application_controller.rb class ApplicationController < ActionController::Base before_filter do |controller| redirect_to new_login_url unless controller.send(:logged_in?) ...

Using JQUERY to locate checkboxes within a specified jQuery SELECTOR based on a partial match of a string present in the OnClick Attribute

Our latest challenge with JQUERY involves finding checkboxes in a JQuery SELECTOR by matching part of a string within the OnClick Attribute. Finding checkboxes based on NAME or ID is easy, but our application generates HTML with checkboxes like this: <i ...

Stop Caching with Jquery Infinite Scroll (IAS)

I am using jQuery + IAS to implement infinite scroll functionality on my website. However, I have encountered an issue where the cache is being disabled when making requests for new content. Specifically, the URL that is accessed to retrieve the next page ...

I am curious to see the number of people who have made their selection

I am currently using JavaScript to alter the text value from "select" to "selected". My next step is to include the selected text in a cart. Can you please provide some guidance? Thank you in advance. PHP CODE : <a class='btn slct' href=&ap ...

Access and retrieve xlsx file from a Java-based Restful backend

When I upload an excel file from my UI using an ajax-post call and try to read it from my backend Restful service Java code, I am encountering issues in printing the excel file contents correctly. Although the file name and other attributes are printing co ...

Implementing dynamic data binding in JavaScript templates

I've been experimenting with jQuery and templates, and I managed to create a basic template binding system: <script type="text/template" id="Template"> <div>{0}</div> </script> Furthermore... var buffer = ''; v ...

fancy box appears when double-clicking on a div element

Help needed: How can I open a div in fancybox on double clicking another div using jQuery with Rails 3.1? Here is the function I have inside document.ready() $("#a1").dblclick(function () { $.get("/projects/edit/"+this.id,{ u:$('#user').val ...

What is the best way to delete an added element once a DIV has been toggled with JQuery?

I'm facing an issue where I need to add an element to a DIV that has a toggle function. However, every time I click the toggle again after adding the element, the same element is appended once more, resulting in duplicate elements. Upon observation, ...

What is the best way to retrieve an ID when parsing JSON recursively?

Could you provide guidance on how to retrieve the IDs of all children when parsing JSON data? I have attempted to use a recursive function, but it seems to be calling infinitely. For reference, here is my code snippet: http://jsfiddle.net/Ds8vQ/ for(var ...

Implementing JavaScript to showcase a list extracted from an API dataset

I'm currently undertaking a project where I am integrating an API from a specific website onto my own webpage. { "data": [{ "truckplanNo":"TCTTV___0D010013", "truckplanType":"COLLECTION", " ...

The placement is set to absolute, with a designated height

Here is an example http://jsfiddle.net/HnfCU/ I am using jQuery to toggle the visibility of the .child div. The position of the .child is set to absolute relative to its parent element, .parent. The challenge I am facing is adjusting the height of the .ch ...

Tips for modifying an axios instance during response interception

Is there a way to automatically update an axios instance with the latest token received in a response, without making a second request? The new token can be included in any response after any request, and I want to make sure that the last received token ...

Having multiple HTML select elements and utilizing jQuery AJAX

I am looking to implement a dynamic multiple select using AJAX and jQuery. The first select (c1) is functioning correctly. When I click on it, it triggers the appearance of another select (c2). Similarly, clicking on the second select (c2) should lead to ...

Exploring the world of Spring MVC: Utilizing partial view fragments

I've recently started working with Spring MVC on a new project and I'm doing some research to ensure it's set up properly for long-term success. One aspect of the project will require me to manually update small sections of the page using A ...