Tích Hợp AJAX Để Tải Danh Mục Danh Mục Tùy Chỉnh Và Tạo Dropdown Tùy Chỉnh Trong WordPress

/**
 * Xử lý yêu cầu AJAX để tải danh mục dựa trên ID danh mục chính.
 */
function wpex_implement_ajax() {
    if (isset($_POST['main_catids']) && $_POST['main_catids'] != 0) {
        $categories = get_categories(array(
            'child_of' => (int) $_POST['main_catids'],
            'hide_empty' => 1,
            'taxonomy' => 'location'
        ));
        
        $option = '<option value="0" selected="selected">-- Chọn Quận / Huyện --</option>';
        
        foreach ($categories as $cat) {
            $is_selected = isset($_GET['qh']) && $_GET['qh'] == $cat->term_id ? ' selected' : '';
            $option .= '<option value="' . esc_attr($cat->term_id) . '"' . $is_selected . '>' . esc_html($cat->cat_name) . '</option>';
        }
        
        echo $option;
        wp_die(); // Thay thế die() bằng wp_die() để xử lý AJAX chính xác.
    }
}
add_action('wp_ajax_wpex_ajax_calls', 'wpex_implement_ajax');
add_action('wp_ajax_nopriv_wpex_ajax_calls', 'wpex_implement_ajax');

/**
 * Tùy chỉnh lớp Walker để hiển thị danh mục trong dropdown.
 */
class Walker_Custom_CategoryDropdown extends Walker_CategoryDropdown {
    
    public function start_el(&$output, $category, $depth = 0, $args = array(), $id = 0) {
        $pad = str_repeat('&nbsp;', $depth * 3);
        $cat_name = apply_filters('list_cats', $category->name, $category);
        
        $value_field = isset($args['value_field']) && isset($category->{$args['value_field']}) ? $args['value_field'] : 'term_id';
        
        $output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr($category->{$value_field}) . "\"";
        
        if ((string) $category->{$value_field} === (string) $args['selected']) {
            $output .= ' selected="selected"';
        }
        
        $output .= ' data-uri="' . esc_url(get_term_link($category)) . '" ';
        $output .= '>';
        $output .= $pad . esc_html($cat_name);
        
        if ($args['show_count']) {
            $output .= '&nbsp;&nbsp;(' . number_format_i18n($category->count) . ')';
        }
        
        $output .= "</option>\n";
    }
}

/**
 * Tùy chỉnh lớp Walker để tạo dropdown với các nhóm optgroup.
 */
class WP_Walker_Optgroup extends Walker_CategoryDropdown {

    var $optgroup = false;

    public function start_el(&$output, $category, $depth = 0, $args = array(), $id = 0) {
        $pad = str_repeat(' ', $depth * 3);
        $cat_name = apply_filters('list_cats', $category->name, $category);
        
        if ($depth == 0) {
            $this->optgroup = true;
            $output .= '<select class="level-' . $depth . '" label="' . esc_attr($cat_name) . '" >';
        } else {
            $this->optgroup = false;
            $output .= '<option class="level-' . $depth . '" value="' . esc_attr($category->term_id) . '"';
            if ($category->term_id == $args['selected']) {
                $output .= ' selected="selected"';
            }
            $output .= '>' . $pad . esc_html($cat_name);
            if ($args['show_count']) {
                $output .= ' (' . esc_html($category->count) . ')';
            }
            $output .= "</option>";
        }
    }

    public function end_el(&$output, $object, $depth = 0, $args = array()) {
        if ($depth == 0 && $this->optgroup) {
            $output .= '</select>';
        }
    }
}