담당 기능
이전 관리자 페이지 CRUD 기능 추가 이어서 수정 페이지 기능 구현을 해보겠습니다.
프로젝트 구조는 다음과 같습니다.
기능 구현할 때 사용된 객체/메서드/패턴은 이전 포스팅에서 자세하게 설명했으므로 생략하겠습니다.
프로젝트 구조
admin_memberView
이전 포스팅에서 회원 상세 정보 페이지를 구현했습니다.
수정하기 버튼을 클릭 시 Controller에 요청을 보내는 코드를 구현합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<c:set var="path" value="${pageContext.request.contextPath}"/>
<script src="${path}/resources/include/js/bootstrap.js"></script>
<link rel="stylesheet" href="${path}/resources/include/style.css">
<script src="${path}/resources/include/jquery-3.6.3.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>adminList</title>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script type="text/javascript">
function daumZipCode() {
new daum.Postcode({
oncomplete: function(data) {
var addr = ''; // 주소 변수
var extraAddr = ''; // 참고항목 변수
if (data.userSelectedType === 'R') {
addr = data.roadAddress;
} else {
addr = data.jibunAddress;
}
if(data.userSelectedType === 'R'){
if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
extraAddr += data.bname;
}
if(data.buildingName !== '' && data.apartment === 'Y'){
extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
}
if(extraAddr !== ''){
extraAddr = ' (' + extraAddr + ')';
}
document.getElementById("address1").value = extraAddr;
} else {
document.getElementById("address2").value = '';
}
document.getElementById('zipcode').value = data.zonecode;
document.getElementById("address1").value = addr;
document.getElementById("address2").focus();
}
}).open();
}
</script>
<style>
body {
font-family: Arial, sans-serif;
}
h2 {
padding: 20px;
text-align: center;
color: #333;
}
table {
width: 600px;
margin: 0 auto;
border-collapse: collapse;
}
table td {
padding: 8px;
}
#profileimg{
text-align: center;
}
input[type="email"],
input[type="password"],
input[type="text"]{
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
width: 100%;
padding: 8px 16px;
background-color: #4CAF50;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
.button-container {
display: flex;
justify-content: space-between;
margin-top: 16px;
}
.button-container button {
width: 48%;
}
#container {
display: flex;
height: 100%;
width: 100%;
flex-direction: column;
}
#category {
display: flex;
flex-direction: column;
height: 100%;
width: 15%;
gap: 25px;
align-items: center;
border-right: 1px solid #000000;
padding-top: 50px;
}
div a.menubar {
text-decoration: none;
display: flex;
color: #000;
padding: 25px 25px 25px 25px;
font-weight: bold;
}
</style>
</head>
<body>
<%@ include file="../header.jspf" %>
<div id="container">
<div style="display: flex; height: auto;">
<div id="category" class="menu" style="width:10%; height:auto;">
<a class="menubar" href="${path}/admin/memberList">회원관리</a>
<a class="menubar" href="${path}/trip/list_admin.do">관광명소 관리</a>
<a class="menubar" href="${path}/review/list.do" >리뷰리스트 관리</a>
<a class="menubar" href="${path}/faq/list.do">FAQ</a>
</div>
<h2 style="font-size: 20px; margin-left: 100px;">프로필 수정</h2>
<form name="form1" id="form1" method="post" style="text-align: left; padding-left: 100px; margin-top: 80px; ">
<table width="600px" >
<tr>
<td colspan="2" id="profileimg">
<img style="width:200px; height:200px;" src="../resources/images/car.gif" class="img-thumbnail rounded-circle">
</td>
</tr>
<tr>
<td>이메일</td>
<td>이름</td>
</tr>
<tr>
<td><input type="email" id="mem_email" name="mem_email" value="${dto.mem_email}" readonly></td>
<td><input type="text" id="mem_name" name="mem_name" value="${dto.mem_name}"></td>
</tr>
<tr>
<td>비밀번호</td>
<td >비밀번호 확인</td>
</tr>
<tr>
<td><input type="password" id="mem_pass" name="mem_pass" value="${dto.mem_pass}" readonly></td>
<td><input type="password" id="passwd_ck" name="passwd_ck" value="${dto.mem_pass}" readonly></td>
<tr>
<td>닉네임</td>
<td>전화번호</td>
</tr>
<tr>
<td><input type="text" id="mem_nickname" name="mem_nickname" value="${dto.mem_nickname}"></td>
<td><input type="text" id="mem_phone" name="mem_phone" value="${dto.mem_phone}"></td>
</tr>
<tr>
<td style="text-align:center;">우편번호</td>
<td><input type="text" id="mem_zipcode" name="mem_zipcode" onclick="daumZipCode()" value="${dto.mem_zipcode}" placeholder="우편번호 찾기" readonly></td>
</tr>
<tr>
<td colspan="2"><input type="text" id="mem_address1" name="mem_address1" value="${dto.mem_address1}" readonly></td>
</tr>
<tr>
<td colspan="2"><input type="text" id="mem_address2" name="mem_address2" value="${dto.mem_address2}" placeholder="상세주소를 입력해주세요."></td>
</tr>
<tr>
<td colspan="2">
<input type="hidden" name="mem_num" value="${dto.mem_num}">
<button type="button" id="userUpdate">수정하기</button>
</td>
</tr>
<tr>
<td colspan="2"><button type="button" id="logback" name="logback">목록</button>
<div style="color: red;">${message}</div></td>
</tr>
</table>
</form>
</div>
<script>
$("#logback").click(function (){
location.href="${path}/admin/memberList";
});
$("#userUpdate").click(function (){
var mem_name = $("#mem_name").val();
var mem_nickname = $("#mem_nickname").val();
var mem_phone = $("#mem_phone").val();
var mem_zipcode = $("#mem_zipcode").val();
var mem_address1 = $("#mem_address1").val();
var mem_address2 = $("#mem_address2").val();
if(mem_name == ""){
alert("이름은 필수입니다.");
$("#mem_name").focus();
return;
}
if(mem_nickname == ""){
alert("닉네임을 입력하세요.");
$("#mem_nickname").focus();
return;
}
if(mem_phone == ""){
alert("번호를 입력하세요.");
$("#mem_phone").focus();
return;
}
if(mem_zipcode == ""){
alert("우편번호를 입력하세요.");
$("#mem_zipcode").focus();
return;
}
if(mem_address2 == ""){
alert("상세주소를 입력하세요.");
$("#mem_address2").focus();
return;
}
if(confirm("정보 수정 완료")){
document.form1.action="${path}/admin/userUpdate";
document.form1.submit();
}
});
</script>
</div>
</body>
</html>
간단한 안정성 검사를 통해서 null값이 들어오지 못하게 코드를 구현합니다.
빈 값이 없다면 confirm 메서드에 작성한 "정보 수정 완료" 메시지가 웹단에 표출되며 action 경로로 요청을 보냅니다.
다음으로 action 경로에 작성한 요청을 Controller에서 요청을 받아서 작업합니다.
Controller
이전 포스티에서 작업한 AdminContorller에 세부 url 요청 처리를 해줍니다.
자바 스크림트로 간단한 안전성 검사를 통해서 null값이 들어오는 걸 막았지만, 혹시 모르니 null값이 들어오면 service 단으로 요청을 보내지 못하게 코드 구현을 해줍니다.
@RequestMapping("/userUpdate")
public String UpdateUser(MemberDTO dto) throws Exception{
//회원 정보가 null이 들어오면 작동 안함.
if (dto != null){
adminService.updateMember(dto);
}
return "redirect:/admin/memberList";
}
추가적으로 메인 페이지에 표출할 게시물 개수를 선정하기 위해 테이블에 레코드 개수의 값을 구해주는 코드를 추가적으로 구현해줍니다.
@RequestMapping("/adminPage.do")
public ModelAndView adminPage(ModelAndView mav) throws Exception{
List<FaqDTO> items = faqService.list();
List<MemberDTO> memberList = adminService.memberList();
//레코드 개수
int memberCount = adminService.memberCount();
mav.setViewName("admin/admin_main");
mav.addObject("memberList", memberList);
mav.addObject("list", items);
// View 단에 전송
mav.addObject("memberCount", memberCount);
return mav;
}
Service
Service 단에서는 DAO에 요청을 보내주는 코드만 작성합니다.
// 수정 기능 추가
@Override
public void updateMember(MemberDTO dto) {
memberDao.updateMember(dto);
}
// 관리자 메인 페이지 ajax 박스 데이터 개수 정하는 메서드
@Override
public int memberCount() throws Exception {
return memberDao.memberCount();
}
DAO
DAO에서는 mapper 파일에 요청을 보내는 네임스페이스, id 값을 적어줍니다.
// admin 회원 정보 업데이트
@Override
public void updateMember(MemberDTO dto) {
sqlSession.update("admin.updateMember" , dto);
}
// admin 메인 페이지 회원 레코드 조회
@Override
public int memberCount() throws Exception {
return sqlSession.selectOne("admin.memberCount");
}
mapper
<update id="updateMember">
update member
set mem_name=#{mem_name},mem_nickname=#{mem_nickname},mem_zipcode=#{mem_zipcode}
,mem_address1=#{mem_address1},mem_address2=#{mem_address2}
where mem_num=#{mem_num}
</update>
<select id="memberCount" resultType="int">
select count(*)
from member
</select>
구현 결과
추가적으로 메인 페이지에 레코드 개수대로 표출할 수 있는 코드를 추가합니다.
<div class="container" style="flex-basis: 50%;">
<div class="container">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<h3>회원관리</h3>
<button class="btn" type="button" onclick="memberList()" style="float:right;">
<i class="bi bi-plus-lg"></i>
</button>
</div>
<table class="table table-hover">
<thead>
<tr>
<th>이메일</th>
<th>이름</th>
<th>주소</th>
<th>가입일자</th>
</tr>
</thead>
<tbody>
<c:forEach var="dto" items="${memberList}" varStatus="status">
<c:choose>
<c:when test="${status.index < 4}">
<tr>
<td>${dto.mem_email}</td>
<td><a href="${path}/admin/view.do?mem_num=${dto.mem_num}">${dto.mem_name}</a></td>
<td>${dto.mem_address1}</td>
<td><fmt:formatDate value="${dto.mem_join_date}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
</tr>
</c:when>
</c:choose>
</c:forEach>
</tbody>
</table>
</div>
</div>
<c:forEach> 태그로 memberList를 가져오고 <c:when> 문은 memberList index 개수 4개 이하까지만 데이터를 표출해 줄 수 있게 코드 구현을 했습니다.
결과를 확인합니다.
마치며
오늘은 [회원관리] 페이지 구현 중 수정 페이지를 구현했습니다.
다음 포스팅에서 뵙겠습니다.
'[ Project ] > Team' 카테고리의 다른 글
[ Team ] OAuth - Kakao API 로그인 구현 (0) | 2023.06.17 |
---|---|
[ Team ] OAuth - NAVER API 로그인 구현 (0) | 2023.06.16 |
[ Team ] 관리자 페이지 생성/ CRUD 구현 (목록/상세정보) (1) | 2023.06.14 |
[ Team ] 팀 프로젝트 기획 (0) | 2023.06.11 |
[ Team ] 팀 프로젝트 개요 (0) | 2023.06.09 |