[Spring Boot] TO-DO List 만들기 - 아이템 삭제하기 편

aylee·2022년 6월 24일
1

SpringBoot-ToDoList

목록 보기
3/4
post-thumbnail

🌱 포스트 순서 🌱

  1. 아이템 삭제하기
    https://wikidocs.net/book/7601 의 내용을 응용하였습니다.

[1] 아이템 삭제하기

각 아이템 마다 삭제 버튼이 달려있고, 그 삭제 버튼을 누르면 해당 아이템이 지워지는 걸 만들고자 한다.

(1) Controller 수정하기

삭제 기능을 만들어서 추가하면 된다.

package com.mysite.todo;

import java.util.List;
import java.util.Map;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@RequiredArgsConstructor
@Controller
public class ToDoController {

    private final ToDoService toDoService;

    @RequestMapping("/todo")
    public String list(Model model){
        List<ToDoEntity> toDoEntityList = this.toDoService.getList();
        model.addAttribute("toDoEntityList",toDoEntityList);
        return "todolist";
    }

    @RequestMapping("/")
    public String root(){
        return "redirect:/todo";
    }

    @PostMapping("/todo/create")
    public String todoCreate(@RequestParam String content){
        this.toDoService.create(content);
        return "redirect:/todo";
    }

// 삭제 기능 
    @DeleteMapping("/todo/delete/{id}")
    public String todoDelete(@PathVariable Integer id){
        this.toDoService.delete(id);
        return "redirect:/todo";
    }
}

지우고자 하는 아이템의 아이디를 매개변수로 활용한다.

(2) Service 수정하기
데이터베이스에서 지우는 역할을 수행할 로직을 만들어준다.

package com.mysite.todo;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.transaction.Transactional;

@RequiredArgsConstructor
@Service
public class ToDoService {
    private final ToDoRepository toDoRepository;

    public List<ToDoEntity> getList(){
        return this.toDoRepository.findAll();
    }

    public void create(String content){
        ToDoEntity toDoEntity = new ToDoEntity();
        toDoEntity.setContent(content);
        toDoEntity.setCompleted(false);
        this.toDoRepository.save(toDoEntity);
    }

    @Transactional
    public void delete(Integer id){
        ToDoEntity toDoEntity = toDoRepository.findById(id)
                .orElseThrow(()->new IllegalArgumentException("해당 아이템이 없습니다. id=" + id));

        this.toDoRepository.delete(toDoEntity);
    }
}

(3) html 수정하기

(i) 각 아이템마다 삭제 버튼 만들어주기

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>To Do List</title>
</head>
<body>
    <h1>투두리스트</h1>
    <form th:action="@{/todo/create}" method="post">
        <input name="content" placeholder="오늘의 할 일을 적어보세요!"/>
        <button>작성</button>
    </form>
    <table>
        <thead>
        <tr>
            <th>번호</th>
            <th>할 일</th>
            <th>수행 여부</th>
            <th>삭제</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="todoentity : ${toDoEntityList}" >
            <td th:text="${todoentity.id}"></td>
            <td th:text="${todoentity.content}"></td>
            <td th:text="${todoentity.completed}"></td>
            <td><button id="delete-btn">삭제</button></td>
        </tr>
        </tbody>
    </table>
</body>
</html>

결과물은 다음과 같다.

(ii) 삭제 버튼에 기능 더하기

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>To Do List</title>
</head>
<body>
    <h1>투두리스트</h1>
    <form th:action="@{/todo/create}" method="post">
        <input name="content" placeholder="오늘의 할 일을 적어보세요!"/>
        <button>작성</button>
    </form>
    <table>
        <thead>
        <tr>
            <th>번호</th>
            <th>할 일</th>
            <th>수행 여부</th>
            <th>삭제</th>
        </tr>
        </thead>
        <tbody>
        <tr th:block th:each="todoentity : ${toDoEntityList}" >
            <td th:text="${todoentity.id}"></td>
            <td th:text="${todoentity.content}"></td>
            <td th:text="${todoentity.completed}"></td>
            <td><button id="delete-btn" th:onclick="deleteItem([[${todoentity.id}]])">삭제</button></td>
        </tr>
        </tbody>
    </table>
</body>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>

function deleteItem(id){
    console.log(id)
    const url = "/todo/delete/"+id
    $.ajax({
        type:'delete',
        url:url,
        contentType:'application/json; charset=utf-8'
        }).done(function() {
        alert('할 일이 삭제되었습니다.');
        window.location.href = '/';
        }).fail(function (error){
        alert(JSON.stringify(error));
        });
       }
</script>
</html>

결과물은 다음과 같다.

OK를 누르면 제대로 삭제된 걸 확인할 수 있다.

+) 끝없는 삽질의 기록

(i) 왜 첫번째 값만 리턴되는 거야?

처음에 작성한 코드는 다음과 같다.

<td th:text="${todoentity.id}" id="id" th:value="${todoentity.id}"></td>

$('delete-btn').on('click', function (e) {
     var id = $('id').attr('value');
     const url = '/todo/delete/'+id
     console.log(id)
     $.ajax({
      method: 'delete',
      url: url,
      contentType:'application/json; charset=utf-8'
  }).done(function() {
      alert('할 일이 삭제되었습니다.');
      window.location.href = '/';
  }).fail(function (error){
      alert(JSON.stringify(error));
  });
});

위처럼 작성했을 때는 값이 1번 값만 리턴되었다.
첫번째 버튼만 작동했으며, 어찌저찌 고쳐서 다른 버튼을 눌러도
첫번째 값만 삭제되는 그런 악몽 같은 결과를 마주했다.

그러다가 알게 된 사실이
var id = $('id').attr('value');

는 단순히 'td#id의 value값에 해당하는 것을 1개 찾는 것이라서
가장 첫번째 값을 가져온다는 점이였다.

그래서 이걸 각자의 id를 넣을 수 있도록 수정한게 (ii) 삭제 버튼에 기능더하기 이다.

각자의 값을 넣어주니 아주 잘 작동한다 👏

profile
미래를 구체화 하는 중

1개의 댓글

comment-user-thumbnail
2022년 12월 8일

항상 잘보고 있습니다! 다름이 아니라 html 부분을 똑같이 해도 함수가 선언이 안되고, [[]] 부분이 오류가 뜨는데 적으신 코드처럼 해도 잘 작동하나요,,?

답글 달기