[게시판 프로젝트] 회원 정보 수정(1)

J_Eddy·2021년 12월 14일
1

📌 회원 정보 수정 _ 내 정보 수정

Intro

회원정보 수정에는 내정보 수정, 패스원드 변경, 회원탈퇴가 있다. 이번 포스트에서는 내 정보 수정을 다뤄보겠다.

처음에는 아래와 같이 My Page에서 탭을 나누어 만들었다. 하지만 만들고 나서 직접 사용해 보니 다른탭으로 이동할 때 카테고리(?) 같은 탭이 없어서 불편하였다.

카테고리 형식으로 아래와 같이 수정하여 View를 구성하였다.

이번 포스트에서는 회원관리 정보를 위주로 다루기 때문에 게시물 관련 정보는 추후에 업로드 하도록 하겠다.

사이드 바

사이드바는 아래와 같이 구성하여 Thymeleaf의 fragments를 이용하여 해당 page에 include시켰다

<html xmlns:th="http://www.thymeleaf.org">
<head>
    ...
</head>
<body>
<div th:fragment="mySideBar">
    <div id="sidebar-wrapper">
        <ul class="sidebar-nav">
            <li class="sidebar-brand">
                <a>마이페이지</a>
            </li>
            <li>
                <a th:href="@{/board/myBoard}">내 게시물</a>
            </li>
            <li>
                <a th:href="@{/board/myOldBoard}">오래된 게시물</a>
            </li>
            <li>
                <a th:href="@{/account/myinfo}">내 정보 수정</a>
            </li>
            <li>
                <a th:href="@{/account/password}">패스워드 변경</a>
            </li>
            <li>
                <a th:href="@{/account/withdrawal}">회원 탈퇴</a>
            </li>

        </ul>
    </div>
</div>
<script> ... </script>
</body>
</html>

내 정보

내 정보 수정 view는 아래와 같이 구현하였다. form형식으로 DB에 저장되어있는 해당 회원의 정보를 thymeleaf의 Object와 field를 이용하여서 받아왔다. 당시 이 페이지를 구현할 때 Thymeleaf 사용이 처음이어서 다양한 방법을 적용해 보자 해서 Object로 구현했다.

회원은 닉네임과 생년월일을 수정할 수 있고, 닉네임을 수정 시 JS의 ajax를 이용해 비동기 방식으로 중복 체크를 진행 하였다. 뿐만 아니라 생년월일을 수정하면 자동으로 나이가 계산되도록 JS를 작성하였다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>...</head>
<body>
...
  
<div th:include="fragments/mypagesidebar"> </div> // 사이드바 include
    <form class="form-signin" th:action="@{/account/myinfo}" method="post" th:object="${member}">

        <h1 class="h3 mb-3 fw-normal">내 정보 수정</h1>
        <hr>

        <input type="hidden" class="form-control" th:field="*{id}" th:readonly="readonly" >
        <input type="hidden" class="form-control" th:field="*{role}" th:readonly="readonly" >

        <div class="mb-3">
            <label th:for="username">이메일</label>
            <input type="email" class="form-control" th:field="*{username}" th:readonly="readonly" >
        </div>

        <div class="mb-3">
            <label th:for="nickname">닉네임</label>
            <input type="text" class="form-control" th:field="*{nickname}" oninput="nicknameModify()">
            <span class="nickname_ok">사용 가능한 이름입니다.</span>
            <span class="nickname_already">누군가 이 이름을 사용하고 있어요.</span>
        </div>

        <label class="mb-3 form-label" for="birth">생년월일</label>
        <div class="mb-3" id="birth" onchange="checkAgeModify()">
            <div class="birth dropdown">
                <select  class="form-control" id="year" name="year">
                    <option th:value="*{year}" th:text="*{year}" selected></option>
                    <option value="">년(YY)</option>
                    <th:block th:each="a: ${#numbers.sequence(2001,1900)}">
                        <option th:value="${a}" th:text="${a}"></option>
                    </th:block>
                </select>
            </div>

            <div class="birth mx-1 dropdown">
                <select  class="form-control" id="month" name="month">
                    <option th:value="*{month}" th:text="*{month}" selected></option>
                    <option value="">월(mm)</option>
                    <th:block th:each="month: ${#numbers.listFormatInteger(#numbers.sequence(1,12),2)}">
                        <option class="dropdown-item" th:value="${month}" th:text="${month}"></option>
                    </th:block>
                </select>
            </div>

            <div class="birth dropdown">
                <select  class="form-control" id="day" name="day">
                    <option th:value="*{day}" th:text="*{day}" selected></option>
                    <option value="">일(dd)</option>
                    <th:block th:each="day: ${#numbers.listFormatInteger(#numbers.sequence(1,31),2)}">
                        <option class="dropdown-item" th:value="${day}" th:text="${day}"></option>
                    </th:block>
                </select>
            </div>
            <span id="birth_check_msg"></span>
        </div>

        <div class="mb-3">
            <label for="age">나이</label>
            <input type="text" class="form-control" id="age" th:readonly="readonly" >
        </div>

        <div class="mb-3">
            <label th:for="gender">성별</label>
            <input type="text" class="form-control" id="gender" name="gender" th:value="*{gender.value}" hidden >
            <input type="text" class="form-control"  th:value="*{gender.title}" readonly>
        </div>

        <div class="mb-3">
            <button class="w-100 btn btn-lg btn-primary" type="submit" onclick="return modifyCheckAll()">수정</button>
        </div>

        <div class="mb-3">
            <a type="button" style="color:white" class="w-100 btn btn-lg btn-secondary" onclick="window.history.back();">취소</a>
        </div>

    </form>
  
