728x90
728x90
SMALL
HTML, CSS, JavaScript + Spring Boot + MyBatis + MySQL 으로 게시판 만들기 (6)
안녕하세요! 이번 포스트에서는 게시판 애플리케이션에 추가적인 기능을 구현하고 최적화를 다루겠습니다.
1. 게시글 검색 기능 추가
게시글을 검색할 수 있는 기능을 추가하여 사용자가 원하는 게시글을 쉽게 찾을 수 있도록 하겠습니다.
1.1 index.html 수정
검색 입력 필드를 추가합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MyBoard</title>
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<div class="container">
<h1>게시판</h1>
<form id="postForm">
<input type="text" id="title" placeholder="제목" required>
<textarea id="content" placeholder="내용" required></textarea>
<button type="submit">게시글 작성</button>
</form>
<input type="text" id="search" placeholder="검색어를 입력하세요">
<button onclick="searchPosts()">검색</button>
<div id="posts"></div>
</div>
<script src="/js/scripts.js"></script>
</body>
</html>
1.2 scripts.js 수정
검색 기능을 구현합니다.
document.addEventListener("DOMContentLoaded", function() {
const postForm = document.getElementById("postForm");
const postsDiv = document.getElementById("posts");
postForm.addEventListener("submit", function(event) {
event.preventDefault();
const title = document.getElementById("title").value;
const content = document.getElementById("content").value;
fetch("/api/posts", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ title: title, content: content })
})
.then(response => response.json())
.then(data => {
fetchPosts();
alert("게시글이 작성되었습니다.");
})
.catch(error => {
console.error("Error:", error);
alert("게시글 작성 중 오류가 발생했습니다.");
});
});
function fetchPosts() {
fetch("/api/posts")
.then(response => response.json())
.then(posts => {
postsDiv.innerHTML = "";
posts.forEach(post => {
const postDiv = document.createElement("div");
postDiv.classList.add("post");
postDiv.innerHTML = `
<h3>${post.title}</h3>
<p>${post.content}</p>
<button class="edit" onclick="editPost(${post.id}, '${post.title}', '${post.content}')">수정</button>
<button class="delete" onclick="deletePost(${post.id})">삭제</button>
`;
postsDiv.appendChild(postDiv);
});
})
.catch(error => console.error("Error:", error));
}
window.editPost = function(id, title, content) {
if (confirm("이 게시글을 수정하시겠습니까?")) {
document.getElementById("title").value = title;
document.getElementById("content").value = content;
postForm.onsubmit = function(event) {
event.preventDefault();
fetch(`/api/posts/${id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
title: document.getElementById("title").value,
content: document.getElementById("content").value
})
})
.then(response => response.json())
.then(data => {
fetchPosts();
postForm.reset();
postForm.onsubmit = postFormSubmitHandler;
alert("게시글이 수정되었습니다.");
})
.catch(error => {
console.error("Error:", error);
alert("게시글 수정 중 오류가 발생했습니다.");
});
}
}
}
window.deletePost = function(id) {
if (confirm("이 게시글을 삭제하시겠습니까?")) {
fetch(`/api/posts/${id}`, {
method: "DELETE"
})
.then(response => {
fetchPosts();
alert("게시글이 삭제되었습니다.");
})
.catch(error => {
console.error("Error:", error);
alert("게시글 삭제 중 오류가 발생했습니다.");
});
}
}
window.searchPosts = function() {
const query = document.getElementById("search").value.toLowerCase();
fetch("/api/posts")
.then(response => response.json())
.then(posts => {
postsDiv.innerHTML = "";
posts.filter(post => post.title.toLowerCase().includes(query) || post.content.toLowerCase().includes(query))
.forEach(post => {
const postDiv = document.createElement("div");
postDiv.classList.add("post");
postDiv.innerHTML = `
<h3>${post.title}</h3>
<p>${post.content}</p>
<button class="edit" onclick="editPost(${post.id}, '${post.title}', '${post.content}')">수정</button>
<button class="delete" onclick="deletePost(${post.id})">삭제</button>
`;
postsDiv.appendChild(postDiv);
});
})
.catch(error => console.error("Error:", error));
}
const postFormSubmitHandler = postForm.onsubmit;
fetchPosts();
});
2. 페이지네이션 기능 추가
게시글이 많아질 경우 페이지네이션을 통해 게시글을 나누어 볼 수 있도록 합니다.
2.1 index.html 수정
페이지네이션을 위한 버튼을 추가합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MyBoard</title>
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<div class="container">
<h1>게시판</h1>
<form id="postForm">
<input type="text" id="title" placeholder="제목" required>
<textarea id="content" placeholder="내용" required></textarea>
<button type="submit">게시글 작성</button>
</form>
<input type="text" id="search" placeholder="검색어를 입력하세요">
<button onclick="searchPosts()">검색</button>
<div id="posts"></div>
<div id="pagination"></div>
</div>
<script src="/js/scripts.js"></script>
</body>
</html>
2.2 scripts.js 수정
페이지네이션 기능을 구현합니다.
document.addEventListener("DOMContentLoaded", function() {
const postForm = document.getElementById("postForm");
const postsDiv = document.getElementById("posts");
const paginationDiv = document.getElementById("pagination");
let currentPage = 1;
const postsPerPage = 5;
postForm.addEventListener("submit", function(event) {
event.preventDefault();
const title = document.getElementById("title").value;
const content = document.getElementById("content").value;
fetch("/api/posts", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ title: title, content: content })
})
.then(response => response.json())
.then(data => {
fetchPosts();
alert("게시글이 작성되었습니다.");
})
.catch(error => {
console.error("Error:", error);
alert("게시글 작성 중 오류가 발생했습니다.");
});
});
function fetchPosts(page = 1) {
fetch("/api/posts")
.then(response => response.json())
.then(posts => {
postsDiv.innerHTML = "";
const start = (page - 1) * postsPerPage;
const end = start + postsPerPage;
posts.slice(start, end).forEach(post => {
const postDiv = document.createElement("div");
postDiv.classList.add("post");
postDiv.innerHTML = `
<h3>${post.title}</h3>
<p>${post.content}</p>
<button class="edit" onclick="editPost(${post.id}, '${post.title}', '${post.content}')">수정</button>
<button class="delete" onclick="deletePost(${post.id})">삭제</button>
`;
postsDiv.appendChild(postDiv);
});
renderPagination(posts.length, page);
})
.catch(error => console.error("Error:", error));
}
function renderPagination(totalPosts, currentPage) {
paginationDiv.innerHTML = "";
const totalPages = Math.ceil(totalPosts / postsPerPage);
for (let i = 1; i <= totalPages; i++) {
const pageButton = document.createElement("button");
pageButton.innerText = i;
pageButton.classList.add(i === currentPage ? "active" : "");
pageButton.onclick = () => fetchPosts(i);
paginationDiv.appendChild(pageButton);
}
}
window.editPost = function(id, title, content) {
if (confirm("이 게시글을 수정하시겠습니까?")) {
document.getElementById("title").value = title;
document.getElementById("content").value = content;
postForm.onsubmit = function(event) {
event.preventDefault();
fetch(`/api/posts/${id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
title: document.getElementById("title").value,
content: document.getElementById("content").value
})
})
.then(response => response.json())
.then(data => {
fetchPosts();
postForm.reset();
postForm.onsubmit = postFormSubmitHandler;
alert("게시글이 수정되었습니다.");
})
.catch(error => {
console.error("Error:", error);
alert("게시글 수정 중 오류가 발생했습니다.");
});
}
}
}
window.deletePost = function(id) {
if (confirm("이 게시글을 삭제하시겠습니까?")) {
fetch(`/api/posts/${id}`, {
method: "DELETE"
})
.then(response => {
fetchPosts();
alert("게시글이 삭제되었습니다.");
})
.catch(error => {
console.error("Error:", error);
alert("게시글 삭제 중 오류가 발생했습니다.");
});
}
}
window.searchPosts = function() {
const query = document.getElementById("search").value.toLowerCase();
fetch("/api/posts")
.then(response => response.json())
.then(posts => {
postsDiv.innerHTML = "";
posts.filter(post => post.title.toLowerCase().includes(query) || post.content.toLowerCase().includes(query))
.forEach(post => {
const postDiv = document.createElement("div");
postDiv.classList.add("post");
postDiv.innerHTML = `
<h3>${post.title}</h3>
<p>${post.content}</p>
<button class="edit" onclick="editPost(${post.id}, '${post.title}', '${post.content}')">수정</button>
<button class="delete" onclick="deletePost(${post.id})">삭제</button>
`;
postsDiv.appendChild(postDiv);
});
renderPagination(posts.length, 1);
})
.catch(error => console.error("Error:", error));
}
const postFormSubmitHandler = postForm.onsubmit;
fetchPosts();
});
3. 마무리
이제 게시판 애플리케이션에 검색 및 페이지네이션 기능을 추가하여 사용자 경험을 향상시켰습니다. 다음 포스트에서는 더 많은 최적화와 추가 기능을 다뤄보겠습니다. 많은 기대 부탁드립니다!
블로그 포스트에 대한 의견이나 질문이 있으시면 댓글로 남겨주세요!
728x90
728x90
LIST