본문 바로가기
Web Development/Spring Legacy

[Spring / Legacy] multiple input file을 이용한 파일 전체/부분 삭제 구현 (Javascript)

by 감자맹고우 2021. 12. 31.
728x90
반응형

Spring Legacy 프로젝트를 진행하는 도중, 여러 개의 파일을 한번 에 추가해야 할 일이 있었다.

여러 개의 Single 파일을 한 줄씩 입력하게 하면 편했겠지만, 많은 파일을 한 번에 올릴 확률이 더 크기 때문에 Multiple 속성 ( '<input type="file" id="file" multiple>' ) 으로 구현하였다.

 

그러다보니 예상치 못한 문제에 부딪혔었는데, 부딪혔던 문제와 해결 방법을 기록으로 남겨 공유하고자 한다.

 

 

※ File 타입의 Input은 반드시 알아두어야 할 점이 있다.

value 값을 사용자가 선택하는 것 외에 임의적으로 입력할 수 없도록 되어 있다는 점이다.

생각해보자.

코드에서 파일을 직접 입력할 수 있다면 보안 이슈가 아주 쉽게 발생하게 될 것이다.

그러니 input 밖에서 파일을 따로 처리하고 싶다면, 사용자에게 입력받은 파일을 변수에 할당하여 처리하면 된다.

 

const files = $('#file')[0].files;

 

 

반응형

 

 

1. 파일 전체 삭제

 

전체 삭제는 간단하다. File Input의 value 값을 초기화 하면 된다.

 

const deleteAll = () => {
	$('#file').val('');
}

 

 

 

2. 파일 개별 삭제

 

multiple 속성의 File Input은 사용자에게 입력받은 값을 FileList로 처리한다.

FileList는 Array와는 다르지만, Array로 처리할 수 있다.

 

그렇기 때문에 FileList를 Array로 처리하기 위해 Array.from을 사용하였고,

( https://stackoverflow.com/questions/3144419/how-do-i-remove-a-file-from-the-filelist/3162319 )

 

Array를 FileList로 처리하기 위해 Javscript가 제공하는 DataTransfer 객체를 이용하였다.

( https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer )

 

 

const delete = (fileNum) => {	//fileNum은 li 의 index 값
    const dataTransfer = new DataTransfer();
    
    let files = $('#file')[0].files;	//사용자가 입력한 파일을 변수에 할당
    
    let fileArray = Array.from(files);	//변수에 할당된 파일을 배열로 변환(FileList -> Array)
    
    fileArray.splice(fileNum, 1);	//해당하는 index의 파일을 배열에서 제거
    
    fileArray.forEach(file => { dataTransfer.items.add(file); });
    //남은 배열을 dataTransfer로 처리(Array -> FileList)
    
    $('#file')[0].files = dataTransfer.files;	//제거 처리된 FileList를 돌려줌
}

 

 

이렇게 하고, console.log(files)를 찍어 보면 FileList 가 제대로 삭제 처리 되고 있음을 알 수 있다 !

 

 

================================= 2022.12.05 추가 =================================

 

p.s. DOM 요소 index 찾는 방법 추가 ( 현재 요소가 몇 번째인지 찾는 방법 )

 

// 개별 파일의 삭제 버튼에 적용할 메소드
const delete = (obj) => {
    //현재 버튼(obj)의 상위 요소 중 가장 가까운 div 요소를 찾음
    //div는 선택한 파일 목록을 보여주는 부분
    const div = $(obj).closest('div');
    
    //div에서 'button' 태그 중 현재 버튼(obj)의 index가 몇 번째인지 확인
    //0부터 시작
    const index = div.find('button').index(obj);
    
    ~~~ 이하 부분 처리는 동일 ~~~
}

 

 

🤞 도움이 되셨기를 바랍니다. 한 번의 클릭과 댓글은 어딘가의 누군가에게 진실로 큰 힘이 됩니다. 🐱‍🏍

 

728x90
반응형

댓글