<footer th:replace="fragments/common :: footer"></footer>

<script> ... </script>
</body>
</html>

닉네임 중복 check JS

api를 이용해 닉네임 중복 JS이다 해당 api로 이 회원의 id와 회원이 입력한 닉네임 값이 전달된다.

function nicknameModify(){

    $.ajax({
        type :"post",
        url :"/api/nicknameModify",
        data : {"id" : id.val(), "nickname" : nickname.val()},
        dataType : "JSON",
        success : function(result){
            if(result.result == "0"){
                $('.nickname_ok').css({"display" : "inline-block","color" : "blue"});
                $('.nickname_already').css("display", "none");
                nicknameCheck = 1;
            }else{
                $('.nickname_ok').css("display","none");
                $('.nickname_already').css({"display" :"inline-block", "color" : "red"});
                nicknameCheck = 0;
            }
        },
        error : function(){
            alert("ajax 실행 실패");
        }
    });
}

이후 아래와 같은 서비스를 거쳐 map형식으로 값을 리턴한다.

//닉네임 수정 중복 검사
    public HashMap<String, Object> nicknameModify(String nickname, Long id) {
        List<String> findNickname = memberQueryRepository.findExistNickname(id).getResults();

        HashMap<String, Object> map = new HashMap<>();
        map.put("result", findNickname.contains(nickname));
        return map;
    }

이 때 닉네임 체크시 본인의 닉네임은 제외 하고 체크해야한다. 만일 본인것도 포함해서 체크하게된다면 사용자의 닉네임은 언제나 중복일 것이다. 이는 QueryDsl을 이용하여 작성하였다.

//본인것 제외한 닉네임 찾기
    public QueryResults<String> findExistNickname(Long id) {
        return queryFactory.select(QMemberEntity.memberEntity.nickname)
                .from(QMemberEntity.memberEntity)
                .where(QMemberEntity.memberEntity.id.ne(id))
                .fetchResults();
    }

닉네임 중복 시

사용가능 닉네임

나이 계산 JS

$(document).ready(function () {
    const now = new Date();
    const nowYear = now.getFullYear();
    const nowAge_input = nowYear - $("#year").val() + 1;
    const nowAge = nowYear - $("#year option:selected").val() + 1;
    $("#age").val(nowAge);
    $("#age_input").val(nowAge_input);
});

회원정보 update 처리

이후 수정 버튼을 누를시 validate 체크 후 이상이 없다면 해당 form의 값들이 post형식으로 전달되어 회원 정보가 업데이트 된다.

profile
논리적으로 사고하고 해결하는 것을 좋아하는 개발자입니다.

0개의 댓글