comment.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. $(function() {
  2. // 댓글입력 창 높이 자동조정
  3. $.each($('textarea[data-autoresize]'), function () {
  4. $(this).on('keyup input', function () {
  5. Comment.resizeTextarea(this);
  6. }).removeAttr('data-autoresize');
  7. });
  8. });
  9. const Comment =
  10. {
  11. callback: "",
  12. listID: "commentList",
  13. writeID: "commentWrite",
  14. method: {write: "store", edit: "update", reply: "reply"},
  15. mode: "",
  16. code: "",
  17. bid: 0,
  18. pid: 0,
  19. cid: 0,
  20. uid: 0,
  21. total: 0,
  22. page: 0,
  23. perPage: 0,
  24. minLength: 0,
  25. maxLength: 0,
  26. listForm: null,
  27. writeForm: null,
  28. saveHtml: null,
  29. saveBefore: null,
  30. useEditor: false,
  31. queryString: null,
  32. tinymce: null,
  33. // 댓글 기본설정
  34. init: function(config)
  35. {
  36. if(!config.hasOwnProperty("code") && !config.hasOwnProperty("bid") && !config.hasOwnProperty("pid")) {
  37. return false;
  38. }
  39. this.code = config.code;
  40. this.bid = config.bid;
  41. this.pid = config.pid;
  42. this.callback = (BASE_URL + "/board/" + String(this.code) + "/" + String(this.pid) + "/comment");
  43. this.listForm = document.getElementById(this.listID);
  44. this.writeForm = document.getElementById(this.writeID);
  45. // 댓글 입력창
  46. let form = this.writeForm.getElementsByTagName("form")[0];
  47. this.minLength = Number(form.elements["min_length"].value);
  48. this.maxLength = Number(form.elements["max_length"].value);
  49. this.saveHtml = this.writeForm.innerHTML; // 댓글 입력 창 저장
  50. },
  51. // 초기화
  52. reset: function(form)
  53. {
  54. this.mode = "write";
  55. this.cid = 0;
  56. this.saveBefore = null;
  57. if (typeof form !== "undefined") {
  58. if(form.elements["mode"].value !== "write") {
  59. form.style.display = "none";
  60. }
  61. form.elements["mode"].value = "write";
  62. form.elements["bid"].value = "";
  63. form.elements["pid"].value = "";
  64. form.elements["cid"].value = "";
  65. form.elements["uid"].value = "";
  66. form.elements["length"].value = "0";
  67. form.elements["content"].value = "";
  68. if (form.elements.hasOwnProperty("username")) {
  69. form.elements["username"].value = "";
  70. }
  71. if (form.elements.hasOwnProperty("password")) {
  72. form.elements["password"].value = "";
  73. }
  74. if (form.elements.hasOwnProperty("is_secret")) {
  75. form.elements["is_secret"].checked = false;
  76. }
  77. let length = form.getElementsByClassName("comment-length");
  78. if (length.length > 0) {
  79. length[0].innerText = "0";
  80. }
  81. form.elements["btn_comment_submit"].disabled = false;
  82. form.elements["btn_comment_cancel"].disabled = false;
  83. this.resizeTextarea(form.elements["content"]);
  84. }
  85. if (this.useEditor) {
  86. tinyMCE.activeEditor.setContent("");
  87. }
  88. },
  89. // 댓글 목록 새로고침
  90. refresh: function() {
  91. this.list(this.page);
  92. },
  93. // textarea 높이 조절
  94. resizeTextarea: function(e)
  95. {
  96. $(e).css("height", "auto").css("height", e.scrollHeight + (e.offsetHeight - e.clientHeight));
  97. },
  98. // 댓글 영역으로 스크롤 이동
  99. scrollReplyNow: function(cid)
  100. {
  101. if (typeof cid != "undefined" && cid) {
  102. let offset = $("#comment_" + cid).offset();
  103. if (typeof offset != "undefined") {
  104. window.document.body.scrollTop = offset.top;
  105. document.getElementById("comment_" + cid).scrollIntoView();
  106. }
  107. }
  108. },
  109. // 댓글 영역 강조
  110. focusCommentBox: function(cid)
  111. {
  112. if (typeof cid != "undefined" && cid) {
  113. $("#comment_" + cid).effect("highlight", {
  114. 'color': '#4f4f4f'
  115. }, 1500);
  116. }
  117. },
  118. // 금지 단어 확인
  119. filterSpamKeyword: function (content)
  120. {
  121. let ret = "";
  122. $.ajax({
  123. headers: {"X-CSRF-TOKEN": CSRF},
  124. url: (BASE_URL + "/api/filterSpamKeyword"),
  125. type: "post",
  126. dataType: "json",
  127. async: false,
  128. cache: false,
  129. data: {subject: "", content: content},
  130. success: function (res) {
  131. ret = res.content;
  132. },
  133. error: function (xhr, status, err) {
  134. procErrorEvent(xhr, status, err);
  135. }
  136. });
  137. return ret;
  138. },
  139. // 글자수 확인
  140. checkByte: function(e)
  141. {
  142. let form = e.form;
  143. if (typeof form !== "undefined") {
  144. let hiddenInputLength = form.elements["length"];
  145. let spanInputLength = form.getElementsByClassName("comment-length")[0];
  146. let textarea = form.elements["content"];
  147. let length = textarea.value.length;
  148. let tinymce = form.getElementsByTagName("iframe");
  149. if (this.useEditor) {
  150. let editor = tinymce[0].contentDocument.body;
  151. length = editor.innerText.trim().length;
  152. if (this.maxLength > 0 && length > this.maxLength) {
  153. editor.innerHTML = editor.innerHTML.substr(0, this.maxLength);
  154. length = editor.innerHTML.length;
  155. }
  156. } else {
  157. if (this.maxLength > 0 && length > this.maxLength) {
  158. textarea.value = textarea.value.substr(0, this.maxLength);
  159. length = textarea.value.length;
  160. }
  161. }
  162. // 글자 수 저장
  163. hiddenInputLength.value = length;
  164. // 글자 수 출력
  165. if (typeof spanInputLength !== "undefined") {
  166. spanInputLength.innerText = length;
  167. }
  168. }
  169. },
  170. // 목록
  171. list: function(page, cid, message, sort) {
  172. if(!this.code && !this.bid && !this.pid) {
  173. return false;
  174. }
  175. if (!page || page < 1 || page === Number.POSITIVE_INFINITY) {
  176. page = 1;
  177. }
  178. let listURL = (this.callback + "?page=" + page);
  179. if (sort) {
  180. listURL += "&sort=" + sort;
  181. }
  182. $('#' + this.listID).load(listURL, function (response, status, xhr) { // HTML 형식으로 뎃글목록 출력
  183. if(status !== "success") {
  184. return;
  185. }
  186. let total = this.children.total.value;
  187. let page = this.children.page.value;
  188. let perPage = this.children.per_page.value;
  189. document.getElementById("txtCommentRows").innerText = total;
  190. document.getElementById("txtPostCommentCnt").innerText = total;
  191. if (message) { // 알림이 있을 경우 alert
  192. alert(message);
  193. }
  194. Comment.total = total;
  195. Comment.page = page;
  196. Comment.perPage = perPage;
  197. Comment.focusCommentBox(cid);
  198. Comment.scrollReplyNow(cid);
  199. });
  200. },
  201. // 댓글 등록/수정
  202. submit: function(e)
  203. {
  204. e.blur();
  205. e.disabled = true;
  206. $(e.form).validate({
  207. onkeyup: false,
  208. onclick: false,
  209. onfocusout: false,
  210. rules: {
  211. username: {required: "#username:enabled", minlength: 2, maxlength: 10},
  212. password: {required: "#password:enabled", minlength: 3, maxlength: 10},
  213. mode: {required: true, contains: ["write", "edit", "reply"]},
  214. content: {
  215. required: true,
  216. normalizer: function (value) {
  217. if(Comment.useEditor) {
  218. return tinyMCE.activeEditor.getContent({format: "text"}).trim();
  219. }else{
  220. return value.trim();
  221. }
  222. },
  223. minlength: Comment.minLength,
  224. maxlength: function() {
  225. return (Comment.maxLength > 0 ? Comment.maxLength : 500)
  226. }
  227. },
  228. is_secret: {number: true}
  229. },
  230. messages: {
  231. username: {required: "이름을 입력하세요.", minlength: "이름은 두 글자 이상 입력하세요.", maxlength: "이름은 10자까지 입력 가능합니다."},
  232. password: {required: "비밀번호를 입력하세요.", minlength: "비밀번호는 3자 이상 입력하세요.", maxlength: "비밀번호는 10자까지 입력 가능합니다."},
  233. mode: {required: "댓글 처리중 오류가 발생하였습니다.", contains: "잘못된 요청입니다."},
  234. content: {required: "댓글을 입력해주세요."},
  235. is_secret: {number: true}
  236. },
  237. showErrors: function (errorMap, errorList) {
  238. if (this.numberOfInvalids()) {
  239. setTimeout(function() {
  240. alert(errorList[0].message);
  241. errorList[0].element.focus();
  242. if(Comment.useEditor) {
  243. tinyMCE.activeEditor.getBody().scrollIntoView();
  244. }else{
  245. window.scrollTo({top: errorList[0].element.offsetTop});
  246. }
  247. }, 100);
  248. e.disabled = false;
  249. }
  250. },
  251. submitHandler: function (form)
  252. {
  253. let formData = new FormData(form);
  254. let spamKeyword = Comment.filterSpamKeyword(formData.get("content")); // 금지 단어 검사
  255. if (spamKeyword) {
  256. alert("내용에 금지어 ('" + spamKeyword + "')가 포함 되어있습니다.");
  257. form.elements["content"].focus();
  258. return false;
  259. }
  260. let page;
  261. let mode = formData.get("mode");
  262. if(mode === "write") {
  263. formData.append("bid", Comment.bid);
  264. formData.append("pid", Comment.pid);
  265. page = Math.ceil((Number(Comment.total) + 1) / Comment.perPage);
  266. }else{
  267. page = Comment.page;
  268. }
  269. if(mode === "edit") {
  270. formData.append("_method", "PUT");
  271. }
  272. // 버튼 비활성화
  273. form.elements["btn_comment_submit"].disabled = true;
  274. form.elements["btn_comment_cancel"].disabled = true;
  275. $.ajax({
  276. headers: {'X-CSRF-TOKEN': CSRF},
  277. url: (Comment.callback + "/" + Comment.method[mode]),
  278. type: "post",
  279. cache: false,
  280. async: true,
  281. contentType: false,
  282. processData: false,
  283. data: formData,
  284. dataType: "json",
  285. beforeSend: function () {
  286. if (formData.get("uid")) { // 권한 확인
  287. if (!loginCheck()) {
  288. return xhr.abort();
  289. }
  290. }
  291. showLoading();
  292. },
  293. success: function (res) {
  294. if (res.success) {
  295. Comment.list(page, res.cid);
  296. }else{
  297. alert(res.message);
  298. }
  299. },
  300. error: function (xhr, status, err) {
  301. procErrorEvent(xhr, status, err);
  302. },
  303. complete: function() {
  304. Comment.reset(form);
  305. hideLoading();
  306. }
  307. });
  308. }
  309. });
  310. $(e.form).submit();
  311. },
  312. // 수정, 답글
  313. write: function(e, mode)
  314. {
  315. e.blur();
  316. if(typeof e === "undefined") {
  317. return false;
  318. }
  319. if(typeof mode === "undefined" || mode == null || !mode) {
  320. return false;
  321. }
  322. if(!mode in this.method) {
  323. return false;
  324. }
  325. let formData = new FormData(e.form); // 댓글 영역
  326. let mediaFormID = ("#fCommentWrite_" + formData.get("cid")); // 현재 답글 번호
  327. let $saveBefore = $(this.saveBefore); // 이전 댓글 창
  328. let $target = $(mediaFormID); // 현재 댓글 창
  329. if(this.cid === formData.get("cid") && this.saveBefore === mediaFormID && this.mode === mode) {
  330. $saveBefore.toggle();
  331. }else{
  332. $saveBefore.html("");
  333. $target.show();
  334. let writeForm = $target.html(this.saveHtml).get(0).firstElementChild;
  335. // 답글
  336. if(mode === "reply") {
  337. if(writeForm.elements.hasOwnProperty("username")) {
  338. writeForm.elements["username"].value = "";
  339. }
  340. if(writeForm.elements.hasOwnProperty("is_secret")) {
  341. writeForm.elements["is_secret"].checked = false;
  342. }
  343. writeForm.elements["content"].value = "";
  344. }
  345. // 수정
  346. if(mode === "edit") {
  347. if(writeForm.elements.hasOwnProperty("username")) {
  348. writeForm.elements["username"].value = formData.get("username");
  349. }
  350. if(writeForm.elements.hasOwnProperty("is_secret")) {
  351. writeForm.elements["is_secret"].checked = Boolean(formData.get("is_secret").checked);
  352. }
  353. writeForm.elements["content"].value = formData.get("content");
  354. // 입력창 높이 조절
  355. this.resizeTextarea(writeForm.elements["content"]);
  356. }
  357. writeForm.elements["mode"].value = mode;
  358. writeForm.elements["bid"].value = formData.get("bid");
  359. writeForm.elements["pid"].value = formData.get("pid");
  360. writeForm.elements["cid"].value = formData.get("cid");
  361. writeForm.elements["uid"].value = formData.get("uid");
  362. // textarea ID 할당
  363. if(writeForm) {
  364. writeForm.elements["content"].setAttribute("id", formData.get("content") + "_" + formData.get("cid"));
  365. // 1:1 문의 게시판은 에디터를 사용
  366. if(this.useEditor) {
  367. tinyMCE.EditorManager.execCommand('mceAddEditor', true, writeForm.elements["content"]);
  368. }
  369. // 글자 수 확인
  370. this.checkByte(formData.get("content"));
  371. }
  372. }
  373. this.mode = mode;
  374. this.cid = formData.get("cid");
  375. this.saveBefore = mediaFormID; // 현재 영역
  376. },
  377. // 댓글 삭제
  378. delete: function(e)
  379. {
  380. e.blur();
  381. let formData = new FormData(e.form);
  382. $.ajax({
  383. url: (this.callback + "/delete"),
  384. type: "delete",
  385. cache: false,
  386. async: false,
  387. data: {bid: formData.get("bid"), pid: formData.get("pid"), cid: formData.get("cid"), _method: "DELETE"},
  388. dataType: "json",
  389. beforeSend: function(xhr) {
  390. if (!formData.get("uid")) { // 권한 확인
  391. const password = prompt("댓글 비밀번호 확인이 필요합니다.\n비밀번호를 입력해주세요.");
  392. if (!password) {
  393. return false;
  394. }
  395. this.url += ("?passwd=" + encodeURIComponent(password.trim()));
  396. } else {
  397. if (!loginCheck()) {
  398. return xhr.abort();
  399. }
  400. }
  401. if (!confirm("댓글을 삭제하시겠습니까?")) {
  402. return false;
  403. }
  404. },
  405. success: function (res) {
  406. if (res.success) {
  407. alert("댓글이 삭제되었습니다.");
  408. Comment.refresh();
  409. }else{
  410. alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
  411. }
  412. Comment.reset();
  413. },
  414. error: function (xhr, status, err) {
  415. procErrorEvent(xhr, status, err);
  416. }
  417. });
  418. return false;
  419. },
  420. // 댓글 신고
  421. blame: function(e)
  422. {
  423. e.blur();
  424. if(!loginCheck()) {
  425. return false;
  426. }
  427. // 신고 접수 유효성 적용
  428. $("#fCommentBlame").validate({
  429. onkeyup: false,
  430. onclick: false,
  431. onfocusout: false,
  432. rules: {
  433. type: {required: true, contains: ['1', '2', '3', '4', '5', '6', '7', '8', '9']},
  434. reason: {
  435. required: true, normalizer: function (value) {
  436. return $.trim(value);
  437. }, maxlength: 1000
  438. }
  439. },
  440. messages: {
  441. type: {required: "신고 유형을 선택해주세요.", contains: "잘못된 요청입니다."},
  442. reason: {required: "신고 내용을 입력해주세요.", maxlength: "신고 내용은 {0}자까지 입력 가능합니다."}
  443. },
  444. showErrors: function (errorMap, errorList) {
  445. if (this.numberOfInvalids()) {
  446. alert(errorList[0].message);
  447. errorList[0].element.focus();
  448. }
  449. },
  450. submitHandler: function (form) {
  451. if (confirm("신고를 접수하시겠습니까?")) {
  452. let formData = new FormData(form);
  453. formData.append("bid", e.form.elements["bid"].value);
  454. formData.append("pid", e.form.elements["pid"].value);
  455. formData.append("cid", e.form.elements["cid"].value);
  456. $.ajax({
  457. url: (Comment.callback + "/blame"),
  458. type: "post",
  459. cache: false,
  460. contentType: false,
  461. processData: false,
  462. data: formData,
  463. dataType: "json",
  464. beforeSend: function (xhr) {
  465. if (!loginCheck()) {
  466. xhr.abort();
  467. }
  468. },
  469. success: function (res) {
  470. if (res.success) {
  471. alert("감사합니다. 신고가 접수되었습니다. 이용 규칙을 위반한 것으로 확인되면 댓글이 삭제됩니다.");
  472. } else {
  473. alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
  474. }
  475. },
  476. error: function (xhr, status, err) {
  477. procErrorEvent(xhr, status, err);
  478. },
  479. complete : function() {
  480. $("#commentBlameModal").modal('hide');
  481. }
  482. });
  483. }
  484. }
  485. });
  486. },
  487. // 추천
  488. like: function (e) {
  489. let formData = new FormData(e.form);
  490. formData.append("type", e.value);
  491. $.ajax({
  492. url: (this.callback + "/like"),
  493. type: "post",
  494. cache: false,
  495. contentType: false,
  496. processData: false,
  497. data: formData,
  498. dataType: "json",
  499. beforeSend: function (xhr) {
  500. if (!loginCheck()) {
  501. xhr.abort();
  502. }
  503. },
  504. success: function (res) {
  505. if (res.success) {
  506. Comment.toggleLike(formData.get("cid"), 1, !Number(e.dataset.active));
  507. } else {
  508. alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
  509. }
  510. },
  511. error: function (xhr, status, err) {
  512. procErrorEvent(xhr, status, err);
  513. }
  514. });
  515. },
  516. // 비추천
  517. dislike: function (e) {
  518. let formData = new FormData(e.form);
  519. formData.append("type", e.value);
  520. $.ajax({
  521. url: (this.callback + "/dislike"),
  522. type: "post",
  523. cache: false,
  524. contentType: false,
  525. processData: false,
  526. data: formData,
  527. dataType: "json",
  528. beforeSend: function (xhr) {
  529. if (!loginCheck()) {
  530. xhr.abort();
  531. }
  532. },
  533. success: function (res) {
  534. if (res.success) {
  535. Comment.toggleLike(formData.get("cid"), 2, !Number(e.dataset.active));
  536. } else {
  537. alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
  538. }
  539. },
  540. error: function (xhr, status, err) {
  541. procErrorEvent(xhr, status, err);
  542. }
  543. });
  544. },
  545. // 댓글 입력 취소
  546. cancel: function (e) {
  547. if (e.form.mode.value === "write") {
  548. e.form.elements["mode"].value = "write";
  549. e.form.elements["cid"].value = "";
  550. e.form.elements["length"].value = "0";
  551. e.form.elements["content"].value = "";
  552. if (typeof e.form.elements["is_secret"] !== "undefined") {
  553. e.form.elements["is_secret"].checked = false;
  554. }
  555. let length = e.form.getElementsByClassName("comment-length");
  556. if (length.length > 0) {
  557. length[0].innerText = "0";
  558. }
  559. } else {
  560. e.form.parentNode.style.display = "none";
  561. e.form.parentNode.innerHTML = "";
  562. }
  563. this.reset(e.form);
  564. },
  565. /*
  566. * 댓글 에디터 옵션 변경
  567. * 1:1 게시판에서 댓글을 작성하면 실행
  568. */
  569. setInitEditor: function () {
  570. let tinyMCEExtendSetting = {
  571. min_height: 210,
  572. max_height: 310,
  573. file_browser_url: (BASE_URL + "/board/" + this.code + "/uploader"),
  574. init_instance_callback: function (editor) {
  575. editor.on('SetContent', function (e) {
  576. let iframeRows = e.target.contentDocument.body.getElementsByTagName("iframe");
  577. if (iframeRows > 0) {
  578. $(e.content).filter("iframe").attr("src", ""); // iframe src 주소
  579. }
  580. });
  581. editor.on('keyup', function () {
  582. Comment.checkByte(editor.targetElm);
  583. });
  584. editor.on('keypress', function () {
  585. Comment.checkByte(editor.targetElm);
  586. // document.getElementById(e.target.dataset.id).value = e.currentTarget.textContent;
  587. });
  588. }
  589. };
  590. this.tinymce = tinymce.init(Object.assign(tinyMCE.activeEditor.settings, tinyMCEExtendSetting));
  591. this.useEditor = true;
  592. },
  593. // 좋아요/싫어요 처리
  594. toggleLike: function (cid, type, active) {
  595. let btnCommentLike = document.getElementById("comment_" + cid).getElementsByClassName("btn-comment-like")[0];
  596. let btnCommentDisLike = document.getElementById("comment_" + cid).getElementsByClassName("btn-comment-dislike")[0];
  597. if (type === 1) {
  598. this.setLike(cid, active);
  599. if (Number(btnCommentDisLike.dataset.active)) {
  600. this.setDislike(cid, false);
  601. }
  602. } else if (type === 2) {
  603. this.setDislike(cid, active);
  604. if (Number(btnCommentLike.dataset.active)) {
  605. this.setLike(cid, false);
  606. }
  607. }
  608. },
  609. // 좋아요 갱신
  610. setLike: function (cid, active) {
  611. let button = document.getElementById("comment_" + cid).getElementsByClassName("btn-comment-like")[0];
  612. let rows = Number(button.dataset.rows);
  613. if (active) {
  614. rows = (rows + 1);
  615. button.innerHTML = '<i class="fas fa-thumbs-up"></i><span> ' + String(rows) + '</span>';
  616. button.dataset.active = "1";
  617. } else {
  618. rows = (rows > 0 ? rows - 1 : rows);
  619. button.innerHTML = '<i class="far fa-thumbs-up"></i><span> ' + String(rows) + '</span>';
  620. button.dataset.active = "0";
  621. }
  622. button.dataset.rows = rows;
  623. },
  624. // 싫어요 갱신
  625. setDislike: function (cid, active) {
  626. let button = document.getElementById("comment_" + cid).getElementsByClassName("btn-comment-dislike")[0];
  627. let rows = Number(button.dataset.rows);
  628. if (active) {
  629. rows = (rows + 1);
  630. button.innerHTML = '<i class="fas fa-thumbs-down"></i><span> ' + String(rows) + '</span>';
  631. button.dataset.active = "1";
  632. } else {
  633. rows = (rows > 0 ? rows - 1 : rows);
  634. button.innerHTML = '<i class="far fa-thumbs-down"></i><span> ' + String(rows) + '</span>';
  635. button.dataset.active = "0";
  636. }
  637. button.dataset.rows = rows;
  638. }
  639. };
  640. // 댓글 입력하면 창 크기 조절
  641. $(document).on("keyup input", "textarea[data-autoresize]", function() {
  642. Comment.resizeTextarea(this);
  643. });
  644. // 댓글 글자수 확인
  645. $(document).on('keydown keyup', "textarea.comment-content", function (e) {
  646. Comment.checkByte(this);
  647. });
  648. // 댓글 등록
  649. $(document).on("click", "button.btn-comment-submit", function () {
  650. Comment.submit(this);
  651. });
  652. // 댓글 답글
  653. $(document).on("click", "button.btn-comment-reply", function() {
  654. Comment.write(this, "reply");
  655. });
  656. // 댓글 수정
  657. $(document).on("click", "button.btn-comment-edit", function () {
  658. Comment.write(this, "edit");
  659. });
  660. // 댓글 취소
  661. $(document).on("click", "button.btn-comment-cancel", function () {
  662. Comment.cancel(this);
  663. });
  664. // 댓글 삭제
  665. $(document).on("click", "button.btn-comment-delete", function () {
  666. Comment.delete(this);
  667. });
  668. // 댓글 신고
  669. $(document).on("click", "button.btn-comment-blame", function() {
  670. Comment.blame(this);
  671. });
  672. // 댓글 추천하기
  673. $(document).on("click", "button.btn-comment-like", function () {
  674. Comment.like(this);
  675. });
  676. // 댓글 비추천하기
  677. $(document).on("click", "button.btn-comment-dislike", function () {
  678. Comment.dislike(this);
  679. });
  680. // 댓글 페이징 처리
  681. $(document).on("click", "#commentList > ul > li > a", function (e) {
  682. e.preventDefault();
  683. return Comment.list(Number(params('page', this.href)));
  684. });
  685. // 댓글 정렬
  686. $(document).on("change", "select#commentSort", function () {
  687. Comment.list(null, null, null, this.value);
  688. });
  689. // 댓글 신고 모달 열리면 초기화
  690. $(document).on("show.bs.modal", "#commentBlameModal", function(e) {
  691. let form = e.currentTarget.getElementsByTagName("form")[0];
  692. form.elements["type"].selectedIndex = 0;
  693. form.elements["reason"].value = "";
  694. if(!IS_USER) {
  695. return false;
  696. }
  697. });