Hệ thống pháp luật

BỘ TƯ PHÁP
-------

CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM
Độc lập - Tự do - Hạnh phúc
---------------

Số: 1503/BTP-PBGDPL
V/v hướng dẫn thực hiện thủ tục yêu cầu Tòa án công nhận kết quả hòa giải thành ở cơ sở

Hà Nội, ngày 05 tháng 05 năm 2017

 

Kính gửi: Ủy ban nhân dân các tỉnh, thành phố trực thuộc Trung ương

Bộ luật tố tụng dân sự được Quốc hội khóa XIII thông qua ngày 25/11/2015, có hiệu lực thi hành từ ngày 01/7/2016 (sau đây gọi là Bộ luật), tại Chương XXXIII của Bộ luật quy định “Thủ tục công nhận kết quả hòa giải thành ngoài Tòa án”. Để tạo điều kiện cho các bên tham gia hòa giải thành ở cơ sở thực hiện việc đề nghị Tòa án nhân dân công nhận kết quả hòa giải thành, sau khi thống nhất với Tòa án nhân dân tối cao, Bộ Tư pháp hướng dẫn như sau:

1. Điều kiện công nhận kết quả hòa giải thành ở cơ sở

1.1. Các bên tham gia thỏa thuận hòa giải có đầy đủ năng lực hành vi dân sự;

1.2. Vụ, việc được hòa giải tuân thủ đúng quy định pháp luật về hòa giải ở cơ sở;

1.3. Các bên tham gia thỏa thuận hòa giải là người có quyền, nghĩa vụ đối với nội dung thỏa thuận hòa giải. Trường hợp nội dung thỏa thuận hòa giải thành liên quan đến quyền, nghĩa vụ của người thứ ba thì phải được người thứ ba đồng ý;

1.4. Có văn bản hòa giải thành. Nội dung thỏa thuận hòa giải thành là hoàn toàn tự nguyện, không vi phạm điều cấm của luật, không trái đạo đức xã hội, không nhằm trốn tránh nghĩa vụ với Nhà nước hoặc người thứ ba;

1.5. Một hoặc cả hai bên có đơn yêu cầu Tòa án công nhận kết quả hòa giải thành ở cơ sở.

2. Tòa án có thẩm quyền ra quyết định công nhận kết quả hòa giải thành ở cơ sở là Tòa án nhân dân cấp huyện nơi người yêu cầu cư trú, làm việc3. Thủ tục yêu cầu Tòa án ra quyết định công nhận kết quả hòa giải thành ở cơ sở

3.1. Người yêu cầu công nhận kết quả hòa giải thành ở cơ sở (là một bên hoặc cả hai bên) phải gửi đơn đến Tòa án theo quy định tại Điều 418 Bộ luật tố tụng dân sự năm 2015.

a) Đơn yêu cầu phải có các nội dung chủ yếu sau đây:

- Ngày, tháng, năm làm đơn;

- Tên Tòa án có thẩm quyền ra quyết định công nhận kết quả hòa giải thành ở cơ sở;

- Tên, địa chỉ; số điện thoại, fax, địa chỉ thư điện tử (nếu có) của người yêu cầu;

- Tên, địa chỉ của những người có liên quan đến việc nội dung thỏa thuận hòa giải thành ở cơ sở (nếu có);

- Tên, địa chỉ của Hòa giải viên, tổ hòa giải đã tiến hành hòa giải;

- Các thông tin khác mà người yêu cầu xét thấy cần thiết cho việc giải quyết yêu cầu của mình;

- Người yêu cầu là cá nhân phải ký tên hoặc điểm chỉ, nếu là cơ quan, tổ chức thì đại diện hợp pháp của cơ quan, tổ chức đó phải ký tên và đóng dấu vào phần cuối đơn; trường hợp tổ chức yêu cầu là doanh nghiệp thì việc sử dụng con dấu được thực hiện theo quy định của Luật doanh nghiệp.

(Xem mẫu đơn đính kèm Công văn này).

b) Kèm theo đơn yêu cầu, người yêu cầu phải gửi văn bản về kết quả hòa giải thành theo quy định của pháp luật về hòa giải ở cơ sở.

Văn bản về kết quả hòa giải thành do hòa giải viên ở cơ sở lập theo quy định tại Khoản 4 Điều 21 và Khoản 2 Điều 24 Luật hòa giải ở cơ sở năm 2013.

Văn bản hòa giải thành gồm các nội dung chính sau đây:

- Căn cứ tiến hành hòa giải;

- Thông tin cơ bản về các bên;

- Nội dung chủ yếu của vụ, việc;

- Diễn biến của quá trình hòa giải;

- Thỏa thuận đạt được và giải pháp thực hiện;

- Quyền và nghĩa vụ của các bên;

- Phương thức, thời hạn thực hiện thỏa thuận;

- Chữ ký hoặc điểm chỉ của các bên và của hòa giải viên.

(Xem mẫu văn bản hòa giải thành ở cơ sở đính kèm Công văn này).

3.2. Thời hạn gửi đơn: Trong thời hạn 06 tháng, kể từ ngày lập văn bản hòa giải thành.

4. Trình tự, thủ tục công nhận kết quả hòa giải thành ở cơ sở của Tòa án theo quy định của pháp luật tố tụng dân sự (Điều 419 Bộ luật tố tụng dân sự).

5. Hiệu lực của Quyết định công nhận hoặc không công nhận kết quả hòa giải thành ở cơ sở của Tòa án

5.1. Quyết định công nhận hoặc không công nhận kết quả hòa giải thành ở cơ sở của Tòa án có hiệu lực thi hành ngay, không bị kháng cáo, kháng nghị theo thủ tục phúc thẩm.

5.2. Việc Tòa án không công nhận kết quả hòa giải thành ở cơ sở không ảnh hưởng đến nội dung và giá trị pháp lý của kết quả hòa giải ở cơ sở.

5.3. Quyết định công nhận kết quả hòa giải thành ngoài Tòa án được thi hành theo pháp luật về thi hành án dân sự.

