Tối Ưu Hóa Classic Editor: Thêm Tìm Kiếm Danh Mục

by daiphucminh

🔍

Đoạn mã PHP & JS để tìm kiếm danh mục tức thời (Live Search) trong khu vực soạn thảo

1. 💡 Giới Thiệu và Mục Đích

Khi bạn sử dụng **Classic Editor** và quản lý một trang web có hàng trăm hoặc hàng nghìn danh mục (categories) hay các thuật ngữ phân loại (taxonomies) khác (như Product Categories trong WooCommerce), việc tìm kiếm và chọn danh mục trở nên vô cùng khó khăn.

Đoạn mã này giải quyết vấn đề bằng cách **thêm một ô tìm kiếm tức thời (Live Search Box)** vào phía trên hộp meta danh mục. Nó sử dụng JavaScript để lọc danh sách ngay trên giao diện người dùng mà không cần tải lại trang.

2. ⚒️ Hướng Dẫn Cài Đặt

Quan trọng: Bạn nên luôn sử dụng **Child Theme** (Theme con) và sao lưu file functions.php trước khi thực hiện bất kỳ thay đổi nào.

  1. Truy cập file functions.php của theme đang hoạt động.
  2. Sao chép toàn bộ đoạn mã PHP bên dưới.
  3. Dán đoạn mã vào cuối file functions.php (trước thẻ đóng ?> nếu có).
  4. Lưu file và truy cập vào trang chỉnh sửa bài viết (Post Editor) để kiểm tra kết quả.

3. 💻 Đoạn Mã Nguồn (Dán vào functions.php)

<?php
/* -------------------------------------------------------
 Classic Editor Category Search (CECS)
 Works with ALL post types having category checklist
 ------------------------------------------------------- */

/* 1. Load ALL categories (Bỏ giới hạn hiển thị danh mục) */
add_filter('wp_terms_checklist_args', function($args) {
    $args['number'] = 0; // Hiển thị tất cả danh mục
    $args['checked_ontop'] = false;
    return $args;
});

/* 2. CSS - Định kiểu cho ô tìm kiếm và hộp danh mục */
add_action('admin_head', function () {
    ?>
    <style>
        .cecs-search-input {
            width: 100%;
            box-sizing: border-box;
            margin-bottom: 8px;
            padding: 6px 8px;
        }

        #category-all,
        .tabs-panel {
            resize: vertical !important; /* Cho phép thay đổi chiều cao */
            overflow: auto !important;
            min-height: 120px;
            max-height: 220px; /* Chiều cao mặc định */
        }
    </style>
    <?php
});

/* 3. JS - Thêm ô tìm kiếm và Logic lọc tức thời */
add_action('admin_enqueue_scripts', function () {

    $screen = get_current_screen();
    if (!$screen) return;

    // Chỉ chạy ở trang chỉnh sửa bài viết hoặc trang tạo mới
    if ($screen->base !== 'post' && $screen->base !== 'post-new') return;

    add_action('admin_print_footer_scripts', function () {
?>
<script>
document.addEventListener('DOMContentLoaded', function () {

    // Lấy ALL taxonomy checklist
    const containers = document.querySelectorAll('.tabs-panel, #category-all');

    containers.forEach((container, idx) => {

        if (!container) return;
        if (container.querySelector('.cecs-search-input')) return;

        // Tạo ô input
        const input = document.createElement('input');
        input.type = 'text';
        input.placeholder = 'Tìm kiếm danh mục...';
        input.className = 'cecs-search-input';

        container.prepend(input);

        // Logic Lọc danh mục
        input.addEventListener('input', function () {

            const kw = this.value.trim().toLowerCase();
            const allLi = Array.from(container.querySelectorAll('li'));
            const allLabels = Array.from(container.querySelectorAll('label'));

            if (!kw) {
                // Nếu không có từ khóa, hiển thị lại tất cả
                allLi.forEach(li => li.style.display = '');
                return;
            }

            allLi.forEach(li => li.style.display = 'none'); // Ẩn tất cả

            allLabels.forEach(label => {
                const text = (label.textContent || '').toLowerCase();
                if (text.includes(kw)) {
                    const li = label.closest('li');
                    if (!li) return;

                    li.style.display = ''; // Hiển thị mục khớp

                    // Hiển thị danh mục cha (Parent) nếu danh mục con khớp
                    let parent = li.parentElement.closest('li');
                    while (parent) {
                        parent.style.display = '';
                        parent = parent.parentElement.closest('li');
                    }
                }
            });
        });
    });
});
</script>
<?php
    });
});

/* 4. JS - Giữ Chiều cao khi Resize (Khắc phục lỗi trình duyệt) */
add_action('admin_print_footer_scripts', function () { ?>
<script>
document.addEventListener('DOMContentLoaded', function () {

    const boxes = document.querySelectorAll('.tabs-panel, #category-all');

    boxes.forEach(box => {
        if (!box) return;

        // Đảm bảo các style đã được áp dụng
        box.style.resize = "vertical";
        box.style.overflow = "auto";
        box.style.maxHeight = "220px"; 

        let isResizing = false;

        box.addEventListener('mousedown', function(e) {
            const rect = box.getBoundingClientRect();
            // Kiểm tra xem chuột có gần mép dưới để resize không
            if (rect.bottom - e.clientY < 20) {
                isResizing = true;
                box.style.maxHeight = "none"; // Tắt max-height khi resize
            }
        });

        document.addEventListener('mouseup', function() {
            if (isResizing) {
                isResizing = false;
                const h = box.offsetHeight;
                box.style.height = h + "px"; // Thiết lập chiều cao cố định
                box.style.maxHeight = "none";
            }
        });
    });
});
</script>
<?php });
?>

4. ✅ Lợi Ích Chính

  • Tìm kiếm Tức thời: Lọc danh mục ngay khi gõ, tăng tốc độ làm việc.
  • Hỗ trợ Phân cấp: Tự động hiển thị danh mục cha khi danh mục con khớp với từ khóa.
  • Tùy chỉnh Chiều cao: Cho phép người dùng kéo chuột để thay đổi chiều cao hộp danh mục, cải thiện khả năng quan sát.
Chúc bạn thành công khi áp dụng đoạn mã này vào WordPress!

Related Posts

Leave a Comment

-
00:00
00:00
Update Required Flash plugin
-
00:00
00:00