[Spring] Todo 페이지에 deadline 추가하기 (+BootStrap Datepicker 사용)

민지·2024년 2월 22일
0
post-custom-banner

/list-todos에서 보여지는 화면에서 add todo 버튼을 눌렀을 때, description뿐만 아니라 deadline도 따로 입력하고 싶다.

1. addTodo.jsp 코드 리팩토링 - <form:label>, deadline field 추가

<form:label>은 Spring framework에서 HTML 요소를 생성하는데 사용된다. 이 요소는 웹 어플리케이션의 폼을 만들 때 사용된다. (HTML 정리 노션 참고)

또한 form 태그 안의 다양한 입력요소를 그룹화할 수 있는 태그에는 fieldset 태그를 추가해, 가독성을 좋게 만들어준다. 이때, fieldset의 class="md-3"을 추가해, addTodo.jsp 화면의 description 입력필드와 submit 버튼 사이의 여백을 준다. (부트스트랩 클래스다. 참고 링크 )

이러한 수정사항을 반영한 addTodo.jsp의 body 부분은 아래와 같다.

  '<body>
    <div class = "container">
      <h1>Enter Todo Details</h1>
      <form:form method = "post" modelAttribute="todo">
        <fieldset class = "mb-3">
          <form:label path = "description">Description : </form:label>
          <form:input type = "text" path="description" required = "required" /> 
          <form:errors path = "description" cssClass = "text-warning"/> <br>
        </fieldset>

        <fieldset class = "mb-3">
          <form:label path = "deadline">Deadline : </form:label>
          <form:input type = "text" path="deadline" required = "required" /> 
          <form:errors path = "deadline" cssClass = "text-warning"/> <br>
        </fieldset>

        <form:input type = "hidden" path="id"/> <br>
        <form:input type = "hidden" path="done"/> <br>
        <input type = "submit" class = "btn btn-success"/>
      </form:form>
      <script src="webjars/bootstrap/5.1.3/js/bootstrap.min.js"></script>
      <script src="webjars/jquery/3.6.0/jquery.min.js"></script>
    </div>
  </body>

"/add-todo 실행결과 화면"

이 Deadline 날짜 형식은 /list-todos의 날짜 형식과 다르기에, 어플리케이션의 deadline 형식을 1개로 통일시키려고 한다.

2. application.properties - 어플리케이션 표준 날짜 형식 통일시키기

spring.mvc.format.date = yyyy-MM-dd

spring.mvc.format.date에서 소문자 m은 분, 대문자 M은 month이다.

실행결과, list-todos, add-todo, update-todo의 모든 날짜 형식이 yyyy-MM-dd로 바뀌었다!

추가적으로, update 실행했더니 id값이 순서대로 되어있지 않고 뒤죽박죽이라, listTodos.jsp의 table 필드에 존재하던 id필드를 모두 지웠다.

3. TodoController - addNewTodoPage()에서 deadline 하드코딩 수정

수정 전 코드

// add-todo - POST
	@RequestMapping(value = "/add-todo", method = RequestMethod.POST)
	public String addNewTodoPage(ModelMap model, @Valid Todo todo, BindingResult result) {

		if (result.hasErrors()) {
			return "addTodo";
		}
		String username = (String) model.get("name");
		todoService.AddTodo(username, todo.getDescription(), LocalDate.now().plusYears(1), false);
		return "redirect:list-todos";
	}

하드코딩되어있는 deadline ; LocalDate.now().plusYears(1)

수정 후 코드

// add-todo - POST
	@RequestMapping(value = "/add-todo", method = RequestMethod.POST)
	public String addNewTodoPage(ModelMap model, @Valid Todo todo, BindingResult result) {

		if (result.hasErrors()) {
			return "addTodo";
		}
		String username = (String) model.get("name");
		todoService.AddTodo(username, todo.getDescription(), todo.getDeadline(), false);
		return "redirect:list-todos";
	}

양방향 바인딩 다시 recap

(내 포스팅 부분 발췌 - Spring-todo 시리즈 14번째 글);

첫번째 방향은 내가 작성한 자바코드의 Bean -> form 양식으로의 바인딩 이다. 다시 말해, showNewTodoPage()메서드에서 작성한 todo 객체는 디폴트로 ""으로 초기화되기에, addTodo.jsp에서도 공백으로 표시되는 것으로 생각할 수 있다.

