게시판 만들기 (상세화면)

Back-End/Spring 2019. 7. 4. 12:17
728x90
반응형

게시판 만들기 (상세화면)



 list.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    <c:forEach var="row" items="${map.list}"
    <!-- 컨트롤러에서 map안에 list를 넣었기 때문에 이렇게 받는다. -->
    <tr>
        <td>${row.bno}</td>
        <td>

//클릭하면 컨트롤러의 view.do로 이동하고, 게시물번호, 페이지번호,
//검색 옵션, 키워드를 같이 넘긴다.
//그렇게 같이 넘겨야 페이지나 검색이 풀리지 않는다.

<a href="${path}/board/view.do?bno=${row.bno}>      
&curPage=${map.pager.curPage} //페이지 번호
&search_option=${map.search_option} 
&keyword=${map.keyword}">${row.title}</a></td>
        <td>${row.name}</td>
        <td><fmt:formatDate value="${row.regdate}"
            pattern="yyyy-MM-dd HH:mm:ss"/> </td>
        <td>${row.viewcnt}</td>
    </tr>
    </c:forEach>    
cs



BoardController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RequestMapping("view.do", method=RequestMethod.GET)
    //list.jsp 페이지에서 넘긴 게시물번호, 페이지번호, 검색옵션, 키워드를 받는다.
    public ModelAndView view(@RequestParam int bno,
        @RequestParam int curPage,
        @RequestParam String search_option,
        @RequestParam String keyword,                    
        HttpSession session) throws Exception {
 
        //조회수 증가 처리
        boardService.increaseViewcnt(bno);

BoardServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    //조회수 증가 처리
//조회수 처리를 할때 일정 시간이 지난후 다시 클릭할때만 조회수가 증가하도록 설정.
    @Override
    public void increaseViewcnt(int bno, HttpSession session)
//글번호와 세션에 저장된 값들을 매개값으로 받음 
            throws Exception {
        long update_time=0; // null을 방지하기 위해 초기값을 null로 설정
        if(session.getAttribute("update_time_"+bno)!=null) {
            //최근에 조회수를 올린 시간이 null이 아니면
            update_time=
                    (long)session.getAttribute("update_time_"+bno);
        }
        long current_time=System.currentTimeMillis();
        //일정 시간이 경과한 후 조회수 증가 처리
        if(current_time - update_time > 5*1000) {
//그러니까 조회수가 1증가했을때로부터 5000초 후에 다시 클릭을 해야 조회수가 다시 1증가한다는 말..
            //조회수 증가 처리
            boardDao.increateViewcnt(bno);
            //조회수를 올린 시간 저장
            session.setAttribute("update_time_"+bno, current_time);
        }
    }
 
cs



BoardDAOImpl.java

1
2
3
4
5
    //조회수 증가 처리
    @Override
    public void increateViewcnt(int bno) throws Exception {
        sqlSession.update("board.increaseViewcnt", bno);
    }
cs



boardMapper.xml

1
2
3
4
5

<mapper namespace="board">

<!-- 조회수 증가 처리 -->
    <update id="increaseViewcnt">
//글번호에 해당하는 조회수를 +1하는 쿼리문
        update board set viewcnt=viewcnt+1
        where bno=#{bno}
    </update>

cs



        ModelAndView mav=new ModelAndView();
        mav.setViewName("board/view"); //포워딩할 뷰의 이름
        
        //view로 자료를 넘기기 위해 mav에 값들을 저장해서 view.jsp로 리턴시킴
        mav.addObject("dto"boardService.read(bno)); //상세보기를 한번 클릭하면 조회수를 1 증가시켜야 하므로 조회수 증가 구문


BoardServiceImpl.java

1
2
3
4
    @Override
    public BoardDTO read(int bno) throws Exception {
        return boardDao.read(bno);
    }
cs



BoardDAOImpl.java

1
2
3
4
5
    //게시물 조회
    @Override
    public BoardDTO read(int bno) throws Exception {
        return sqlSession.selectOne("board.read", bno); 
    }
cs



boardMapper.xml

1
2
3
4
5
6
7
8
<mapper namespace="board">
 
<select id="read" 
resultType="com.example.spring02.model.board.dto.BoardDTO">
//board테이블의 작성자와 member테이블의 유저아이디가 같고, 글번호가 클릭한 글번호와 같은
//글번호, 제목, 조회수, 날짜, 내용, 이름, 작성자를 검색.
        select bno,title,regdate,content,viewcnt,name,writer 
        from board b, member m
        where b.writer=m.userid and bno=#{bno}    
    </select>
cs




        mav.addObject("curPage", curPage);
        mav.addObject("search_option", search_option);
        mav.addObject("keyword", keyword);
        return mav; //  views/board/view.jsp로 넘어가서 출력됨
    }