6. Người nộp đơn yêu cầu Tòa án ra quyết định công nhận kết quả hòa giải thành ở cơ sở phải nộp tiền tạm ứng lệ phí giải quyết việc dân sự theo quy định tại Khoản 2 Điều 146 Bộ luật tố tụng dân sự năm 2015 và Khoản 1 Điều 36 Nghị quyết số 326/2016/NQ-UBTVQH14 ngày 30/12/2016 của Ủy ban thường vụ Quốc hội quy định về mức thu, miễn, giảm, thu, nộp, quản lý và sử dụng án phí và lệ phí Tòa án.

Mức lệ phí là 300.000 đồng quy định tại Danh mục án phí, lệ phí Tòa án ban hành kèm theo Nghị quyết số 326/2016/UBTVQH14. Trường hợp được miễn hoặc không phải nộp tiền tạm ứng lệ phí Tòa án thực hiện theo quy định của Nghị quyết số 326/2016/NQ-UBTVQH14.

7. Việc yêu cầu Tòa án ra quyết định công nhận kết quả hòa giải thành ở cơ sở là hoàn toàn tự nguyện, các bên có quyền gửi đơn yêu cầu hoặc không gửi đơn yêu cầu.

Bộ Tư pháp đề nghị Ủy ban nhân dân các tỉnh, thành phố trực thuộc Trung ương chỉ đạo Sở Tư pháp phổ biến quy định này đến hòa giải viên ở cơ sở để hướng dẫn cho các bên tranh chấp thực hiện sau khi tiến hành hòa giải thành.

Trong quá trình thực hiện, nếu phát sinh vướng mắc, đề nghị phản ánh kịp thời về Bộ Tư pháp (Vụ Phổ biến, giáo dục pháp luật, qua đồng chí Nguyễn Thị Quế, số điện thoại 04.62739470, email: quent@moj.gov.vn)./.

 


Nơi nhận:
- Như trên;
- Bộ trưởng (để báo cáo);
- Tòa án nhân dân tối cao (để phối hợp);
- Sở Tư pháp các tỉnh, thành phố trực thuộc TW (để thực hiện);
- Cục Công nghệ thông tin, Bộ Tư pháp (để đăng tải);
- Lưu: VT, Vụ PBGDPL.

KT. BỘ TRƯỞNG
THỨ TRƯỞNG




Phan Chí Hiếu

 

CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM
Độc lập – Tự do – Hạnh phúc
-----------------

ĐƠN YÊU CẦU

GIẢI QUYẾT VIỆC DÂN SỰ

(V/v: yêu cầu công nhận kết quả hòa giải thành ở cơ sở)

Kính gửi: TÒA ÁN NHÂN DÂN …...............(1)

Họ tên người yêu cầu:

1(2)...................................................................................... Sinh năm: …...........................

Địa chỉ (3):............................................................................................................................

Số điện thoại: …...................................................................Fax:.......................................

Địa chỉ thư điện tử: …..........................................................................(nếu có).

2................................................................................Sinh năm: ........................................

Địa chỉ:...............................................................................................................................

Số điện thoại: …...................................................................Fax:........................................

Địa chỉ thư điện tử: …..........................................................................(nếu có).

Hòa giải viên

1. Họ và tên:

Tổ hòa giải:..........................................................................................................................

2. Họ và tên (4):....................................................................................................................

Tổ hòa giải: ........................................................................................................................

Tôi (chúng tôi) xin trình bày với Tòa án nhân dân (5) ....................................................

việc như sau: ……………………………………………………………………………………

1. Vấn đề yêu cầu Tòa án giải quyết: Ra quyết định công nhận kết quả hòa giải thành ngoài Tòa án giữa ông (bà) .............................................. với ông (bà) …................................................ về tranh chấp …..........................................................................

2. Lý do, mục đích yêu cầu Tòa án giải quyết vấn đề nêu trên: Nhằm bảo đảm thực hiện thỏa thuận hòa giải thành ở cơ sở.

3. Căn cứ của việc yêu cầu Tòa án giải quyết những vấn đề nêu trên: Biên bản hòa giải thành được lập ngày .... tháng .... năm …...

4. Nội dung, thỏa thuận hòa giải thành yêu cầu Tòa án công nhận .................................

...........................................................................................................................................

...........................................................................................................................................

5. Tên và địa chỉ của những người có liên quan đến những vấn đề yêu cầu Tòa án giải quyết(6): …......................................................................................................

6. Thông tin khác(7): ….......................................................................................................

Danh mục tài liệu, chứng cứ kèm theo đơn gồm có(8):

1. ........................................................................................................................................

2. ........................................................................................................................................

3. ........................................................................................................................................

Tôi cam kết những lời khai trong đơn là hoàn toàn đúng sự thực.

 

 

…........., ngày.......tháng......năm... (9)
NGƯỜI YÊU CẦU(10)

Hướng dẫn ghi mẫu đơn:

(1) và (5) Ghi tên Tòa án nhân dân cấp huyện có thẩm quyền giải quyết việc dân sự; Cần ghi rõ Tòa án nhân dân huyện nào thuộc tỉnh, thành phố trực thuộc trung ương nào (ví dụ: Tòa án nhân dân huyện A thuộc tỉnh B) và địa chỉ của Tòa án đó.

(2) Nếu người yêu cầu là cá nhân thì ghi họ tên; nếu người yêu cầu là cơ quan, tổ chức thì ghi tên cơ quan, tổ chức và ghi họ, tên của người đại diện hợp pháp của cơ quan, tổ chức yêu cầu đó.

(3) Ghi địa chỉ nơi cư trú tại thời điểm nộp đơn yêu cầu giải quyết việc dân sự. Nếu người yêu cầu là cá nhân thì ghi đầy đủ địa chỉ nơi cư trú (ví dụ: Nguyễn Văn A, cư trú tại thôn B, xã C, huyện M, tỉnh H); nếu người yêu cầu là cơ quan, tổ chức thì ghi địa chỉ trụ sở chính của cơ quan, tổ chức đó (ví dụ: Công ty TNHH Hin Sen có trụ sở: Số 20 phố LTK, quận HK, thành phố H). Ghi địa chỉ nơi làm việc nếu người yêu cầu là cá nhân (ví dụ: Công ty TNHH Hải An, số 264 phố ĐC, quận BĐ, thành phố H).

(4) Ghi hòa giải viên thứ hai đối với trường hợp có 02 hòa giải viên cùng tiến hành hòa giải.

(6) Ghi rõ họ tên và địa chỉ nơi cư trú, địa chỉ nơi làm việc của những người mà người yêu cầu cho rằng có liên quan đến vấn đề yêu cầu Tòa án giải quyết.

