hyeonga_code

reProject_22_Ajax로 List값 화면에 뿌리기, community 페이지 DB 연결 본문

Project_WEATHERWEAR

reProject_22_Ajax로 List값 화면에 뿌리기, community 페이지 DB 연결

hyeonga 2024. 1. 9. 05:59
반응형

 

 

reProject_21_스케줄러 활용, 날씨 API 활용_OpenWeatherMap

reProject_20_스케줄러 활용, 날씨 API 활용_OpenWeatherMap 2024.01.06 - [Project] - reProject_19_Spring Scheduler 이용해서 만료된 쿠키에 적용하기 2024.01.05 프로젝트 메인 페이지에서 날씨를 활용한 상품을 추천해

hyeonga493.tistory.com

 

2024-01-08

현재 프로젝트에 community 페이지에서 jsp에 박아둔 코드의 style을 display:none인 상태에서 메뉴 클릭시 display:flex로 설정하여 화면에 출력되게 하고있다. 클릭하는 순간 ajax를 통해 데이터를 화면에 <c:forEach>태그를 사용하여 뿌려주려 했는데 화면을 다시 로드하지 않는 이상 화면에 데이터가 뿌려지지 않아 div안에 innerHTML()로 데이터를 뿌려주기로 결정했다.

 

 

1. 값을 가지고 다닐 NoticeVO.java 클래스를 com.w2.notice 패키지에 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.w2.notice;
 
import java.util.Date;
 
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
 
@Getter
@Setter
@ToString
public class NoticeVO {
    
    private String noId;
    private String noWriter;
    private Date noDate;
    private String noTitle;
    private String noContent;
    private String noImage;
    private String noFile;
    private int noView;
}
 

 

 

 

2. ClientAjaxController.java 클래스 생성

-- ClientGetController/ClientPostController에 전부 다 작성하기엔 코드가 너무 길어질 것 같아 Ajax를 처리하는 Controller를 하나 생성

-- ajax에 반환하고 싶은 데이터를 Map에 담아 return하면 script에서 'map 이름'.'담은 이름'으로 담긴 값을 가져다 사용할 수 있다. ajax에 대해 더 알아봐야겠다.

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
package com.w2.client.controller;
 
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.w2.client.cart.ClientCartService;
import com.w2.client.notice.ClientNoticeService;
import com.w2.client.product.ClientProductService;
import com.w2.weather.WeatherService;
 
@Controller
public class ClientAjaxController {
 
    @Autowired
    private ClientNoticeService noticeService;
 
    @PostMapping("getNotice.do")
    @ResponseBody
    public Map<String, Object> getNotice() {
        
        Map<String, Object> resultMap = new HashMap<String, Object>();
        
        resultMap.put("result""yes");
        resultMap.put("noticeList", noticeService.getNotice());
        System.out.println("list : " + resultMap.get("noticeList"));
        return resultMap;
    }
}

 

 

 

 

3. com.w2.client.notice 패키지에 ClientNoticeService.java 인터페이스 생성

1
2
3
4
5
6
7
8
9
10
11
12
package com.w2.client.notice;
 
import java.util.List;
 
import com.w2.notice.NoticeVO;
 
public interface ClientNoticeService {
 
    // 공지사항 조회
    public List<NoticeVO> getNotice();
}
 

 

 

 

4. com.w2.client.notice.impl 패키지에 ClientNoticeServiceImpl.java 클래스 생성

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
package com.w2.client.notice.impl;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.w2.client.notice.ClientNoticeDAO;
import com.w2.client.notice.ClientNoticeService;
import com.w2.notice.NoticeVO;
 
@Service("noticeService")
public class ClientNoticeServiceImpl implements ClientNoticeService {
 
    @Autowired
    private ClientNoticeDAO noticedao;
 
    // 공지사항 조회
    @Override
    public List<NoticeVO> getNotice() {
        System.out.println("2. [ Impl ] : getNotice");
 
        return noticedao.getNotice();
    }
 
}
 

 

 

 

5. com.w2.client.notice 패키지에 ClientNoticeDAO.java 클래스 생성

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
package com.w2.client.notice;
 
import java.util.List;
 
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
 
import com.w2.notice.NoticeVO;
 
 
@Repository
public class ClientNoticeDAO {
    
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;
 
    // 공지사항 조회
    public List<NoticeVO> getNotice() {
        System.out.println("3. [ Notice DAO ] getNotice");
        
        return sqlSessionTemplate.selectList("NoticeDAO.getNotice");
    }
}
 

 

 

 

6. mapping 폴더에 notice-mapping.xml 파일 생성

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
 
<!-- MyBatis 다운 파일 PDF 에서 붙여넣은 내용입니다. -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
                 
<mapper namespace="NoticeDAO">
 
    <select id="getNotice" resultType="noticevo">
        SELECT noId, noWriter, noDate, noTitle, noView FROM notice ORDER BY noDate DESC;
    </select>
</mapper>

 

 

 

7. mybatis-config.xml 파일 수정

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
<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
                "http://mybatis.org/dtd/mybatis-3-config.dtd">
 
<configuration>
    
    <typeAliases>
        <!-- typeAlias
                - 매핑파일에서 사용하는 type을 지정
                - 애플리케이션에서 SQL 문으로 값을 전달합니다
                - SQL 문 실행 시 반환되는 레코드를 저장하는 용도로 사용하기 위한 빈을 생성합니다.-->
        <typeAlias type="com.w2.client.ClientVO" alias="client" />
        <typeAlias type="com.w2.client.cart.ClientCartVO" alias="clientCart" />
        <typeAlias type="com.w2.product.ProductVO" alias="provo" />
        <typeAlias type="com.w2.product.ProductPriceVO" alias="pricevo" />
        <typeAlias type="com.w2.util.ImageVO" alias="imvo" />
        <typeAlias type="com.w2.product.OptionVO" alias="opvo" />
        <typeAlias type="com.w2.weather.WeatherVO" alias="weathervo" />
        <typeAlias type="com.w2.notice.NoticeVO" alias="noticevo" />
    </typeAliases>
 
    <!-- SQL 작성문을 지정하여 mapper 파일 경로 알려주는 역할입니다. -->
    <mappers>
        <mapper resource="mappings/client-mapping.xml" />
        <mapper resource="mappings/client-product-mapping.xml" />
        <mapper resource="mappings/client-cart-mapping.xml" />
        <mapper resource="mappings/weather-mapping.xml" />
        <mapper resource="mappings/notice-mapping.xml" />
    </mappers>
</configuration>

 

 

 

8. client_community.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
83
84
85
86
87
88
89
90
91
92
93
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WEATHERWEAR</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="/w2/resources/client/client_js/client_community.js"></script>
    <link rel="stylesheet" href="/w2/resources/client/client_css/client_base_style.css">
    <link rel="stylesheet" href="/w2/resources/client/client_css/client_community_style.css">
</head>
<body>
    <div class="container">
        <%@ include file="/WEB-INF/views/client/base/client_header.jspf" %>
        <div class="body">
            <div class="community_body">
                <ul class="community_menu">
                    <li id="notice_btn">Notice</li>
                    <li id="review_btn">Review</li>
                    <li id="qna_btn">QnA</li>
                </ul>                
    <!-- NOTICE -->
                <div class="noticeList">
                    <h2>NOTICE</h2>
                    <div class="notice_table" id="notice_table">
                        
                    </div>
                </div>    
    <!-- Review -->
                <div class="reviewList">
                    <h2>REVIEW</h2>
                    <div class="review_table">
                        <ul class="review_header">
                            <li class="review_head no">NO</li>
                            <li class="review_head product">PRODUCT</li>
                            <li class="review_head con">CONTENT</li>
                            <li class="review_head writer">WRITER</li>
                            <li class="review_head date">DATE</li>
                            <li class="review_head view">VIEW</li>
                        </ul>
                        <ul class="review_content">
                            <li class="review_con no">1</li>
                            <li class="review_con product">
                                <a href="#" class="community_a">
    <!-- 상품상세로 이동 -->                                상품123(이미지)
                                </a>
                            </li>
                            <li class="review_con content">
                                <a href="#" class="community_a">
                                <span>
    <!-- 해당 리뷰로 이동 -->                                상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 상품 질이 매우 좋네요 
                                </span>
                                </a>
                            </li>
                            <li class="review_con writer">client</li>
                            <li class="review_con date">2023-12-01</li>
                            <li class="review_con view">53</li>
                        </ul>
                    </div>
                </div>    
    <!-- QnA -->
                <div class="qnaList">
                    <h2>QnA</h2>
                    <div class="qna_table">
                        <ul class="qna_header">
                            <li class="qna_head no">NO</li>
                            <li class="qna_head title">TITLE</li>
                            <li class="qna_head writer">WRITER</li>
                            <li class="qna_head date">DATE</li>
                            <li class="qna_head view">VIEW</li>
                        </ul>
                        <ul class="qna_content">
                            <li class="qna_con no">1</li>
                            <li class="qna_con title">
                                <a href="#" class="community_a">
    <!-- 문의 상세로 이동 -->                                재고 문의
                                </a>
                            </li>
                            <li class="qna_con writer">client</li>
                            <li class="qna_con date">2023-12-01</li>
                            <li class="qna_con view">2</li>
                        </ul>
                    </div>
                </div>
            </div>
 
        </div>
        <%@ include file="/WEB-INF/views/client/base/client_footer.jspf" %>
    </div>
</body>
</html>

 

 

 

9. client_community_style.css 수정

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
@charset "UTF-8";
 
.community_menu {
    list-style: none;
    display: flex;
    padding-left: 0;
    width: 50%;
    font-size: x-large;
    color: silver;
}
 
.community_a {
    text-decoration: none;
    color: black;
}
 
.community_menu > li {
    display: inline;
    margin: 5px auto;
    text-align: center;
}
 
.community_body {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
}
 
.noticeList{
    width: 90%;
    display: none;
    flex-direction: column;
    align-items: center;
}
 
.notice_table {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
}
 
.notice_table > ul {
    width: 100%;
    height: 40px;
    list-style-type: none;
    display: flex;
    flex-direction: row;
    align-items: inherit;
    padding: 0px;
    margin: 0;
    border : 1px solid pink;
}
 
.notice_table > ul > li {
    border : 1px solid pink;
}
 
.notice_head {
    display: inline-block;
    margin: 5px auto;
    text-align: center;
}
 
.reviewList{
    width: 90%;
    display: none;
    flex-direction: column;
    align-items: center;
}
 
.review_table {
    width: 90%;
    display: flex;
    flex-direction: column;
    align-items: center;
}
 
.review_table > ul {
    width: 100%;
    height: 40px;
    list-style-type: none;
    display: flex;
    flex-direction: row;
    align-items: inherit;
    padding: 0px;
    margin: 0;
    border : 1px solid pink;
}
 
.review_table > ul > li {
    border : 1px solid pink;
}
 
.review_head {
    display: inline-block;
    margin: 5px auto;
    text-align: center;
}
 
.qnaList{
    width: 90%;
    display: none;
    flex-direction: column;
    align-items: center;
}
 
.qna_table {
    width: 90%;
    display: flex;
    flex-direction: column;
    align-items: center;
}
 
.qna_table > ul {
    width: 90%;
    height: 40px;
    list-style-type: none;
    display: flex;
    flex-direction: row;
    align-items: inherit;
    padding: 0px;
    margin: 0;
    border : 1px solid pink;
}
 
.qna_table > ul > li {
    border : 1px solid pink;
}
 
.qna_head {
    display: inline-block;
    margin: 5px auto;
    text-align: center;
}
 
.no { width: 5%; text-align: center; }
.title { width: 63%; padding-left: 15px;}
.writer { width: 10%; text-align: center; }
.date { width: 15%; text-align: center; }
.view { width: 7%; text-align: center; }
.product { width: 20%; text-align: center; }
.con { width: 30%; }
.content { 
    width: 30%;
    max-width: 30%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis; 
}
 

 

 

 

10. client_community.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
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
 * 
 */
$(document).ready(function(){
    // 클릭 시 페이지로 이동
    const notice_btn = document.querySelector("#notice_btn");
    const review_btn = document.querySelector("#review_btn");
    const qna_btn = document.querySelector("#qna_btn");
    
    const noticeList = document.querySelector(".noticeList");
    const reviewList = document.querySelector(".reviewList");
    const qnaList = document.querySelector(".qnaList");
    
    // 다른 카테고리 숨기기
    const showForm = (target) => {
        noticeList.style.display = 'none';    
        reviewList.style.display = 'none';    
        qnaList.style.display = 'none';
        
        target.style.display="flex";
    }
    
    // 선택된 메뉴 강조
    const select = (target) => {
        notice_btn.style.color = "silver";
        review_btn.style.color = "silver";
        qna_btn.style.color = "silver";
        
        target.style.color="dimgrey";
    }
    
    notice_btn.addEventListener('click', () => {
        showForm(noticeList);
        select(notice_btn);
        getNotice();
    });
    
    review_btn.addEventListener('click', () => {
        showForm(reviewList);
        select(review_btn);
    });
    
    qna_btn.addEventListener('click', () => {
        showForm(qnaList);
        select(qna_btn);
    });
})    
 
function getNotice(){
    let noticeList = [];
    console.log("getNotice()");
    $.ajax({
        url: "/w2/getNotice.do",
        type: "POST",
        dataType: "json",
        success: function(resultMap){
            result = JSON.stringify(resultMap);
            console.log("resultMap : " + resultMap);
            console.log("resultMap.result : " + resultMap.result);
            console.log("resultMap.noticeList : " + resultMap.noticeList);
            console.log("result.result : " + result.result);
            
            if(resultMap.result =='yes'){
                console.log(">> result : " + resultMap.result);
                
                list = resultMap.noticeList;
                let noticeDiv = "<ul class='notice_header'><li class='notice_head no'>NO</li><li class='notice_head title'>TITLE</li>";
                noticeDiv += "<li class='notice_head writer'>WRITER</li><li class='notice_head date'>DATE</li><li class='notice_head view'>VIEW</li></ul>";
                
                $.each(list, function(index, notice){
                    console.log(index + ":" + dateFormat(new Date(notice.noDate)));
                    noticeDiv += "<ul class='notice_content'><li class='notice_con no'>";
                    noticeDiv += (index+1);
                    noticeDiv += "</li><li class='notice_con title'><a href='noticeInfo.do?noId=";
                    noticeDiv += notice.noId;
                    noticeDiv += "' class='community_a'>";
                    noticeDiv += notice.noTitle;
                    noticeDiv += "</a></li><li class='notice_con writer'>";
                    noticeDiv += notice.noWriter;
                    noticeDiv += "</li><li class='notice_con date'>";
                    noticeDiv += dateFormat(new Date(notice.noDate));
                    noticeDiv += "</li><li class='notice_con view'>";
                    noticeDiv += notice.noView;
                    noticeDiv += "</li></ul>";
                }); 
                
                document.querySelector("#notice_table").innerHTML = noticeDiv;
            }
        },
        error : function(error){
            alert("ajax는 실패입니다.");
        }
    });
}
 
 
function dateFormat(date){
    let month = date.getMonth() + 1;
    let day = date.getDate();
 
    month = month>=10? month : '0' + month;
    day = day>=10? day : '0' + day;
    
    return date.getFullYear() + '-' + month + '-' + day;
}

 

 

 

>> 실행

 

 

>>>이와 같은 방식으로 QNA 게시판도 구현하려고 한다 

>>> QNA 게시판

 

>>> REVIEW 게시판

 

 

 

-- 현재는 리스트 페이지만 구현하였고 상세 페이지는 모달을 이용하여 팝업처럼 띄우는 방식으로 구현할 예정이다.

반응형