728x90

첨부파일을 드래그로 순서 변경 가능하게 구현한 스크립트 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Drag and Drop</title>
    <style>
        .file-list-box {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            justify-content: flex-start;
            align-items: center;
            border: 2px dashed #ccc;
            padding: 10px;
            min-height: 100px;
        }

        .file-list-box .img-box {
            width: 100px;
            height: 100px;
            border-radius: 8px;
            overflow: hidden;
        }

        .file-list-box .img-box img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .over {
            border: 2px dashed #000;
        }
    </style>
</head>
<body>
    <div class="file-box" data-max-files="5" id="file-box-1">
        <div class="file-s-tit">사진올리기</div>
        <div class="file-list-box attachBookingList" data-id="1"></div>
        <button class="btn-file" type="button" onclick="openFileInput(1)">사진추가</button>
        <input type="file" name="addFile" id="fileInput-1" class="file-input" style="display: none;" accept="image/*" multiple>
    </div>

    <div class="file-box" data-max-files="5" id="file-box-2">
        <div class="file-s-tit">사진올리기</div>
        <div class="file-list-box attachBookingList" data-id="2"></div>
        <button class="btn-file" type="button" onclick="openFileInput(2)">사진추가</button>
        <input type="file" name="addFile" id="fileInput-2" class="file-input" style="display: none;" accept="image/*" multiple>
    </div>

    <script>
        function openFileInput(id) {
            document.getElementById(`fileInput-${id}`).click();
        }

        function handleFiles(files, targetBox) {
            const maxFiles = parseInt(targetBox.closest('.file-box').dataset.maxFiles);
            const currentFiles = targetBox.querySelectorAll('.img-box').length;
            const totalFiles = currentFiles + files.length;

            if (totalFiles > maxFiles) {
                alert(`최대 ${maxFiles}개의 파일만 업로드할 수 있습니다.`);
                return;
            }

            Array.from(files).forEach(file => {
                if (!file.type.startsWith('image/')) return;

                const reader = new FileReader();
                reader.onload = function(e) {
                    const newImage = document.createElement('div');
                    newImage.classList.add('img-box');
                    newImage.innerHTML = `<img src="${e.target.result}" alt="이미지">`;
                    targetBox.appendChild(newImage);
                };
                reader.readAsDataURL(file);
            });
        }

        document.addEventListener('DOMContentLoaded', () => {
            document.querySelectorAll('.file-input').forEach(input => {
                input.addEventListener('change', function(event) {
                    const targetBox = document.querySelector(`.file-list-box[data-id="${this.id.split('-')[1]}"]`);
                    handleFiles(event.target.files, targetBox);
                    this.value = '';
                });
            });

            document.querySelectorAll('.file-list-box').forEach(box => {
                box.addEventListener('dragover', function(event) {
                    event.preventDefault();
                    event.stopPropagation();
                    this.classList.add('over');
                });

                box.addEventListener('dragleave', function(event) {
                    event.preventDefault();
                    event.stopPropagation();
                    this.classList.remove('over');
                });

                box.addEventListener('drop', function(event) {
                    event.preventDefault();
                    event.stopPropagation();
                    this.classList.remove('over');
                    const files = event.dataTransfer.files;
                    handleFiles(files, this);
                });
            });
        });
    </script>
</body>
</html>

 

// 파일 업로드 처리 함수
function handleFileUpload(event, listBoxSelector) {
  const files = event.target.files;
  const fileListBox = document.querySelector(listBoxSelector);

  // 파일 목록 표시
  for (let i = 0; i < files.length; i++) {
    const fileItem = document.createElement('div');
    fileItem.classList.add('file-item');
    fileItem.textContent = files[i].name;
    fileItem.draggable = true;
    fileItem.addEventListener('dragstart', handleDragStart);
    fileItem.addEventListener('dragover', handleDragOver);
    fileItem.addEventListener('drop', handleDrop);
    fileListBox.appendChild(fileItem);
  }
}

// 드래그 시작 이벤트 핸들러
function handleDragStart(event) {
  event.dataTransfer.setData('text/plain', null);
  event.currentTarget.classList.add('dragging');
}

// 드래그 오버 이벤트 핸들러
function handleDragOver(event) {
  event.preventDefault();
  event.currentTarget.classList.add('drag-over');
}

// 드롭 이벤트 핸들러
function handleDrop(event) {
  event.preventDefault();
  event.currentTarget.classList.remove('drag-over');

  const draggedItem = document.querySelector('.dragging');
  const dropTarget = event.currentTarget;
  const fileListBox = event.currentTarget.parentNode;

  // 파일 목록 순서 변경
  fileListBox.insertBefore(draggedItem, dropTarget);
}

// 파일 추가 버튼 클릭 이벤트 핸들러
document.querySelectorAll('.btn-file').forEach(button => {
  button.addEventListener('click', () => {
    const fileInput = button.parentNode.querySelector('.file-input');
    fileInput.click();
  });
});

// 파일 선택 이벤트 핸들러
document.querySelectorAll('.file-input').forEach(input => {
  input.addEventListener('change', (event) => {
    const listBoxSelector = event.target.parentNode.parentNode.querySelector('.file-list-box').classList[1];
    handleFileUpload(event, `.${listBoxSelector}`);
  });
});
728x90

+ Recent posts