(7) Ghi những thông tin khác mà người yêu cầu xét thấy cần thiết cho việc giải quyết yêu cầu của mình.

(8) Ghi rõ Biên bản hòa giải thành ở cơ sở lập ngày, tháng, năm nào, tại đâu và tên các tài liệu, chứng cứ kèm theo đơn yêu cầu gồm có những gì, là bản sao hay bản chính, đánh số thứ tự (ví dụ: 1. Bản sao Giấy khai sinh của...; 2. Bản sao giấy chứng nhận quyền sử dụng đất....).

(9) Ghi địa điểm, thời gian làm đơn yêu cầu (ví dụ: Hà Nội, ngày ….. tháng …... năm........ ).

(10) Nếu người yêu cầu là cá nhân thì phải có chữ ký hoặc điểm chỉ của người yêu cầu đó; nếu là cơ quan tổ chức yêu cầu thì người đại diện hợp pháp của cơ quan, tổ chức yêu cầu ký tên, ghi rõ họ tên, chức vụ của mình và đóng dấu của cơ quan, tổ chức đó. Trường hợp tổ chức yêu cầu là doanh nghiệp thì việc sử dụng con dấu theo quy định của Luật doanh nghiệp.

 

Xã, phường, thị trấn:
.................................
Thôn, tổ dân phố:
...........................

CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM
Độc lập - Tự do - Hạnh phúc
---------------

 

BIÊN BẢN HÒA GIẢI THÀNH Ở CƠ SỞ

 

Hôm nay, vào........ giờ........... phút, ngày.........tháng......năm.........

Tại: .......................................................................................................................................

Tiến hành hòa giải tranh chấp ở cơ sở

Căn cứ tiến hành hòa giải(1):.............................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

Thành phần gồm có:

Người tiến hành hòa giải:

- Ông (Bà)............................................................................ - Hòa giải viên.

- Ông (Bà)............................................................................ (2)

Các bên tranh chấp:

Ông (Bà)(3):............................................................................................................................

Địa chỉ(4):................................................................................................................................

Ông (Bà):...............................................................................................................................

Địa chỉ:..................................................................................................................................

Người có quyền và nghĩa vụ liên quan:

Ông (Bà):...............................................................................................................................

Địa chỉ:..................................................................................................................................

Nội dung chủ yếu của vụ, việc (5):

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

Diễn biến quá trình hòa giải(6):

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

Thỏa thuận đạt được và giải pháp thực hiện:

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

Quyền và nghĩa vụ của các bên:

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

Phương thức, thời hạn thực hiện thỏa thuận:

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

.............................................................................................................................................

Cuộc hòa giải kết thúc hồi........giờ.......phút ngày...... tháng....... năm......., biên bản được lập thành ….... bản, gửi 02 bên tranh chấp, mỗi bên 01 bản, tổ hòa giải thôn, tổ dân phố (7) …..........01 bản và được các bên nhất trí cùng ký tên dưới đây.

 

Các bên đạt được thỏa thuận hòa giải thành (8)



Ký ghi rõ họ tên

Người được mời tham gia hòa giải



Ký ghi rõ họ tên

Hòa giải viên




Ký ghi rõ họ tên

 

Hướng dẫn ghi Biên bản hòa giải thành ở cơ sở:

(1) Ghi một trong các bên tranh chấp yêu cầu hòa giải hoặc do hòa giải viên chứng kiến, biết vụ việc thuộc phạm vi hòa giải hoặc theo đề nghị của cơ quan, tổ chức, cá nhân có liên quan (ví dụ: Theo đề nghị của Hội Phụ nữ thôn, bản... hoặc theo đề nghị của bà Nguyễn Thị Y là mẹ đẻ chị Nguyễn Thị B).

(2) Ghi “Hòa giải viên” nếu có 02 hòa giải viên thực hiện hòa giải hoặc ghi chức vụ, chức sắc của người được mời tham gia hòa giải như trưởng họ, già làng, giáo phu trưởng, hoặc người có trình độ pháp lý, kiến thức xã hội hoặc đại diện của cơ quan, tổ chức... (Ví dụ: Ông Nguyễn Văn A - Trưởng họ, người được mời tham gia hòa giải).

(3) Nếu bên tranh chấp là cá nhân thì ghi họ tên; nếu bên tranh chấp là cơ quan, tổ chức thì ghi tên cơ quan, tổ chức và ghi họ, tên của người đại diện hợp pháp của cơ quan, tổ chức đó.

(4) Ghi địa chỉ nơi cư trú tại thời điểm tiến hành hòa giải. Nếu bên tranh chấp là cá nhân thì ghi đầy đủ địa chỉ nơi cư trú (ví dụ: thôn B, xã C, huyện M, tỉnh H); nếu bên tranh chấp là cơ quan, tổ chức thì ghi địa chỉ trụ sở chính của cơ quan, tổ chức đó (ví dụ: Công ty TNHH Hin Sen có trụ sở: Số 20 phố LTK, quận HK, thành phố H). Ghi địa chỉ nơi làm việc nếu bên tranh chấp là cá nhân (ví dụ: Công ty TNHH Hải An, số 264 phố ĐC, quận BĐ, thành phố H).

(5) Ghi tóm tắt tranh chấp, mâu thuẫn giữa các bên.

(6) Ghi diễn biến của buổi hòa giải, ý kiến các bên.

(7) Ghi rõ địa chỉ thôn, tổ dân phố (ví dụ: thôn A, xã B, huyện C, tỉnh M hoặc tổ dân phố số 1, phường X, quận Y, thành phố H).

(8) Nếu bên tranh chấp là cá nhân thì phải có chữ ký hoặc điểm chỉ của người đó; nếu là cơ quan tổ chức thì người đại diện hợp pháp của cơ quan, tổ chức yêu cầu ký tên, ghi rõ họ tên, chức vụ của mình và đóng dấu của cơ quan, tổ chức đó.



