Dropzonejs resort appended images

Viewed 306

I have dropzone box and I've implemented sortable into it. As my form submits with html and not ajax I had to add hidden inputs where I push my selected images with dropzonejs therefore I could get them in back-end.

So far everything I explained above is working

Issue

As I mentioned I've implemented sortable functionality into dropzonejs and it does sort images in dropzone box, but not in my appended hidden input

In order to get sorted images in back-end I need to apply that sortable into my appended input as well.

Code

HTML

//Drop zone box
<div class="dropzone" id="my-awesome-dropzone" action="#">
  <div class="fallback">
     <input name="cimages[]" type="file" multiple />
  </div>
  <div class="clearfix"></div>
</div>
// append hidden input include selected images for back-end use
<div id="botofform"></div>

Script

Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("#my-awesome-dropzone", {
  headers: {
    "X-CSRF-TOKEN": $("meta[name='csrf-token']").attr("content")
  },
  autoProcessQueue : false,
  acceptedFiles: ".jpeg,.jpg,.png,.gif",
  dictDefaultMessage: "Drag an image here to upload, or click to select one",
  maxFiles: 15, // Maximum Number of Files
  maxFilesize: 8, // MB
  addRemoveLinks: true,
  dictRemoveFile: 'Remove',
  dictFileTooBig: 'Image is bigger than 8MB',

  // append hidden input and add selected images
  accept: function(file) {
      let fileReader = new FileReader();
      fileReader.readAsDataURL(file);
      fileReader.onloadend = function() {
          let content = fileReader.result;
          $('#botofform').append('<input type="hidden" class="cimages" name="cimages[]" value="'+ content +'">');
          file.previewElement.classList.add("dz-success");
      }
      file.previewElement.classList.add("dz-complete");
  }
});
// reorder images in dropzone box (need to get this results into "$('#botofform').append" above)
$(function(){
  $(".dropzone").sortable({
    items:'.dz-preview',
    cursor: 'move',
    opacity: 0.5,
    containment: '.dropzone',
    distance: 20,
    tolerance: 'pointer',
  });
});

Question

  1. How can I apply sortable results into my appended input?
  2. How do I reduce $('#botofform') items (inputs) when an image gets removed by dropzonejs?
1 Answers

You can use data-attribute for both your div where image is added and input field .So, whenever new file is uploaded you can use setAttribute("data-id", count) here count can be any random number only make sure this value should be same for both input and div because this will help us to remove and sort inputs .

Now , for sorting inputs you can use stop event this will get called when sorting is stop .Inside this you can loop through dropzone div and then get attribute which we have added earlier using this attribute we can find the input and append same to botofform div.

Finally , for deleting files you can use remove files event this will get called whenever remove link is clicked so here you simply need to get that data-id which is added to div then use this attribute to remove input as well.

Demo Code :

var count;
var random;
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("#my-awesome-dropzone", {
  headers: {
    "X-CSRF-TOKEN": $("meta[name='csrf-token']").attr("content")
  },
  autoProcessQueue: false,
  acceptedFiles: ".jpeg,.jpg,.png,.gif",
  dictDefaultMessage: "Drag an image here to upload, or click to select one",
  maxFiles: 15, // Maximum Number of Files
  maxFilesize: 8, // MB
  addRemoveLinks: true,
  dictRemoveFile: 'Remove',
  dictFileTooBig: 'Image is bigger than 8MB',

  // append hidden input and add selected images
  accept: function(file) {

    let fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.onloadend = function() {
      random = 1 + Math.floor(Math.random() * 1000);
      count = $(".dz-complete").length + "_" + random;
      let content = fileReader.result;
      console.log(count)
      //add dataid
      $('#botofform').append('<input type="text" class="cimages" name="cimages[]" data-id = "' + count + '" value="' + content + '">');

      file.previewElement.classList.add("dz-success");
      file.previewElement.setAttribute("data-id", count);

    }

    file.previewElement.classList.add("dz-complete");

  },
  removedfile: function(file) {
    console.log("inside remove --" + file.previewElement.getAttribute("data-id"))
    var ids = file.previewElement.getAttribute("data-id") // get attr where file is been removed 
    $("#botofform input[data-id=" + ids + "]").remove() //remove input field as well
    file.previewElement.remove(); //remove file


  }
});

$(function() {
  $(".dropzone").sortable({
    items: '.dz-preview',
    cursor: 'move',
    opacity: 0.5,
    containment: '.dropzone',
    distance: 20,
    tolerance: 'pointer',
    stop: function(event, ui) {
      //cloned div
      var cloned = $('div#botofform').clone()
      $('#botofform').html("") //empty it
      //loop through dropzone..
      $('.dropzone .dz-complete').each(function() {
        var data_id = $(this).data('id') //get data-id
        $(cloned).find("input[data-id=" + data_id + "]").clone().appendTo($('#botofform')) //find input which has that data-id and append same to bottmform
      });


    }

  });
});
<link rel="stylesheet" href=" http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/dropzone.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
//Drop zone box
<div class="dropzone" id="my-awesome-dropzone" action="#">
  <div class="fallback">
    <input name="cimages[]" type="file" multiple />
  </div>
  <div class="clearfix"></div>
</div>
<div id="botofform"></div>

Related