我有两个具有父类别和子类别的数组,每个数组都出现在一个选择列表中,如何使子类别仅显示其父类别中的项目?
<?php $carMakes = array(
'show_option_all' => '',
'show_option_none' => ('All Makes'),
'orderby' => 'ID',
'order' => 'ASC',
'show_count' => 0,
'hide_empty' => 1,
'child_of' => 25,
'exclude' => 0,
'echo' => 1,
'selected' => 0,
'hierarchical' => 0,
'name' => 'cat',
'id' => '',
'class' => 'postform',
'depth' => 0,
'tab_index' => 0,
'taxonomy' => 'category',
'hide_if_empty' => false
); ?>
<?php $carModels = array(
'name' => 'subcat',
'hierarchical' => 1,
'parent' => get_cat_id('model'),
'show_option_none' => ('All Models'),
'hide_empty' => 0 );
?>
<?php wp_dropdown_categories($carMakes); ?>
<?php wp_dropdown_categories($carModels); ?>
只需要显示属于汽车的汽车模型,例如
Make=Toyota Model=Supra
Model=Corolla
Model=Tundra
以下是类别结构的示例
Make (parent category)
-Toyota
-Nissan
-Mazda
-Ford
Model (parent category)
-Supra
-Skyline
-Mustang
-Rx7
-Corolla
答案 0 :(得分:6)
总是希望使用Ajax对链式选择进行练习,所以,在这里我们去;)
这是一个完整的插件,应该安装在wp-content/plugins/your-plugin-name
文件夹中。由三个文件组成,插件本身,Javascript文件和Ajax加载器映像。
安装插件并激活,在以下主题模板文件中插入以下内容:
<?php
if( class_exists( 'BRSFL_Chained_Selection' ) ) {
// Parameters: ( $cat_id, $dropdown_text )
BRSFL_Chained_Selection::print_cats( 1, 'All Makes' );
}
?>
此外,根据需要调整对wp_dropdown_categories
的两次调用。查看代码注释以获取详细信息。
为了响应类别下拉菜单中的更改,修改了子类别下拉列表
<?php
/**
* Plugin Name: Chained Categories
* Plugin URI: http://stackoverflow.com/q/15748968/1287812
* Description: Demonstration of chained categories with Ajax.
* Plugin structure based on <a href="https://gist.github.com/3804204">Plugin Class Demo</a>, by Thomas Scholz.
* Use the dropdowns in the theme with this PHP method call: BRSFL_Chained_Selection::print_cats();
* Author: Rodolfo Buaiz
* Author URI: http://wordpress.stackexchange.com/users/12615/brasofilo
*/
add_action(
'plugins_loaded',
array ( BRSFL_Chained_Selection::get_instance(), 'plugin_setup' )
);
class BRSFL_Chained_Selection
{
/**
* Plugin instance.
*
* @see get_instance()
* @type object
*/
protected static $instance = NULL;
/**
* URL to this plugin's directory.
*
* @type string
*/
public $plugin_url = '';
/**
* Path to this plugin's directory.
*
* @type string
*/
public $plugin_path = '';
/**
* Access this plugin’s working instance
*
* @wp-hook plugins_loaded
* @since 2012.09.13
* @return object of this class
*/
public static function get_instance()
{
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
/**
* Used for regular plugin work.
*
* @wp-hook plugins_loaded
* @since 2012.09.10
* @return void
*/
public function plugin_setup()
{
$this->plugin_url = plugins_url( '/', __FILE__ );
$this->plugin_path = plugin_dir_path( __FILE__ );
$this->load_language( 'chainedselections' );
add_action( 'wp_enqueue_scripts', array( $this, 'script_enqueuer' ) );
add_action( 'wp_ajax_custom_query', array( $this, 'custom_query' ) );
add_action( 'wp_ajax_nopriv_custom_query', array( $this, 'custom_query' ) );
}
/**
* Constructor. Intentionally left empty and public.
*
* @see plugin_setup()
* @since 2012.09.12
*/
public function __construct() {}
/**
* Enqueue frontend scripts
*/
public function script_enqueuer()
{
wp_register_script(
'ajax-quote'
, plugin_dir_url( __FILE__ ) . '/ajax.js'
, array( 'jquery' )
);
wp_enqueue_script( 'ajax-quote' );
wp_localize_script(
'ajax-quote'
, 'wp_ajax'
, array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
, 'ajaxnonce' => wp_create_nonce( 'ajax_chained_selection_validate' )
, 'icon' => plugin_dir_url( __FILE__ ) . '/ajax-loader.gif'
)
);
}
/**
* Ajax create sub-categories dropdown
*/
public function custom_query()
{
// Security
check_ajax_referer( 'ajax_chained_selection_validate', 'security' );
// Check if jQuery posted the data
if( !isset( $_POST[ 'chained_subcat_id' ] ) )
return false;
// Adjust parameters
$carMakes = array(
'show_option_all' => '',
'show_option_none' => 'All ' . $_POST[ 'chained_subcat_name' ],
'orderby' => 'ID',
'order' => 'ASC',
'show_count' => 0,
'hide_empty' => 0,
'exclude' => 0,
'echo' => 1,
'selected' => 0,
'child_of' => $_POST[ 'chained_subcat_id' ],
'hierarchical' => 1,
'name' => 'chained-subcontainer',
'id' => '',
'class' => 'postform',
'depth' => 1,
'tab_index' => 0,
'taxonomy' => 'category',
'hide_if_empty' => false
);
// Print sub-categories
wp_dropdown_categories( $carMakes );
exit();
}
/**
* Loads translation file.
*
* Accessible to other classes to load different language files (admin and
* front-end for example).
*
* @wp-hook init
* @param string $domain
* @since 2012.09.11
* @return void
*/
public function load_language( $domain )
{
$locale = apply_filters( 'plugin_locale', get_locale(), $domain );
// Load translation from wp-content/languages if exist
load_textdomain(
$domain, WP_LANG_DIR . $domain . '-' . $locale . '.mo'
);
// Load regular plugin translation
load_plugin_textdomain(
$domain,
FALSE,
$this->plugin_path . '/languages'
);
}
/**
* Print the dropdown in the frontend
*/
public static function print_cats( $cat_id, $dropdown_text )
{
// Adjust parameters
$carMakes = array(
'show_option_all' => '',
'show_option_none' => $dropdown_text,
'orderby' => 'ID',
'order' => 'ASC',
'show_count' => 0,
'hide_empty' => 0,
'exclude' => 0,
'echo' => 1,
'selected' => 0,
'child_of' => $cat_id,
'hierarchical' => 1,
'name' => 'chained-categories',
'id' => '',
'class' => 'postform',
'depth' => 1,
'tab_index' => 0,
'taxonomy' => 'category',
'hide_if_empty' => false
);
// Print categories
wp_dropdown_categories( $carMakes );
// Empty dropdown for sub-categories
echo '<div id="chained-subcontainer">
<select name="chained-subcategories" id="chained-subcategories">
<option value="">- Select a category first -</option>
</select>
</div>';
}
}
jQuery( document ).ready( function( $ )
{
var data = {
action: 'custom_query',
security: wp_ajax.ajaxnonce
};
$( "#chained-categories" ).on( "change", function( e )
{
// Add specific data to the variable, used to query the sub-categories
data[ 'chained_subcat_id' ] = $( this ).val();
data[ 'chained_subcat_name' ] = $(
'#chained-categories option[value='
+ $( this ).val()
+ ']'
).text();
// A sub-category was selected
if( $( this ).val() > 0 )
{
// Ajax loader icon
$( '#chained-subcontainer' ).html( '<img src="' + wp_ajax.icon + '">' );
// Ajax call
$.post(
wp_ajax.ajaxurl,
data,
// No error checking is being done with the response
function( response )
{
$( '#chained-subcontainer' ).html( response );
}
);
}
// No selection, show default
else
{
$( '#chained-subcontainer' ).html( '<select name="chained-subcategories" id="chained-subcategories"><option value="">- Select a category first -</option></select>' );
}
});
} );
答案 1 :(得分:2)
为什么不使用对象? 你需要一家工厂来制造汽车。
一个很棒的参考:http://sourcemaking.com/creational_patterns
我还想考虑保持对象小巧,简单,尽可能少。将功能分解为简单的概念,如“make”和“show”。这使它们可以互换和可扩展。您最终只能要求$ this-&gt; model-&gt;
我会这样做:
1个组织数据的对象//模型
另一个用于构建行// controller
另一个显示//视图
要开始这样看,先写一些函数,以了解你想知道什么。
foreach (make)->show(models);
您可能会发现需要以不同的方式查询数据...换句话说,请事先向db询问更具体的问题,而不是在收到数据后对其进行过滤。也许过滤现在似乎更快,但是你还需要做多少其他问题和过滤?
还有一条评论:php更具有控制性,而javascript则更具视角。我说用最恰当和最简单的上下文解决问题 - 在这个问题上坚持使用php。
答案 2 :(得分:1)
在没有AJAX的情况下执行此操作的唯一方法是获取所有“Make”类别的列表,然后使用带有child_of参数的wp_dropdown_categories()为每个“Make”的每个“Model”生成一个下拉列表。在页面加载时隐藏所有“Make”下拉列表,将更改事件处理程序附加到“Make”下拉列表,当它被调用时,显示相应的“Model”下拉列表,同时隐藏所有其余内容。显示/隐藏可以使用jQuery或纯JS完成。每个“模型”下拉列表都必须有一个唯一的ID,可用于识别它所属的“Make”。