web-dev-qa-db-ja.com

SELECTED親分類に基づいてサブ分類を表示します

ドロップダウンが2つあります。最初のものは、カスタム投稿タイプからの親分類のリストを含みます。そして、2つ目は一度にすべての下位分類を含みます。しかし、私はselected親分類のサブ分類のみを表示しようとしています(他の親分類のすべてのサブ分類ではありません)。たとえば、最初のドロップダウンから親分類を選択した場合、2番目のドロップダウンにはそのサブ分類のみが表示されます。この目標を達成するためのphpロジックは見つかりません。 「プロファイルの編集」ページにこれら2つのドロップダウンを表示しています。これが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日更新:script.jsが追加され、JS変数を受け取るためのfunctions.phpに数行追加されました。

2
shihab

これを行うための完全に機能するスニペットを次に示します。

  • 正しいWordPressテーブルスタイルを追加しました
  • これには、分類の子を用語オブジェクトに追加するためにsmyles_get_taxonomy_hierarchyを追加する必要があります
  • 子が存在しない場合、これは子のドロップダウンを非表示にします
  • これは、NAMEではなくTERM IDに基づいてすべてを処理(および保存)します。後で言葉遣いやスラッグを変更する場合は、あらゆる種類の問題が発生するので、常に用語IDを使用する必要があります。

example

ここのコード構文強調表示機能はHTML/JS/PHPの混合を処理できないようですので、ここにGitHub Gistの作業コードがあります: https://Gist.github.com/tripflex/527dd82db1d1f3bf82f761486fcc33

壊す:

まず、その用語オブジェクトに子を持つ分類配列を生成するために、私の関数を含める必要があります。

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
}
4
sMyles

単純な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
1
hamdirizal

あなたはjs/jQueryを使用することでそれを達成できます。もっと多くの方法があるかもしれませんが、2つは私の心に浮かびます。

  1. 親選択の変更を監視し、選択した親オプションに基づいて子選択オプションにajaxを設定します。
  2. 親選択の変更を監視し、選択した親オプションに基づいて、関連しないオプションを子選択から非表示にします。

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が返す用語を取得し、それらを使用して何でも実行します。例えば。それらから選択オプションを作成します。

[〜#〜] nb [〜#〜]これを入力しているのはかなり遅いので、完璧な例ではありませんが、大まかな例です。あなたのケースでサンプルを機能させるにはコーデックスを参照してください https://codex.wordpress.org/AJAX_in_Plugins

1
Antti Koskinen