[JavaScript] 첨부파일 다중파일 multiple 업로드
Ver1. 파일 첨부 시 최대 개수가 넘으면 현재 선택된 파일은 전부 첨부를 안 하는 방식.
See the Pen [T] 다중파일 업로드 v1 by green526 (@green526) on CodePen.
Ver2. 파일 첨부 시 최대 개수를 넘으면 최대 개수 까지만 첨부하는 방식.
See the Pen by green526 (@green526) on CodePen.
코드
html
<div class="insert">
<form method="POST" onsubmit="return false;" enctype="multipart/form-data">
<input type="file" onchange="addFile(this);" multiple />
<div class="file-list"></div>
</form>
</div>
css
.insert {
padding: 20px 30px;
display: block;
width: 600px;
margin: 5vh auto;
height: 90vh;
border: 1px solid #dbdbdb;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.insert .file-list {
height: 200px;
overflow: auto;
border: 1px solid #989898;
padding: 10px;
}
.insert .file-list .filebox p {
font-size: 14px;
margin-top: 10px;
display: inline-block;
}
.insert .file-list .filebox .delete i{
color: #ff5353;
margin-left: 5px;
}
javascript
var fileNo = 0;
var filesArr = new Array();
// Ver1.
/* 첨부파일 추가 */
function addFile(obj){
var maxFileCnt = 5; // 첨부파일 최대 개수
var attFileCnt = document.querySelectorAll('.filebox').length; // 기존 추가된 첨부파일 개수
var remainFileCnt = maxFileCnt - attFileCnt; // 추가로 첨부가능한 개수
var curFileCnt = obj.files.length; // 현재 선택된 첨부파일 개수
// 첨부파일 개수 확인
if (curFileCnt > remainFileCnt) {
alert("첨부파일은 최대 " + maxFileCnt + "개 까지 첨부 가능합니다.");
} else {
for (const file of obj.files) {
// 첨부파일 검증
if (validation(file)) {
// 파일 배열에 담기
var reader = new FileReader();
reader.onload = function () {
filesArr.push(file);
};
reader.readAsDataURL(file);
// 목록 추가
let htmlData = '';
htmlData += '<div id="file' + fileNo + '" class="filebox">';
htmlData += ' <p class="name">' + file.name + '</p>';
htmlData += ' <a class="delete" onclick="deleteFile(' + fileNo + ');"><i class="far fa-minus-square"></i></a>';
htmlData += '</div>';
$('.file-list').append(htmlData);
fileNo++;
} else {
continue;
}
}
}
// 초기화
document.querySelector("input[type=file]").value = "";
}
// Ver2.
/* 첨부파일 추가 */
function addFile(obj){
var maxFileCnt = 5; // 첨부파일 최대 개수
var attFileCnt = document.querySelectorAll('.filebox').length; // 기존 추가된 첨부파일 개수
var remainFileCnt = maxFileCnt - attFileCnt; // 추가로 첨부가능한 개수
var curFileCnt = obj.files.length; // 현재 선택된 첨부파일 개수
// 첨부파일 개수 확인
if (curFileCnt > remainFileCnt) {
alert("첨부파일은 최대 " + maxFileCnt + "개 까지 첨부 가능합니다.");
}
for (var i = 0; i < Math.min(curFileCnt, remainFileCnt); i++) {
const file = obj.files[i];
// 첨부파일 검증
if (validation(file)) {
// 파일 배열에 담기
var reader = new FileReader();
reader.onload = function () {
filesArr.push(file);
};
reader.readAsDataURL(file)
// 목록 추가
let htmlData = '';
htmlData += '<div id="file' + fileNo + '" class="filebox">';
htmlData += ' <p class="name">' + file.name + '</p>';
htmlData += ' <a class="delete" onclick="deleteFile(' + fileNo + ');"><i class="far fa-minus-square"></i></a>';
htmlData += '</div>';
$('.file-list').append(htmlData);
fileNo++;
} else {
continue;
}
}
// 초기화
document.querySelector("input[type=file]").value = "";
}
/* 첨부파일 검증 */
function validation(obj){
const fileTypes = ['application/pdf', 'image/gif', 'image/jpeg', 'image/png', 'image/bmp', 'image/tif', 'application/haansofthwp', 'application/x-hwp'];
if (obj.name.length > 100) {
alert("파일명이 100자 이상인 파일은 제외되었습니다.");
return false;
} else if (obj.size > (100 * 1024 * 1024)) {
alert("최대 파일 용량인 100MB를 초과한 파일은 제외되었습니다.");
return false;
} else if (obj.name.lastIndexOf('.') == -1) {
alert("확장자가 없는 파일은 제외되었습니다.");
return false;
} else if (!fileTypes.includes(obj.type)) {
alert("첨부가 불가능한 파일은 제외되었습니다.");
return false;
} else {
return true;
}
}
/* 첨부파일 삭제 */
function deleteFile(num) {
document.querySelector("#file" + num).remove();
filesArr[num].is_delete = true;
}
/* 폼 전송 */
function submitForm() {
// 폼데이터 담기
var form = document.querySelector("form");
var formData = new FormData(form);
for (var i = 0; i < filesArr.length; i++) {
// 삭제되지 않은 파일만 폼데이터에 담기
if (!filesArr[i].is_delete) {
formData.append("attach_file", filesArr[i]);
}
}
$.ajax({
method: 'POST',
url: '/register',
dataType: 'json',
data: formData,
async: true,
timeout: 30000,
cache: false,
headers: {'cache-control': 'no-cache', 'pragma': 'no-cache'},
success: function () {
alert("파일업로드 성공");
},
error: function (xhr, desc, err) {
alert('에러가 발생 하였습니다.');
return;
}
})
}
참고
https://velog.io/@xedni/JavaScript-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C-FormData
JavaScript | 파일 업로드 (FormData)
업로드 된 파일을 자바스크립트로 다루는 방법에 대해 알아보자.
velog.io
https://taeny.dev/javascript/file-object/
💾 자바스크립트 File 객체
자바스크립트에서 이미지나 동영상, 오디오 등 대용량 파일을 업로드할 때, file 객체를 이용한다. 이번 포스팅에서는 file 객체에 대한 내용을 정리해보았다. 1. File 객체 2. URL로 접근 3. FileReader로
taeny.dev
https://developer.mozilla.org/ko/docs/Web/HTML/Element/Input/file
- HTML: Hypertext Markup Language | MDN
file 유형의
요소에는 저장 장치의 파일을 하나 혹은 여러 개 선택할 수 있습니다. 그 후, 양식을 제출해 서버로 전송하거나, File API를 사용한 JavaScript 코드로 조작할 수 있습니다.
developer.mozilla.org
https://hianna.tistory.com/346
[HTML] input type='file' 속성 알아보기 ( 파일 입력 )
웹페이지에서 사용자의 로컬 파일을 입력받기 위해서는 다음과 같이 input 태그의 type속성을 file로 지정하는 방법을 사용합니다. See the Pen read file by anna (@hianna) on CodePen. 여기에서는 input의 type..
hianna.tistory.com
https://tyrannocoding.tistory.com/54
파일 업로드 쉽게 구현하기 (Spring Ajax 다중파일 업로드 & 개별삭제 & 개수제한 & 초기화) ②
파일 업로드 게시판 파일 업로드가 되는 게시판은 대부분의 사이트에 꼭 하나씩 있습니다. 사이트를 구축할 때 기본이 되는 파일 업로드이지만 불편함 없이 다양한 기능이 필요할 때도 있습니
tyrannocoding.tistory.com