cs




view.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
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!-- views/board/view.jsp -->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
<script src="${path}/include/js/common.js"></script>
 
<!-- ckeditor의 라이브러리를 사용하기 위해 추가하는 코드 -->
<script src="${path}/ckeditor/ckeditor.js"></script>

 
<script>
$(function(){ //자동으로 실행되는 코드
    //댓글 목록 출력
    listReply2();
    
    //댓글 쓰기
    $("#btnReply").click(function(){
        var replytext=$("#replytext").val(); //댓글 내용
        var bno="${dto.bno}"//게시물 번호
        var param="replytext": replytext, "bno": bno};
        //var param="replytext="+replytext+"&bno="+bno;
        $.ajax({
            type: "post",
            url: "${path}/reply/insert.do",
            data: param,
            success: function(){
                alert("댓글이 등록되었습니다.");
                listReply2(); //댓글 목록 출력
            }
        });
    });
    
    $(".fileDrop").on("dragenter dragover",function(e){
        //기본 효과 막음
        e.preventDefault();
    });
    $(".fileDrop").on("drop",function(e){
        e.preventDefault();
        //첫번째 첨부파일
        var files=e.originalEvent.dataTransfer.files;
        var file=files[0];
        //폼 데이터에 첨부파일 추가
        var formData=new FormData();
        formData.append("file",file);
        $.ajax({
            url: "${path}/upload/uploadAjax",
            data: formData,
            dataType: "text",
            processData: false,
            contentType: false,
            type: "post",
            success: function(data){
                //console.log(data);
                //data : 업로드한 파일 정보와 Http 상태 코드
                var fileInfo=getFileInfo(data);
                //console.log(fileInfo);
                var html="<a href='"+fileInfo.getLink+"'>"+
                    fileInfo.fileName+"</a><br>";
                html += "<input type='hidden' class='file' value='"
                    +fileInfo.fullName+"'>";
                $("#uploadedList").append(html);
            }
        });
    });
    
    
    //목록 버튼
    $("#btnList").click(function(){
        location.href="${path}/board/list.do";
    });
    //수정 버튼
    $("#btnUpdate").click(function(){
        //첨부파일 이름들을 폼에 추가
        var str="";
        $("#uploadedList .file").each(function(i){
            str+=
                "<input type='hidden' name='files["+i+"]' value='"
                +$(this).val()+"'>";
        });
        $("#form1").append(str);
        document.form1.action="${path}/board/update.do";
        document.form1.submit();
    });
    //삭제 버튼
    $("#btnDelete").click(function(){
        if(confirm("삭제하시겠습니까?")){
            document.form1.action="${path}/board/delete.do";
            document.form1.submit();
        }
    });
    
    listAttach();
    
    //첨부파일 삭제
    //id가 uploadedList인 태그의 class가 file_del인 태그 클릭
    $("#uploadedList").on("click",".file_del",function(e){
        var that=$(this); //클릭한 태그
//data: {fileName: $(this).attr("data-src") },        
        $.ajax({
            type: "post",
            url: "${path}/upload/deleteFile",
            data: "fileName="+    $(this).attr("data-src"),        
            dataType: "text",
            success: function(result){
                if(result=="deleted"){
                    //화면에서 태그 제거
                    that.parent("div").remove();
                }
            }
        });
    });
    
    $("#btnSave").click(function(){
        var str="";
        // uploadedList 내부의 .file 태그 각각 반복
        $("#uploadedList .file").each(function(i){
            console.log(i);
            //hidden 태그 구성
            str += 
"<input type='hidden' name='files["+i+"]'    value='"
    + $(this).val()+"'>";
        });
        //폼에 hidden 태그들을 붙임
        $("#form1").append(str);
        document.form1.submit();
    });
    
});
//댓글 목록 출력 함수
function listReply(){
    $.ajax({
        type: "get",
        url: "${path}/reply/list.do?bno=${dto.bno}",
        success: function(result){
            //result : responseText 응답텍스트(html)
            $("#listReply").html(result);
        }
    });
}
//타임스탬프값(숫자형)을 문자열 형식으로 변환
function changeDate(date){
    date = new Date(parseInt(date));
    year=date.getFullYear();
    month=date.getMonth();
    day=date.getDate();
    hour=date.getHours();
    minute=date.getMinutes();
    second=date.getSeconds();
    strDate = 
        year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
    return strDate;
}
 
