processQueue не работает, если в Dropzone не добавлено новое изображение

Я включаю Dropzone в свою форму, которая содержит другие данные. Для процесса создания это хорошо работает. Изображения можно перетаскивать в поле Dropzone, и при нажатии кнопки «Сохранить» изображения будут отправлены вместе с остальными данными формы.

Я также использовал эту же страницу для процесса редактирования, чтобы пользователи могли редактировать отправленные изображения и другие соответствующие данные. Загруженные изображения извлекаются и отображаются в Dropzone через блок кода «Блок с загруженными изображениями» ниже.

Здесь возникает проблема. Если пользователь не добавляет новое изображение в Dropzone, то нажатие на «Save_button» не приведет к загрузке формы! Я думаю, что processQueue ничего не делает, потому что очередь изображений пуста и, следовательно, не отправляет форму.

Вопрос: Есть ли способ принудительно отправить форму? Например, вызвать событие «отправка нескольких», чтобы можно было отправить другие данные формы?

Dropzone.prototype.defaultOptions.dictDefaultMessage = "Drop images here to upload<br>(.jpg, .jpeg, .gif, .png)";

Dropzone.options.myDropzone = {
url: '/addpage',
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 5,
maxFilesize: 1,
acceptedFiles: '.png,.jpg,.jpeg,.gif',
addRemoveLinks: true,
init: function () {
   dzClosure = this;
   myDropzone1 = this;

   //Block with uploaded images, start
   var imagesList = ["http://www/path/to//image1.jpg"]
   
   for (var i = 0; i < imagesList.length; i++) {
       var mockFile = { id: i, name: "Image " + i, filename: imagesList[i], size: 1, type: "image/jpg", status: Dropzone.QUEUED, accepted: true, upload: {} };
       myDropzone1.emit("addedfile", mockFile);

       myDropzone1.createThumbnailFromUrl(mockFile, imagesList[i], "", "");
       myDropzone1.files.push(mockFile);
       myDropzone1.emit("complete", mockFile);
   }
   //Block with uploaded images, end

   document.getElementById("Save_button").addEventListener("click", function (e) {

       e.preventDefault();
       e.stopPropagation();

       var success = true;

       if (!someFormValuesValidation())
           success = false;

       if (!success) {
           alert("Form validation failed, please check values.");
           return false;
       }
       else {
           dzClosure.processQueue();
       }
   });

   this.on("sendingmultiple", function (data, xhr, formData) {
       $('#loading').show();

       formData.append("Title", jQuery("#Title").val());
       formData.append("Price", jQuery("#Price").val());
       formData.append("Quantity", jQuery("#Quantity").val());
   });

   this.on("successmultiple", function (file, result) {
       if (result.Response == "0") {
           alert("Success!");
       } else {
           alert("There is a problem: " + result.Error);
       }
       file.status = Dropzone.QUEUED;
       myDropzone1.status = Dropzone.QUEUED;

       $('#loading').hide();
   });

   this.on("maxfilesexceeded", function (file) {
       this.removeFile(file);
       alert("Can't add more images. Maximum only 5 images");
   });

}
}
<form action="/addpage" autocomplete="off" id="Form" method="post" enctype="multipart/form-data">
<div class="dropzone" id="my-dropzone">
    <div class="fallback">
    <input name="Images" type="file" multiple />
    </div>
</div>
<button type="button" class="save-btn" id="Save_button">Save</button>
</form>


person J K    schedule 30.11.2018    source источник


Ответы (2)


Я думаю, что processQueue ничего не делает, потому что очередь изображений пуста и, следовательно, не отправляет форму.

Да, очередь действительно пуста, запустите console.log( myDropzone1.getQueuedFiles() ) в консоли браузера, и вы получите пустой массив ([]).

Есть ли способ принудительно отправить форму?

В вашем mockFile установите status на Dropzone.QUEUED:

var mockFile = { ..., status: Dropzone.QUEUED, ... };

И mockFile должен иметь upload элемент, который может быть просто {} таким:

