Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Удаление элементов из files[i] (<input multiple="">) (https://javascript.ru/forum/jquery/30213-udalenie-ehlementov-iz-files%5Bi%5D-input-multiple%3D.html)

ksevelyar 27.07.2012 21:53

Удаление элементов из files[i] (<input multiple="">)
 
Хочу, чтобы можно было выборочно удалять изображения после добавления их через <input multiple="">.

Но напрямую это сделать видимо нельзя: http://www.w3.org/TR/FileAPI/#dfn-filelist

"The HTMLInputElement interface [html] has a readonly attribute of type FileList, which is what is being accessed in the above example. Other interfaces with a readonly attribute of type FileList include the DataTransfer interface [html]".

Как можно это обойти и удалять files[i] по клику на .remove?

Извиняюсь за смесь js и jquery:

http://jsfiddle.net/mUHeU/1/

$(document).ready(function() {

var fileSelect = document.getElementById("fileSelect"),
    fileElem = document.getElementById("fileElem");

fileSelect.addEventListener("click", function (e) {
  if (fileElem) {
    fileElem.click();
  }
  e.preventDefault(); // prevent navigation to "#"
}, false);

$('#fileElem').change(function()
{
  handleFiles(this.files);
});


function bytesToSize(bytes) {
  var kilobyte = 1024;
  var megabyte = kilobyte * 1024;
  var gigabyte = megabyte * 1024;
  var terabyte = gigabyte * 1024;

  if ((bytes >= 0) && (bytes < kilobyte)) {
    return bytes;

  } else if ((bytes >= kilobyte) && (bytes < megabyte)) {
    return (bytes / kilobyte).toFixed(0) + 'K';

  } else if ((bytes >= megabyte) && (bytes < gigabyte)) {
    return (bytes / megabyte).toFixed(1) + 'M';

  } else if ((bytes >= gigabyte) && (bytes < terabyte)) {
    return (bytes / gigabyte).toFixed(2) + 'G';

  } else if (bytes >= terabyte) {
    return (bytes / terabyte).toFixed(2) + 'T';

  }
}


function handleFiles(files) {
  var d = document.getElementById("filelist");
  var list = document.createElement("ul");
  d.appendChild(list);
  for (var i=0; i < files.length; i++) {
    var li = document.createElement("li");
    list.appendChild(li);

    var a = document.createElement("a");
    a.setAttribute('href','#');
    a.setAttribute('alt','');
    li.appendChild(a);

    var img = document.createElement("img");
    img.src = window.URL.createObjectURL(files[i]);;
    img.onload = function() {
      window.URL.revokeObjectURL(this.src);
    }
    a.appendChild(img);

    var name = $("<span class='name'>" + files[i].name + "</span>");
    $(a).append(name);

    var size = $("<span class='size'>" + bytesToSize(files[i].size) + "</span>");
    $(a).append(size);

    var remove = $("<a href='#remove' id=" + i + " class='remove'>remove</a>");
    $(li).append(remove);

  }
}

$('.remove').live("click", function(event) {
  event.preventDefault();
  alert("Handler for .click() called.");
});


});

vadim5june 27.07.2012 22:08

Что то не работает Ваш пример в хроме у меня
А API File System не хотите воспользовться?
window.URL-пишет undefined
вот есть аналогичный взятый из статьи -загружать только картинки
http://all-html5.narod.ru/3/Blob3.htm

ksevelyar 27.07.2012 22:17

Цитата:

Сообщение от vadim5june (Сообщение 192234)
Что то не работает Ваш пример в хроме у меня

И правда, в Хроме не работает. Видимо нужно с опаской относиться к сниппетам с MDN :)


Видимо из-за этих строчек:

Код:

window.URL.createObjectURL(files[i]);
window.URL.revokeObjectURL(this.src);

Переделаю.

Цитата:

Сообщение от vadim5june (Сообщение 192234)
А API File System не хотите воспользовться?

Спасибо за наводку, погуглю.

vadim5june 27.07.2012 22:18

Цитата:

Сообщение от ksevelyar (Сообщение 192237)
Код:

А API File System не хотите воспользовться?
Спасибо за наводку, погуглю.

http://www.html5rocks.com/ru/tutorials/file/filesystem/
а это BLOB
http://www.html5rocks.com/ru/tutorials/file/dndfiles/

ksevelyar 29.07.2012 00:38

Цитата:

Сообщение от vadim5june (Сообщение 192234)
Что то не работает Ваш пример в хроме у меня
А API File System не хотите воспользовться?
window.URL-пишет undefined
вот есть аналогичный взятый из статьи -загружать только картинки
http://all-html5.narod.ru/3/Blob3.htm

Поправил пример, к сожалению почти весь код из handleFiles пришлось перетащить внутрь reader.onload. Пишешь код, а потом калечишь его ради кроссбраузерности.

http://jsfiddle.net/ksevelyar/mUHeU/4/

Правда к решению основной проблемы (удалять файлы из filelist) меня это не приблизило. FileSystem API я сразу отмёл, так как он работает только в Хроме.

Посмотрел похожие вопросы на stackoverflow — видимо это вообще нельзя сделать.

Очень жаль. Значит всё же придётся сразу загружать всё на сервер через ajax, вместо того, чтобы показывать локальные превью.

Deff 29.07.2012 00:42

ksevelyar,
Идеальные решения есть ток через флешь - ищите мультизагрузка файлов через флеш - там есть и Drag-and-drop решения: добавления изъятия файлов
Но ко всем подобным скриптам нужна и даётся еще и серверная сторона

vadim5june 29.07.2012 01:06

Цитата:

Сообщение от Deff (Сообщение 192571)
ksevelyar,
Идеальные решения есть ток через флешь -

флешь умирает-его скоро не будет
по моему уже нет в эппловских девайсах
гугл тож против настроен

Deff 29.07.2012 01:14

vadim5june,
Ну тады поправка - На сегодняшний - день...

Мейл.ru вон сделал через Silverlight - но раз - новая установка - (мало у кого стоит)
Два - у них можно доверять сервису - в отличе от всяких новых вариантов - флешь стоит у 90% пользователей
И три - пока нет кроссбраузерных решений лучше

Mukhtar 02.03.2013 15:58

Спасибо за ответы. Значит никак нельзя сделать, чтобы изображения удалялись из превьюшек?!
Наверняка можно обойти это, например считать все выбранные файлы из input type="file" и сравнивать с нужным. Потом убрать этот файл из списка и дело с концом )))

makas 13.03.2017 07:47

Ну удалять изображения из превьюшек дело же не хитрое, более сложнее удалить изображение из загрузки (если загрузка идет при помощи стандартной кнопки)

Как я реализовал это.
Пользователь нажимает на кнопку загрузки файлов, выбирает нужные, появляются превьюшки выбранных файлов. Далее может еще и еще нажимать на выбор файлов и они будут добавляться к превьюшкам.
Стандартно в html нельзя добавлять новые файлы к уже выбранным, стандартно загрузятся на сервер только последние выбранные. Но... никто не мешает создавать новые поля для файлов.
То есть, пользователь выбрал файлы, они отобразились в списке превьюшек, дальше обычным стилем делаем display:none для input file, и создаем рядом с ним новый input file
Таким образом кажется, что нажимаешь на одну и ту же кнопку и добавляешь новые файлы, а на самом деле каждое добавление происходит от нового input

Ну а как удалять теперь файлы из загрузки, понятно.
При удалении из превьюшки, удаляем весь input type="file" и все.
Но... есть одна проблема, если используете multiple, то файлы удаляться будут группами, сколько было выбрано файлов за один раз, столько и удалиться.
Чтобы можно было удалять файлы по одному, нужно и выбирать их по одному, то есть не использовать multiple. Пусть пользователь добавляет файлы по одному, но зато и удалять их сможет по одному.


Часовой пояс GMT +3, время: 22:52.