회원 테스트
페이지 정보
본문
ㄹㅇㄴㅁㄹㅇㄴㅁㄹㅇㄴㅁ
- 다음글ee 24.10.07
댓글목록

수정2님의 댓글
<?php
// 파일 업로드 처리
$uploadDir = __DIR__ . '/uploads/';
if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = $_POST['title'] ?? '';
$writer = $_POST['writer'] ?? '';
$content = $_POST['content'] ?? '';
$uploadedFiles = [];
if (!empty($_FILES['files']['name'][0])) {
foreach ($_FILES['files']['name'] as $i => $name) {
$tmpName = $_FILES['files']['tmp_name'][$i];
$ext = pathinfo($name, PATHINFO_EXTENSION);
$saveName = uniqid() . '.' . $ext;
$target = $uploadDir . $saveName;
if (move_uploaded_file($tmpName, $target)) {
$uploadedFiles[] = $saveName;
}
}
}
// DB 저장 코드 추가 가능 (제목, 작성자, 내용, $uploadedFiles)
echo '<script>alert("글이 등록되었습니다.");location.href="list.html";</script>';
exit;
}
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>글쓰기</title>
<link href="daisyui@3.9.4/dist/full.css"" TARGET="_blank" rel="nofollow">https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.tailwindcss.com"></script>
<style>
.dropzone { border: 2px dashed #a3a3a3; border-radius: 8px; padding: 30px 0; text-align: center; transition: border-color 0.2s;}
.dropzone.dragover { border-color: #2563eb; background: #f0f6ff;}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto py-8 px-4">
<div class="mb-6 flex items-center justify-between">
<h1 class="text-2xl font-bold">글쓰기</h1>
<a href="list.html" class="btn btn-neutral btn-sm">목록</a>
</div>
<form class="card bg-white shadow p-6 space-y-4" action="" method="post" enctype="multipart/form-data">
<div>
<label class="label"><span class="label-text">제목</span></label>
<input type="text" name="title" class="input input-bordered w-full" required>
</div>
<div>
<label class="label"><span class="label-text">작성자</span></label>
<input type="text" name="writer" class="input input-bordered w-full" required>
</div>
<div>
<label class="label"><span class="label-text">내용</span></label>
<textarea name="content" class="textarea textarea-bordered w-full h-40" required></textarea>
</div>
<div>
<label class="label"><span class="label-text">첨부파일 (드래그앤드롭 가능)</span></label>
<div id="dropzone" class="dropzone">
<span id="dropzone-text">여기로 파일을 드래그하거나 클릭하여 첨부하세요</span>
<input type="file" name="files[]" id="fileInput" class="hidden" multiple>
</div>
<ul id="fileList" class="mt-2"></ul>
</div>
<div class="flex justify-end gap-2">
<button type="reset" class="btn btn-outline">초기화</button>
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form>
</div>
<script>
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('fileInput');
const fileList = document.getElementById('fileList');
dropzone.addEventListener('click', () => fileInput.click());
dropzone.addEventListener('dragover', (e) => {
e.preventDefault(); dropzone.classList.add('dragover');
});
dropzone.addEventListener('dragleave', () => dropzone.classList.remove('dragover'));
dropzone.addEventListener('drop', (e) => {
e.preventDefault(); dropzone.classList.remove('dragover');
fileInput.files = e.dataTransfer.files;
updateFileList();
});
fileInput.addEventListener('change', updateFileList);
function updateFileList() {
fileList.innerHTML = '';
Array.from(fileInput.files).forEach(f => {
const li = document.createElement('li');
li.textContent = f.name + ' (' + Math.round(f.size/1024) + 'KB)';
fileList.appendChild(li);
});
}
</script>
</body>
</html>

수정2님의 댓글
<!-- ... (상단 PHP/HTML 동일) ... -->
<div>
<label class="label"><span class="label-text">첨부파일 (드래그앤드롭 가능)</span></label>
<div id="dropzone" class="dropzone cursor-pointer">
<span id="dropzone-text">여기로 파일을 드래그하거나 클릭하여 첨부하세요</span>
<input type="file" id="fileInput" class="hidden" multiple>
</div>
<ul id="fileList" class="mt-2"></ul>
</div>
<!-- ... (나머지 폼 동일) ... -->
<script>
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('fileInput');
const fileList = document.getElementById('fileList');
const form = document.querySelector('form');
let filesToUpload = [];
dropzone.addEventListener('click', () => fileInput.click());
dropzone.addEventListener('dragover', e => { e.preventDefault(); dropzone.classList.add('dragover'); });
dropzone.addEventListener('dragleave', () => dropzone.classList.remove('dragover'));
dropzone.addEventListener('drop', e => {
e.preventDefault(); dropzone.classList.remove('dragover');
addFiles(e.dataTransfer.files);
});
fileInput.addEventListener('change', () => addFiles(fileInput.files));
function addFiles(fileListObj) {
for (let file of fileListObj) {
if (!filesToUpload.some(f => f.name === file.name && f.size === file.size)) {
filesToUpload.push(file);
}
}
updateFileList();
fileInput.value = ''; // input 초기화 (같은 파일 다시 선택 가능)
}
function updateFileList() {
fileList.innerHTML = '';
filesToUpload.forEach((f, idx) => {
const li = document.createElement('li');
li.className = 'flex items-center gap-2 mb-1';
li.innerHTML = `
<span class="badge badge-outline">${f.name} (${Math.round(f.size/1024)}KB)</span>
<button type="button" class="btn btn-xs btn-error" aria-label="삭제" data-idx="${idx}">X</button>
`;
fileList.appendChild(li);
});
// 삭제 이벤트
fileList.querySelectorAll('button[data-idx]').forEach(btn => {
btn.onclick = e => {
filesToUpload.splice(Number(btn.dataset.idx), 1);
updateFileList();
};
});
}
// 폼 제출 시 filesToUpload를 FormData에 append
form.addEventListener('submit', function(e) {
if (!filesToUpload.length) return; // 첨부파일 없으면 기본 동작
e.preventDefault();
const fd = new FormData(form);
filesToUpload.forEach(f => fd.append('files[]', f));
fetch(form.action, { method: 'POST', body: fd })
.then(res => res.text())
.then(html => document.write(html));
});
</script>
