(function($){ $(document).ready(function(){ var currentChildEditId = null; var originalChildHTML = ""; function cancelChildEdit(){ if(!currentChildEditId) return; var c = $("#comment_" + currentChildEditId); c.html(originalChildHTML); currentChildEditId = null; } // ------------------------------------------------------------------------ // 대댓글 작성 완료 시 이벤트 (자식 댓글 수 증가 처리) // ------------------------------------------------------------------------ $(document).on("childReplyAdded", function(e, cid) { var commentEl = $("#comment_" + cid); // 만약 선택된 댓글이 자식 댓글이면 상위의 부모 댓글을 찾아 업데이트 if(commentEl.hasClass("child-comment")){ var parentCommentEl = commentEl.parents("li.comment-item:not(.child-comment)").first(); if(parentCommentEl.length) { commentEl = parentCommentEl; } } var replyCountLink = commentEl.find(".reply-count-link"); if(replyCountLink.length) { var currentText = replyCountLink.text(); var match = currentText.match(/\d+/); var count = match ? parseInt(match[0], 10) + 1 : 1; replyCountLink.html(' 답글 ' + count + '개'); } else { // 부모 댓글에만 답글 버튼 추가 commentEl.append( '
' + ' ' + ' 답글 1개' + ' ' + '
' ); } }); // ------------------------------------------------------------------------ // 1) 대댓글(child) 수정 로직 (UI 요소를 .remove() 후 텍스트만 추출) // ------------------------------------------------------------------------ $(document).off("click", ".comment-edit-btn.child-edit").on("click", ".comment-edit-btn.child-edit", function(e){ e.preventDefault(); e.stopPropagation(); var c = $(this).closest(".child-comment"); var cid = c.data("comment-id"); // 이미 다른 댓글 수정 중이라면 우선 취소 if(currentChildEditId && currentChildEditId !== cid){ cancelChildEdit(); } currentChildEditId = cid; originalChildHTML = c.html(); // 취소 시 복원용 // 1) .comment-content 복제 var contentClone = c.find(".comment-content").clone(); // 2) 이 안에서 “수정/삭제/신고” 관련 버튼·아이콘을 전부 제거 // (사용자님 상황에 맞게 필요한 클래스/태그 추가 가능) contentClone.find(` .comment-edit-btn, .child-edit, .child-delete-btn, .comment-pin-btn, .comment-like-btn, .comment-dislike-btn, .dropdown-menu, .dropdown-item, a.dropdown-item:contains('수정'), a.dropdown-item:contains('삭제'), a.dropdown-item:contains('신고') `).remove(); // contentClone에서 HTML → 순수 텍스트로 var oh = contentClone.html() || ""; var ot = $("
").html(oh).text(); // 대댓글에 "@작성자명"으로 시작할 경우 제거 var t = c.data("commenter-name") || ""; if(t && ot.indexOf("@" + t) === 0) { ot = ot.substring(("@" + t).length).trim(); } // 원본 댓글 영역 비우고 수정 폼 생성 c.empty(); var actionUrl = (typeof AJAX_COMMENT_ACTION_URL !== "undefined") ? AJAX_COMMENT_ACTION_URL : "/comment/comment_action.php"; var f = ""; f += '
'; f += ' '; f += ' '; f += ' '; f += ' '; f += ' '; f += '
'; f += ' '; f += ' '; f += '
'; } f += ' '; f += ' '; f += '
'; f += ''; c.append(f); var fm = c.find(".child-inline-edit-form"); fm.find(".btn-cancel, .btn-reply").removeClass("d-none"); fm.find(".btn-reply").prop("disabled", false); fm.find(".btn-cancel").on("click", function(ev){ ev.preventDefault(); cancelChildEdit(); }); // wr_content 입력 감지 -> "수정" 버튼 활성/비활성 fm.on("input", "[name='wr_content']", function(){ var v = $(this).val().trim(); fm.find(".btn-reply").prop("disabled", (v.length < 1)); }); // 수정 폼 전송 (AJAX) fm.on("submit", function(ev){ ev.preventDefault(); $.ajax({ url: fm.attr("action"), type: "POST", data: fm.serialize(), dataType: "json", success: function(r){ if(r.success){ var cid = fm.find("input[name='comment_id']").val(); $("#comment_" + cid).replaceWith(r.comment_html); if(typeof updateRatingSummary === "function") { updateRatingSummary(); } currentChildEditId = null; } } }); }); }); // ------------------------------------------------------------------------ // 2) 대댓글(child) 작성 로직 // ------------------------------------------------------------------------ $(document).off("click", ".child-reply-btn").on("click", ".child-reply-btn", function(e){ e.preventDefault(); e.stopPropagation(); // 기존에 열린 reply-form이 있으면 닫기 $(".child-reply-form-container").remove(); var b = $(this), tc = b.closest(".child-comment"); var co = $('
'); b.closest(".d-flex").after(co); var t = tc.data("commenter-name") || ""; var h = ""; var actionUrl = (typeof AJAX_COMMENT_ACTION_URL !== "undefined") ? AJAX_COMMENT_ACTION_URL : "/comment/comment_action.php"; h += '
'; h += ' '; h += ' '; h += ' '; h += ' '; h += ' '; h += ' '; h += '
'; h += ' '; h += '
'; h += ' '; h += '
'; h += '
'; h += ' '; h += ' '; h += '
'; h += ' '; h += ' '; h += '
'; h += '
'; co.html(h); }); // 글자 입력 시 "답글" 버튼 활성/비활성 $(document).on("input", ".child-reply-comment-form [name='wr_content']", function(){ var f = $(this).closest("form"); f.find(".btn-reply").prop("disabled", $(this).val().trim().length < 1); }); // 취소 버튼 클릭 시 폼 제거 $(document).on("click", ".child-reply-form-container .btn-cancel", function(e){ e.preventDefault(); $(this).closest(".child-reply-form-container").remove(); }); // ------------------------------------------------------------------------ // 대댓글(child) 작성 폼 AJAX 제출 // ------------------------------------------------------------------------ $(document).on("submit", ".child-reply-comment-form", function(e){ e.preventDefault(); var f = $(this); if(f.data("submitted")) return; f.data("submitted", true); var b = f.find("button[type='submit']"); b.prop("disabled", true); $.ajax({ url: f.attr("action"), type: "POST", data: f.serialize(), dataType: "json", success: function(r){ if(r.success){ // 전체 댓글 수 업데이트 if(r.total_comments !== undefined){ $("#total-comments").text(r.total_comments); } else { var x = parseInt($("#total-comments").text(), 10) || 0; $("#total-comments").text(x + 1); } var tc = f.closest(".child-reply-form-container").closest(".child-comment"); var cid = tc.data("comment-id"); // reply_list 컨테이너 확인 (li/ul) var nr = $("#reply_list_" + cid); if(!nr.length){ nr = $('
  • '); tc.append(nr); } // 새 댓글 요소 생성 var newElem = $(r.reply_html); var newCommentId = newElem.data("comment-id"); // 중복 체크 var existing = $( "#new_replies_" + cid + " li.child-comment[data-comment-id='" + newCommentId + "'], " + "#reply_list_" + cid + " li.child-comment[data-comment-id='" + newCommentId + "']" ); if(existing.length){ existing.first().replaceWith(newElem); existing.not(":first").remove(); } else { nr.prepend(newElem); } // 폼 제거, 이벤트 트리거 f.closest(".child-reply-form-container").remove(); $(document).trigger("childReplyAdded", [cid]); } }, error: function(xhr, status, error){ console.log("AJAX error:", status, error); }, complete: function(){ f.data("submitted", false); b.prop("disabled", false); } }); }); // ------------------------------------------------------------------------ // 3) 좋아요/싫어요 (child) // ------------------------------------------------------------------------ $(document).off("click", ".comment-like-btn.child-like").on("click", ".comment-like-btn.child-like", function(e){ e.preventDefault(); var cid = $(this).data("id"); if(!cid) return; var b = $(this), l = b.find("span"), db = b.closest(".bo_vc_act").find(".comment-dislike-btn.child-dislike span"); var actionUrl = (typeof AJAX_COMMENT_ACTION_URL !== "undefined") ? AJAX_COMMENT_ACTION_URL : "/comment/comment_action.php"; $.ajax({ url: actionUrl, type: "POST", dataType: "json", data: { action: "vote", bo_table: (typeof BO_TABLE !== "undefined") ? BO_TABLE : "", comment_id: cid, vote_type: "good" }, success: function(res){ if(res.success){ var ng = res.good_count || 0, nog = res.nogood_count || 0; l.text(ng); db.text(nog); b.find("i") .removeClass("hand_up hand_up-2") .addClass(res.new_vote_type==="good" ? "hand_up-2" : "hand_up"); b.closest(".bo_vc_act") .find(".comment-dislike-btn.child-dislike i") .removeClass("hand_down hand_down-2") .addClass(res.new_vote_type==="nogood" ? "hand_down-2" : "hand_down"); } } }); }); $(document).off("click", ".comment-dislike-btn.child-dislike").on("click", ".comment-dislike-btn.child-dislike", function(e){ e.preventDefault(); var cid = $(this).data("id"); if(!cid) return; var b = $(this), lb = b.closest(".bo_vc_act").find(".comment-like-btn.child-like span"), db = b.find("span"); var actionUrl = (typeof AJAX_COMMENT_ACTION_URL !== "undefined") ? AJAX_COMMENT_ACTION_URL : "/comment/comment_action.php"; $.ajax({ url: actionUrl, type: "POST", dataType: "json", data: { action: "vote", bo_table: (typeof BO_TABLE !== "undefined") ? BO_TABLE : "", comment_id: cid, vote_type: "nogood" }, success: function(res){ if(res.success){ var ng = res.good_count || 0, nog = res.nogood_count || 0; lb.text(ng); db.text(nog); b.closest(".bo_vc_act") .find(".comment-like-btn.child-like i") .removeClass("hand_up hand_up-2") .addClass(res.new_vote_type==="good" ? "hand_up-2" : "hand_up"); b.find("i") .removeClass("hand_down hand_down-2") .addClass(res.new_vote_type==="nogood" ? "hand_down-2" : "hand_down"); } } }); }); // ------------------------------------------------------------------------ // 4) 더 보기 (more-replies) 로딩 // ------------------------------------------------------------------------ $(document).off("click", ".more-replies").on("click", ".more-replies", function(e){ e.preventDefault(); var cid = $(this).data("comment-id"); var nextPage = parseInt($(this).data("next-page"), 10); $(this).closest(".more-replies-container").remove(); window.loadRepliesAndOpen(cid, nextPage); }); // ------------------------------------------------------------------------ // 5) AJAX로 자식 댓글을 불러오기(loadRepliesAndOpen) // ------------------------------------------------------------------------ window.loadRepliesAndOpen = function(cid, page, cb, newId, newHtml){ var c = $("#comment_" + cid), r = $("#replies_" + cid); if(!c.length){ if(typeof cb === "function") cb(); return; } if(!r.length){ r = $('
    '); c.append(r); } var rl = $("#reply_list_" + cid); if(!rl.length){ rl = $(''); r.append(rl); } if(page === 1 && rl.is(":empty")){ rl.html("
    "); } else { rl.find("#temp-spinner").remove(); rl.append("
    "); } var requestUrl; if(page > 1){ requestUrl = (typeof AJAX_COMMENT_REPLIES_URL !== "undefined") ? AJAX_COMMENT_REPLIES_URL : "/comment/ajax_comment_replies.php"; } else { requestUrl = (typeof COMMENT_REPLY_URL !== "undefined") ? COMMENT_REPLY_URL : "/comment/comment_reply.php"; } $.ajax({ url: requestUrl, type: "GET", data: { bo_table: (typeof BO_TABLE !== "undefined") ? BO_TABLE : "", comment_id: cid, page: page, limit: 10 }, dataType: "html", success: function(res){ $("[data-comment-id='" + cid + "'].more-replies-container").remove(); $("[data-comment-id='" + cid + "'].more-replies").remove(); var $res = $(res); var $replyList = $res.filter("#reply_list_" + cid); if(!$replyList.length){ $replyList = $res.find("#reply_list_" + cid); } var newList = $replyList.html() || ""; rl.find("#temp-spinner").remove(); if(page === 1){ rl.html(newList); } else { rl.append(newList); } // #new_replies_{cid}가 없으면 새로 생성 var nr = $("#new_replies_" + cid); if(!nr.length){ nr = $(''); r.prepend(nr); } if(newId !== undefined && newHtml){ var existingItem = nr.find("li.child-comment[data-comment-id='" + newId + "']"); if(!existingItem.length){ nr.prepend($(newHtml)); } else { existingItem.replaceWith($(newHtml)); } } var moreWrapper = $res.find(".more-replies-container"); if(moreWrapper.length){ var existingContainer = r.find(".more-replies-container[data-comment-id='" + cid + "']"); if(existingContainer.length){ existingContainer.remove(); } r.append(moreWrapper); } else { var moreLink = $res.find(".more-replies"); if(moreLink.length){ var existingLink = r.find(".more-replies[data-comment-id='" + cid + "']"); if(existingLink.length){ existingLink.remove(); } r.append(moreLink); } } if(typeof cb === "function"){ cb(); } }, error: function(){ if(typeof cb === "function") cb(); } }); }; }); })(jQuery);