| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719 |
- $(function() {
- Comment.init();
- Comment.list();
- // 댓글입력 창 높이 자동조정
- $.each($('textarea[data-autoresize]'), function () {
- $(this).on('keyup input', function () {
- Comment.resizeTextarea(this);
- }).removeAttr('data-autoresize');
- });
- });
- const Comment =
- {
- callback: "",
- listID: "commentList",
- writeID: "commentWrite",
- method: {write: "store", modify: "update", reply: "reply"},
- mode: "", // write, modify, reply
- code: "",
- bid: 0,
- pid: 0,
- cid: 0,
- total: 0,
- page: 0,
- perPage: 0,
- minLength: 0,
- maxLength: 0,
- listForm: null,
- writeForm: null,
- saveHtml: null,
- saveBefore: null,
- useEditor: false,
- // 댓글 기본설정
- init: function()
- {
- this.listForm = document.getElementById(this.listID);
- // 댓글 목록
- if(this.listForm !== null) {
- this.code = document.getElementById("code").value;
- this.bid = document.getElementById("bid").value;
- this.pid = document.getElementById("pid").value;
- this.callback = (BASE_URL + "/board/" + String(this.code) + "/" + String(this.pid) + "/comment");
- }
- this.writeForm = document.getElementById(this.writeID);
- // 댓글 입력창
- if(IS_USER && this.writeForm !== null) {
- let form = this.writeForm.getElementsByTagName("form")[0];
- this.minLength = Number(form.elements["min_length"].value);
- this.maxLength = Number(form.elements["max_length"].value);
- this.saveHtml = this.writeForm.innerHTML; // 댓글 입력 창 저장
- this.reset(form);
- }
- },
- // 초기화
- reset: function(form)
- {
- this.mode = "write";
- this.cid = 0;
- this.saveBefore = null;
- if (typeof form !== "undefined") {
- form.elements["mode"].value = "write";
- form.elements["cid"].value = "";
- form.elements["length"].value = "0";
- form.elements["content"].value = "";
- if (typeof form.elements["is_secret"] !== "undefined") {
- form.elements["is_secret"].checked = false;
- }
- let $length = form.getElementsByClassName("comment-length");
- if ($length.length > 0) {
- $length[0].innerText = "0";
- }
- form.elements["btn_comment_submit"].disabled = false;
- form.elements["btn_comment_cancel"].disabled = false;
- this.resizeTextarea(form.elements["content"]);
- }
- if (this.useEditor) {
- tinyMCE.activeEditor.setContent("");
- }
- },
- // 댓글 목록 새로고침
- refresh: function() {
- this.list(this.page);
- },
- // textarea 높이 조절
- resizeTextarea: function(e)
- {
- $(e).css('height', 'auto').css('height', e.scrollHeight + (e.offsetHeight - e.clientHeight));
- },
- // 댓글 영역으로 스크롤 이동
- scrollReplyNow: function(cid)
- {
- if (typeof cid != "undefined" && cid) {
- let offset = $('#comment_' + cid).offset();
- if(typeof offset != "undefined"){
- window.document.body.scrollTop = offset.top;
- }
- }
- },
- // 댓글 영역 강조
- focusCommentBox: function(cid)
- {
- if (typeof cid != "undefined" && cid) {
- $('#comment_' + cid).effect('highlight', {
- 'color': '#FFFFC6'
- }, 1500);
- }
- },
- // 금지 단어 확인
- filterSpamKeyword: function (content)
- {
- let ret = "";
- $.ajax({
- headers: {'X-CSRF-TOKEN': CSRF},
- url: (BASE_URL + '/api/filterSpamKeyword'),
- type: 'POST',
- dataType: 'JSON',
- async: false,
- cache: false,
- data: {subject: "", content: content},
- success: function (res) {
- ret = res.content;
- },
- error: function (xhr, status, err) {
- procErrorEvent(xhr, status, err);
- }
- });
- return ret;
- },
- // 글자수 확인
- checkByte: function(e)
- {
- let form = e.form;
- if (typeof form !== "undefined") {
- let hiddenInputLength = form.elements["length"];
- let spanInputLength = form.getElementsByClassName("comment-length")[0];
- let textarea = form.elements["content"];
- let length = textarea.value.length;
- let tinymce = form.getElementsByTagName("iframe");
- if (this.useEditor) {
- let editor = tinymce[0].contentDocument.body;
- length = editor.innerText.trim().length;
- if (this.maxLength > 0 && length > this.maxLength) {
- editor.innerHTML = editor.innerHTML.substr(0, this.maxLength);
- length = editor.innerHTML.length;
- }
- } else {
- if (this.maxLength > 0 && length > this.maxLength) {
- textarea.value = textarea.value.substr(0, this.maxLength);
- length = textarea.value.length;
- }
- }
- // 글자 수 저장
- hiddenInputLength.value = length;
- // 글자 수 출력
- if (typeof spanInputLength !== "undefined") {
- spanInputLength.innerText = length;
- }
- }
- },
- // 목록
- list: function(page, cid, message, sort) {
- if (!page || page < 1 || page === Number.POSITIVE_INFINITY) {
- page = 1;
- }
- let listURL = (this.callback + "?page=" + page);
- if (sort) {
- listURL += "&sort=" + sort;
- }
- $('#' + this.listID).load(listURL, function (response, status, xhr) { // HTML 형식으로 뎃글목록 출력
- let total = this.children.total.value;
- let page = this.children.page.value;
- let perPage = this.children.per_page.value;
- if (total) { // 댓글 수 표시
- document.getElementById("txtCommentRows").innerText = total;
- document.getElementById("txtPostCommentCnt").innerText = total;
- }
- if (message) { // 알림이 있을 경우 alert
- alert(message);
- }
- Comment.page = page;
- Comment.perPage = perPage;
- Comment.total = total;
- Comment.focusCommentBox(cid);
- Comment.scrollReplyNow(cid);
- });
- return false;
- },
- // 댓글 등록/수정
- submit: function(e)
- {
- e.blur();
- e.disabled = true;
- $(e.form).validate({
- onkeyup: false,
- onclick: false,
- onfocusout: false,
- rules: {
- mode: {required: true, contains: ["write", "modify", "reply"]},
- content: {
- required: true,
- normalizer: function (value) {
- if(Comment.useEditor) {
- return tinyMCE.activeEditor.getContent({format: "text"}).trim();
- }else{
- return value.trim();
- }
- },
- minlength: Comment.minLength,
- maxlength: Comment.maxLength
- },
- is_secret: {number: true}
- },
- messages: {
- mode: {required: "댓글 처리중 오류가 발생하였습니다.", contains: "잘못된 요청입니다."},
- content: {required: "댓글을 입력해주세요."},
- is_secret: {number: true}
- },
- showErrors: function (errorMap, errorList) {
- if (this.numberOfInvalids()) {
- setTimeout(function() {
- alert(errorList[0].message);
- errorList[0].element.focus();
- if(Comment.useEditor) {
- tinyMCE.activeEditor.getBody().scrollIntoView();
- }else{
- window.scrollTo({top: errorList[0].element.offsetTop});
- }
- }, 100);
- e.disabled = false;
- }
- },
- submitHandler: function (form)
- {
- let mode = form.elements["mode"].value;
- let content = form.elements["content"].value;
- let spamKeyword = Comment.filterSpamKeyword(content); // 금지 단어 검사
- if (spamKeyword) {
- alert("내용에 금지어 ('" + spamKeyword + "')가 포함 되어있습니다.");
- form.elements["content"].focus();
- return false;
- }
- // 댓글 등록
- let formData = $(form).serializeArray();
- formData.push({name: "bid", value: Comment.bid});
- formData.push({name: "pid", value: Comment.pid});
- // 버튼 비활성화
- form.elements["btn_comment_submit"].disabled = true;
- form.elements["btn_comment_cancel"].disabled = true;
- $.ajax({
- headers: {'X-CSRF-TOKEN': CSRF},
- url: (Comment.callback + "/" + Comment.method[mode]),
- type: 'post',
- cache: false,
- async: true,
- data: formData,
- dataType: 'json',
- beforeSend: function (xhr) {
- if (!loginCheck()) {
- xhr.abort();
- }
- showLoading();
- },
- success: function (res) {
- if (res.success) {
- let page = (mode === "write" ? Math.ceil((Number(Comment.total) + 1) / Comment.perPage) : Comment.page);
- Comment.list(page, res.commentID);
- }else{
- alert(res.message);
- }
- Comment.reset(form);
- },
- error: function (xhr, status, err) {
- procErrorEvent(xhr, status, err);
- },
- complete: function() {
- hideLoading();
- }
- });
- }
- });
- $(e.form).submit();
- },
- // 수정, 답글
- write: function(e, mode)
- {
- if(!loginCheck()) {
- return false;
- }
- if(typeof e === "undefined") {
- return false;
- }
- if(typeof mode == "undefined" || mode == null || !mode) {
- return false;
- }
- if($.inArray(mode, ["write", "modify", "reply"]) < 0) {
- return false;
- }
- let listForm = e.form; // 댓글 영역
- let writeForm = null;
- let cid = (listForm.elements["cid"].value || 0);
- let mediaFormID = ("#fCommentWrite_" + cid);
- let $saveBefore = $(this.saveBefore); // 이전 답글
- let $target = $(mediaFormID); // 현재 답글
- // 답글
- if(mode === "reply") {
- if(this.cid === cid && this.saveBefore === mediaFormID && this.mode === mode) {
- $saveBefore.toggle(); // 기존 댓글 창 보기/숨김
- }else{
- $saveBefore.html("");
- $target.show();
- writeForm = $target.html(this.saveHtml).get(0).firstElementChild;
- writeForm.elements["mode"].value = mode;
- writeForm.elements["cid"].value = cid;
- }
- }
- // 수정
- if(mode === "modify") {
- $saveBefore.html("");
- $target.show();
- writeForm = $target.html(this.saveHtml).get(0).firstElementChild;
- writeForm.elements["content"].value = listForm.content.value; // 내용 대입
- if(typeof writeForm.elements["is_secret"] !== "undefined") {
- writeForm.elements["is_secret"].checked = Boolean(listForm.is_secret.value === '1'); // 비밀글 체크
- }
- writeForm.elements["mode"].value = mode;
- writeForm.elements["cid"].value = cid;
- // 입력창 높이 조절
- this.resizeTextarea(writeForm.elements["content"]);
- }
- // textarea ID 할당
- if(writeForm) {
- writeForm.elements["content"].setAttribute("id", writeForm.elements["content"].name + "_" + cid);
- // 1:1 문의 게시판은 에디터를 사용
- if(this.useEditor) {
- tinyMCE.init(tinyMCE.activeEditor.settings);
- tinyMCE.EditorManager.execCommand('mceAddEditor', true, writeForm.elements["content"]);
- }
- // 글자 수 확인
- this.checkByte(writeForm.elements["content"]);
- }
- this.mode = mode;
- this.cid = cid;
- this.saveBefore = mediaFormID; // 현재 영역
- },
- // 댓글 삭제
- delete: function(e)
- {
- e.blur();
- if (confirm("정말 삭제 하시겠습니까?")) {
- let bid = e.form.bid.value;
- let pid = e.form.pid.value;
- let cid = e.form.cid.value;
- $.ajax({
- url: (this.callback + "/delete"),
- type: 'delete',
- cache: false,
- async: false,
- data: {bid: bid, pid: pid, cid: cid, _method: "delete"},
- dataType: 'json',
- beforeSend: function(xhr) {
- if(!loginCheck()) {
- xhr.abort();
- }
- },
- success: function (res) {
- if (res.success) {
- alert("댓글이 삭제되었습니다.");
- Comment.refresh();
- }else{
- alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
- }
- Comment.reset();
- },
- error: function (xhr, status, err) {
- procErrorEvent(xhr, status, err);
- }
- });
- }
- return false;
- },
- // 댓글 신고
- blame: function(e)
- {
- e.blur();
- if(!loginCheck()) {
- return false;
- }
- let bid = e.form.bid.value;
- let pid = e.form.pid.value;
- let cid = e.form.cid.value;
- // 신고 접수 유효성
- $("#fCommentBlame").validate({
- onkeyup: false,
- onclick: false,
- onfocusout: false,
- rules: {
- blame_type: {required: true, contains: ['1', '2', '3', '4', '5', '6', '7', '8', '9']},
- blame_reason: {required: true, normalizer: function (value) {return $.trim(value);}, maxlength: 1000}
- },
- messages: {
- blame_type: {required: "신고 유형을 선택해주세요.", contains: "잘못된 요청입니다."},
- blame_reason: {required: "신고 내용을 입력해주세요.", maxlength: "신고 내용은 {0}자까지 입력 가능합니다."}
- },
- showErrors: function (errorMap, errorList) {
- if (this.numberOfInvalids()) {
- alert(errorList[0].message);
- errorList[0].element.focus();
- }
- },
- submitHandler: function(form) {
- if (confirm("신고를 접수하시겠습니까?")) {
- $.ajax({
- url: (this.callback + "/blame"),
- type: 'post',
- cache: false,
- async: false,
- data: {bid: bid, pid: pid, cid: cid, type: form.blame_type.value, reason: form.blame_reason.value},
- dataType: 'json',
- beforeSend: function (xhr) {
- if(!loginCheck()) {
- xhr.abort();
- }
- },
- success: function (res) {
- form.blame_type.value = "";
- form.blame_reason.value = "";
- if (res.success) {
- alert("감사합니다. 신고가 접수되었습니다. 이용 규칙을 위반한 것으로 확인되면 댓글이 삭제됩니다.");
- }else{
- alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
- }
- $('div.modal').modal('hide');
- },
- error: function (xhr, status, err) {
- procErrorEvent(xhr, status, err);
- }
- });
- }
- }
- });
- },
- // 추천
- like: function (e) {
- let bid = e.form.bid.value;
- let pid = e.form.pid.value;
- let cid = e.form.cid.value;
- let type = e.value;
- let active = Number(e.dataset.active);
- $.ajax({
- url: (this.callback + "/like"),
- type: 'post',
- cache: false,
- async: false,
- data: {bid: bid, pid: pid, cid: cid, type: type},
- dataType: 'json',
- beforeSend: function (xhr) {
- if (!loginCheck()) {
- xhr.abort();
- }
- },
- success: function (res) {
- if (res.success) {
- Comment.toggleLike(cid, 1, !active);
- } else {
- alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
- }
- },
- error: function (xhr, status, err) {
- procErrorEvent(xhr, status, err);
- }
- });
- },
- // 비추천
- dislike: function (e) {
- let bid = e.form.bid.value;
- let pid = e.form.pid.value;
- let cid = e.form.cid.value;
- let type = e.value;
- let active = Number(e.dataset.active);
- $.ajax({
- url: (this.callback + "/dislike"),
- type: 'post',
- cache: false,
- async: false,
- data: {bid: bid, pid: pid, cid: cid, type: type},
- dataType: 'json',
- beforeSend: function (xhr) {
- if (!loginCheck()) {
- xhr.abort();
- }
- },
- success: function (res) {
- if (res.success) {
- Comment.toggleLike(cid, 2, !active);
- } else {
- alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
- }
- },
- error: function (xhr, status, err) {
- procErrorEvent(xhr, status, err);
- }
- });
- },
- // 댓글 입력 취소
- cancel: function ($this) {
- if ($this.form.mode.value === "write") {
- $this.form.elements["mode"].value = "write";
- $this.form.elements["cid"].value = "";
- $this.form.elements["length"].value = "0";
- $this.form.elements["content"].value = "";
- if (typeof $this.form.elements["is_secret"] !== "undefined") {
- $this.form.elements["is_secret"].checked = false;
- }
- let $length = $this.form.getElementsByClassName("comment-length");
- if ($length.length > 0) {
- $length[0].innerText = "0";
- }
- } else {
- $this.form.parentNode.style.display = "none";
- $this.form.parentNode.innerHTML = "";
- }
- this.reset($this.form);
- },
- /*
- * 댓글 에디터 옵션 변경
- * 1:1 게시판에서 댓글을 작성하면 실행
- */
- setInitEditor: function () {
- let tinyMCEExtendSetting = {
- min_height: 210,
- max_height: 310,
- init_instance_callback: function (editor) {
- editor.on('SetContent', function (e) {
- let iframeRows = e.target.contentDocument.body.getElementsByTagName("iframe");
- if (iframeRows > 0) {
- $(e.content).filter("iframe").attr("src", ""); // iframe src 주소
- }
- });
- editor.on('keyup', function () {
- Comment.checkByte(editor.targetElm);
- });
- editor.on('keypress', function () {
- Comment.checkByte(editor.targetElm);
- // document.getElementById(e.target.dataset.id).value = e.currentTarget.textContent;
- });
- }
- };
- tinymce.init(Object.assign(tinyMCE.activeEditor.settings, tinyMCEExtendSetting));
- this.useEditor = true;
- },
- // 좋아요/싫어요 처리
- toggleLike: function (cid, type, active) {
- let btnCommentLike = document.getElementById("comment_" + cid).getElementsByClassName("btn-comment-like")[0];
- let btnCommentDisLike = document.getElementById("comment_" + cid).getElementsByClassName("btn-comment-dislike")[0];
- if (type === 1) {
- this.setLike(cid, active);
- if (Number(btnCommentDisLike.dataset.active)) {
- this.setDislike(cid, false);
- }
- } else if (type === 2) {
- this.setDislike(cid, active);
- if (Number(btnCommentLike.dataset.active)) {
- this.setLike(cid, false);
- }
- }
- },
- // 좋아요 갱신
- setLike: function (cid, active) {
- let button = document.getElementById("comment_" + cid).getElementsByClassName("btn-comment-like")[0];
- let rows = Number(button.dataset.rows);
- if (active) {
- rows = (rows + 1);
- button.innerHTML = '<i class="fas fa-thumbs-up"></i><span> ' + String(rows) + '</span>';
- button.dataset.active = "1";
- } else {
- rows = (rows > 0 ? rows - 1 : rows);
- button.innerHTML = '<i class="far fa-thumbs-up"></i><span> ' + String(rows) + '</span>';
- button.dataset.active = "0";
- }
- button.dataset.rows = rows;
- },
- // 싫어요 갱신
- setDislike: function (cid, active) {
- let button = document.getElementById("comment_" + cid).getElementsByClassName("btn-comment-dislike")[0];
- let rows = Number(button.dataset.rows);
- if (active) {
- rows = (rows + 1);
- button.innerHTML = '<i class="fas fa-thumbs-down"></i><span> ' + String(rows) + '</span>';
- button.dataset.active = "1";
- } else {
- rows = (rows > 0 ? rows - 1 : rows);
- button.innerHTML = '<i class="far fa-thumbs-down"></i><span> ' + String(rows) + '</span>';
- button.dataset.active = "0";
- }
- button.dataset.rows = rows;
- }
- };
- // 댓글 입력하면 창 크기 조절
- $(document).on("keyup input", "textarea[data-autoresize]", function() {
- Comment.resizeTextarea(this);
- });
- // 댓글 글자수 확인
- $(document).on('keydown keyup', "textarea.comment-content", function (e) {
- Comment.checkByte(this);
- });
- // 댓글 등록
- $(document).on("click", "button.btn-comment-submit", function () {
- Comment.submit(this);
- });
- // 댓글 답글
- $(document).on("click", "button.btn-comment-reply", function() {
- Comment.write(this, "reply");
- });
- // 댓글 수정
- $(document).on("click", "button.btn-comment-modify", function () {
- Comment.write(this, "modify");
- });
- // 댓글 취소
- $(document).on("click", "button.btn-comment-cancel", function () {
- Comment.cancel(this);
- });
- // 댓글 삭제
- $(document).on("click", "button.btn-comment-delete", function () {
- Comment.delete(this);
- });
- // 댓글 신고
- $(document).on("click", "button.btn-comment-blame", function() {
- Comment.blame(this);
- });
- // 댓글 추천하기
- $(document).on("click", "button.btn-comment-like", function () {
- Comment.like(this);
- });
- // 댓글 비추천하기
- $(document).on("click", "button.btn-comment-dislike", function () {
- Comment.dislike(this);
- });
- // 댓글 페이징 처리
- $(document).on("click", "#commentList > nav > ul > li > a", function () {
- let page = Number(params('page', this.href));
- return Comment.list(page);
- });
- // 댓글 정렬
- $(document).on("change", "select#commentSort", function () {
- Comment.list(null, null, null, this.value);
- });
- // 댓글 신고 모달 열리면 초기화
- $(document).on("show.bs.modal", "#commentBlameModal", function(e) {
- let form = e.currentTarget.getElementsByTagName("form")[0];
- form.elements["blame_type"].selectedIndex = 0;
- form.elements["blame_reason"].value = "";
- });
|