/list-todos에서 보여지는 화면에서 add todo 버튼을 눌렀을 때, description뿐만 아니라 deadline도 따로 입력하고 싶다.
<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개로 통일시키려고 한다.
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필드를 모두 지웠다.
// 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에 추가한 것!
deadline input type = “text”로 해서, 날짜를 텍스트처럼 입력하고 처리했다. 하지만, 실제로 날짜 팝업이 나와 deadline을 선택하게 바꾸고 싶었다. 이를 위해 Bootstrap Datepicker를 사용할 것이다.
Bootstrap Datepicker는 날짜 관련 팝업을 추가할 수 있게 하는 프레임워크.
<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 뷰 화면에 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을 써야 했다.
성공!
<%@ 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 필드 추가참고
이 시리즈는 Udemy 강의의 내용을 정리한 것입니다.
https://www.udemy.com/course/spring-boot-and-spring-framework-korean/