Todo.java 파일 (dto)
package kr.or.connect.todolist.dto;
public class Todo {
private Integer id;
private String title;
private String name;
private Integer sequence;
private String type;
private String regdate;
private String longRegdate;
public String getLongRegdate() {
return longRegdate;
}
public void setLongRegdate(String longRegdate) {
this.longRegdate = longRegdate;
}
public Todo(Integer id, String title, String name, Integer sequence, String type, String regdate,
String longRegdate) {
super();
this.id = id;
this.title = title;
this.name = name;
this.sequence = sequence;
this.type = type;
this.regdate = regdate;
this.longRegdate = longRegdate;
}
public Todo() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSequence() {
return sequence;
}
public void setSequence(Integer sequence) {
this.sequence = sequence;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getRegdate() {
return regdate;
}
public void setRegdate(String regdate) {
this.regdate = regdate;
}
@Override
public String toString() {
return "Todo [id=" + id + ", title=" + title + ", name=" + name + ", sequence=" + sequence + ", type=" + type
+ ", regdate=" + regdate + ", longRegdate=" + longRegdate + "]";
}
}
TodoDao.java 파일 (dao)
package kr.or.connect.todolist.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import kr.or.connect.todolist.dto.Todo;
public class TodoDao {
private static String dburl = "jdbc:mysql://localhost:3306/connectdb";
private static String dbUser = "connectuser";
private static String dbpasswd = "1234";
public List<Todo> getTodoList() {
List<Todo> list = new ArrayList<>();
try {
Class.forName("cohttp://m.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "select id, title, name, sequence, type, DATE_FORMAT(regdate, '%Y.%m.%d') "
+ "AS regdate, regdate AS longRegdate from todo where type = 'TODO' order by sequence asc, longRegdate desc";
try (Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
PreparedStatement ps = conn.prepareStatement(sql)) {
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
String title = rs.getString(2);
String name = rs.getString(3);
int sequence = rs.getInt("sequence");
String type = rs.getString(5);
String regdate = rs.getString(6);
String longRegdate = rs.getString(7);
Todo todo = new Todo(id, title, name, sequence, type, regdate, longRegdate);
list.add(todo);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return list;
}
public List<Todo> getDoingList() {
List<Todo> list = new ArrayList<>();
try {
Class.forName("cohttp://m.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "select id, title, name, sequence, type, DATE_FORMAT(regdate, '%Y.%m.%d') "
+ "AS regdate, regdate AS longRegdate from todo where type = 'DOING' order by sequence asc, longRegdate desc";
try (Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
PreparedStatement ps = conn.prepareStatement(sql)) {
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
String title = rs.getString(2);
String name = rs.getString(3);
int sequence = rs.getInt("sequence");
String type = rs.getString(5);
String regdate = rs.getString(6);
String longRegdate = rs.getString(7);
Todo todo = new Todo(id, title, name, sequence, type, regdate, longRegdate);
list.add(todo);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return list;
}
public List<Todo> getDoneList() {
List<Todo> list = new ArrayList<>();
try {
Class.forName("cohttp://m.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "select id, title, name, sequence, type, DATE_FORMAT(regdate, '%Y.%m.%d') "
+ "AS regdate, regdate AS longRegdate from todo where type = 'DONE' order by sequence asc, longRegdate desc";
try (Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
PreparedStatement ps = conn.prepareStatement(sql)) {
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
String title = rs.getString(2);
String name = rs.getString(3);
int sequence = rs.getInt("sequence");
String type = rs.getString(5);
String regdate = rs.getString(6);
String longRegdate = rs.getString(7);
Todo todo = new Todo(id, title, name, sequence, type, regdate, longRegdate);
list.add(todo);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return list;
}
public void update_todo(int id) {
try {
Class.forName("cohttp://m.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "UPDATE todo SET type = 'DOING' WHERE id = ?";
try (Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
int rowsUpdated = ps.executeUpdate();
if (rowsUpdated > 0) {
System.out.println("Record updated successfully.");
} else {
System.out.println("No record found for the provided ID.");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void update_doing(int id) {
try {
Class.forName("cohttp://m.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "UPDATE todo SET type = 'DONE' WHERE id = ?";
try (Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
int rowsUpdated = ps.executeUpdate();
if (rowsUpdated > 0) {
System.out.println("Record updated successfully.");
} else {
System.out.println("No record found for the provided ID.");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public int addTodo(Todo todo) {
int insertCount = 0;
try {
Class.forName("cohttp://m.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "insert into todo(title, name, sequence, type) values(?, ?, ?, 'TODO');";
try (Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, todo.getTitle());
ps.setString(2, todo.getName());
ps.setInt(3, todo.getSequence());
insertCount = ps.executeUpdate();
} catch (Exception ex) {
ex.printStackTrace();
}
return insertCount;
}
}
Main.java 파일 (서블릿)
메인 페이지 열기 및 데이터 가져오기
package kr.or.connect.todolist.api;
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.or.connect.todolist.dao.TodoDao;
import kr.or.connect.todolist.dto.Todo;
@WebServlet("/main")
public class Main extends HttpServlet {
private static final long serialVersionUID = 1L;
public Main() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
TodoDao todoDao = new TodoDao();
List<Todo> todolist = todoDao.getTodoList();
List<Todo> doingList = todoDao.getDoingList();
List<Todo> doneList = todoDao.getDoneList();
request.setAttribute("todoList", todolist);
request.setAttribute("doingList", doingList);
request.setAttribute("doneList", doneList);
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/jsp/TodoList.jsp");
requestDispatcher.forward(request, response);
}
}
Todo_to_Doing.java 파일 (서블릿)
TODO 타입을 DOING 타입으로 변경하는 update 기능
package kr.or.connect.todolist.api;
import java.io.BufferedReader;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cohttp://m.google.gson.JsonObject;
import cohttp://m.google.gson.JsonParser;
import kr.or.connect.todolist.dao.TodoDao;
@WebServlet("/todotodoing")
public class Todo_to_Doing extends HttpServlet {
private static final long serialVersionUID = 1L;
public Todo_to_Doing() {
super();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
TodoDao todoDao = new TodoDao();
String taskId = null;
try {
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
JsonObject json = JsonParser.parseString(sb.toString()).getAsJsonObject();
taskId = json.get("taskId").getAsString();
} catch (Exception e) {
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getWriter().write("Error parsing JSON");
return;
}
todoDao.update_todo(Integer.parseInt(taskId));
}
}
DOING_to_DONE.java 파일 (서블릿)
DOING 타입을 DONE 타입으로 변경하는 update 기능
package kr.or.connect.todolist.api;
import java.io.BufferedReader;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cohttp://m.google.gson.JsonObject;
import cohttp://m.google.gson.JsonParser;
import kr.or.connect.todolist.dao.TodoDao;
@WebServlet("/doingtodone")
public class Doing_to_Done extends HttpServlet {
private static final long serialVersionUID = 1L;
public Doing_to_Done() {
super();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
TodoDao todoDao = new TodoDao();
String taskId = null;
try {
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
JsonObject json = JsonParser.parseString(sb.toString()).getAsJsonObject();
if(json.get("taskId") != null) {
taskId = json.get("taskId").getAsString();
}
} catch (Exception e) {
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getWriter().write("Error parsing JSON");
return;
}
todoDao.update_doing(Integer.parseInt(taskId));
}
}
AddPage.java 파일 (서블릿)
TODO를 추가하는 페이지 열기
package kr.or.connect.todolist.api;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/add")
public class AddPage extends HttpServlet {
private static final long serialVersionUID = 1L;
public AddPage() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/jsp/addTodoList.jsp");
requestDispatcher.forward(request, response);
}
}
AddAction.java (서블릿)
TODO를 추가하는 기능
package kr.or.connect.todolist.api;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.or.connect.todolist.dao.TodoDao;
import kr.or.connect.todolist.dto.Todo;
@WebServlet("/addtodo")
public class AddAction extends HttpServlet {
private static final long serialVersionUID = 1L;
public AddAction() {
super();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
TodoDao todoDao = new TodoDao();
Todo todo = new Todo();
String task = request.getParameter("task");
String assignee = request.getParameter("assignee");
String priority = request.getParameter("priority");
System.out.println("Task: " + task);
System.out.println("Assignee: " + assignee);
System.out.println("Priority: " + priority);
todo.setTitle(task);
todo.setName(assignee);
todo.setSequence(Integer.parseInt(priority));
todoDao.addTodo(todo);
response.sendRedirect(request.getContextPath() + "/main");
}
}
TodoList.jsp
메인 페이지 jsp 파일
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<meta charset="UTF-8">
<title>TodoList</title>
<link rel="stylesheet" href="../todolist/css/TodoList.css?after" />
<script src="../todolist/js/TodoList.js"></script>
</head>
<body>
<header class="header">
<div class="addButtons">
<Button id="addButton" onclick="window.location.href = 'add';">새로운 TODO 등록</Button>
</div>
</header>
<div class="diagonal-text">
나의 해야할 일들
</div>
<div class="container">
<div class="column">
<h2 class="colTitle">TODO</h2>
<div class="taskList">
<ul id="todoTask">
<c:forEach var="todo" items="${requestScope.todoList}">
<li data-sequence="${todo.sequence}" data-regdate="${todo.longRegdate}">
<h3 class="taskTitle">${todo.title}</h3>
<p class="taskDesc">등록날짜: ${todo.regdate}, ${todo.name}, 우선순위 ${todo.sequence}</p>
<button class="todo_taskButton" data-id="${todo.id}">-></button>
</li>
</c:forEach>
</ul>
</div>
</div>
<div class="column">
<h2 class="colTitle">DOING</h2>
<div class="taskList">
<ul id="doingTask">
<c:forEach var="doing" items="${requestScope.doingList}">
<li data-sequence="${doing.sequence}" data-regdate="${doing.longRegdate}">
<h3 class="taskTitle">${doing.title}</h3>
<p class="taskDesc">등록날짜: ${doing.regdate}, ${doing.name}, 우선순위
${doing.sequence}</p>
<button class="doing_taskButton" data-id="${doing.id}">-></button>
</li>
</c:forEach>
</ul>
</div>
</div>
<div class="column">
<h2 class="colTitle">DONE</h2>
<div class="taskList">
<ul id="doneTask">
<c:forEach var="done" items="${requestScope.doneList}">
<li data-sequence="${done.sequence}" data-regdate="${done.longRegdate}">
<h3 class="taskTitle">${done.title}</h3>
<p class="taskDesc">등록날짜: ${done.regdate}, ${done.name}, 우선순위
${done.sequence}</p>
</li>
</c:forEach>
</ul>
</div>
</div>
</div>
</body>
</html>
addTodoList.jsp 파일
Todo 추가하는 페이지 jsp 파일
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="../todolist/css/addTodoList.css?after" />
<script src="../todolist/js/addTodoList.js"></script>
</head>
<body>
<header class="header">
<h1 class="addTitle">할일 등록</h1>
</header>
<div class="main">
<div class="addForm">
<form action="/todolist/addtodo" method="post">
<label for="task">
어떤 일인가요?
</label>
<input type="text" id="task" name="task" maxlength="24" placeholder="예: Swift 공부하기(24자까지)" required>
<label for="assignee" id="assigneeLabel">
누가 할 일인가요?
</label>
<input type="text" id="assignee" name="assignee" placeholder="예: 홍길동" required>
<label id="radios">우선순위</label>
<div id="radioDiv">
<label>
<input type="radio" name="priority" value="1" required>
1순위
</label>
<label><input type="radio" name="priority" value="2">
2순위
</label>
<label><input type="radio" name="priority" value="3">
3순위
</label>
</div>
<div id="buttonGroup">
<button id="backButton" type="button" onclick="window.location.href = 'main';">< 이전 </button>
<button id="addButton" type="submit">제출</button>
<button id="delButton" type="button">내용지우기</button>
</div>
</form>
</div>
</div>
</body>
</html>
TodoList.css 파일
메인페이지 css
.header {
position: relative;
background-color: white;
height: 100px;
padding: 10px 0;
}
body {
margin: 0 auto;
width: 60%;
}
.addButtons {
position: absolute;
top: 5px;
right: 0;
margin-top: 20px;
margin-right: 10px;
}
#addButton{
width: 160px;
height: 40px;
background-color: #20adee;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
transition: box-shadow 0.3s ease;
}
#addButton:hover {
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.1);
}
.container {
display: flex;
}
.column {
flex: 1;
height: 60px;
padding-left: 20px;
border: 1px solid #ccc;
margin-right: 10px;
background-color: #345461;
}
.colTitle {
margin-top:12px;
margin-bottom: 40px;
color: white;
}
ul {
list-style: none;
margin: 0;
padding: 0;
flex: 1;
}
li {
background-color: #cee5ef;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
width: 100%;
height: 80px;
margin-left: -20px;
position: relative;
}
.taskTitle {
margin-left: 10px;
margin-top: 10px;
font-weight: bold;
}
.taskDesc {
margin-left: 10px;
margin-top: -10px;
}
.todo_taskButton {
position: absolute;
bottom: 20px;
right: 10px;
width:35px;
height:25px;
font-weight: 900;
}
.doing_taskButton {
position: absolute;
bottom: 20px;
right: 10px;
width:35px;
height:25px;
font-weight: 900;
}
.diagonal-text {
position: absolute;
top: 100;
left: 300px;
transform-origin: bottom left;
transform: rotate(-35deg);
color: #345461;
padding: 10px;
font-weight: 900;
font-size: 30px;
}
addTodoList.css
추가 페이지 css 파일
.addTitle {
display: flex;
justify-content: center;
}
body {
margin: 0 auto;
width: 60%;
background-color: #ecf1f0;
}
.header {
background-color: white;
position: fixed;
top: 0;
justify-content: center;
width: 60%;
z-index: 999;
height: 100px;
top: 0;
justify-content: center;
width: 60%;
z-index: 999;
}
.main {
background-color: white;
height: 500px;
}
.addForm {
margin-top: 100px;
margin-left: -100px;
}
form {
max-width: 400px;
margin: 50px auto 0;
}
label {
display: block;
margin-top: 7px;
}
input[type="text"], input[type="radio"] {
margin-top: 5px;
}
#addButton {
margin-left: 150px;
border: none;
color: white;
background-color: #22aded;
font-size: 16px;
}
#delButton {
margin-left: 30px;
border: none;
color: white;
background-color: #22aded;
font-size: 16px;
}
#backButton {
background-color: white;
border: 1px solid #ccc;
font-size: 20px;
text-decoration: underline;
font-weight: bold;
}
#task {
width: 500px;
height: 40px;
font-size: 20px;
padding-left: 5px;
}
#assignee {
width: 270px;
height: 40px;
font-size: 20px;
padding-left: 5px;
}
#assigneeLabel {
margin-top: 30px;
}
#radios {
margin-top: 30px;
}
#radioDiv {
display: flex;
}
#buttonGroup {
margin-top: 50px;
display: flex;
width: 511px;
}
Button {
height: 50px;
width: 150px;
}
TodoList.js 파일
TODO와 DOING 타입의 버튼 클릭시 옆 ul로 이동하는 기능
+ ul 이동시 해당 ul 우선순위 순으로 오름차순, 날짜 순으로 내림차순 하는 기능 추가
새로고침 없이 구현하기 위해 DB에 저장되는것과 별개로 동작
document.addEventListener("DOMContentLoaded", function() {
document.addEventListener("click", function(event) {
var clickedElement = event.target;
if (!clickedElement.classList.contains('todo_taskButton') && !clickedElement.classList.contains('doing_taskButton')) {
return;
}
var clickedUl = clickedElement.closest('ul');
if (!clickedUl)
return;
if (clickedElement.classList.contains('todo_taskButton') && clickedUl.id === "todoTask") {
var taskItem = clickedElement.parentNode;
var taskId = clickedElement.dataset.id;
var doingList = document.getElementById("doingTask");
doingList.appendChild(taskItem);
fetch('todotodoing', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
taskId: taskId
})
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
sortTodoList(1);
clickedElement.classList.remove('todo_taskButton');
clickedElement.classList.add('doing_taskButton');
} else if (clickedElement.classList.contains('doing_taskButton') && clickedUl.id === "doingTask") {
var taskItem = clickedElement.parentNode;
var taskId = clickedElement.dataset.id;
var doneList = document.getElementById("doneTask");
doneList.appendChild(taskItem);
fetch('doingtodone', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
taskId: taskId
})
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
sortTodoList(2);
clickedElement.remove();
}
});
});
function sortTodoList(check) {
var ul = null;
if(check == 1){
ul = document.getElementById("doingTask");
}
else {
ul = document.getElementById("doneTask");
}
var items = Array.from(ul.getElementsByTagName("li"));
items.sort(function(a, b) {
var sequenceA = parseInt(a.dataset.sequence);
var sequenceB = parseInt(b.dataset.sequence);
var regdateA = new Date(a.dataset.regdate);
var regdateB = new Date(b.dataset.regdate);
if (sequenceA !== sequenceB) {
return sequenceA - sequenceB;
} else {
return regdateB - regdateA;
}
});
items.forEach(function(item) {
ul.appendChild(item);
});
}
addTodoList.js 파일
TODO 작성 form 리셋 버튼 기능
document.addEventListener("DOMContentLoaded", function() {
var delButton = document.getElementById("delButton");
if (delButton) {
delButton.addEventListener("click", function() {
var form = document.querySelector(".addForm form");
if (form) {
form.reset();
} else {
console.error("Form element not found");
}
});
} else {
console.error("delButton element not found");
}
});
'개인 프로젝트' 카테고리의 다른 글
메이플 보스 결정석 계산기 (0) | 2024.05.18 |
---|---|
부스트코스 - 네이버 예약 (0) | 2024.03.13 |
부스트코스 - 나를 소개하는 홈페이지 만들기 (1) | 2024.02.27 |