基于前置选择框值从wpdb动态生成子选择框选项
WordPress 二级分类联动下拉框实现方案
1. 更新HTML结构
在原有主分类选择框后新增子分类选择框:
<!-- 主分类选择框 --> <select id="add-item-category-input" name="add-items-category"> <?php global $wpdb; $categories_table = $wpdb->prefix . 'mp_inventory_categories'; $categories = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $categories_table WHERE cat_type = %s", 'main') ); foreach ($categories as $category) { echo '<option value="' . esc_attr($category->sku_ident) . '">'; // 简化分类名格式化逻辑 echo ucwords(str_replace("_", " ", $category->category_name)); echo '</option>'; } ?> </select> <!-- 子分类选择框(初始状态) --> <select id="add-item-subcategory-input" name="add-items-subcategory"> <option value="">请先选择主分类</option> </select>
2. 注册Ajax接口(主题functions.php中添加)
通过WordPress官方Ajax机制实现数据库查询,避免前端直接操作数据库:
// 注册Ajax动作(支持登录/未登录用户) add_action('wp_ajax_get_subcategories', 'get_subcategories_callback'); add_action('wp_ajax_nopriv_get_subcategories', 'get_subcategories_callback'); function get_subcategories_callback() { global $wpdb; $categories_table = $wpdb->prefix . 'mp_inventory_categories'; // 参数校验 if (!isset($_POST['parent_sku']) || empty($_POST['parent_sku'])) { wp_send_json_error('缺少主分类标识'); } $parent_sku = sanitize_text_field($_POST['parent_sku']); // 查询符合条件的子分类 $subcategories = $wpdb->get_results( $wpdb->prepare( "SELECT sku_ident, category_name FROM $categories_table WHERE cat_type = %s AND parent = %s", 'sub', $parent_sku ) ); // 构造返回的选项数据 $options = []; if (!empty($subcategories)) { foreach ($subcategories as $subcat) { $options[] = [ 'value' => $subcat->sku_ident, 'label' => ucwords(str_replace("_", " ", $subcat->category_name)) ]; } } wp_send_json_success($options); }
3. 前端联动逻辑(原生JS版本)
监听主分类选择事件,通过Ajax请求动态生成子分类选项:
document.addEventListener('DOMContentLoaded', function() { const mainCatSelect = document.getElementById('add-item-category-input'); const subCatSelect = document.getElementById('add-item-subcategory-input'); mainCatSelect.addEventListener('change', function() { const parentSku = this.value; subCatSelect.innerHTML = '<option value="">加载中...</option>'; // 发送Ajax请求到WordPress接口 fetch('/wp-admin/admin-ajax.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, body: new URLSearchParams({ action: 'get_subcategories', parent_sku: parentSku }) }) .then(response => response.json()) .then(data => { subCatSelect.innerHTML = ''; if (data.success) { if (data.data.length === 0) { subCatSelect.innerHTML = '<option value="">该主分类无子分类</option>'; } else { // 添加默认提示选项 const defaultOption = document.createElement('option'); defaultOption.value = ''; defaultOption.textContent = '请选择子分类'; subCatSelect.appendChild(defaultOption); // 插入子分类选项 data.data.forEach(subcat => { const option = document.createElement('option'); option.value = subcat.value; option.textContent = subcat.label; subCatSelect.appendChild(option); }); } } else { subCatSelect.innerHTML = `<option value="">加载失败:${data.data}</option>`; } }) .catch(error => { subCatSelect.innerHTML = '<option value="">请求出错</option>'; console.error('Ajax请求错误:', error); }); }); });
关键注意事项
- 所有输出的属性值用
esc_attr()转义,避免XSS风险 - 数据库查询使用
wpdb->prepare()防止SQL注入 - 如果使用jQuery,可替换为
$.ajax()简化代码,需确保ajaxurl全局变量可用(通过wp_localize_script传递)
内容的提问来源于stack exchange,提问作者maxipoo
相关产品推荐
相关产品推荐

