[Spring][쇼핑몰 프로젝트] 18. 상품 등록(2)

YB·2023년 2월 21일
0

쇼핑몰

목록 보기
27/40
post-thumbnail

목표

authorId<input>태그에 데이터를 넣기 위해 '작가'를 선택할 수 있도록 '팝업 창'을 띄우고, 원하는 '작가'를 선택을 하게 되면 팝업창은 닫히고 <input>태그에 해당 작가의 id값이 입력되도록 하는 것이 목표입니다.

1. 작가 선택 버튼 추가 및 css 설정

기존의 작가 입력(authorId) <input>태그 옆에 버튼을 추가할 것입니다. 해당 버튼을 누르게 되면 DB에 등록되어 있는 작가를 선택할 수 있는 팝업창이 뜨도록 구현할 것입니다.

먼저 기존의 작가 <input>태그를 아래의 코드로 수정 및 추가합니다.

첫번째 <input>태그의 경우 사용자에게 보일 부분입니다. 작가의 이름이 출력되도록 할 것입니다. 두번째 <input>태그는 '상품 등록'에 필요로 한 authorId데이터를 저장합니다. 해당 태그는 보이지 않도록 type속성 값을 'hidden'을 부여하였습니다. <button>은 작가 선택을 할 팝업창을 띄우기 위해 추가하였습니다.

<input id="authorName_input" readonly="readonly">
<input id="authorId_input" name="authorId" type="hidden">
<button class="authorId_btn">작가 선택</button>

추가한 태그들의 css설정을 추가하였습니다. goodsEnroll.css에 아래의 코드를 추가합니다.

.authorId_btn {						/* 작가 선택 css 설정 */
    margin-left: 20px;
    width: 14%;
    height: 38px;
    font-weight: 600;
    background-color: #dfe8f5;
    font-size: 15px;
    cursor:pointer;
}
#authorName_input {
    width: 80%;
    text-align: center;
}

2. 버튼 작동 구현

팝업창은 아래의 코드를 통해 작동합니다.

첫 번째 파라미터는 팝업창의 url주소입니다. 두 번째 파라미터는 팝업창의 이름입니다. 마지막 파라미터는 팝 업창에 대한 설정입니다.

어떠한 설정을 할 수 있는지는 아래의 MDN홈페이지에 들어가면 볼 수 있습니다.
팝업창MDN

var window = window.open(url, windowName, [windowFeatures]);

먼저 <script>태그 아래에 버튼이 클릭되었을 때 동작하는 메서드 추가와 해당 구현부에 버튼의 동작을 멈추는 코드를 추가해주고 팝업창 동작을 실행하는 코드를 추가합니다.(해당 버튼이 <form>태그 내부에 추가되어있기 때문에 기능을 막지 않으면 <form>이 전송됩니다.)

/* 작가 선택 버튼 */
$('.authorId_btn').on("click",function(e){
	
	e.preventDefault();
	let popUrl = "/admin/authorPop";
	let popOption = "width = 650px, height=550px, top=300px, left=300px, scrollbars=yes";
	
	window.open(popUrl,"작가 찾기",popOption);	
	
});

위의 코드 작성을 마치고 '작가 선택'버튼을 클릭하면 에러 창이 뜹니다. 아직 url매핑 메서드와 팝업창 jsp를 추가해주지 않았기 때문입니다. 그렇기 때문에 AdminController.java에 아래의 url매핑 메서드를 추가해줍니다.

	/* 작가 검색 팝업창 */
	@GetMapping("/authorPop")
	public void authorPopGET() throws Exception {
		
		logger.info("authorPopGET");
		
	}

views/admin폴더 경로에 authorPop.jsp파일을 추가해줍니다. 그리고 authorPop.jsp파일에 해당 페이지가 팝업 페이지임을 표시하도록 문구를 추가하였습니다.

3. 작가 목록 구현(팝업창)

1) Controller 작업

상품 관리 페이지에서 하였던 작가 리스트를 출력하고 검색 기능을 팝업창에서 구현할 것입니다. 기존의 authorManage.jsp에서 구현한 것을 그대로 가져올 것입니다.

"authorPop" url매핑 메서드에 작가 리스트 구현에 필요로 한 Criteria, Model객체를 파라미터로 추가합니다.

  • "authorManage" url매핑 메서드에 있는 구현부의 코드를 복사하여 구현부에 붙여 넣어줍니다.
  • "팝업창"에 작가 목록 리스트를 5개씩 전송하도록 하기 위해 Criteria에 기본적으로 초기화되어 있는 amount 변수 값 10을 5로 변경해주는 코드를 추가합니다.

	/* 작가 검색 팝업창 */
	@GetMapping("/authorPop")
	public void authorPopGET(Criteria cri, Model model) throws Exception {
		
		logger.info("authorPopGET");
		
		cri.setAmount(5);
		
		/* 게시물 출력 데이터 */
		
		List list = authorService.authorGetList(cri);
		
		if(!list.isEmpty()) {
			model.addAttribute("list", list);
		} else {
			model.addAttribute("listCheck", "empty");
		}
		
		/* 페이지 이동 인터페이스 데이터 */
		model.addAttribute("pageMaker", new PageDTO(cri, authorService.authorGetTotal(cri)));
		
	}

2) View 작업

JSTL을 사용하기 위해서 라이브러리 태그를 파일 상단에 추가하였습니다.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>  

서버로부터 전달받은 "listCheck"와 "pageMaker"데이터를 가지고 '작가 목록'과 '페이지 인터페이스'를 출력하는 코드를 추가합니다. "authorManage.jsp"에 작성한 코드를 복사 붙여 넣기 후 필요양식에 맞게 수정을 하였습니다.

  • css 설정을 추가해주기 위해 아래의 <link>태그를 추가해줍니다.
  • 페이지 인터페이스가 동작하도록 하기 위해 Jquery사용 태그 코드를 추가해주고 'authorPop.jsp'파일 하단에 <script>태그를 추가해준 뒤 아래의 코드를 추가해줍니다.

<link rel="stylesheet" href="../resources/css/admin/authorPop.css">
<script
  src="https://code.jquery.com/jquery-3.4.1.js"
  integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
  crossorigin="anonymous"></script>
  
		<div class="subject_name_warp">
			<span>작가 선택</span>
		</div>
		<div class="content_wrap">
               	<!-- 게시물 표 영역 -->
				<div class="author_table_wrap">
               		<!-- 게시물 O -->
               		<c:if test="${listCheck != 'empty'}">
               			<div class="table_exist">
	                    	<table class="author_table">
	                    		<thead>
	                    			<tr>
	                    				<td class="th_column_1">작가 번호</td>
	                    				<td class="th_column_2">작가 이름</td>
	                    				<td class="th_column_3">작가 국가</td>
	                    			</tr>
	                    		</thead>
	                    		<c:forEach items="${list}" var="list">
	                    		<tr>
	                    			<td><c:out value="${list.authorId}"></c:out> </td>
	                    			<td><c:out value="${list.authorName}"></c:out></td>
	                    			<td><c:out value="${list.nationName}"></c:out> </td>
	                    		</tr>
	                    		</c:forEach>
	                    	</table>
                    	</div>                			
               		</c:if>
               		<!-- 게시물 x -->
               		<c:if test="${listCheck == 'empty'}">
               			<div class="table_empty">
               				등록된 작가가 없습니다.
               			</div>
               		</c:if>
               		
                    <!-- 검색 영역 -->
                    <div class="search_wrap">
                    	<form id="searchForm" action="/admin/authorPop" method="get">
                    		<div class="search_input">
                    			<input type="text" name="keyword" value='<c:out value="${pageMaker.cri.keyword}"></c:out>'>
                    			<input type="hidden" name="pageNum" value='<c:out value="${pageMaker.cri.pageNum }"></c:out>'>
                    			<input type="hidden" name="amount" value='${pageMaker.cri.amount}'>
                    			<button class='btn search_btn'>검 색</button>
                    		</div>
                    	</form>
                    </div>
                    
                    <!-- 페이지 이동 인터페이스 영역 -->
                    <div class="pageMaker_wrap" >
                    
	                    <ul class="pageMaker">
	                    
	                    	<!-- 이전 버튼 -->
	                    	<c:if test="${pageMaker.prev}">
	                    		<li class="pageMaker_btn prev">
	                    			<a href="${pageMaker.pageStart - 1}">이전</a>
	                    		</li>
	                    	</c:if>
	                    	
	                    	<!-- 페이지 번호 -->
	                    	<c:forEach begin="${pageMaker.pageStart}" end="${pageMaker.pageEnd}" var="num">
	                    		<li class="pageMaker_btn ${pageMaker.cri.pageNum == num ? "active":""}">
	                    			<a href="${num}">${num}</a>
	                    		</li>
	                    	</c:forEach>
	                    	
	                    	<!-- 다음 버튼 -->
	                    	<c:if test="${pageMaker.next}">
	                    		<li class="pageMaker_btn next">
	                    			<a href="${pageMaker.pageEnd + 1 }">다음</a>
	                    		</li>
	                    	</c:if>
	                    	
	                    </ul>
	                    
                    </div>               		
               		
					<form id="moveForm" action="/admin/authorPop" method="get">
						<input type="hidden" name="pageNum" value="${pageMaker.cri.pageNum}">
						<input type="hidden" name="amount" value="${pageMaker.cri.amount}">
						<input type="hidden" name="keyword" value="${pageMaker.cri.keyword}">
					</form>               		
               		
               		
		</div>
	</div>

<script>

let searchForm = $('#searchForm');
let moveForm = $('#moveForm');

/* 작거 검색 버튼 동작 */
$("#searchForm button").on("click", function(e){
	
	e.preventDefault();
	
	/* 검색 키워드 유효성 검사 */
	if(!searchForm.find("input[name='keyword']").val()){
		alert("키워드를 입력하십시오");
		return false;
	}
	
	searchForm.find("input[name='pageNum']").val("1");
	
	searchForm.submit();
	
});


/* 페이지 이동 버튼 */
$(".pageMaker_btn a").on("click", function(e){
	
	e.preventDefault();
	
	console.log($(this).attr("href"));
	
	moveForm.find("input[name='pageNum']").val($(this).attr("href"));
	
	moveForm.submit();
	
});	
	
</script>

resources/css/admin 경로에 "authorPop.css"파일을 추가해준 뒤 아래의 코드를 추가해주었습니다.

@charset "UTF-8";

/* 전체 wrap */
.wrapper{
	width:100%;
	height:535px;
}
.subject_name_warp{
	font-size: 33px;
    font-weight: bolder;
    padding-left: 15px;
    background-color: #6AAFE6;
    height: 13%;
    line-height: 70px;
    color: white;
}
.content_wrap{
	height:87%;
}




/* 작가 목록 영역 */
.author_table_wrap{
	padding: 20px 35px
}
.table_exist{
	height:251px;
}
.author_table{
	width: 100%;
    border: 1px solid #d3d8e1;
    text-align: center;
    border-collapse: collapse;
}
.author_table td{
	padding: 10px 5px;
	border : 1px solid #e9ebf0;
}
.author_table thead{
	background-color: #f8f9fd;	
	font-weight: 600;
}
.author_table a{
	color:#1088ed;
	font-weight: 500;
}
.th_column_1{
	width:120px;
}
.th_column_3{
	width:110px;
}


.table_empty{
	text-align: center;
    margin: 101px 0 130px 0;
    font-size: 25px;
}

/* 검색 영역 */
.search_wrap{
	margin-top:25px;
}
.search_input{
    position: relative;
    text-align:center;	
}
.search_input input[name='keyword']{
	padding: 4px 10px;
    font-size: 15px;
    height: 20px;
    line-height: 20px;
}
.search_btn{
	height: 32px;
    width: 80px;
    font-weight: 600;
    font-size: 18px;
    line-height: 20px;
    position: absolute;
    margin-left: 15px;
    background-color: #c3daf7;
}

/* 페이지 버튼 인터페이스 */
.pageMaker_wrap{
    margin-top: 20px;
    margin-bottom: 40px;
}
.pageMaker{
    list-style: none;
    display: inline-block;
}	
.pageMaker_btn {
	text-align: center;	
	float: left;
    width: 30px;
    height: 30px;
    line-height: 30px;
    margin-left: 8px;
    font-size: 15px;
}
.active{
	border : 2px solid black;
	font-weight:400;
}
.next, .prev {
    border: 1px solid #ccc;
    padding: 0 10px;
}
.next a, .prev a {
    color: #ccc;
}

4. 부모 창 데이터 전달

팝업창의 작가 이름을 클릭하였을 때 팝업창이 닫히면서 부모 창의 작가 <input>태그에 데이터 입력되도록 구현할 것입니다.

MDN페이지
Javascript코드를 통해 제어할 것인데 위의 MDN페이지에 있는 부모 창의 요소에 접근하는 방법을 참고하면 됩니다. 링크의 페이지에서 부모 창을 접근하기 위한 키워드는 "openr"입니다.

작가의 이름을 아래의 <a>태그로 감싸줍니다.

  • 태그 속성에 data-name 속성을 추가시켜서 <a>태그에 '작가 이름' 데이터를 저장시켰습니다. 해당 데이터를 Javascript에서 꺼내 쓰기 위해서는 '선택자. data("name")' 코드를 통해 사용할 수 있습니다.
<a class="move" href='<c:out value="${list.authorId}"/>' data-name='<c:out value="${list.authorName}"/>'>
	<c:out value="${list.authorName}"></c:out>
</a>

<script>태그에 추가한 <a>태그를 눌렀을 때 동작시킬 코드를 추가합니다.

  • 작성한 메서드 구현부를 해석하면 <a>태그의 동작을 멈춘 뒤, 'authorId'와 'authorName'변수를 사용자가 클릭한 <a>태그 속성에 저장된 authorId, authorName데이터로 초기화시킵니다. $(opener.document)를 통해 부모 요소에 접근하여 각 <input>태그에 'authorId', 'authorName' 변수의 값을 삽입합니다. 마지막으로 window.close()를 통해 팝업창을 닫습니다.
/* 작가 선택 및 팝업창 닫기 */
$(".move").on("click", function(e){
	
	e.preventDefault();
	
	let authorId = $(this).attr("href");
	let authorName= $(this).data("name");
	$(opener.document).find("#authorId_input").val(authorId);
	$(opener.document).find("#authorName_input").val(authorName);
	
	window.close();

});
profile
개인이 공부한걸 작성하는 블로그입니다..

0개의 댓글