https://magicmk.tistory.com/32
전 편에 thymeleaf의 layout을 적용한 뒤 회원 정보를 컨트롤하는 로직을 구현하다가 머리가 지끈 거려서
화면을 이쁘게 만들어 보고자 이번에는 BootStrap을 적용해 보았다.
✅ BootStrap 적용
우선 해당 사이트에 들어가면 css, js를 다운로드 받을 수 있지만 간단하게 CDN으로 적용하였다.
⏹️ head.html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headFragment">
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 추가 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
</html>
지난 시간에 구성했던 head layout에 css를 추가했다.
⏹️ default.html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
th:with="lang=${#locale.language}" th:lang="${lang}">
<head>
<th:block th:insert="layout/fragments/head :: headFragment"></th:block>
</head>
<body>
<header th:replace="layout/fragments/header :: headerFragment"></header>
<div layout:fragment="content"></div>
<footer th:replace="layout/fragments/footer :: footerFragment"></footer>
<!-- 추가 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
마찬가지로 default layout에도 script를 추가했다.
대부분 아시겠지만 css는 head영역에 script는 body 영역에 넣어야 렌더링에 방해가 되지 않는다.
이렇게만 해주면 Bootstrap 적용이 완료됐다. 이제 Doc를 찾아보거나 여러 example들을 확인하며
클래스를 정의해주면 된다.
✅ BootStrap 실습
⏹️ memberForm.html
이전 시간에 적용했던 유효성 검사 등을 함께 적용했다. (thymeleaf 만세)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/default}">
<head>
<title>회원가입</title>
</head>
<body>
<div layout:fragment="content" class="container">
<form method="post" th:if="${dto == null}">
<div class="form-group">
<label class="form-label mt-4">회원가입</label>
<div class="form-floating mb-3">
<input type="email" name="email" class="form-control" id="floatingInput" placeholder="name@example.com">
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating mb-3">
<input type="text" name="username" class="form-control" id="floatingUsername" placeholder="홍길동">
<label for="floatingInput">User name</label>
</div>
<div class="form-floating mb-4">
<input type="password" name="password" class="form-control" id="floatingPassword" placeholder="Password">
<label for="floatingPassword">Password</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<form method="post" th:unless="${dto == null}">
<div class="form-group">
<label class="form-label mt-4">회원가입</label>
<th:block th:if="${valid_email == null}">
<div class="form-floating mb-3">
<input type="email" name="email" class="form-control" id="floatingInput" placeholder="name@example.com">
<label for="floatingInput">Email address</label>
</div>
</th:block>
<th:block th:unless="${valid_email} == null">
<div class="form-floating mb-3 has-danger">
<input type="email" name="email" class="form-control is-invalid" id="floatingInput" placeholder="name@example.com">
<label for="floatingInput">Email address</label>
<div class="invalid-feedback" th:text="${valid_email}"></div>
</div>
</th:block>
<th:block th:if="${valid_username == null}">
<div class="form-floating mb-3">
<input type="text" name="username" class="form-control" id="floatingUsername" placeholder="홍길동">
<label for="floatingInput">User name</label>
</div>
</th:block>
<th:block th:unless="${valid_username == null}">
<div class="form-floating mb-3 has-danger">
<input type="text" name="username" class="form-control is-invalid" id="floatingUsername" placeholder="홍길동">
<label for="floatingInput">User name</label>
<div class="invalid-feedback" th:text="${valid_username}"></div>
</div>
</th:block>
<div class="form-floating mb-4">
<input type="password" name="password" class="form-control" id="floatingPassword" placeholder="Password">
<label for="floatingPassword">Password</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</body>
</html>
같은 페이지지만 error 메세지를 받았을 때와 받지 않았을 경우를 나눴는데 이것보다 간결하게
만들 수 있을지는 모르겠다...
⏹️ memberForm.html 테스트
회원가입 기본 모습이다 생각보다 예쁜 것 같다.
존재하는 이메일을 넣고 회원가입을 진행해 보겠다.
중복 이메일을 넣고 회원가입 시 저렇게 빨간 테두리에 에러 메세지까지 제대로 출력된다.
이번에는 username의 유효성 검사를 테스트 해봤다.
멋지게 잘 완성된 것 같다.
⏹️ loginForm.html
회원가입 form을 완성했으니 비슷한 login form은 빠르게 넘어간다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/default}">
<head>
<title>로그인</title>
</head>
<body>
<div class="container" layout:fragment="content">
<form th:action="@{/login}" method="post">
<div class="form-group">
<label class="form-label mt-4">로그인</label>
<th:block th:if="${param.error == null}">
<div class="form-floating mb-3">
<input type="email" name="email" class="form-control" id="floatingInput" placeholder="name@example.com">
<label for="floatingInput">Email address</label>
</div>
</th:block>
<th:block th:if="${param.error}">
<div class="form-floating mb-3 has-danger">
<input type="email" name="email" class="form-control is-invalid" id="floatingInput" placeholder="name@example.com">
<label for="floatingInput">Email address</label>
<div class="invalid-feedback">이메일 혹은 비밀번호가 잘못 되었습니다.</div>
</div>
</th:block>
<div class="form-floating mb-4">
<input type="password" name="password" class="form-control" id="floatingPassword" placeholder="Password">
<label for="floatingPassword">Password</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Log in</button>
</form>
</div>
</body>
</html>
⏹️ loginForm.html 테스트
존재하지 않는 이메일을 입력하거나 비밀번호가 틀렸을 경우 위와 같은 메세지를 출력해준다.
✅ 끝
앞으로 남은 페이지들은 위와 같은 방식으로 thymeleaf와 bootstrap을 이용하여 화면을
멋지게 구성할 수 있을 것 같다. 덕분에 머리도 잘 식혔고 회원 정보 관련 로직도
금방 마무리할 수 있을 것 같다.
https://github.com/Kimmingki/board
'Java > Spring Boot 게시판' 카테고리의 다른 글
spring boot 게시판 - 8 <게시물 작성, 조회> (0) | 2022.11.30 |
---|---|
spring boot 게시판 - 7 <회원 정보 수정 및 탈퇴> (2) | 2022.11.24 |
spring boot 게시판 - 5 <thymeleaf layout 적용> (0) | 2022.11.21 |
spring boot 게시판 - 4 <spring security form login 구현> (0) | 2022.11.18 |
spring boot 게시판 - 3 <패스워드 암호화, 회원 목록 조회> (0) | 2022.11.11 |