사용버전
스프링부트 버전 : 2.7.0 - mybatis
A 방법
1. Board 테이블
CREATE TABLE t_board( `board_seq` int auto_increment primary key COMMENT 't_board 테이블 pk', `board_type` varchar(255) COMMENT '게시판 종류', `title` varchar(255) COMMENT '제목', `contents` text COMMENT '내용', `reg_date` timestamp NOT null default current_timestamp() COMMENT '등록일' )ENGINE=InnoDB DEFAULT CHARSET=utf8;
boardType.code 아니라 boardType 의 값으로 설정한다.
<insert id="save" parameterType="kr.so.songjava.mvc.domain.dto.BoardDTO" useGeneratedKeys="true" keyProperty="boardSeq"> INSERT INTO T_BOARD (BOARD_TYPE, TITLE, CONTENTS, REG_DATE ) VALUES(#{boardType}, #{title}, #{contents}, NOW()) </insert> <update id="update" parameterType="kr.so.songjava.mvc.domain.dto.BoardDTO"> UPDATE T_BOARD SET BOARD_TYPE=#{boardType}, TITLE=#{title}, CONTENTS =#{contents} WHERE BOARD_SEQ =#{boardSeq} </update>
2. BaseCodeLabelEnum, BoardType enum class 생성
BaseCodeLabelEnum
/** * 기본 CodeLabelEnum */ public interface BaseCodeLabelEnum { /** 코드를 리턴 */ String code(); /** 라베를 리턴 */ String label(); }
BoardType
import lombok.AllArgsConstructor; import lombok.Getter; /**게시판 종류*/ public enum BoardType implements BaseCodeLabelEnum{ NOTICE("공지사항"), FAQ("자주묻는질문"), INQUIRY("1:1문의"), ; private String code; private String label; BoardType(String label) { this.code=name(); this.label=label; } @Override public String code() { return code; } @Override public String label() { return label; } }
3. BoardDTO boardType 변수 추가
@Data @AllArgsConstructor @NoArgsConstructor @Builder @ToString public class BoardDTO { private int boardSeq; private BoardType boardType; private String title; private String contents; }
4. Board boardType 변수 추가
import java.util.Date; import kr.so.songjava.mvc.domain.enums.BoardType; import lombok.Data; @Data public class Board { private int boardSeq; private BoardType boardType; private String title; private String contents; private Date regDate; }
5. BaseCodeLabelEnumJsonSerializer 클래스 추가
import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.springframework.http.MediaType; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import kr.so.songjava.mvc.domain.enums.BaseCodeLabelEnum; /** *JSON 변환시 BaseCodeLabelEnum 클래스에 대한 변환을 동일하게 처리 */ public class BaseCodeLabelEnumJsonSerializer extends JsonSerializer<BaseCodeLabelEnum>{ @Override public void serialize(BaseCodeLabelEnum value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException , JsonProcessingException { Map<String, Object> map=new HashMap<>(); map.put("code", value.code()); map.put("label", value.label()); jsonGenerator.writeObject(map); } }
6. WebMvcConfig ObjectMapper, MappingJackson2JsonView Bean 등록
@Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper =new ObjectMapper(); SimpleModule simpleModule =new SimpleModule(); simpleModule.addSerializer(BaseCodeLabelEnum.class, new BaseCodeLabelEnumJsonSerializer()); objectMapper.registerModule(simpleModule); return objectMapper; } @Bean public MappingJackson2JsonView mappingJackson2JsonView() { MappingJackson2JsonView jsonView=new MappingJackson2JsonView(); jsonView.setContentType(MediaType.APPLICATION_JSON_VALUE); jsonView.setObjectMapper(objectMapper()); return jsonView; }
출력값 :
{ "code": "SUCCESS", "message": null, "data": [ { "boardSeq": 1, "boardType": { "code": "NOTICE", "label": "공지사항" }, "title": "spring", "contents": null, "regDate": "2022-06-25T17:53:52.000+00:00" } ] }
====================================>====================================>====================================>=======
B 방법
BaseCodeLabelEnum 인터페이스 사용없이, 그리고
5~6번의 BaseCodeLabelEnumJsonSerializer 과 WebMvcConfig 에 빈 등록없이도 간단하게
다음과 같이 어노테이션 추가로 json 형식으로 목록을 불러 올수 있다.
그러나 등록/ 수정시 파라미터 객체 와 불러오기 시 객체를 다르게 설정해야 한다.
Enum 객체 전체 리턴
@JsonFormat(shape = Shape.OBJECT)
@AllArgsConstructor
@Getter
1. 유형 - 등록 및 수정시 BoardTypeInsert , BoardInsertDTO 를 사용
BaseCodeLabelEnum
a) BoardTypeInsert
/**게시판 등록/수정시 파라미터 enum*/ public enum BoardTypeInsert { NOTICE("공지사항"), FAQ("자주묻는질문"), INQUIRY("1:1문의"), ; private String code; private String label; BoardTypeInsert(String label) { this.code=name(); this.label=label; } }
b) BoardInsertDTO
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; /** 등록/수정시 파라미터 */ @Data @AllArgsConstructor @NoArgsConstructor @Builder @ToString public class BoardInsertDTO { private int boardSeq; private BoardTypeInsert boardType; private String title; private String contents; private String keyword; }
swagger
2. 유형 - 목록 불러올시 JSON 객체 포맷 (BoardType, BoardDTO, BoardSearchParameter)
BoardType
/**게시판 종류*/ @JsonFormat(shape = Shape.OBJECT) // 추가 @AllArgsConstructor @Getter public enum BoardType { NOTICE("NOTICE", "공지사항"), FAQ("FAQ" ,"자주묻는질문"), INQUIRY("INQUIRY" ,"1:1문의") ; //@JsonValue // 한개의 데이터만 가져올경우 @JsonFormat 제거후 해당 변수에 @JsonValue 어노테이션 추가 private String code; private String label; }
BoardDTO
/** 데이터를 가져올시 파라미터 */ @Data @AllArgsConstructor @NoArgsConstructor @Builder @ToString public class BoardDTO { private int boardSeq; private BoardType boardType; private String title; private String contents; private String keyword; }
==============================================================================================================================
3. 사용예
검색 처리 파라미터
파라미터 입력이 필요한 경우 1번 유형 BoardTypeInsert 를 사용하고, 반환 처리는 JSON 형식의 전환이 필요하므로 2번 유형을 사용한다.
BoardSearchParameter
@Data public class BoardSearchParameter { private String keyword; private List<BoardTypeInsert> boardTypes; //배열로 다중 검색 처리를 위해 , NOTICE, FAQ,INQUIRY }
컨트롤 사용 예
BoardApiController
/** 1.게시판 검색처리목록리턴 페이징 처리 x */ @GetMapping({"","/"}) @ApiOperation(value="목록조회", notes="1.게시판 검색처리목록리턴 페이징 처리 x") public BaseResponse<List<BoardDTO>> getList(@ApiParam BoardSearchParameter boardSearchParameter) throws Exception{ return new BaseResponse<List<BoardDTO>>(boardService.getList(boardSearchParameter)); } /**2.게시판 페이징 검색처리 목록리턴 - 페이징 검색처리 첫번째 방법 (WebMvcConfig 에 페이지 리졸버 등록 방식) */ @GetMapping({"/pageSearchList"}) @ApiOperation(value="목록조회 - WebMvcConfig 에 페이지 리졸버 등록 방식", notes="2.게시판 페이징 검색처리 목록리턴 ") public BaseResponse<List<BoardDTO>> paginationSearchList( @ApiParam MySQLPageRequest pageRequest, @ApiParam BoardSearchParameter parameter ) throws Exception{ log.info("1.pageRequest :" , pageRequest); PageRequestParameter<BoardSearchParameter> pageRequestParameter=new PageRequestParameter<BoardSearchParameter>(pageRequest, parameter); log.info("2.pageRequestParameter :" , pageRequestParameter); return new BaseResponse<List<BoardDTO>>(boardService.paginationSearchList(pageRequestParameter)); } /** 3. 게시판 페이징 검색처리 목록리턴 - 페이징 검색처리 두번째방법 (전체 갯수 구함) */ @GetMapping({"/pageSearchList2"}) @ApiOperation(value="목록조회 - MysqlPageMaker 사용 ", notes="3.게시판 페이징 검색처리 목록리턴 ") public BaseResponse<List<BoardDTO>> paginationSearchList2( @ApiParam MysqlPageMaker pageMaker ) throws Exception{ int totalCount =boardService.getTotalCount(pageMaker); pageMaker.setTotalCount(totalCount); log.info("1.pageMaker : {} " , pageMaker); log.info("2.totalCount : {}" , totalCount); return new BaseResponse<List<BoardDTO>>(boardService.paginationSearchList2(pageMaker), pageMaker); }
mybatis 에서 boardTypes 으로 사용
<select id="getList" resultType="kr.so.songjava.mvc.domain.entity.Board"> SELECT B.BOARD_SEQ, B.BOARD_TYPE, B.TITLE, B.REG_DATE FROM T_BOARD B <where> <if test="@org.apache.commons.lang3.StringUtils@isNotEmpty(keyword)"> AND B.TITLE LIKE CONCAT('%', #{keyword}, '%') </if> <if test="@org.apache.commons.lang3.ObjectUtils@isNotEmpty(boardTypes)"> AND B.BOARD_TYPE IN ( <foreach collection="boardTypes" item="value" separator=","> #{value} </foreach> ) </if> </where> ORDER BY B.REG_DATE DESC </select>
검색 참조 :
스프링부트 검색 조건 추가 Mybatis Commons-Lang3 라이브러리 IsNotEmpty 사용으로 검색
=>출력 형식 예
{ "code": "SUCCESS", "message": null, "data": [ { "boardSeq": 1, "boardType": { "code": "NOTICE", "label": "공지사항" }, "title": "spring", "contents": null, "regDate": "2022-06-25T17:53:52.000+00:00" } ] }
페이징 처리 파라미터 추가
{ "code": "SUCCESS", "message": null, "pageMaker": { "page": 1, "perPageNum": 10, "pageStart": 0, "totalCount": 1001, "startPage": 1, "endPage": 6, "prev": false, "next": true, "displayPageNum": 6, "tempEndPage": 101, "searchType": null, "keyword": null }, "displayPageNum": 0, "data": [ { "boardSeq": 256, "boardType": { "code": "FAQ", "label": "자주묻는질문" }, "title": "wJmTCEydrm", "contents": null, "regDate": "2022-06-26T03:38:59.000+00:00" }, { "boardSeq": 512, "boardType": { "code": "FAQ", "label": "자주묻는질문" }, "title": "JQvHGGREkU", "contents": null, "regDate": "2022-06-26T03:38:59.000+00:00" }, { "boardSeq": 768, "boardType": { "code": "FAQ", "label": "자주묻는질문" }, "title": "fPwypLLrpP", "contents": null, "regDate": "2022-06-26T03:38:59.000+00:00" } ] }
* @JsonValue 사용할 경우 경우
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat.Shape; import com.fasterxml.jackson.annotation.JsonValue; import lombok.AllArgsConstructor; import lombok.Getter; /**게시판 종류*/ //@JsonFormat(shape = Shape.OBJECT) // 추가 @AllArgsConstructor @Getter public enum BoardType { NOTICE("NOTICE", "공지사항"), FAQ("FAQ" ,"자주묻는질문"), INQUIRY("INQUIRY" ,"1:1문의") ; @JsonValue // 추가 private String code; private String label; }
=>출력 형식 예
{ "code": "SUCCESS", "message": null, "pageMaker": { "page": 1, "perPageNum": 10, "pageStart": 0, "totalCount": 1001, "startPage": 1, "endPage": 6, "prev": false, "next": true, "displayPageNum": 6, "tempEndPage": 101, "searchType": null, "keyword": null }, "displayPageNum": 0, "data": [ { "boardSeq": 256, "boardType": "FAQ", "title": "wJmTCEydrm", "contents": null, "regDate": "2022-06-26T03:38:59.000+00:00" }, { "boardSeq": 512, "boardType": "FAQ", "title": "JQvHGGREkU", "contents": null, "regDate": "2022-06-26T03:38:59.000+00:00" } ] }
C 방법
1. ResponseEntity 사용
2. Map<String, Object> LinkedHashMap 사용
3. ObjectMapper 객체를 담은 후 반환
코드양이 늘어는 것 같아 보이지만, 다른 클래스에 추가 설정도 없고,
반환처리 DTO 및 입력 처리 등 기타 특별한 클래스를들을 만들어 줄 필요도 없고,
json 반화처리에서 제외할 멤버 변수 에 @JsonIgnore 어노테이션만 붙여주면 된다.
@JsonIgnore @ApiModelProperty(hidden=true) private int pageStart; /** 하단 페이징 << 1 2 3 4 5 6 7 8 9 10 >> */ @JsonIgnore @ApiModelProperty(hidden=true) private int totalCount; //전체 개수
또한 필요한 객체를 map 으로 넣고 빼기가 쉽다.
개발자들마다 처리방식들이 다양해서 A , B, C 등 다른 여러 방법들이 많이 있는 것 같은데,
개인적인 생각으로는 쉽게 접근할 수 있는 방법 같아서 나는 C 방법을 사용한다.
/** 1-2 . ObjectMapper 와 @ResponseBody 를 통한 게시판 검색처리목록리턴 페이징 처리 x */ @GetMapping("/om/list1") @ApiOperation(value="ObjectMapper 목록조회 1", notes="2.게시판 검색처리목록리턴 페이징 처리 x") @ResponseBody public String getObjectMaperJsonList1(@ApiParam BoardSearchParameter boardSearchParameter) throws Exception{ List<BoardDTO> boardList =boardService.getList(boardSearchParameter); ObjectMapper objectMapper=new ObjectMapper(); String json=objectMapper.writeValueAsString(boardList); return json; } /** 1-3 . ObjectMapper 와 @ResponseBody 를 통한 게시판 검색처리목록리턴 페이징 처리 x */ @GetMapping("/om/list2") @ApiOperation(value="ObjectMapper 목록조회 1", notes="3.게시판 검색처리목록리턴 페이징 처리 x") @ResponseBody public ResponseEntity<?> getObjectMaperJsonList2(@ApiParam BoardSearchParameter boardSearchParameter) throws Exception{ List<BoardDTO> boardList =boardService.getList(boardSearchParameter); ObjectMapper objectMapper=new ObjectMapper(); String json=objectMapper.writeValueAsString(boardList); return ResponseEntity.status(HttpStatus.OK).body(json); } /** * ★★★★★★ * 1. ResponseEntity<?> 사용 * 2. Map<String, Object> 사용 * 3. ObjectMapper 객체를 담은 후 반환 * * * 1-3 . ObjectMapper 와 @ResponseBody 를 통한 게시판 검색처리목록리턴 페이징 처리 x */ @GetMapping("/om/list3") @ApiOperation(value="ObjectMapper 목록조회 3", notes="4.게시판 검색처리목록리턴 페이징 처리 x") @ResponseBody public ResponseEntity<?> getObjectMaperJsonList3(@ApiParam BoardSearchParameter boardSearchParameter) throws Exception{ //1.map 객체 생성 - LinkedHashMap 입력순으로 출력 Map<String, Object> map=new LinkedHashMap<>(); //2.json 반환 처리할 데이터 가져오기 List<BoardDTO> boardList =boardService.getList(boardSearchParameter); //3. map 에 넣게 map.put("code", BaseResponseCode.SUCCESS); map.put("boardList", boardList); //4. objectMapper 로 json 전환처리 ObjectMapper objectMapper=new ObjectMapper(); String json=objectMapper.writeValueAsString(map); //5. ResponseEntity 로 json 반환 return ResponseEntity.status(HttpStatus.OK).body(json); } /** 3-1 * * . 게시판 페이징 검색처리 목록리턴 - 페이징 검색처리 두번째방법 (전체 갯수 구함) * * ★★★★★★ * 1. ResponseEntity<?> 사용 * 2. Map<String, Object> 사용 * 3. ObjectMapper 객체를 담은 후 반환 * http://localhost:8080/api/board/pageSearchList2?page=2&searchType=INQUIRY */ @GetMapping("/om/list/pagination") @ApiOperation(value="목록조회 - MysqlPageMaker 사용 ObjectMapper ", notes="" + "1. ResponseEntity<?> 사용" + "2. Map<String, Object> 사용" + "3. ObjectMapper 객체를 담은 후 반환") public ResponseEntity<?> omPagination( @ApiParam MysqlPageMaker pageMaker ) throws Exception{ //1.map 객체 생성 - LinkedHashMap 입력순으로 출력 Map<String, Object> map=new LinkedHashMap<>(); //2.json 반환 처리할 데이터 가져오기 int totalCount =boardService.getTotalCount(pageMaker); pageMaker.setTotalCount(totalCount); List<BoardDTO> boardList=boardService.paginationSearchList2(pageMaker); //3. map 에 넣게 map.put("code", BaseResponseCode.SUCCESS); map.put("pageMaker", pageMaker); map.put("data", boardList); //4. objectMapper 로 json 전환처리 ObjectMapper objectMapper=new ObjectMapper(); String json=objectMapper.writeValueAsString(map); //5. ResponseEntity 로 json 반환 return ResponseEntity.status(HttpStatus.OK).body(json); } /** 3-2 코드 간소화 * * . 게시판 페이징 검색처리 목록리턴 - 페이징 검색처리 두번째방법 (전체 갯수 구함) * * ★★★★★★ * 1. ResponseEntity<?> 사용 * 2. Map<String, Object> 사용 * 3. ObjectMapper 객체를 담은 후 반환 * http://localhost:8080/api/board/om/list/pagination?page=2&searchType=INQUIRY */ @GetMapping("/om/list/pagination2") @ApiOperation(value="코드 간소화 목록조회 - MysqlPageMaker 사용 ObjectMapper ", notes="" + "1. ResponseEntity<?> 사용" + "2. Map<String, Object> 사용" + "3. ObjectMapper 객체를 담은 후 반환") public ResponseEntity<?> omPagination2(@ApiParam MysqlPageMaker pageMaker) throws Exception{ //1.map 객체 생성 - LinkedHashMap 입력순으로 출력 Map<String, Object> map=new LinkedHashMap<>(); //2.전체 갯수 구하기 pageMaker.setTotalCount(boardService.getTotalCount(pageMaker)); //3. map 에 넣게 map.put("code", BaseResponseCode.SUCCESS); map.put("pageMaker", pageMaker); map.put("data", boardService.paginationSearchList2(pageMaker)); //4. objectMapper 로 json 전환처리 후 ResponseEntity 로 json 반환 return ResponseEntity.status(HttpStatus.OK).body(new ObjectMapper().writeValueAsString(map)); }
추가적으로 프론트에서 페이징 처리는 다음과 같은 css, 자바스트립트 참초
css
ul#pagingul { text-align: center; display: inline-block; border: 1px solid #ccc; border-right: 0; padding-left: 0rem; } ul#pagingul li { text-align: center; float: left; list-style: none; outline: none; } ul#pagingul li a { display: block; font-size: 14px; padding: 9px 12px; border-right: solid 1px #ccc; box-sizing: border-box; color: #000; text-decoration: none; outline: none; } ul#pagingul li.on { background: #000; } ul#pagingul li.on a { color: #fff; outline: none; }
js
// 페이징 표시 함수 //function(totalData, dataPerPage, pageCount, currentPage) paging: function(){ // console.log("currentPage : " + currentPage); totalPage = Math.ceil(totalData / dataPerPage); //총 페이지 수 if (totalPage < pageCount) { pageCount = totalPage; } let pageGroup = Math.ceil(currentPage / pageCount); // 페이지 그룹 let last = pageGroup * pageCount; //화면에 보여질 마지막 페이지 번호 if (last > totalPage) { last = totalPage; } let first = last - (pageCount - 1); //화면에 보여질 첫번째 페이지 번호 let next = last + 1; let prev = first - 1; let pageHtml = ""; if (prev > 0) { pageHtml += "<li><a href='#' id='prev'> « </a></li>"; } //페이징 번호 표시 for (var i = first; i <= last; i++) { if (currentPage == i) { pageHtml += "<li class='on'><a href='#' id='" + i + "'>" + i + "</a></li>"; } else { pageHtml += "<li><a href='#' id='" + i + "'>" + i + "</a></li>"; } } if (last < totalPage) { pageHtml += "<li><a href='#' id='next'> » </a></li>"; } document.querySelector("#pagingul").innerHTML = pageHtml; // let displayCount = ""; // displayCount = "현재 1 - " + totalPage + " (" + currentPage + "페이지) / " + totalData + "건"; // document.querySelector("#displayCount").innerText = displayCount; //페이징 번호 클릭 이벤트 const paginationClass = document.querySelectorAll("#pagingul li a"); for (let i = 0; i < paginationClass.length; i++) { paginationClass[i].addEventListener("click", function(e) { e.preventDefault(); let $id = this.getAttribute("id") selectedPage = this.innerText; console.log("선택한 페이지 ", selectedPage); if ($id == "next") selectedPage = next; if ($id == "prev") selectedPage = prev; comment.list(selectedPage); }); } },
전체 샘플 코드 예
let totalData; //총 데이터 수 let dataPerPage; //한 페이지에 나타낼 글 수 let pageCount; //페이징 개수 let currentPage; //현재 페이지 let comment = { init: function() { //this.list(); $("#commentAdd").on("click", function(e){ comment.commentAdd(); }); $(".comment-delete").on("click", function(e){ comment.commentDelete(e.target); }); $("#flexSwitchCheckChecked").on("click", function(e){ $("#comment-add-list").toggle(); $("#pagingul").toggle(); }); }, list: function(page) { if (page == undefined || page == "") { page = 1; } const data= { 'nttId':$("#nttId").val(), 'page': ""+page, 'subPageIndex':page } //console.log(data); $.ajax({ url:'/portal/comment/selectArticleCommentList.do', type:'post', contentType:'application/json;charset=UTF-8', data:JSON.stringify(data), dataType:"json", success:function(res){ console.log(res); totalData = res.resultCnt; dataPerPage = res.paginationInfo.recordCountPerPage; pageCount = res.paginationInfo.totalPageCount; currentPage = res.paginationInfo.currentPageNo; //{item.wrterId} //console.log(totalData); //console.log(dataPerPage); //console.log(pageCount); //console.log(currentPage); const LoginUniqId=$("#LoginUniqId").val(); $("#totalData").text('댓글('+totalData+")"); if (res.resState=="success") { let html = ""; res.resultList.forEach(function(item) { html +=` <div class="col-md-12 mb-2" > <div class="card p-3 "> <div class="d-flex justify-content-between align-items-left"> <div class="user d-flex flex-row align-items-left"> <span><small class="font-weight-bold comment-user"><b style="color:#000">${item.frstRegisterNm}</b></small> <small class="font-weight-bold comment-text" id="comment-text-${item.commentNo}" >${item.commentCn}</small> </span> </div> <small>${item.frstRegisterPnttm}</small> </div> <div id="update-comment-textarea-${item.commentNo}" class="mt-3" style="display:none;"> <textarea class="form-control update-comment-textarea" data-id="updateComment-${item.commentNo}" onkeyup="fn_checkByte(this)" >${item.commentCn}</textarea> <sup class="supComment-left" id="sup-updateComment-${item.commentNo}"></sup> </div> `; var html2 =` <div class="action mt-2 " style="text-align:right" > <div class="reply px-4" style="display:inherit"> <div class="icons align-items-center comment-btn" id="commentUpdateFormBtn-${item.commentNo}" data-id='${item.commentNo}' onclick="comment.commentUpdateForm(this)"> <i class="fa fa-trash text-default"></i> 수정 </div> <div class="icons align-items-center comment-btn" style="display:none;" id="commentUpdateBtn-${item.commentNo}" data-id='${item.commentNo}' onclick="comment.commentUpdate(this)"> <i class="fa fa-trash text-default success"></i> 수정 하기 </div> <div class="icons align-items-center comment-btn comment-delete" style=" margin-left: 10px;" data-id='${item.commentNo}' onclick="comment.commentDelete(this)"> <i class="fa fa-trash text-default"></i> 삭제 </div> </div> ` ; if(item.wrterId==LoginUniqId){ html +=html2; } html +=` </div> </div> </div> `; }); $("#comment-add-list").html(html); } //페이징 표시 호출 comment.paging(); //삭제 이벤트 추가 /* let fileDeletes=document.querySelectorAll(".fileDeleteBtn"); for(let i=0; i<fileDeletes.length; i++){ fileDeletes[i].addEventListener("click", function(e){ fileList.fileDelete(e.target.getAttribute("data-id")); }); } */ }, error:function(res){ console.log("error"); console.log(res); } }); }, commentAdd:function(){ const commentContent =$("#commentContent").val(); const nttId=$("#nttId").val(); if(commentContent==""){ tWarning("댓글을 입력해 주세요."); $("#commentContent").focus(); return; } const param={ "commentCn":commentContent, "nttId":nttId } $.ajax({ url:'/portal/comment/insertArticleComment.do', type:'post', contentType:'application/json;charset=UTF-8', data:JSON.stringify(param), success:function(res){ if(res=="success"){ $("#commentContent").val(""); $("#sup-commentContent").html("[0자 / 150]"); comment.list(); } }, error:function(res){ console.log("error"); console.log(res); } }); }, commentDelete:function(e){ if(confirm("정말 삭제 하시겠습니까?")){ const commentNo =$(e).attr("data-id"); console.log(commentNo); const param={ "commentNo":commentNo } $.ajax({ url:'/portal/comment/deleteArticleComment.do', type:'post', contentType:'application/json;charset=UTF-8', data:JSON.stringify(param), success:function(res){ if(res=="success"){ comment.list(); tInfo("삭제 처리 되었습니다."); } }, error:function(res){ console.log("error"); console.log(res); } }); } }, commentUpdateForm:function(e){ const commentNo =$(e).attr("data-id"); // console.log(commentNo); $("#comment-text-"+commentNo).css("display","none"); $("#update-comment-textarea-"+commentNo).show(); $("#commentUpdateFormBtn-"+commentNo).css("display","none"); $("#commentUpdateBtn-"+commentNo).show(); $("#update-comment-textarea-"+commentNo +" textarea").focus(); } , //업데이트 처리 commentUpdate:function(e){ const commentNo =$(e).attr("data-id"); const commentCn=$("#update-comment-textarea-"+commentNo +" textarea").val(); const nttId=$("#nttId").val(); if(commentCn==""){ tWarning("내용을 입력해 주세요."); $("#update-comment-textarea-"+commentNo +" textarea").focus(); return; } const param={ "commentCn":commentCn, "commentNo":commentNo, "nttId":nttId } $.ajax({ url:'/portal/comment/updateArticleComment.do', type:'post', contentType:'application/json;charset=UTF-8', data:JSON.stringify(param), success:function(res){ if(res=="success"){ $("#comment-text-"+commentNo).css("display","block"); $("#update-comment-textarea-"+commentNo).hide(); $("#commentUpdateFormBtn-"+commentNo).css("display","inline"); $("#commentUpdateBtn-"+commentNo).hide(); $("#comment-text-"+commentNo).text(commentCn); tInfo("업데이트 처리 되었습니다.") } }, error:function(res){ console.log("error"); console.log(res); } }); ; } , flexSwitchCheckChecked:function(){ }, // 페이징 표시 함수 //function(totalData, dataPerPage, pageCount, currentPage) paging: function(){ // console.log("currentPage : " + currentPage); totalPage = Math.ceil(totalData / dataPerPage); //총 페이지 수 if (totalPage < pageCount) { pageCount = totalPage; } let pageGroup = Math.ceil(currentPage / pageCount); // 페이지 그룹 let last = pageGroup * pageCount; //화면에 보여질 마지막 페이지 번호 if (last > totalPage) { last = totalPage; } let first = last - (pageCount - 1); //화면에 보여질 첫번째 페이지 번호 let next = last + 1; let prev = first - 1; let pageHtml = ""; if (prev > 0) { pageHtml += "<li><a href='#' id='prev'> « </a></li>"; } //페이징 번호 표시 for (var i = first; i <= last; i++) { if (currentPage == i) { pageHtml += "<li class='on'><a href='#' id='" + i + "'>" + i + "</a></li>"; } else { pageHtml += "<li><a href='#' id='" + i + "'>" + i + "</a></li>"; } } if (last < totalPage) { pageHtml += "<li><a href='#' id='next'> » </a></li>"; } document.querySelector("#pagingul").innerHTML = pageHtml; // let displayCount = ""; // displayCount = "현재 1 - " + totalPage + " (" + currentPage + "페이지) / " + totalData + "건"; // document.querySelector("#displayCount").innerText = displayCount; //페이징 번호 클릭 이벤트 const paginationClass = document.querySelectorAll("#pagingul li a"); for (let i = 0; i < paginationClass.length; i++) { paginationClass[i].addEventListener("click", function(e) { e.preventDefault(); let $id = this.getAttribute("id") selectedPage = this.innerText; console.log("선택한 페이지 ", selectedPage); if ($id == "next") selectedPage = next; if ($id == "prev") selectedPage = prev; comment.list(selectedPage); }); } }, } //textarea 바이트 수 체크하는 함수 function fn_checkByte(obj){ var id=$(obj).attr("data-id"); var strValue = obj.value; var strLen = strValue.length; var str = ""; str += '[' + strLen + '자 / 150]'; if(strLen > 149){ alert("제한 글자를 초과하였습니다."); $(obj).val(strValue.substring(0, 148)); } $("#sup-"+id).html(str); } comment.init();
소스 :
댓글 ( 5)
댓글 남기기