function listReply2(){
    $.ajax({
        type: "get",
        contentType: "application/json",
        url: "${path}/reply/list_json.do?bno=${dto.bno}",
        success: function(result){
            console.log(result);
            var output="<table>";
            for(var i in result){
                var repl=result[i].replytext;
                repl = repl.replace(/  /gi,"&nbsp;&nbsp;");//공백처리
                repl = repl.replace(/</gi,"&lt;"); //태그문자 처리
                repl = repl.replace(/>/gi,"&gt;");
                repl = repl.replace(/\n/gi,"<br>"); //줄바꿈 처리
                
                output += "<tr><td>"+result[i].name;
                date = changeDate(result[i].regdate);
                output += "("+date+")";
                output += "<br>"+repl+"</td></tr>";
            }
            output+="</table>";
            $("#listReply").html(output);
        }
    });
}
 
//첨부파일 리스트를 출력하는 함수
function listAttach(){
    $.ajax({
        type: "post",
        url: "${path}/board/getAttach/${dto.bno}",
        success: function(list){
            // list : json
            //console.log(list);
            $(list).each(function(){
                var fileInfo=getFileInfo(this);
                //console.log(fileInfo);
                var html="<div><a href='"+fileInfo.getLink+"'>"
                    +fileInfo.fileName+"</a>&nbsp;&nbsp;";
                <c:if test="${sessionScope.userid == dto.writer}">    
                    html+="<a href='#' class='file_del' data-src='"
                        +this+"'>[삭제]</a></div>";
                </c:if>
                $("#uploadedList").append(html);
            });
        }
    });
}
 
</script>
 
<style>
<!--css로 스타일 시트를 적용-->
.fileDrop {
    width: 600px;
    height: 100px;
    border: 1px dotted gray;
    background-color: gray;
}
</style>
 
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>게시물 보기</h2>
<!-- 게시물을 작성하기 위해 컨트롤러의 insert.do로 맵핑 -->
<form id="form1" name="form1" method="post"
action="${path}/board/insert.do">
    <div>제목 <input name="title" id="title" size="80"
                    value="${dto.title}"
                    placeholder="제목을 입력하세요">
<!-- placeholder은 제목을 입력할 수 있도록 도움말을 출력함 -->
    </div>
    <div>조회수 : ${dto.viewcnt}    </div>
    <div style="width:800px;">
        내용 <textarea id="content" name="content"
rows="3" cols="80" 
placeholder="내용을 입력하세요">${dto.content}</textarea>
 
<!-- 마찬가지로 내용을 입력하도록 도움말을 출력함 -->
<script>
// ckeditor 적용
//id가 content인 태그 (글의 내용을 입력하는 태그)를 ck에디터를 적용한다는 의미
CKEDITOR.replace("content",{
    filebrowserUploadUrl: "${path}/imageUpload.do",
    height: "300px"
});
</script>

    </div>
    <div> 첨부파일을 등록하세요
        <div class="fileDrop"></div>
        <div id="uploadedList"></div>
    </div>

    <div style="width:700px; text-align:center;">
<!-- 수정,삭제에 필요한 글번호를 hidden 태그에 저장 -->    
        <input type="hidden" name="bno" value="${dto.bno}">
        
        <!-- 본인만 수정,삭제 버튼 표시 -->
        <c:if test="${sessionScope.userid == dto.writer}">
            <button type="button" id="btnUpdate">수정</button>
            <button type="button" id="btnDelete">삭제</button>
        </c:if>
        
        <!-- 목록은 본인이 아니어도 확인이 가능하게 할 예정 -->
        <button type="button" id="btnList">목록</button>
    </div>
</form>


<!-- 댓글 작성 -->
<div style="width:700px; text-align:center;">
     <c:if test="${sessionScope.userid != null }">
         <textarea rows="5" cols="80" id="replytext"
             placeholder="댓글을 작성하세요"></textarea>
         <br>
         <button type="button" id="btnReply">댓글쓰기</button>
     </c:if>
</div>
<!-- 댓글 목록 -->
<div id="listReply"></div>
 
</body>
</html>
cs


728x90
반응형
: