Как удалить файл из числа прикрепленных?

Здравствуйте, уважаемые пользователи.

Возникла такая проблема, которую не могу решить самостоятельно. Суть проблемы вот в чем:
Есть input file, в котором пользователи могут выбрать несколько файлов. Как только пользователь выбирает файлы, в jquery срабатывает событие change, и специальном div сверху отображаются имена всех выбранных файлов. Рядом с каждым именем есть кнопка "Удалить". Необходимо сделать по нажатию на кнопку "Удалить" функцию, которая бы удаляла конкретный файл из числа выбранных, и, соответственно, меняла бы значение input file.

Вот мой вариант, который не работает:
$(document).ready(function() {
	$('body').on('click','#delete',function() { 
		var num=$(this).attr("name");
		alert(num);
		$("#filename")[0].files[num].empty();
		alert ($("#filename")[0].files.length);
	});
    $('body').on('change','#filename',function() { 
		var file_num=$("#filename")[0].files.length;
		for (i=0;i<file_num;i++) {
			$('.files').html($('.files').html()+$("#filename")[0].files[i].name+'<input type="button" value="удалить" id="delete" name="'+i+'" /><br>');
		}
	});
});

Также, был вариант заменить строчку
$("#filename")[0].files[num].empty();
на
$("#filename")[0].files.splice(num);
,но тоже не работает
<div class="files"></div>
<form method="post" enctype="multipart/form-data">
	<input type="file" name="filename" id="filename" multiple />
</form>


Заранее спасибо!
  • Вопрос задан
  • 16425 просмотров
Пригласить эксперта
Ответы на вопрос 4
profesor08
@profesor08 Куратор тега JavaScript
Данные о файлах хранятся в объекте FileList, поля которого только readonly.
$("#filename")[0].files
Это значит, что можно только посмотреть что там, но не менять. Следовательно остается либо удалить все.
$("#filename")[0].value = "";
Либо позволить выбирать только по одному файлу и для каждого файла свой
<input type="file" name="filename" id="filename">
Без атрибута multiple
Ответ написан
Комментировать
IonDen
@IonDen
JavaScript developer. IonDen.com
Вот так: jsfiddle.net/IonDen/p13jcyjj
var file = document.querySelector('.test'),
    removeBtn = document.querySelector('.remove');

removeBtn.addEventListener('click', function () {
    file.value = '';
}, false);
Ответ написан
@Nawot
Можно скопировать все файлы кроме удаленного из input в DataTransfer, а потом обратно в input
Вот код из моего проекта:
const loaders = document.querySelectorAll('.file-loader')

loaders.forEach((loader) =>
{
    const dropBox = loader.querySelector('.file-loader__input-wrapper')
    const input = loader.querySelector('.file-loader__input')
    const files = loader.querySelector('.file-loader__files')


    const refreshFiles = () =>
    {
        // Clear files
        files.innerHTML = ''

        // Make all files
        Array.from(input.files).forEach(file =>
        {
            const el = document.createElement('li')
            el.classList.add('file-lader__file')
            el.classList.add('file-loader-file')

            const elName = document.createElement('span')
            const elDelete = document.createElement('span')

            elName.classList.add('file-loader-file__name')
            elDelete.classList.add('file-loader-file__delete')
            elDelete.addEventListener('click', e =>
            {
                deleteFile(e.target.parentNode)
            })

            elName.textContent = file.name
            elDelete.textContent = 'Удалить файл'

            el.appendChild(elName)
            el.appendChild(elDelete)

            files.appendChild(el)
        })
    }

    const deleteFile = (element) =>
    {
        let dt = new DataTransfer()
        const index = getChildElementIndex(element)

        // Copy all besides deleted
        for(let i=0; i<=input.files.length-1; i++)
            if(i !== index)
                dt.items.add(input.files[i])

        // Replace
        input.files = dt.files

        refreshFiles()
    }

    function getChildElementIndex(element)
    {
        return Array.prototype.indexOf.call(element.parentNode.children, element)
    }


    dropBox.addEventListener('drop', e =>
    {
        input.files = e.dataTransfer.files

        refreshFiles()
        e.preventDefault()
    })
    input.addEventListener('change', e =>
    {
        refreshFiles()
        e.preventDefault()
    })
})
Ответ написан
Комментировать
max_shane
@max_shane
Javascript / Node.js dev
Ваша задача решается на чистом Javascript, путем создания своего Blob объекта (копируете в него данные из files (объект FilesList), затем отправляете на сервер посредством XMLHttpRequest.
Только надо знать основы JS и придется разобраться в работе XMLHttpRequest.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы