Перетаскивание не устанавливает значение ввода, равное файлам. Работает, если выбрано кнопкой ввода - PullRequest
0 голосов
/ 12 июля 2020

Я пытался создать компонент перетаскивания. У нас есть рабочий пример без использования формы или кнопки отправки (это делается при вводе пользователем или перетаскивании).

Я модифицирую компонент, чтобы он работал с оболочкой формы и отправлял данные в другая страница.

Вот js:

const $fileUploader = $('.fileUploader');
const $input = $fileUploader.find('input[type="file"]');
const $label = $fileUploader.find('label');

const showFiles = files => {
    if (files) {
        $label.text(files[0].name);
    }
};

const uploadBulkReports = () => {
  $input.on('change', e => {
    showFiles(e.target.files);

  });
  $fileUploader
    .on('drag dragstart dragend dragover dragenter dragleave drop', e => {
        e.preventDefault();
        e.stopPropagation();
  })
  .on('dragover dragenter', () => {
    $fileUploader.addClass('is-dragover');
  })
    .on('dragleave dragend drop', () => {
    $fileUploader.removeClass('is-dragover');
  })
    .on('drop', e => {
    droppedFiles = e.originalEvent.dataTransfer.files;
    $input.files = e.originalEvent.dataTransfer.files;
    showFiles(droppedFiles);
  });
};

uploadBulkReports();

Наш HTML (я упростил это из C # / Razor)

<form mvc-action="/BulkUpload/Brand" action="/BulkUpload/Brand" enctype="multipart/form-data">
<div class="fileUploader" data-action="/BulkUpload/Brand" data-method="post">
    <div class="fileUploader__input">
      <input class="fileUploader__file" type="file" name="file" id="file" accept=".csv" />
      <label for="file">Click to select a file</label>
      <p class="fileUploader__dragndrop"> or drag it here</p>
      <ul class="small">
        <li>Id: Technical id of the Brand (leave blank to create new)</li>
        <li>Name: Name of the Brand</li>
      </ul>
    </div>
    <a href="#" class="fileUploader__restart fa fa-redo-alt"></a>
    <button class="btn btn-primary mt-2" type="submit">Submit</button>
  </div>
</form>

Насколько я понимаю заключается в том, что при падении $input.files = e.originalEvent.dataTransfer.files; должен установить значение входных файлов на информацию FileData, как и при выборе ввода. По какой-то причине он не работает при отправке.

Мы отправляем только один файл, поэтому я попытался получить доступ к файлу здесь e.originalEvent.dataTransfer.files[0];, но похоже, что он не работает. (e.dataTransfer.files у меня тоже не работает, пришлось пройти метод originalEvent).

Я сделал этот jsfiddle https://jsfiddle.net/lharby/75m8ocva/ хотя не думаю, что это возможно для проверки отправки формы в jsfiddle.

Я хочу знать, идентична ли установка $input.files для отброшенных файлов настройке ввода файла обычным методом. Когда я пытаюсь ввести console.log $input.files после изменения ввода, я получаю undefined, поэтому я предполагаю, что это другой метод.

Надеюсь, кто-то может помочь, если вам нужна дополнительная информация, дайте мне знать.

1 Ответ

1 голос
/ 12 июля 2020

Я хочу знать, идентична ли установка $ input.files для отброшенных файлов настройке ввода файла обычным методом

Нет, существует только один способ заполнения файлов в элементе управления загрузкой файла <input type="file"> и это обычный способ - вы нажимаете на него; он открывает браузер файлов ОС, и вы выбираете файл (ы)

Программная установка файлов в элементе управления загрузкой файлов запрещена по соображениям безопасности. Это означает, что вам придется использовать только AJAX.

.on('drop', e => {
  droppedFiles = e.originalEvent.dataTransfer.files;
  $input.files = e.originalEvent.dataTransfer.files; //<--this won't update file input's internal state
  showFiles(droppedFiles);
});

var ajaxData = new FormData($form.get(0));

$.each( droppedFiles, function(i, file) {
    ajaxData.append( 'file_'+i, file );
});

$.ajax({
    data: ajaxData,
    cache: false,
    contentType: false,
    processData: false,
    success: function(data) { }
});

Но подождите ... есть еще один вроде "взлома", который используют многие онлайн-сервисы, когда вы загружаете страницу в макете только HTML или с отключенным javascript. Причина, по которой это работает, заключается в том, что вы можете перетаскивать файлы через файловый элемент управления без какого-либо кода, давая тот же результат, если бы вы прошли «обычным способом»

Они увеличивают ширину и высоту на файловом элементе управления и сделайте его большим с помощью метки.

$('form').submit(function(e){
  
  e.preventDefault();
  console.log($('#file')[0].files)
  
});
input[type='file'] {
  border: 2px dashed #aaa;
  padding: 100px 50px 20px 130px;
  position: relative;
  background-color: yellow
}

input[type='file']:before {
  content: "drag & drop here";
  display: block;
  position: absolute;
  text-align: center;
  top: 50%;
  left: 50%;
  width: 200px;
  height: 100px;
  margin: -25px 0 0 -100px;
  font-size: 20px;
  font-weight: bold;
}

#submit { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>

<form>

<input type="file" id="file" />

<input type="submit" id="submit">

</form>
...