var mockFile = { ..., status: Dropzone.QUEUED, accepted: true, upload: {} };

ОБНОВИТЬ

Предыдущий ответ на самом деле был предназначен для того, чтобы форма могла быть просто отправлена ​​без данных двоичного изображения, т.е. статус QUEUED и элемент upload предназначены только для того, чтобы кнопка «Сохранить» работала. .

Но если вы действительно собираетесь загрузить обратно все изображения в массиве imagesList, тогда mockFile должен быть действительным _ 16_ объект / экземпляр, и я бы использовал Dropzone.prototype.addFile(), чтобы добавить файл в Dropzone.

И по этой причине ваш цикл for может быть таким простым, как:

for (var i = 0; i < imagesList.length; i++) {
  let name = imagesList[i];
  name = name.substring(name.lastIndexOf('/') + 1);

  fetch(imagesList[i])
    .then(res => res.blob())
    .then(blob => {
      let file = new File([blob], name, blob);
      myDropzone1.addFile(file);
    });
}
person Sally CJ    schedule 05.12.2018
comment
Я следил за вашими фрагментами, и теперь есть несколько отличных улучшений. Но все еще не полностью работает. На странице редактирования, когда я нажимаю кнопку Save_button, форма, кажется, отправляется, но я думаю, что она никогда не отправляется. Показана анимация ajax, которая останется такой навсегда. Точка останова, которую я установил на дополнительной странице, никогда не срабатывает. (В приведенных выше кодах я пропустил анимацию ajax, которая будет отображаться при отправке формы и скрыта, когда это будет сделано) - person J K; 06.12.2018
comment
Можете ли вы создать CodePen или JSFiddle с помощью кода, который вы используете? Консоль показывала ошибки? - person Sally CJ; 06.12.2018
comment
Я имею в виду полный код, который вы используете. Или вы можете добавить код к вопросу как рабочий фрагмент. - person Sally CJ; 06.12.2018
comment
Я обновил код вопроса, включив ваш код и обновив его как можно ближе к коду в моем проекте, игнорируя биты, которые, как мне кажется, не имеют отношения к делу. $ ('# Загрузка'). Show (); покажет оверлейный анимированный gif, и это будет отображаться вечно, когда я нажимаю кнопку Save_button. Я не уверен, как заставить это работать в CodePen или JSFiddle. Пожалуйста, помогите, большое вам спасибо. - person J K; 06.12.2018
comment
Я это заметил. Изображение (это - ›www / path / to // image1.jpg) в Dropzone, есть ссылка на удаление с текстом Удалить файл. После того, как я нажму кнопку «Сохранить», этот текст изменится на «Отменить загрузку» и отобразится #loading ... они продолжаются вечно ... Но отправка никогда не достигает дополнительной страницы, я думаю, поскольку точка останова, которую я установил на дополнительной странице, никогда не срабатывает. Пожалуйста, помогите, большое вам спасибо. - person J K; 06.12.2018
comment
Вы действительно загружаете обратно все изображения в массиве imagesList? Или вы просто редактируете их свойства - например, поле Цена? Если первое, то проверьте обновленный ответ. - person Sally CJ; 06.12.2018
comment
После нажатия кнопки Save_button я увидел в веб-консоли Firefox следующую ошибку: TypeError: Аргумент 2 FormData.append не реализует интерфейс Blob. Да, я намерен загрузить обратно все изображения, так как считаю это проще, чем потенциально удалить некоторые существующие изображения и, возможно, добавить несколько новых изображений. Хорошо, я воспользуюсь вашими новыми кодами и посмотрю, работает ли он. Спасибо. - person J K; 06.12.2018
comment
Я не получаю эту ошибку FormData - ни с вашим исходным кодом (или этой версией), ни с новым, который я предоставил. Поэтому я не уверен, почему у вас возникла эта ошибка. Вы тестировали новый код? - person Sally CJ; 06.12.2018
comment
Да, я протестировал новый код, и он работает должным образом. Но теперь я начинаю понимать, что это может быть нежелательным методом в долгосрочной перспективе, потому что, когда я редактирую, изображения будут повторно загружены, и даже если я удалил изображение из Dropzone (для изображений, которые уже были загружены), это изображение не будет физически удален с сервера. У вас есть какие-либо предложения? Спасибо. - person J K; 07.12.2018
comment
Мне снова нужна твоя помощь. Вы знаете, как повторно поставить изображения в очередь, чтобы я мог повторно отправить страницу? Это представление ajax. Если при отправке возникает ошибка, и пользователь пытается повторно отправить страницу (после исправления значений в других полях), изображения в поле Dropzone больше не находятся в очереди, пользователю придется добавить другое изображение в иметь возможность повторно отправить. - person J K; 20.12.2018
comment
На самом деле, я немного сбит с толку - вы уже не загружаете файлы, если функция someFormValuesValidation() не дает true результата, так зачем вам повторять поставить файлы в очередь? - person Sally CJ; 23.12.2018
comment
Да вы правы. Изображения загружаются, когда someFormValuesValidation () возвращает true, но на стороне сервера есть дальнейшие проверки, поэтому, если на стороне сервера произошла какая-то ошибка, то страница отобразит ошибку, и страница останется. Таким образом, когда это произойдет, для пользователя будет естественным иметь возможность повторно подать заявку после внесения поправок. Прямо сейчас пользователю придется удалить все изображения и снова добавить их. - person J K; 24.12.2018
comment
Нашел другую проблему. Изображения не добавляются и не отображаются в том порядке / последовательности, как в imagesList. Они кажутся довольно случайными. Есть ли способ сделать изображения, показанные в порядке / последовательности, как в imagesList? Примечание. Я использую обновленные коды цикла for. Спасибо. - person J K; 24.12.2018
comment
Пожалуйста, помогите, я все еще борюсь с проблемой отображения изображений в случайном порядке в поле Dropzone. Пожалуйста помоги. Спасибо. - person J K; 02.01.2019
comment
Привет, мне очень жаль, я полностью забыл об этом вопросе - мое плохое. : / Надеюсь, вы нашли решение / обходной путь, но если вам все еще нужна помощь с порядком изображений, дайте мне знать. - person Sally CJ; 12.02.2019
comment
Привет .. действительно супер рад, что ты вернулся. Я все еще застрял, проблема с порядком изображений все еще существует, у меня нет решения. И у меня возникла новая проблема: в браузере Microsoft Edge изображения вообще не отображаются (изображения, которые уже были загружены, не отображаются в поле Dropzone на странице редактирования). Эта новая проблема не возникает в Firefox и Chrome. Пожалуйста помоги. Спасибо. - person J K; 27.02.2019

Спасибо за помощь, из представленных здесь идей я построил следующее решение, которое сработало для меня:

$.get(
  'attachments/actions/fetch-attachments.php',
  {
    parentdirectory: $fromparentdirectory,
    directory: $fromdirectory,
  },
  function (data) {
    var $files = [];
    $.each(data, function (key, row) {
      $files.push({
        name: row.name,
        size: row.size,
        dir: row.dir,
      });
    });

    if ($files) {
      for (var i = 0; i < $files.length; i++) {
        let mockFile = {
          name: $files[i].name,
          size: $files[i].size,
          dataURL: $fromparentdirectory + $fromdirectory + $files[i].name,
          status: Dropzone.QUEUED,
          accepted: true,
          upload: {},
        };

        var ext = $files[i].name.split('.')[1];
        if (ext != 'png' && ext != 'jpg' && ext != 'jpeg') {
          var thumbnail = 'attachments/file.png';
        } else {
          var thumbnail = $fromparentdirectory + $fromdirectory + $files[i].name;
        }

        let name = $files[i];
        name = $files[i].dir + $files[i].name;

        console.log(name);

        fetch(name)
          .then((res) => res.blob())
          .then((blob) => {
            let file = new File([blob], name, blob);
            thisDropzone.addFile(file);
          });
      }
    }
  },
);
person John Lenard Bocal    schedule 11.12.2020