lồng nhau (bên trong) hay không const memberID = 0; const vbID = 'efd0aa83cd4c2f7f75aaec8248c5360a'; // State management cho phân tích let isAnalyzing = false; // Có đang phân tích không let currentAnalyzingAddress = null; // Address đang được phân tích let currentAnalyzingElement = null; // Element đang được phân tích let currentAnalyzingBadge = null; // Badge của element đang phân tích let isPanelOpen = false; // Panel phân tích có đang mở không console.log('Tiện ích loaded - memberID:', memberID, 'vbID:', vbID); function isInViewportAndTabNoiDung(element) { const rect = element.getBoundingClientRect(); const buffer = 1500; // Buffer to preload content below the viewport (approx. 50+ lines) const viewHeight = window.innerHeight || document.documentElement.clientHeight; const isInViewport = rect.top < viewHeight + buffer && rect.bottom >= 0; const isInTabNoiDung = $(element).closest('#tab_noi_dung_vb').length > 0; return isInViewport && isInTabNoiDung; } function getAddress(element) { const validTags = ['trichyeu', 'cancu', 'phan', 'chuong', 'muc', 'tieumuc', 'dieu', 'khoan', 'diem']; const $parent = $(element).closest(validTags.join(',')); if (!$parent.length) { return null; } let addr = $parent.attr('address'); if (!addr && $parent.prop('tagName').toLowerCase() === 'trichyeu') { addr = 'trichyeu'; $parent.attr('address', addr); } return addr || null; } function processTnplClasses($element) { const tnplKeysInLine = new Set(); // key = slug hoặc text (thường là slug) $element.find('tnpl').each(function () { const $tnpl = $(this); const tnplSlug = ($tnpl.attr('slug') || '').trim().toLowerCase(); const tnplKey = tnplSlug || $tnpl.text().trim().toLowerCase(); // Đã xử lý trong cùng dòng => bỏ if (tnplKeysInLine.has(tnplKey)) { return; } tnplKeysInLine.add(tnplKey); let tnplExists = false; // Chỉ duyệt các tnpl đã được tô màu (class on) $('tnpl.on').each(function () { const $existingTnpl = $(this); const existingSlug = ($existingTnpl.attr('slug') || '').trim().toLowerCase(); const existingKey = existingSlug || $existingTnpl.text().trim().toLowerCase(); if ( existingKey === tnplKey && isInViewportAndTabNoiDung($existingTnpl[0]) ) { tnplExists = true; return false; // break each } }); if (!tnplExists) { $tnpl.addClass('on'); } }); } function processQueue() { while (pendingRequests < maxConcurrentRequests && requestQueue.length > 0) { const task = requestQueue.shift(); pendingRequests++; task() .always(() => { pendingRequests--; processQueue(); }); } } function processVisibleParagraphs() { try { $('#tab_noi_dung_vb p:not([is-posted="1"])').each(function () { let $element = $(this); if (isInViewportAndTabNoiDung(this)) { $element.attr('is-posted', '1'); $element.addClass('loading-content'); let p_innerHTML = $element.html(); let address = null; if (cac_cau_hinh.loai_noi_dung.includes('docs')) { address = getAddress($element); } const isSubP = $element.parents('p').length > 0; if (isSubP && !allow_sub_p) { $element.removeClass('loading-content'); return; // Không gửi nếu không cho phép } const postData = { p_content: p_innerHTML, cac_cau_hinh, address }; if (isSubP && allow_sub_p) { postData.sub_p = 1; } requestQueue.push(() => $.ajax({ url: '//tnpl' + (Math.floor(Math.random() * 10) + 1) + '.hethongphapluat.com/tien-ich/tim.tien.ich.php', type: 'POST', data: postData, success: function(response) { $element.html(response); processTnplClasses($element); // Đợi CTTD và các tiện ích load xong rồi mới attach badge if (memberID === 4 && typeof attachPhanTichBadge === 'function') { setTimeout(function() { // $element chính là thẻ p, kiểm tra và attach badge trực tiếp const $parent = $element.closest('phan, chuong, muc, tieumuc, dieu, khoan, diem'); if ($parent.length > 0 && $parent.find('.badge-phan-tich[data-for="' + $parent.attr('address') + '"]').length === 0) { const address = $parent.attr('address'); $element.attr('data-address', address); // Lấy tên loại thẻ cho tooltip const parentType = getParentTypeName($parent.prop('tagName').toLowerCase()); // Append badge VÀO PARENT (dieu, khoan,...) thay vì vào

để tránh xung đột CTTD const $badge = $('Phân tích'); $parent.append($badge); // Thêm class để CSS set position: relative CHỈ cho element có badge $parent.addClass('has-phan-tich-badge'); } // Xử lý các p con (nếu có sub-p) attachPhanTichBadge($element); }, 300); // Đợi 300ms để CTTD render xong } }, complete: function() { $element.removeClass('loading-content'); } }) ); processQueue(); } }); } catch(e) { console.error('Lỗi processVisibleParagraphs:', e); } } $(window).on('scroll resize', function () { processVisibleParagraphs(); }); console.log('Bắt đầu processVisibleParagraphs lần đầu...'); processVisibleParagraphs(); console.log('processVisibleParagraphs lần đầu hoàn thành'); // Chức năng phân tích điều luật (chỉ cho member_id = 4) if (memberID === 4) { // Modal cảnh báo function showWarningModal(message) { // Tạo modal nếu chưa có if ($('#warningModal').length === 0) { const modalHTML = `

