[Spring]Spring쇼핑몰 프로젝트 - Ajax를 활용하여 상품 문의 리스트 만들기 아코디언 리스트
판매자가 상품문의 리스트에서 할 수 있는 기능들은 아래와 같다.
- 상품문의 확인
- 답변 작성폼으로 이동
- 작정한 답변 확인
- 작성한 답변 수정 폼으로 이동
- 작성한 답변 수정
- 작성한 답변 삭제
해당 기능들 중 삭제를 제외한 기능들을 비동기로 처리하였다.
우선 리스트 출력시
리스트에서 상세보기 버튼을 통해서 문의내용을
아코디언 형식으로 출력하였고,
문의 내용을 출력할 때에는 답변을 작성한 경우와
작성하지 않은 경우로 나눠서
답변을 작성한 경우 - 문의내용과 답변을 출력하고,
답변을 작성하지 않은 경우 - 문의내용과 답변입력칸을 출력했다.
문의 리스트
1. 문의리스트.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
<table border="1" id="goodsQnaTable" style="table-layout:fixed" width="800">
<caption>문의 내역</caption>
<tr>
<th width="5%">번호</th>
<th width="20%">상품명</th>
<th width="25%">문의제목</th>
<th width="20%">문의날짜</th>
<th width="20%">상태</th>
<th width="10%">액션</th>
</tr>
<c:set var="num" value="${listcount-(page-1)*10}"/>
<c:forEach var="gql" items="${sellergoodsQnaList}">
<tr <c:if test="${gql.gdsqna_check == 0 }"> class="notcheck"</c:if> height=30px>
<td style="text-align: center;"><!-- 번호 출력 부분 -->
<input type="hidden" id="gdsqna_num" name="gdsqna_num" value="${gql.gdsqna_num}">
<c:out value="${num}"/>
<c:set var="num" value="${num-1}"/>
</td>
<td class="goodsQnaListName" title="${gql.gds_name}"><nobr>${gql.gds_name}</nobr></td>
<td>${gql.gdsqna_title}</td>
<td>
<fmt:formatDate value="${gql.gdsqna_date}" pattern="yyyy-MM-dd HH:mm:ss"/>
</td>
<td style="text-align: center;">
<c:choose>
<c:when test="${gql.gdsqna_answer == 0}">
미답변
</c:when>
<c:when test="${gql.gdsqna_answer == 1}">
답변완료
</c:when>
</c:choose>
</td>
<td style="text-align: center;">
<button id="detailbtn" type="button" onclick="showquestiondetail(${gql.gdsqna_num})">상세보기</button>
</td>
</tr>
<tr>
<td colspan="6">
<div id="questiondetail${gql.gdsqna_num}" class="hide"></div>
</td>
</tr>
</c:forEach>
</table>
|
cs |
forEach문으로 <tr> 2개식 출력하여
첫번째 tr은 리스트에서 보여줄 정보를 출력하고,
두번째 tr은 ajax의 결과값이 출력될 수 있도록 id와 class를 설정해준다.
id는 forEach로 여러 tr을 추가할 예정이기 때문에
특정할 수 있도록 하기 위해 id값에 각 문의의 번호를 붙였고,
class는 ajax가 동작하기 전에는 보이지 않도록 hide로 설정한다.
미리보기 버튼은 onclick으로 ajax를 호출하고,
ajax를 호출할 때 각 문의의 번호를 가져간다.
2. 문의 리스트CSS
1
2
3
|
.hide {display:none;}
.show {display:table-row;}
|
cs |
class가 hide인 경우에는 display:none 으로 보이지 않게 하고,
show인 경우에는 display:table-row 로 tr 요소처럼 보이게 한다.
3. 문의 리스트 ajax.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
function showquestiondetail(gdsqna_num) {
// class가 hide인 경우
if($("#questiondetail"+gdsqna_num).hasClass('hide')) {
$.ajax({
url : '/showgoodsQnadetail', // 요청 할 주소
type : 'post',
dataType : 'text',
data : {
"gdsqna_num" : gdsqna_num,
},
success : function(data) { // 요청 완료 시
$("#questiondetail"+gdsqna_num).html(data);
$("#questiondetail"+gdsqna_num).removeClass('hide').addClass('show'); // class에 hide를 지우고, show를 추가한다.
},
error :function(xhr,status,error){
console.log("code:"+xhr.status+"\n"+"message:"+xhr.responseText+"\n"+"error:"+error);
alert(xhr.status);
}
});
// class가 show인 경우
}else if($("#questiondetail"+gdsqna_num).hasClass('show')) {
$("#questiondetail"+gdsqna_num).empty();
$("#questiondetail"+gdsqna_num).removeClass('show').addClass('hide'); // class에 show를 지우고, hide를 추가한다.
}
}
|
cs |
ajax 요청시 class가 hide라면 ajax를 요청한 뒤에 show로 변경하고,
class가 show면 해당 tr요소 내에 있는 데이터를 empty()로 비우고, hide로 변경해서
아코디언 형태로 view페이지를 출력한다.
4. 컨트롤러.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 판매자 문의 상세목록으로 이동
@RequestMapping(value = "/showgoodsQnadetail")
public String showgoodsQnadetail(@RequestParam("gdsqna_num") int gdsqna_num, Model model) throws Exception{
// 답변이 달렸는지 확인하기
int answer = goodsQnaService.getGoodsQnaAnswer(gdsqna_num);
model.addAttribute("answer", answer);
// 문의확인 업데이트
goodsQnaService.updateCheckQna(gdsqna_num);
// 문의 가져오기
GoodsQnaVO goodsquestion = goodsQnaService.getGoodsQuestionDetail(gdsqna_num);
model.addAttribute("goodsquestion", goodsquestion);
// 답변이 있다면 답변 가져오기
if(answer == 1) {
GoodsQnaVO goodsanswer = goodsQnaService.getGoodsAnswerDetail(gdsqna_num);
model.addAttribute("goodsanswer", goodsanswer);
}
return "seller/ajaxgoodsqnadetail";
}
|
cs |
컨트롤러에서는 우선 해당 문의의 답변여부컬럼 (답변했으면 1, 안했으면0)
에 접근하여
답변이 달렸는지 확인한 뒤에
답변이 달렸다면 문의와 답변을 같이 가져오고,
답변이 없다면 문의만 가져온다.
5. ajax 상세페이지.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
<!-- 문의글 -->
<table id="questionTable" border="1" style="table-layout:fixed" >
<caption>문의</caption>
<tr>
<th width="100">상품 정보</th>
<td style="border-right: none;" width="100">
<img src="<%=request.getContextPath() %>/resources/images/thumbnailimage/${goodsquestion.gds_thumbnail}" height="100" width="100" />
</td>
<td style="border-left: none; white-space:nowrap; overflow: hidden;" width="500">
${goodsquestion.gds_name}
<br><br>
<div style="text-align: right"> <a href="goodsupdate?&gds_num=${goodsquestion.gds_num}">상품 수정하기</a></div>
</td>
<td width="100" >
<fmt:formatDate value="${goodsquestion.gdsqna_date}" pattern="yyyy-MM-dd HH:mm:ss"/>
</td>
</tr>
<tr>
<th width="100">문의 제목</th>
<td colspan="3">${goodsquestion.gdsqna_title}</td>
</tr>
<tr>
<th width="100">문의 내용</th>
<td colspan="3">
<c:if test="${goodsquestion.fname ne null}">
<img src="<%=request.getContextPath() %>/resources/upload/goodsqna/${goodsquestion.fname}"/> <br><br>
</c:if>
<pre style="border: none; background: none;">${goodsquestion.gdsqna_content}</pre>
</td>
</tr>
</table>
<c:choose>
<!-- 답변이 있을 경우 -->
<c:when test="${answer == 1 }">
<div id="goodsQnaAnswer${goodsanswer.gdsqna_num}">
<table border="1">
<caption>답변</caption>
<tr>
<th width="100">답변 제목</th>
<td>${goodsanswer.gdsqna_title}</td>
<th width="100">답변 등록일</th>
<td><fmt:formatDate value="${goodsanswer.gdsqna_date}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
</tr>
<tr>
<th>문의내용</th>
<td colspan="3"><pre style="border: none; background: none;">${goodsanswer.gdsqna_content}</pre></td>
</tr>
<tr>
<td colspan="4" align="center">
<input type="button" onclick="updategoodsqnaanswer(${goodsanswer.gdsqna_num})" value="수정">
<input type="button" onclick="location='deletegoodsqnaanswer?gdsqna_num=${goodsanswer.gdsqna_num}'" value="삭제">
</td>
</tr>
</table>
</div>
</c:when>
<!-- 답변이 없을 경우 -->
<c:when test="${answer == 0 }">
<form action="goodsqnaanswer" method="post">
<input type="hidden" id="gdsqna_num" name="gdsqna_num" value="${goodsquestion.gdsqna_num}">
<table border="1">
<caption>답변 등록</caption>
<tr>
<th width="100">답변 제목</th>
<td><input type="text" id="gdsqna_title" name="gdsqna_title" size="100"></td>
</tr>
<tr>
<th width="100">문의내용</th>
<td><textarea id="gdsqna_content" name="gdsqna_content" cols="102" rows="10"></textarea></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="답변 등록">
</td>
</tr>
</table>
</form>
</c:when>
</c:choose>
|
cs |
상세보기를 클릭하면 상품문의의 내용이 출력되고,
<c:choose> 태그를 활용하여
답변이 있는 경우 에는 답변 출력
답변이 없는 경우 - 답변 입력칸 출력
이 되도록 한다.
답변 수정의 경우 상세보기와 동일하게 onclick으로 ajax를 호출하며,
ajax를 호출할 때 각 문의의 번호를 가져간다.
답변영역의 경우 div로 감싸고, id값은 문의 리스트와
동일하게 특정할 수 있도록 문의 번호를 추가하여 설정해준다.
6. 수정 ajax.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
function updategoodsqnaanswer(gdsqna_num) {
$.ajax({
url : '/updategoodsqnaanswerform',
type : 'post',
dataType : 'text',
data : {
"gdsqna_num" : gdsqna_num,
},
success : function(data) {
$("#goodsQnaAnswer"+gdsqna_num).html(data);
},
error :function(xhr,status,error){
console.log("code:"+xhr.status+"\n"+"message:"+
xhr.responseText+"\n"+"error:"+error); alert(xhr.status);
}
});
}
|
cs |
7. 수정 controller.java
1
2
3
4
5
6
7
8
9
10
11
|
// 상품 문의 답변 수정 폼
@RequestMapping(value = "/updategoodsqnaanswerform")
public String updategoodsqnaanswerform(@RequestParam(value = "gdsqna_num") int gdsqna_num,
Model model) {
// 받아온 gdsqna_num으로 수정할 답변 정보 불러오기
GoodsQnaVO answer = goodsQnaService.getGoodsAnswer(gdsqna_num);
model.addAttribute("answer", answer);
return "seller/ajaxgoodsqnaanswerupdate";
}
|
cs |
8. ajax 답변 수정.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<form action="<%=request.getContextPath()%>/updategoodsqnaanswer" method="post">
<input type="hidden" id="gdsqna_num" name="gdsqna_num" value="${answer.gdsqna_num}">
<table border="1" id="goodsQnaAnswer${answer.gdsqna_num}">
<caption>답변 수정</caption>
<tr>
<th width="100">답변 제목</th>
<td><input type="text" id="gdsqna_title" name="gdsqna_title" size="100" value="${answer.gdsqna_title }"></td>
</tr>
<tr>
<th width="100">답변 내용</th>
<td><textarea id="gdsqna_content" name="gdsqna_content" cols="102" rows="10">${answer.gdsqna_content }</textarea></td>
</tr>
<tr>
<td colspan="4" align="center">
<input type="submit" value="수정">
</td>
</tr>
</table>
</form>
|
cs |
9. 실행화면