반대로, 두 번째 방향은 내가 form 양식에서 입력한 값이 -> 내가 작성한 자바코드의 Bean으로의 바인딩이다. 다시 말해, addTodo.jsp에서 입력한 description값이 -> addNewTodoPage()메서드의 Todo 객체로의 바인딩됨을 뜻한다. 참고로, path 속성을 통해 바인딩될 자바 객체의 위치를 찾을 수 있다.

즉, 특정 빈에 바인딩되어 있던 목표 날짜를 AddTodo메서드를 통해 todo list에 추가한 것!

4. deadline input="text" 수정 - BootStrap DatePicker

deadline input type = “text”로 해서, 날짜를 텍스트처럼 입력하고 처리했다. 하지만, 실제로 날짜 팝업이 나와 deadline을 선택하게 바꾸고 싶었다. 이를 위해 Bootstrap Datepicker를 사용할 것이다.

Bootstrap Datepicker는 날짜 관련 팝업을 추가할 수 있게 하는 프레임워크.

pom.xml - Bootstrap Datapicker 추가

<dependency>
  <groupId>org.webjars</groupId>
  <artifactId>bootstrap-datepicker</artifactId>
  <version>1.9.0</version>
</dependency>

어플리케이션 재실행하면, Maven Dependencies 하위에 bootstrap-datepicker-1.9.0.jar 발견!

addTodo.jsp → js, css 선언문 추가

addTodo.jsp 뷰 화면에 Bootstrap-datepicker를 사용하기 위해 해당 파일 위치를 복사해 넣어두기


// js -> 하단의 body태그 윗부분
<script src="webjars/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script> 

// css -> head태그 상단에
<link href = "webjars/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.standalone.min.css" rel = "stylesheet">

이제 bootstrap-datapicker를 이용해, deadline 필드와 연결지어, 사용자가 deadline 필드를 선택하면 날짜 팝업창이 뜨게끔 해줘야 한다.

구글 - bootstrap datapicker - 참고 링크

<script type = "text/javascript">
			$('#deadline').datepicker({
			    format: 'yyyy-mm-dd'
			});
</script>

format은 앞에서 설정한 spring.mvc.format.date와 동일한 형식으로 하려 함. 하지만 datapicker에서는 소문자 mm을 써야 했다.

성공!

마치며.. - 최종 수정코드

addTodo.jsp 최종코드
 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<link href = "webjars/bootstrap/5.1.3/css/bootstrap.min.css" rel = "stylesheet">
		<link href = "webjars/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.standalone.min.css" rel = "stylesheet">
		<title>Add Todo Page</title>
	</head>
	<body>
		<div class = "container">
			<h1>Enter Todo Details</h1>
			<form:form method = "post" modelAttribute="todo">
				<fieldset class = "mb-3">
					<form:label path = "description">Description : </form:label>
					<form:input type = "text" path="description" required = "required" /> 
					<form:errors path = "description" cssClass = "text-warning"/> <br>
				</fieldset>
				
				<fieldset class = "mb-3">
					<form:label path = "deadline">Deadline : </form:label>
					<form:input type = "text" path="deadline" required = "required" /> 
					<form:errors path = "deadline" cssClass = "text-warning"/> <br>
				</fieldset>
				
				<form:input type = "hidden" path="id"/> <br>
				<form:input type = "hidden" path="done"/> <br>
				<input type = "submit" class = "btn btn-success"/>
			</form:form>
			<script src="webjars/bootstrap/5.1.3/js/bootstrap.min.js"></script>
			<script src="webjars/jquery/3.6.0/jquery.min.js"></script>
			<script src="webjars/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
			<script type = "text/javascript">
			$('#deadline').datepicker({
			    format: 'yyyy-mm-dd'
			});
			</script>
		</div>
	</body>
</html>
  • <form:label>, <fieldset>, deadline 필드 추가
  • bootstrap-datepicker - js, css 추가


참고
이 시리즈는 Udemy 강의의 내용을 정리한 것입니다.
https://www.udemy.com/course/spring-boot-and-spring-framework-korean/

profile
배운 내용을 바로바로 기록하자!
post-custom-banner

0개의 댓글