根据选定的父分类显示子分类

时间:2019-02-17 作者:Shihab

我有两个下拉列表。第一个包含自定义帖子类型的父分类列表。第二个一次包含所有子分类。但我试图只显示selected 父分类法(不是来自其他父分类法的所有子分类法)。例如,如果我从第一个下拉列表中选择父分类,那么第二个下拉列表应该只显示它的子分类。我没找到php 实现这一目标的逻辑。我在“编辑个人资料”页面上显示这两个下拉列表。这是我的密码functions.php

<?php
function slcustom_user_profile_fields($user) { ?>
<h1 id="temppp">Select a parent taxonomy</h1>
<select name="parent_category" id="parent_category">
  <?php
    global $wpdb;
    $parentCat = $wpdb->get_results( "SELECT name FROM wp_terms WHERE term_id IN (SELECT term_id FROM wp_term_taxonomy WHERE taxonomy = \'project_category\' AND parent = 0)" );
    foreach ( $parentCat as $cat ) { ?>
      <option value="<?php echo esc_attr( $cat->name ) ?>"<?php echo selected( $user->parent_category, $cat->name ); ?>><?php echo $cat->name; ?></option>
    <?php }
  ?>
</select>

<p>Select a child taxonomy</p>
<select name="child_category" id="child_category">
  <?php 
//trying to bring this $termName value from JS
if(isset($_POST[\'selectedParentName\'])) {
  $termName = isset($_POST[\'selectedParentName\']);
}

$termId = get_term_by(\'name\', $termName, \'project_category\');
$selectedTermId = $termId->term_id;

  $id = $selectedTermId;
    $childCats = $wpdb->get_results( "SELECT name FROM wp_terms WHERE term_id IN (SELECT term_id FROM wp_term_taxonomy WHERE taxonomy = \'project_category\' AND parent = ".$id." )" );
    foreach ($childCats as $childCat) { ?>
      <option value="<?php echo esc_attr( $childCat->name ) ?>"<?php echo selected( $user->child_category, $childCat->name ); ?>><?php echo $childCat->name; ?></option>
    <?php }
  ?>
</select>
<?php
}
add_action(\'show_user_profile\', \'slcustom_user_profile_fields\');
add_action(\'edit_user_profile\', \'slcustom_user_profile_fields\');


function save_custom_user_profile_fields($user_id) {
    if( current_user_can(\'edit_user\', $user_id) ) {
        update_user_meta($user_id, \'parent_category\', $_POST[\'parent_category\']);
        update_user_meta($user_id, \'child_category\', $_POST[\'child_category\']);
    }
}
add_action(\'personal_options_update\', \'save_custom_user_profile_fields\');
add_action(\'edit_user_profile_update\', \'save_custom_user_profile_fields\');

script.js

$(\'select#parent_category\').on(\'change\', function() {
  var selectedParentName = this.value; //it tracks changes dropdown value
  $.ajax({
    type: \'POST\',
    url: \'http://localhost:3000/wp-content/themes/mytheme/functions.php\',
    data: { selectedParentName : selectedParentName }, //trying to send this \'selectedParentName\' to functions.php
    success: function(data) {
       var sendThisDataToPHP = selectedParentName;
    }
  });
});
2019年2月19日更新:脚本。添加了js,函数上的行数很少。php接收JS变量。

3 个回复
最合适的回答,由SO网友:sMyles 整理而成

这里有一个功能齐全的代码片段。

我添加了正确的WordPress表格样式这需要添加我的smyles_get_taxonomy_hierarchy 要将分类法的子对象添加到术语对象,如果不存在子对象,则会隐藏子下拉列表,这将根据TERM ID 不是NAME .. 您应该始终使用术语ID,就好像您决定以后更改措辞/slug一样,您将遇到各种问题

example

这里的代码语法highlighter似乎无法处理HTML/JS/PHP的混合,所以这里有一个GitHub工作代码要点:https://gist.github.com/tripflex/527dd82db1d1f3bf82f761486fcc3303

细分:

首先需要包含my函数,以生成该术语对象中包含子对象的分类法数组:

if ( ! function_exists( \'smyles_get_taxonomy_hierarchy\' ) ) {
    /**
     * Recursively get taxonomy and its children
     *
     * @param string $taxonomy
     * @param int    $parent Parent term ID (0 for top level)
     * @param array  $args   Array of arguments to pass to get_terms (to override default)
     *
     * @return array
     */
    function smyles_get_taxonomy_hierarchy( $taxonomy, $parent = 0, $args = array( \'hide_empty\' => false ) ) {

        $defaults = array(
            \'parent\'     => $parent,
            \'hide_empty\' => false
        );
        $r        = wp_parse_args( $args, $defaults );
        // get all direct decendants of the $parent
        $terms = get_terms( $taxonomy, $r );
        // prepare a new array.  these are the children of $parent
        // we\'ll ultimately copy all the $terms into this new array, but only after they
        // find their own children
        $children = array();
        // go through all the direct decendants of $parent, and gather their children
        foreach ( $terms as $term ) {
            // recurse to get the direct decendants of "this" term
            $term->children = smyles_get_taxonomy_hierarchy( $taxonomy, $term->term_id );
            // add the term to our new array
            $children[ $term->term_id ] = $term;
        }

        // send the results back to the caller
        return $children;
    }
}
jQuery/JavaScript代码处理:

jQuery( function($){
    // slcustom_categories var should be available here
    $(\'#parent_category\').change( function(e){
        var child_cat_select = $( \'#child_category\' );
        var term_id = $(this).val();

        console.log( \'Parent Category Changed\', term_id );

        // Remove any existing
        child_cat_select.find( \'option\' ).remove();

        // Loop through children and add to children dropdown
        if( slcustom_categories && slcustom_categories[ term_id ] && slcustom_categories[ term_id ][\'children\'] ){
            console.log( \'Adding Children\', slcustom_categories[ term_id ][\'children\'] );
            $.each( slcustom_categories[term_id][\'children\'], function( i, v ){
                console.log( \'Adding Child: \', v );
                child_cat_select.append( \'<option value="\' + v[\'term_id\'] + \'">\' + v[ \'name\' ] + \'</option>\');
            });

            // Show if child cats
            $( \'#child_category_row\' ).show();
        } else {
            // Hide if no child cats
            $( \'#child_category_row\' ).hide();
        }
    });

    // Trigger change on initial page load to load child categories
    $(\'#parent_category\').change();
});
输出字段的函数:

function slcustom_user_profile_fields( $user ){

    $categories = smyles_get_taxonomy_hierarchy( \'project_category\' );
    $parent_category = $user->parent_category;
    $child_category = $user->child_category;
//  $parent_category = 52; // used for testing
//  $child_category = 82; // used for testing
    $parent_has_children = ! empty( $parent_category ) && $categories[ $parent_category ] && ! empty( $categories[ $parent_category ]->children );

    // Creative way to use wp_localize_script which creates a JS variable from array
    // You should actually change this to load your JavaScript file and move JS below to that file
    wp_register_script( \'slcustom_user_profile_fields\', \'\' );
    wp_localize_script( \'slcustom_user_profile_fields\', \'slcustom_categories\', $categories );
    wp_enqueue_script( \'slcustom_user_profile_fields\' );
    ?>
    <h1 id="temppp">Select a parent taxonomy</h1>
    <table class="form-table">
        <tbody>
            <tr>
                <th>
                    Parent
                </th>
                <td>
                    <select name="parent_category" id="parent_category">
                    <?php
                        foreach( (array) $categories as $term_id => $cat ){
                            ?>
                            <option value="<?php echo esc_attr( $term_id ) ?>"<?php echo selected( $parent_category, $term_id ); ?>><?php echo $cat->name; ?></option>
                            <?php
                        }
                    ?>
                    </select>
                </td>
            </tr>
            <tr id="child_category_row" style="<?php if( ! $parent_has_children ){ echo \'display: none;\'; }?>">
                <th>
                    Child
                </th>
                <td>
                    <select name="child_category" id="child_category">
                        <?php
                            if( $parent_has_children ){
                                foreach( (array) $categories[$parent_category]->children as $c_term_id => $child ){
                                    ?>
                                    <option value="<?php echo esc_attr( $c_term_id ) ?>"<?php echo selected( $child_category, $c_term_id ); ?>><?php echo $child->name; ?></option>
                                    <?php
                                }
                            }
                        ?>
                    </select>
                </td>
            </tr>
        </tbody>
    </table>
    <?php
}

SO网友:Antti Koskinen

您可以通过使用js/jQuery来实现这一点。也许有更多的方法,但我想到了两种。

观察父选择上的更改,并根据所选父选项使用ajax填充子选择选项


EDIT 19.2.2019

add_action( \'wp_ajax_my_action\', \'my_action\' );
function my_action() {

  // check if user is logged in
  // is ajax request nonce valid
  // other stuff to make sure we can trust this request

  $selected_aprent_tax = strip_tags($_POST[\'parent_cat\']);

  $tax_query = new WP_Tax_Query(array(
    \'taxonomy\'  =>  \'project_category\',
    \'parent\'    =>  $selected_aprent_tax,
  ));

  if ( $tax_query->terms ) {
    wp_send_json_success( $tax_query->terms );
  } else {
    wp_send_json( array() );
    wp_die();
  }

}
然后使用my_action 作为ajax请求中的动作参数来触发上述函数。并将ajax请求发送到admin_url( \'admin-ajax.php\' ).

使用jQuery脚本,您可以获取php返回的术语,并对它们执行任何操作。E、 g.从中创建选择选项。

NB 我打字的时候已经很晚了,所以这不是一个完美的例子,而是一个粗略的例子。请参考法典,使示例适用于您的情况,https://codex.wordpress.org/AJAX_in_Plugins

SO网友:hamdirizal

可以使用简单的foreach循环。

假设我有一个自定义分类法"books"

这就是我获得所有家长条款的方式:

$terms = get_terms(array(\'taxonomy\' => \'books\', \'hide_empty\' => false ));
$parents = array();
foreach ($terms as $item) {
    if($item->parent===0){
        $parents[] = $item;
    }
}
print_r($parents); //Show all the parent objects
在ajax调用中,发送父id以获取子对象列表,如下所示:

$parent = $_POST[\'parent\'];
$terms = get_terms(array(\'taxonomy\' => \'books\', \'hide_empty\' => false ));
$children = array();
foreach ($terms as $item) {
    if($item->parent === $parent){
        $children[] = $item;
    }
}
print_r($children); //show all children objects

相关推荐

隐藏加载更多的AJAX按钮,如果没有更多的用户加载或少于该数量?

如果没有更多的用户要加载或用户数小于此数字,如何隐藏加载更多Ajax按钮<script type=\"text/javascript\"> var ajaxurl = \"<?php echo admin_url( \'admin-ajax.php\' ); ?>\"; var page = 2; jQuery(function($) { $(\'body\').on(\'click\', \'.loadmorefollowing\', fu