`; $('body').append(modalHTML); } $('#warningModalBody').html('

' + message + '

'); $('#warningModal').modal('show'); } // Hàm lấy tên tiếng Việt của thẻ function getParentTypeName(tagName) { const typeNames = { 'phan': 'Phần', 'chuong': 'Chương', 'muc': 'Mục', 'tieumuc': 'Tiểu mục', 'dieu': 'Điều', 'khoan': 'Khoản', 'diem': 'Điểm' }; return typeNames[tagName] || 'Nội dung'; } function attachPhanTichBadge($container) { const validTags = 'phan, chuong, muc, tieumuc, dieu, khoan, diem'; $container.find('p').each(function() { const $p = $(this); const $parent = $p.closest(validTags); if ($parent.length > 0) { const address = $parent.attr('address'); // Kiểm tra đã có badge cho parent này chưa if ($parent.find('.badge-phan-tich[data-for="' + address + '"]').length === 0) { // Lưu address vào data attribute $p.attr('data-address', address); // Lấy tên loại thẻ cho tooltip const parentType = getParentTypeName($parent.prop('tagName').toLowerCase()); // Append badge vào PARENT, không vào

const $badge = $('Phân tích'); $parent.append($badge); // Thêm class để CSS set position: relative CHỈ cho element có badge $parent.addClass('has-phan-tich-badge'); } } }); } // Helper: Escape HTML entities function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return String(text).replace(/[&<>"']/g, function(m) { return map[m]; }); } // Helper: Convert Markdown to HTML (đơn giản) function markdownToHtml(markdown) { if (!markdown) return ''; let html = markdown; // Headers html = html.replace(/^### (.*$)/gim, '

$1
'); html = html.replace(/^## (.*$)/gim, '

$1

'); html = html.replace(/^# (.*$)/gim, '

$1

'); // Bold html = html.replace(/\*\*(.*?)\*\*/g, '$1'); // Italic html = html.replace(/\*(.*?)\*/g, '$1'); // Blockquote html = html.replace(/^> (.*$)/gim, '
$1
'); html = html.replace(/^> (.*$)/gim, '
$1
'); // Lists (unordered) html = html.replace(/^\- (.*$)/gim, '
  • $1
  • '); html = html.replace(/(
  • .*<\/li>)/s, '
      $1
    '); // Lists (ordered) html = html.replace(/^\d+\. (.*$)/gim, '
  • $1
  • '); // Line breaks và paragraphs html = html.split('\n\n').map(para => { para = para.trim(); if (para.startsWith('')) { return para; } if (para) { return '

    ' + para.replace(/\n/g, '
    ') + '

    '; } return ''; }).join('\n'); // Clean up multiple line breaks html = html.replace(/\n{3,}/g, '\n\n'); return html; } // Panel fixed position function closePhanTichPanel() { const $panel = $('#phanTichPanel'); if ($panel.length) { $panel.removeClass('show'); setTimeout(() => { $panel.remove(); }, 300); } // Reset highlight và badge khi đóng panel if (currentAnalyzingElement) { currentAnalyzingElement.removeClass('highlight-border-persistent'); } if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); currentAnalyzingBadge.data('hovering', false); currentAnalyzingBadge.css({display: 'none'}); // Ẩn badge khi đóng } // Reset tất cả các element khác (trong trường hợp có nhiều) $('#tab_noi_dung_vb .highlight-border-persistent').removeClass('highlight-border-persistent'); $('#tab_noi_dung_vb .badge-phan-tich-container.analyzing').each(function() { $(this).text('Phân tích').removeClass('analyzing').data('analyzing', false); }); // Check: có CTTD pointer đang mở không? const $visiblePointers = $('.pointer:visible'); const hadCTTDOpen = $visiblePointers.length > 0; if (hadCTTDOpen) { // CÓ CTTD đang mở → giữ rightdocinfo ẩn console.log('ℹ️ CTTD pointer is visible, keeping rightdocinfo hidden'); } else { // KHÔNG có CTTD → SHOW lại rightdocinfo const $rightdocinfo = $('#rightdocinfo'); if ($rightdocinfo.length > 0) { $rightdocinfo.show(); console.log('✅ Showing rightdocinfo back (no CTTD pointer)'); } } // Reset state isAnalyzing = false; currentAnalyzingAddress = null; currentAnalyzingElement = null; currentAnalyzingBadge = null; isPanelOpen = false; // Đánh dấu panel đã đóng console.log('✅ Panel closed, state reset, isPanelOpen = false'); } // Panel đã song song với rightdocinfo → không cần MutationObserver nữa console.log('✅ Panel running in standalone mode (parallel to rightdocinfo)'); // Resize event để update panel dimensions khi browser resize let resizeTimer; $(window).on('resize', function() { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { if (isPanelOpen && $('#phanTichPanel').length > 0) { updatePanelDimensions(); console.log('✅ Panel dimensions updated on window resize'); } }, 250); // Debounce 250ms }); // Function để detect và áp dụng dimensions từ rightdocinfo function updatePanelDimensions() { const $panel = $('#phanTichPanel'); const $rightdocinfo = $('#rightdocinfo'); const $docRightCol = $('#doc-right-col'); if ($panel.length === 0) return; // Ưu tiên: doc-right-col > rightdocinfo let $reference = $docRightCol.length > 0 ? $docRightCol : $rightdocinfo; // Nếu reference bị ẩn (display:none), tạm show để get dimensions let wasHidden = false; if ($reference.length > 0 && !$reference.is(':visible')) { wasHidden = true; $reference.css('visibility', 'hidden').show(); } if ($reference.length > 0) { const refWidth = $reference.outerWidth(); const refOffset = $reference.offset(); if (refWidth && refOffset) { // Tính vị trí right từ edge màn hình const windowWidth = $(window).width(); const rightPosition = windowWidth - (refOffset.left + refWidth); $panel.css({ 'width': refWidth + 'px', 'right': rightPosition + 'px' }); console.log('✅ Panel dimensions updated:', { width: refWidth + 'px', right: rightPosition + 'px', reference: $reference.attr('id') }); } else { console.warn('⚠️ Could not get dimensions from reference element'); } // Restore trạng thái hidden nếu cần if (wasHidden) { $reference.hide().css('visibility', ''); } } else { console.warn('⚠️ No reference element found for panel dimensions'); } } function openPhanTichPanel(address, vbID) { console.log('openPhanTichPanel called with address:', address); console.log('Current state - isAnalyzing:', isAnalyzing, 'currentAnalyzingAddress:', currentAnalyzingAddress); // Kiểm tra nếu đang phân tích element khác if (isAnalyzing && currentAnalyzingAddress && currentAnalyzingAddress !== address) { const currentName = getElementDisplayName(currentAnalyzingAddress); console.warn('Already analyzing:', currentAnalyzingAddress, 'Cannot analyze:', address); showWarningModal('Vui lòng chờ phân tích ' + currentName + ' hoàn tất...'); return; } // Nếu đang phân tích cùng element → không làm gì if (isAnalyzing && currentAnalyzingAddress === address) { console.log('Already analyzing this element, ignoring duplicate request'); return; } // Panel sẽ fixed position append vào body const $rightdocinfo = $('#rightdocinfo'); // KHÔNG ẨN CTTD pointer - cho phép CTTD và panel cùng tồn tại console.log('Panel opening, CTTD pointer can stay visible'); // ẨN rightdocinfo để tiết kiệm không gian if ($rightdocinfo.length > 0) { $rightdocinfo.hide(); console.log('Hidden rightdocinfo to save space'); } // XÓA highlight persistent của TẤT CẢ elements cũ trước $('#tab_noi_dung_vb .highlight-border-persistent').removeClass('highlight-border-persistent'); console.log('Removed all previous highlight-border-persistent'); // Tìm element đang được phân tích và badge của nó const $element = $('[address="' + address + '"]'); const $badge = $element.find('.badge-phan-tich-container[data-for="' + address + '"]').first(); // Set state isAnalyzing = true; currentAnalyzingAddress = address; currentAnalyzingElement = $element; currentAnalyzingBadge = $badge; console.log('State set:', { isAnalyzing: isAnalyzing, currentAnalyzingAddress: currentAnalyzingAddress, elementFound: $element.length > 0, badgeFound: $badge.length > 0 }); // Thêm highlight persistent cho element MỚI này $element.addClass('highlight-border-persistent'); // Thay đổi badge thành "Đang phân tích..." và giữ hiển thị if ($badge.length > 0) { $badge.text('Đang phân tích...').addClass('analyzing'); // Giữ badge hiển thị và ở đúng vị trí $badge.data('analyzing', true); $badge.data('hovering', true); // Prevent auto-hide console.log('Badge set to analyzing state'); // Đảm bảo badge hiển thị ở đúng vị trí (vì dùng position: fixed) showPhanTichBadgeForParent($element); } // Tạo panel nếu chưa có - fixed position append vào body if ($('#phanTichPanel').length === 0) { const panelHTML = `
    Phân tích điều luật
    Đang phân tích...

    Đang phân tích...

    `; // Append vào body (fixed position không cần container cụ thể) $('body').append(panelHTML); // Detect width từ rightdocinfo và áp dụng cho panel updatePanelDimensions(); // Trigger show và set flag setTimeout(() => { $('#phanTichPanel').addClass('show'); isPanelOpen = true; console.log('✅ Panel opened (fixed position), isPanelOpen = true'); }, 10); } else { $('#phanTichPanelBody').html(`
    Đang phân tích...

    Đang phân tích...

    `); // Update dimensions khi re-open updatePanelDimensions(); $('#phanTichPanel').addClass('show'); isPanelOpen = true; console.log('✅ Panel re-opened (fixed position), isPanelOpen = true'); } // Bind nút đóng và ESC $(document).off('click.closePhanTich').on('click.closePhanTich', '.close-phan-tich', function() { closePhanTichPanel(); }); $(document).off('keyup.closePhanTich').on('keyup.closePhanTich', function(e) { if (e.key === 'Escape') closePhanTichPanel(); }); // Bind nút refresh - phân tích lại $(document).off('click.refreshPhanTich').on('click.refreshPhanTich', '.btn-refresh-phan-tich', function(e) { e.preventDefault(); e.stopPropagation(); const $btn = $(this); const $icon = $btn.find('i'); // Disable button và thêm animation $btn.prop('disabled', true); $icon.addClass('fa-spin'); console.log('🔄 Refresh: Phân tích lại address:', address); // Show loading trong panel $('#phanTichPanelBody').html(`
    Đang phân tích lại...

    Đang xóa cache và phân tích lại...

    `); // Gọi API xóa cache trước deletePhanTichCache(address, vbID, function(deleteSuccess) { if (deleteSuccess) { console.log('✅ Cache deleted, now re-analyzing...'); // Sau khi xóa cache, gọi lại API phân tích callPhanTichAPI(address, vbID, function() { // Enable lại button $btn.prop('disabled', false); $icon.removeClass('fa-spin'); }); } else { console.error('❌ Failed to delete cache'); $('#phanTichPanelBody').html(` `); $btn.prop('disabled', false); $icon.removeClass('fa-spin'); } }); }); // Gọi API phân tích (dùng function helper) callPhanTichAPI(address, vbID); } // Helper: Gọi API phân tích (tách riêng để dùng lại) function callPhanTichAPI(address, vbID, callback) { const randomServer = Math.floor(Math.random() * 10) + 1; $.ajax({ url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/phan.tich.dieu.luat.php', type: 'POST', contentType: 'application/json', timeout: 300000, // 5 phút data: JSON.stringify({ address: address, vb_id: vbID }), success: function(response) { console.log('Analysis complete for:', address, response); // Reset badge về trạng thái bình thường (nhưng vẫn hiển thị) if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); console.log('Badge reset to normal state'); } // Reset state analyzing để có thể phân tích element khác isAnalyzing = false; console.log('State reset: isAnalyzing = false, can analyze other elements now'); if (response.ok) { // Render kết quả phân tích let html = ''; html += '
    '; html += '
    ' + escapeHtml(response.ten_van_ban) + '
    '; if (response.so_hieu) { html += 'Số hiệu: ' + escapeHtml(response.so_hieu) + '
    '; } html += 'Điều khoản: ' + escapeHtml(response.address) + ''; if (response.from_cache) { html += ' Cache'; } html += '
    '; html += '
    ' + markdownToHtml(response.phan_tich) + '
    '; if (response.usage) { html += '
    '; html += 'Thống kê: '; html += 'Input tokens: ' + (response.usage.promptTokenCount || 0) + ', '; html += 'Output tokens: ' + (response.usage.candidatesTokenCount || 0); html += '
    '; } $('#phanTichPanelBody').html(html); } else { $('#phanTichPanelBody').html(` `); } if (callback) callback(); }, error: function(xhr, status, error) { console.error('Analysis error:', error); // Reset badge về trạng thái bình thường if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); } // Reset state analyzing isAnalyzing = false; let errorMsg = error; if (xhr.responseJSON && xhr.responseJSON.error) { errorMsg = xhr.responseJSON.error; } $('#phanTichPanelBody').html(` `); if (callback) callback(); } }); } // Helper: Xóa cache phân tích function deletePhanTichCache(address, vbID, callback) { const randomServer = Math.floor(Math.random() * 10) + 1; $.ajax({ url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/delete.phan.tich.cache.php', type: 'POST', contentType: 'application/json', timeout: 10000, data: JSON.stringify({ address: address, vb_id: vbID }), success: function(response) { console.log('Delete cache response:', response); if (callback) callback(response.ok || false); }, error: function(xhr, status, error) { console.error('Delete cache error:', error); if (callback) callback(false); } }); } // Helper: Lấy tên hiển thị của element từ address function getElementDisplayName(address) { if (!address) return 'nội dung'; const $element = $('[address="' + address + '"]'); if ($element.length === 0) return address; // Parse address: vd "dieu_3_khoan_29" -> "Khoản 29 Điều 3" // Address format: lớn đến nhỏ (phan > chuong > muc > dieu > khoan > diem) const parts = address.split('_'); const displayParts = []; for (let i = 0; i < parts.length; i += 2) { if (i + 1 < parts.length) { const type = getParentTypeName(parts[i]); const num = parts[i + 1]; displayParts.push(type + ' ' + num); } } // Reverse để hiển thị từ nhỏ đến lớn: "Khoản 29 Điều 3" (thay vì "Điều 3 Khoản 29") return displayParts.reverse().join(' '); } function openPhanTichModal(address, vbID) { // Tạo modal nếu chưa có if ($('#modalPhanTich').length === 0) { const modalHTML = ` `; $('body').append(modalHTML); } // Reset và hiển thị modal với loading $('#modalPhanTichBody').html(`
    Đang phân tích...

    Đang phân tích...

    `); $('#modalPhanTich').modal('show'); // AJAX request const randomServer = Math.floor(Math.random() * 10) + 1; $.ajax({ url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/phan.tich.dieu.luat.php', type: 'POST', contentType: 'application/json', data: JSON.stringify({ address: address, vb_id: vbID }), success: function(response) { if (response.ok) { // Render kết quả phân tích let html = ''; // Header thông tin văn bản html += '
    '; html += '
    ' + escapeHtml(response.ten_van_ban) + '
    '; if (response.so_hieu) { html += 'Số hiệu: ' + escapeHtml(response.so_hieu) + '
    '; } html += 'Điều khoản: ' + escapeHtml(response.address) + ''; html += '
    '; // Nội dung phân tích (Markdown -> HTML) html += '
    '; html += markdownToHtml(response.phan_tich); html += '
    '; // Thông tin usage (nếu có) if (response.usage) { html += '
    '; html += 'Thống kê: '; html += 'Input tokens: ' + (response.usage.promptTokenCount || 0) + ', '; html += 'Output tokens: ' + (response.usage.candidatesTokenCount || 0); html += '
    '; } $('#modalPhanTichBody').html(html); } else { $('#modalPhanTichBody').html(` `); } }, error: function(xhr, status, error) { let errorMsg = error; if (xhr.responseJSON && xhr.responseJSON.error) { errorMsg = xhr.responseJSON.error; } $('#modalPhanTichBody').html(` `); } }); } // Helpers: show/hide badge cho parent element (dieu, khoan,...) với position: fixed function showPhanTichBadgeForParent($parent) { // Lấy badge CỦA CHÍNH parent này (match data-for với address của parent) const parentAddress = $parent.attr('address'); const $badge = $parent.find('.badge-phan-tich-container[data-for="' + parentAddress + '"]').first(); if ($badge.length === 0) { console.warn('No badge found for parent:', parentAddress); return; } // Ẩn TẤT CẢ các badge khác để tránh overlap $('.badge-phan-tich-container').not($badge).each(function() { const $otherBadge = $(this); // Chỉ ẩn badge KHÔNG đang analyzing if (!$otherBadge.data('analyzing')) { $otherBadge.css({display: 'none'}); } }); // Show badge tạm để tính width $badge.css({display: 'inline-block', opacity: 0, visibility: 'hidden'}); const badgeWidth = $badge.outerWidth(); // Tính toán vị trí fixed dựa trên offset của parent const offset = $parent.offset(); const scrollTop = $(window).scrollTop(); const scrollLeft = $(window).scrollLeft(); // Position badge top-right của parent và show $badge.css({ display: 'inline-block', visibility: 'visible', opacity: 1, top: (offset.top - scrollTop) + 'px', left: (offset.left + $parent.outerWidth() - badgeWidth - scrollLeft - 5) + 'px' // -5px padding }); console.log('Showing badge for:', parentAddress, 'at position:', $badge.css('top'), $badge.css('left')); $parent.addClass('highlight-border'); } function hidePhanTichBadgeForParent($parent) { const $badge = $parent.find('.badge-phan-tich-container').first(); if ($badge.length === 0) return; $badge.css({display: 'none', opacity: 0}); $parent.removeClass('highlight-border'); } // Biến lưu element đang hover let currentHoveredElement = null; let hoverDebounceTimer = null; // Dùng mousemove để track chính xác element nào đang được hover $(document).on('mousemove', '#tab_noi_dung_vb', function(e) { // Tìm element gần nhất (phan, chuong, muc, dieu, khoan, diem) tại vị trí chuột const $target = $(e.target).closest('phan, chuong, muc, tieumuc, dieu, khoan, diem'); if ($target.length === 0) { // Không hover vào element nào return; } const address = $target.attr('address'); // Nếu đang hover vào cùng element → skip if (currentHoveredElement && currentHoveredElement[0] === $target[0]) { return; } // Clear debounce timer cũ if (hoverDebounceTimer) { clearTimeout(hoverDebounceTimer); } // Debounce để tránh trigger quá nhiều hoverDebounceTimer = setTimeout(function() { // Element thay đổi console.log('Hover changed to:', address); // Set flag hovering cho element mới $target.data('hovering', true); // Cancel timeout nếu có const timeoutId = $target.data('hideTimeout'); if (timeoutId) { clearTimeout(timeoutId); } // Ẩn badge của TẤT CẢ elements khác $('#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem') .not($target) .each(function() { const $el = $(this); // Chỉ xóa highlight-border, KHÔNG xóa highlight-border-persistent $el.removeClass('highlight-border'); // Ẩn badge nếu KHÔNG đang analyzing const $badge = $el.find('.badge-phan-tich-container'); if ($badge.length && !$badge.data('analyzing')) { $badge.css({display: 'none'}); } }); // Attach badge nếu chưa có if (address && $target.find('.badge-phan-tich-container[data-for="' + address + '"]').length === 0) { const parentType = getParentTypeName($target.prop('tagName').toLowerCase()); const $badge = $('Phân tích'); console.log('Creating badge for address:', address, 'parentType:', parentType); $target.append($badge); $target.addClass('has-phan-tich-badge'); } // Show badge cho element này if ($target.find('.badge-phan-tich-container').length > 0) { showPhanTichBadgeForParent($target); } // Update current hovered element currentHoveredElement = $target; }, 50); // Debounce 50ms }); // Event delegation cho hover ra khỏi #tab_noi_dung_vb $(document).on('mouseleave', '#tab_noi_dung_vb', function(e) { // Clear current hovered element currentHoveredElement = null; // Ẩn tất cả badge không đang analyzing sau một khoảng thời gian setTimeout(function() { if (currentHoveredElement === null) { // Chỉ ẩn nếu thực sự không hover vào element nào $('#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem') .each(function() { const $el = $(this); const $badge = $el.find('.badge-phan-tich-container'); if ($badge.length && !$badge.data('analyzing')) { $badge.css({display: 'none'}); } }); console.log('Mouse left tab_noi_dung_vb, hiding all badges'); } }, 300); }); // Event delegation cho hover ra khỏi parent (giữ lại cho badge behavior) $(document).on('mouseleave', '#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem', function(e) { const $parent = $(this); const parentAddress = $parent.attr('address'); const $badge = $parent.find('.badge-phan-tich-container[data-for="' + parentAddress + '"]').first(); // Set flag parent not hovering $parent.data('hovering', false); // Nếu badge đang analyzing thì KHÔNG ẩn, GIỮ hiển thị if ($badge.length > 0 && $badge.data('analyzing')) { console.log('Badge is analyzing, keep visible'); return; } // Delay để có thời gian di chuột vào badge const timeoutId = setTimeout(() => { // Chỉ ẩn nếu cả parent và badge đều không hover và không analyzing if ($badge.length > 0 && !$parent.data('hovering') && !$badge.data('hovering') && !$badge.data('analyzing')) { hidePhanTichBadgeForParent($parent); } }, 300); // Tăng lên 300ms $parent.data('hideTimeout', timeoutId); }); // Hover vào badge → giữ hiển thị $(document).on('mouseenter', '.badge-phan-tich-container', function(e) { e.stopPropagation(); const $badge = $(this); const $parent = $badge.parent(); $badge.data('hovering', true); // Cancel timeout của parent const timeoutId = $parent.data('hideTimeout'); if (timeoutId) { clearTimeout(timeoutId); } }); // Hover ra khỏi badge → ẩn nếu không hover parent $(document).on('mouseleave', '.badge-phan-tich-container', function(e) { const $badge = $(this); $badge.data('hovering', false); const $parent = $badge.parent(); // Nếu badge đang analyzing thì KHÔNG ẩn, GIỮ hiển thị if ($badge.data('analyzing') || $badge.hasClass('analyzing')) { console.log('Badge is analyzing on mouseleave, keep visible'); return; } setTimeout(() => { // Chỉ ẩn nếu cả parent và badge đều không hover và không analyzing if (!$parent.data('hovering') && !$badge.data('hovering') && !$badge.data('analyzing') && !$badge.hasClass('analyzing')) { hidePhanTichBadgeForParent($parent); } }, 300); }); // Event delegation cho hover vào badge → hiện tooltip $(document).on('mouseenter', '.badge-phan-tich, .badge-phan-tich-container, .badge-phan-tich-fixed', function() { const $badge = $(this); const parentType = $badge.attr('data-parent-type') || 'Nội dung'; if ($badge.find('.badge-tooltip').length === 0) { const $tooltip = $('Phân tích chi tiết nội dung ' + parentType + ' này'); $badge.append($tooltip); setTimeout(() => $tooltip.addClass('show'), 10); } }); // Event delegation cho hover ra khỏi badge → ẩn tooltip $(document).on('mouseleave', '.badge-phan-tich, .badge-phan-tich-container, .badge-phan-tich-fixed', function() { const $tooltip = $(this).find('.badge-tooltip'); if ($tooltip.length > 0) { $tooltip.removeClass('show'); setTimeout(() => $tooltip.remove(), 300); } }); // Event delegation cho click badge → mở panel $(document).on('click', '.badge-phan-tich, .badge-phan-tich-container, .badge-phan-tich-fixed', function(e) { e.preventDefault(); e.stopPropagation(); const $badge = $(this); console.log('Badge clicked! Element:', $badge[0]); console.log('Badge parent:', $badge.parent().prop('tagName'), $badge.parent().attr('address')); console.log('Badge data-for:', $badge.attr('data-for')); console.log('Badge data-parent-type:', $badge.attr('data-parent-type')); // Nếu badge đang analyzing thì không cho click if ($badge.hasClass('analyzing') || $badge.data('analyzing')) { console.log('Badge is analyzing, click ignored'); return; } // Lấy address từ data-for attribute const address = $badge.attr('data-for'); console.log('Will analyze address:', address, 'vbID:', vbID); if (address && vbID) { openPhanTichPanel(address, vbID); } else { console.error('Missing address or vbID', {address, vbID}); showWarningModal('Không tìm thấy địa chỉ điều luật hoặc ID văn bản!'); } }); // Ẩn badge khi click vào CTTD $(document).on('click', 'cttd.chuthichtudong span, dctk span, dctd span', function(e) { console.log('CTTD clicked'); // Ẩn TẤT CẢ badge KHÔNG đang analyzing $('.badge-phan-tich-container').each(function() { const $badge = $(this); if (!$badge.data('analyzing') && !$badge.hasClass('analyzing')) { $badge.css({display: 'none'}); console.log('Hiding badge:', $badge.attr('data-for')); } }); }); // Update badge position khi scroll hoặc resize (vì dùng position: fixed) function updateBadgePositions() { $('.badge-phan-tich-container:visible').each(function() { const $badge = $(this); const $parent = $badge.parent(); // Cập nhật position nếu parent đang hover HOẶC badge đang analyzing if ($parent.length && ($parent.is(':hover') || $badge.data('analyzing'))) { // Re-calculate position const offset = $parent.offset(); const scrollTop = $(window).scrollTop(); const scrollLeft = $(window).scrollLeft(); const badgeWidth = $badge.outerWidth(); $badge.css({ top: (offset.top - scrollTop) + 'px', left: (offset.left + $parent.outerWidth() - badgeWidth - scrollLeft - 5) + 'px' }); } }); } $(window).on('scroll', updateBadgePositions); $(window).on('resize', updateBadgePositions); } });