본문 바로가기

Spring

OX퀴즈 프로그램 -3(View, Form) - thymeleaf

구현해야 할 페이지 구성

 

- Form(QuizForm 클래스) 추가

@Data
@AllArgsConstructor
@NoArgsConstructor
public class QuizForm {
    private Integer id;
    
@NotBlank
    private String question;
    private Boolean answer;
   
 @NotBlank
    private String author;
    private Boolean newQuiz;    //등록or변경 판정용
}
 
 
cs

 

필드를 선언하는 형태는 Entity클래스와 비슷하지만 역할은 다름

Entity: DB에 매칭되는 클래스. 테이블에 존재하는 컬럼만을 필드로 가짐.

Form: 클라이언트의 입력폼에 연결되는 클래스.

 

@NotBlank

 

유효성을 검사하는 어노테이션(Validation)

 

Null check 어노테이션 종류

 

 

- crud.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>OX퀴즈 서비스: CRUD</title>
</head>
<body>
<h1>OX 퀴즈 서비스: CRUD</h1>
<h3 th:text="${title}">제목</h3>
<p th:if="${complete}" th:text="${complete}" style="color: blue"></p>
 
<form method="post"
      th:action="${quizForm.newQuiz}? @{/quiz/insert} : @{/quiz/update}"
      th:object="${quizForm}">
    <label>퀴즈 내용:</label><br>
    <textarea rows="5" cols="50" th:field="*{question}"></textarea>
    <br>
    <div th:if="${#fields.hasErrors('question')}" th:errors="*{question}" style="color: red"></div>
    <label>퀴즈 답변: </label><br>
    <input type="radio" value="true" th:field="*{answer}">O
    <input type="radio" value="false" th:field="*{answer}">X
    <br>
    <div th:if="${#fields.hasErrors('answer')}" th:errors="*{answer}" style="color: red"></div>
    <label>작성자: </label><br>
    <input type="text" th:field="*{author}" />
    <br>
    <div th:if="${#fields.hasErrors('author')}" th:errors="*{author}" style="color: red"></div>
    <input th:if="${id}" type="hidden" th:field="*{id}">
    <input type="submit" value="등록">
</form>
<br>
 
<hr>
 
<div th:if="${quizForm.newQuiz}" style="margin: 10px">
    <h3>등록퀴즈목록: <a th:href="@{/quiz/play}">Play</a></h3>
    <br>
    <p th:if="${msg}" th:text="${msg}" style="color: red"></p>
 
    <table border="0" th:unless="${#lists.isEmpty(list)}" style="table-layout: fixed;">
        <tr style="background-color: #6667AB">
            <th>ID</th>
            <th>제목</th>
            <th>해답</th>
            <th>작성자</th>
            <th>편집</th>
            <th>삭제</th>
        </tr>
        <tr th:each="obj : ${list}" align="center">
            <td th:text="${obj.id}"></td>
            <td th:text="${obj.question}" align="left"></td>
            <td th:text="${obj.answer} == true? '○' : 'X'"></td>
            <td th:text="${obj.author}"></td>
            <td>
                <form method="get" th:action="@{/quiz/{id}(id=${obj.id})}">
                    <input type="submit" value="편집">
                </form>
            </td>
            <td>
                <form method="post" th:action="@{/quiz/delete}">
                    <input type="hidden" name="id" th:value="${obj.id}">
                    <input type="submit" value="삭제">
                </form>
            </td>
        </tr>
    </table>
 
    <p th:if="${#lists.isEmpty(list)}">등록된 퀴즈가 없습니다.</p>
</div>
 
<p th:unless="${quizForm.newQuiz}">
    <a th:href="@{/quiz}">CRUD 화면으로</a>
</p>
 
</body>
</html>
 
cs

 

<p th:if="${complete}" th:text="${complete}" style="color: blue"></p>

 

퀴즈내용 추가/수정/삭제시 알림메시지를 표시할 구문

 

th:action="${quizForm.newQuiz}? @{/quiz/insert} : @{/quiz/update}"

 

하나의 입력폼을 새 퀴즈 등록(insert), 기존 퀴즈 수정(update) 두 로직에 모두 쓰기위해

삼항연산자를 사용(newQuiz값이 true면 insert, false면 update)

 

th:field="*{필드명}"

 

th:object에 등록된 클래스(QuizForm)의 필드를 지정하는 문법.

 

th:field="${QuizForm.question}

=>th:field="*{question} 

 

두 식은 같음.

주의) th:object가 지정된 form태그  안에서만 유효함.

 

${#fields.hasErrors('필드명')}" th:errors="*{필드명}

 

해당 필드에 오류가 검출(Validation)되었을때, 오류구문을 출력함.

 

 th:each="obj : ${list}"

 

추후 Controller에서 넘겨받을(Model) list객체에 등록된 모든 퀴즈를 출력하기위해

반복문으로 작성(작성요령은 java의 enhanced for와 같음.)

 

 

 

 

play.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>OX퀴즈 서비스: Play</title>
</head>
<body>
    <h1>OX퀴즈 서비스: Play</h1>
    <h3>퀴즈</h3>
    <th:block th:if="${msg}">
        <p th:text="${msg}" style="color: red"></p>
        <a th:href="@{/quiz/}">메인화면으로 이동</a>
    </th:block>
    <th:block th:unless="${msg}">
        <p th:text="${quizForm.question}">퀴즈내용</p>
        <form th:action="@{/quiz/check}" th:object="${quizForm}" method="post">
            <input type="hidden" th:field="*{id}">
            <button name="answer" value="true">O</button>
            <button name="answer" value="false">X</button>
        </form>
    </th:block>
</body>
</html>
 
cs

 

answer.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>OX퀴즈 서비스: 결과</title>
</head>
<body>
<h1>OX퀴즈 서비스: 결과</h1>
<h2 th:text="${msg}" style="color: red">메세지 표시</h2>
    <a th:href="@{/quiz/play}">계속 풀기</a>
    <a th:href="@{/quiz}">메인화면으로</a>
</body>
</html>
 
cs

 

 

 

crud.html
play.html
answer.html