스프링

[Spring, Thymeleaf] Form 심화

gilssang97 2021. 9. 23. 10:22

Form 심화

우리는 Form 기본에 추가적으로 다양한 정보를 확인해보고자 한다.

  • 싱글 체크박스
  • 멀티 체크박스
  • 라디오 박스
  • 셀렉트 박스

우리는 이 4가지들을 간단한 예시를 통해 알아보려고 한다.

노트북 소유 유무, 사용 주 언어, 개발 환경, 이메일을 입력받으려고 한다.

노트북 소유 유무는 싱글 체크박스, 사용 주 언어는 멀티 체크 박스, 개발 환경은 라디오 박스, 이메일은 인풋박스와 셀렉트박스를 사용하여 구성하려고 한다.

구현

싱글 체크박스

private Boolean notebook;
  • Person객체에 노트북 소유 여부를 저장할 변수이다.
<label>
        <p class="label-txt"><b>노트북 소유 여부를 입력하세요.</b></p>
    </label>
    <label class="check">
        <input type="checkbox" class="input" th:field="*{notebook}">
        <label class="check" th:for="notebook">노트북 소유 여부</label>
    </label>
  • th:field를 활용하여 Person객체의 notebook 변수의 값을 싱글 체크박스로 저장한다.

멀티 체크박스

private List<String> lang;
  • Person객체에 주 언어를 저장할 리스트를 선언한다.
Map<String, String> lang = languageMap();
model.addAttribute("lang", lang);
private Map<String, String> languageMap() {
    Map<String, String> lang = new HashMap<>();
    lang.put("python", "파이썬");
    lang.put("java", "자바");
    lang.put("c++", "C++");

    return lang;
}    
  • 사용자가 선택할 수 있는 맵(저장될 문자열, 화면에 출력될 문자열)을 만들어 model에 저장하여 사용할 수 있도록 한다.
<label>
    <p class="label-txt"><b>주 언어를 입력하세요.</b></p>
</label>
<label th:each="lan : ${lang}" class="check">
    <input type="checkbox" class="input" th:field="*{lang}" th:value="${lan.key}">
    <label class="check" th:for="${#ids.prev('lang')}" th:text="${lan.value}"></label>
</label>
  • model에 담은 lang을 for문으로 돌려 체크박스와 해당 체크박스를 설명할 라벨을 만든다.
  • id, name을 person객체의 lang을 통해 자동 생성해주고 th:value(실제로 lang에 저장될 값)을 lan의 key값으로 설정해준다.
  • 체크박스를 설명할 라벨의 경우 th:field="*{lang}"에서 자동 생성해주는 id, name을 맞춰주기 위해 ${#ids.prev('lang')}을 사용한다.
  • 체크박스를 설명할 라벨의 텍스트는 lan의 value값으로 설정한다.

라디오 박스

private Environment envs;
  • Person객체에 개발환경을 저장할 Environment클래스를 선언한다.
public enum Environment {
   Windows("윈도우"), MAC("맥");

   private final String desc;

    Environment(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }
}
  • 구성환경을 선택하기 위해 Environment라는 enum 클래스를 생성하였다.
  • 해당 enum 클래스에는 Windows, MAC이 존재하고 이에 대한 설명을 desc로 하여 추가하였다.
Person person = new Person();
person.setEnvs(Environment.Windows);
model.addAttribute("person", person);

model.addAttribute("envs", Environment.values());
  • 라디오 박스는 체크를 하지 않아도 null 값으로 오게되어 추후 처리에 문제가 생길 수도 있다.
  • 라디오 박스가 한번 체크되면 무조건 골라야하는 특성을 활용해 default로 Windows로 설정해놓아 null 값으로 오지 않게 설정한다.
  • 화면에 선택지를 뿌려주기 위해 값들을 모델에 전달한다.
<label>
    <p class="label-txt"><b>개발 환경을 선택하세요.</b></p>
</label>
<label th:each="env : ${envs}" class="check">
    <input type="radio" class="input" th:field="*{envs}" th:value="${env.name()}">
    <label class="check" th:for="${#ids.prev('envs')}" th:text="${env.getDesc()}"></label>
</label>
  • 라디오 박스도 멀티 체크 박스와 마찬가지로 Environment의 요소들을 활용해 for문으로 라디오박스와 해당 라디오 박스를 설명할 라벨을 만든다.
  • 이용 방법 자체는 멀티 체크 박스와 동일하다.

셀렉트 박스

private String emailId;
private String platform;
  • Person객체에 이메일 ID를 저장하기 위한 문자열과 메일서비스플랫폼을 저장하기 위한 문자열을 선언한다.
List<String> platforms = platformList();
model.addAttribute("platforms", platforms);
private List<String> platformList() {
    List<String> platform = new ArrayList<>();
    platform.add("naver.com");
    platform.add("gmail.com");
       platform.add("daum.net");

    return platform;
}
  • 사용자가 선택할 수 있는 리스트(플랫폼 종류)를 만들어 model에 저장하여 사용할 수 있도록 한다.
<label>
    <p class="label-txt"><b>이메일을 입력하세요.</b></p>
</label>
<label class="check">
    <input type="text" class="input select" th:field="*{emailId}">
    <span>@</span>
    <select th:field="*{platform}">
        <option value="">주소를 선택하세요.</option>
        <option th:each="plat : ${platforms}" th:text="${plat}" th:value="${plat}"></option>
    </select>
</label>
  • 먼저, 이메일 ID를 받기위한 인풋 박스를 하나 깔아둔다.
  • 이메일 구분을 위한 @을 span을 통해 화면에 뿌려준다.
  • 셀렉트 박스는 이전에 멀티 체크박스, 라디오박스에서 했던 것과 비슷하게 th:fieldperson.platform을 id, name 값이 설정되게 한다.
  • 그리고 첫 번째 옵션은 default로 설정하라는 문구의 옵션을 깔아두고 그 뒤에 for문을 돌리면서 미리 설정해놓은 플랫폼을 화면에 뿌려준다.

출력

<label>
    <p class="label-txt" th:text="'이름은 ' + ${person.name} + '입니다.'"></p>
    <p class="label-txt" th:text="|나이는 ${person.age}입니다.|"></p>
    <p class="label-txt" th:utext="|학과는 <b>${person.department}</b>입니다.|"></p>
    <p class="label-txt" th:utext="|전공은 <b>${person.major}</b>입니다.|"></p>
    <p class="label-txt" th:text="${person.notebook} ? '노트북을 소유중입니다.' : '노트북이 없습니다'"></p>
    <div th:each="lan : ${person.lang}">
        <p class="label-txt" th:text="|주 언어는 ${lan}입니다.|"></p>
    </div>
    <p class="label-txt" th:text="|개발환경은 ${person.envs.desc}입니다.|"></p>
    <p class="label-txt" th:text="|이메일은 ${person.emailId}@${person.platform}입니다.|"></p>
</label>

결과

입력


요약