스프링과 JPA 기반 웹 애플리케이션 개발 #40 관심 주제 등록 뷰

Jake Seo·2021년 6월 8일
0

스프링과 JPA 기반 웹 애플리케이션 개발 #40 관심 주제 등록 뷰

해당 내용은 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발의 강의 내용을 바탕으로 작성된 내용입니다.

강의를 학습하며 요약한 내용을 출처를 표기하고 블로깅 또는 문서로 공개하는 것을 허용합니다 라는 원칙 하에 요약 내용을 공개합니다. 출처는 위에 언급되어있듯, 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발입니다.

제가 학습한 소스코드는 https://github.com/n00nietzsche/jakestudy_webapp 에 지속적으로 업로드 됩니다. 매 커밋 메세지에 강의의 어디 부분까지 진행됐는지 기록해놓겠습니다.


관심 주제 등록 뷰

application.properties

# 개발할 때만 create-drop 혹은 update를 사용하고, 운영 환경에서는 validate를 사용한다.
spring.jpa.hibernate.ddl-auto=create-drop

# 개발 시 SQL 로깅을 해서 어떤 값으로 어떤 SQL이 실행되는지 확인한다.
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

프론트엔드 라이브러리

타임리프 자바스크립트 템플릿

<script type="application/javascript" th:inline="javascript">
</script>

Ajax 호출 시 CSRF 넣는 방법

  • 다음 시간에

SettingsController 내용 추가

    @GetMapping(TAGS_MAPPING_PATH)
    public String updateTagForm(@LoginAccount Account loginAccount, Model model) {
        model.addAttribute(loginAccount);
        return TAGS_MAPPING_PATH;
    }

    @PostMapping(TAGS_MAPPING_PATH)
    public String updateTag() {
        return TAGS_MAPPING_PATH;
    }

@GetMapping, @PostMapping 패스에 대한 메소드만 먼저 만들어두었다.

프론트엔드 라이브러리 추가

  "dependencies": {
    "@yaireo/tagify": "^4.2.0",
    "bootstrap": "^4.6.0",
    "cropper": "^4.1.0",
    "font-awesome": "^4.7.0",

settings/tags.html 추가

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
    <title>관심 태그 수정</title>
    <th:block th:replace="fragments :: headLibraryInjection"></th:block>
</head>

<body class="bg-light">

<th:block th:replace="fragments :: main-nav"></th:block>
<div th:replace="fragments :: email-verify-alarm"></div>

<div class="container">
    <!-- row의 기본은 col-12만큼의 크기를 갖는다.-->
    <div class="row mt-5 justify-content-center">
        <div class="col-2">
            <div th:replace="fragments :: settings-menu(currentMenu='tags')"></div>
        </div>
        <div class="col-8">
            <div th:if="${message}" class="alert alert-info alert-dismissible fade show mt-3" role="alert">
                <span th:text="${message}">메시지</span>
                <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                    <span aria-hidden="true">x</span>
                </button>
            </div>
            <div class="row">
                <h2 class="col-12">관심있는 스터디 주제</h2>
            </div>
            <div class="row">
                <div class="col-12">
                    <div class="alert alert-info" role="alert">
                        참여하고 싶은 스터디 주제를 입력해주세요. 해당 주제의 스터디가 생기면 알림을 받을 수 있습니다. 태그를 입력하고 콤마(,)
                        또는 엔터를 입력하세요.
                    </div>
                    <input id="tags" type="text" name="tags" th:value="${#strings.listJoin(tags, ',')}"
                           class="tagify-outside" aria-describedby="tagHelp">
                </div>
            </div>
        </div>
    </div>
    <th:block th:replace="fragments :: footer"></th:block>
</div>

<script th:replace="fragments :: form-validation"></script>
<script type="application/javascript">
    $(function () {
        function tagRequest(url, tagTitle) {
            $.ajax({
                dataType: "json",
                autoComplete: {
                    enabled: true,
                    rightKey: true
                },
                contentType: "application/json; charset=utf-8",
                method: "POST",
                // URL에는 ADD, REMOVE 등이 들어갈 것임
                url: "/settings/tags" + url,
                data: JSON.stringify({'tagTitle': tagTitle})
            }).done(function (data, status) {
                console.log(`${data} and status is ${status}`);
            });
        }

        function onAdd(e) {
            console.log(e);
            tagRequest("/add", e.detail.data.value);
        }

        function onRemove(e) {
            tagRequest("/remove", e.detail.data.value);
        }

        let tagInput = document.querySelector("#tags");

        let tagify = new Tagify(tagInput, {
            pattern: /^.{0,20}$/,
            dropdown: {
                enabled: 1 // 한글자 치면 추천 태그를 띄워줌
            } // 맵 태그들
        });

        tagify.on("add", onAdd);
        tagify.on("remove", onRemove);

        // Tagify 의 input 박스에 클래스 추가
        tagify.DOM.input.classList.add('form-control');
        // Tagify의 input 요소를엘리먼트의 밖(tagify.DOM.scope)으로, 하기 바로 전에
        tagify.DOM.scope.parentNode.insertBefore(tagify.DOM.input, tagify.DOM.scope);
    });
</script>
</body>
</html>

Tagify 객체를 초기화해주고 .on() 메소드를 이용하여 tagify에 태그가 추가되거나 삭제될 때 동작할 콜백 함수들을 매개변수로 넣어주었다. 태그가 추가되면 onAdd 함수가 실행되고, 태그가 삭제되면 onRemove 함수가 실행된다.

현재는 컨트롤러의 해당 패스에 해당하는 메소드가 동작하지 않는 상태니까 서버쪽에서 이제 만들어주면 된다.

profile
풀스택 웹개발자로 일하고 있는 Jake Seo입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. 프론트엔드: Javascript, React 백엔드: Spring Framework에 관심이 있습니다.

0개의 댓글