Metabox listy rozwijanej taksonomii w zapleczu

9

Stworzyłem niestandardową taksonomię o nazwie Brandsi nadałem jej hierarchiczność, dzięki czemu mogę dodawać tam marki i modele samochodów i zachować ich relacje, jak poniżej:

  • Bród
    • Mustang
    • Mondeo
    • Skupiać

Problem w tym, że ta lista może być dość długa i potrzebna jest tylko jedna marka i jeden model na post, więc pola wyboru są mylące.

Myślę, że podzielę ten metaboks na dwa (jeden dla marki i jeden dla modelu) i sprawię, że będą rozwijane. Kiedy więc marka zostanie wybrana w pierwszym menu, w drugim menu pojawią się tylko modele powiązane z tą marką. Ale nie mam pojęcia, jak to zakodować. Może ktoś mógłby mi pokazać przykład?

Kovas
źródło

Odpowiedzi:

10

Oto przykład. Stworzyłem także Gist z bardziej ogólnym kodem.

add_action('add_meta_boxes', 'my_custom_metabox');
function my_custom_metabox() {
    add_meta_box('custom-taxonomy-dropdown','Brands','taxonomy_dropdowns_box','post','side','high');
}

function taxonomy_dropdowns_box( $post ) {
    wp_nonce_field('custom-dropdown', 'dropdown-nonce');
    $terms = get_terms( 'brands', 'hide_empty=0');
    $object_terms = wp_get_object_terms( $post->ID, 'brands', array('fields'=>'ids'));

    // you can move the below java script to admin_head
?>
    <script type="text/javascript">
        jQuery(document).ready(function() {
                jQuery('#custombrandoptions').change(function() {
                    var custombrand = jQuery('#custombrandoptions').val();
                    if ( custombrand == '0') {
                        jQuery('#custommodeloptions').html('');
                            jQuery('#modelcontainer').css('display', 'none');
                    } else {
                        var data = {
                            'action':'get_brand_models',
                            'custombrand':custombrand,
                            'dropdown-nonce': jQuery('#dropdown-nonce').val()
                        };
                        jQuery.post(ajaxurl, data, function(response){
                            jQuery('#custommodeloptions').html(response);
                            jQuery('#modelcontainer').css('display', 'inline');
                        });
                    }
                });
        });
    </script>
    <?php
    echo "Brand:";
    echo "<select id='custombrandoptions' name='custombrands[]'>";
    echo "<option value='0'>None</option>";
    foreach ( $terms as $term ) {
        if ( $term->parent == 0) {
            if ( in_array($term->term_id, $object_terms) ) {
                $parent_id = $term->term_id;
                echo "<option value='{$term->term_id}' selected='selected'>{$term->name}</option>";
            } else {
                echo "<option value='{$term->term_id}'>{$term->name}</option>";
            }
        }
    }
    echo "</select><br />";
    echo "<div id='modelcontainer'";
    if ( !isset( $parent_id)) echo " style='display: none;'";
    echo ">";
    echo "Models:";
    echo "<select id='custommodeloptions' name='custombrands[]'>";
    if ( isset( $parent_id)) {
        $models = get_terms( 'brands', 'hide_empty=0&child_of='.$parent_id);
        foreach ( $models as $model ) {
             if ( in_array($model->term_id, $object_terms) ) {
                echo "<option value='{$model->term_id}' selected='selected'>{$model->name}</option>";
            } else {
                echo "<option value='{$model->term_id}'>{$model->name}</option>";
            }
        }
    }
    echo "</select>";
    echo "</div>";
}

add_action('save_post','save_my_custom_taxonomy');
function save_my_custom_taxonomy( $post_id ) {
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
        return;

    if ( !wp_verify_nonce($_POST['dropdown-nonce'], 'custom-dropdown'))
        return;

    $brands = array_map('intval', $_POST['custombrands']);
    wp_set_object_terms($post_id, $brands, 'brands');
}

add_action('wp_ajax_get_brand_models', 'get_brand_models');
function get_brand_models() {
    check_ajax_referer('custom-dropdown', 'dropdown-nonce');
    if (isset($_POST['custombrand'])) {
        $models = get_terms( 'brands', 'hide_empty=0&child_of='. $_POST['custombrand']);
        echo "<option value='0'>Select one</option>";
        foreach ($models as $model) {
            echo "<option value='{$model->term_id}'>{$model->name}</option>";
        }
    }
    die();
}
Hameedullah Khan
źródło
@Hameedullah całkiem ciężkie rzeczy hameedullah, mimo wszystko świetna robota. +1
VicePrez
@Hameedullah bardzo miło. Ale mam z tym problem. Wkleiłem cały ten kod do funkcji.php, a kiedy przechodzę do zaplecza posta, otrzymuję to: Ostrzeżenie: Zdefiniuj () oczekuje co najmniej 2 parametrów, 1 podanych w (wskazuje na ten wiersz kodu:) if ( define('DOING_AUTOSAVE') && DOING_AUTOSAVE ).
Kovas
proszę zmień zdefiniuj na zdefiniowane np.if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ))
Hameedullah Khan
@Hameedullah to jest świetne, dzięki za rozwiązanie :)
Kovas
był podekscytowany znalezieniem tego fragmentu i wypróbował go na stronie. Używam go na niestandardowym typie postów, a nie na postach, ale nie widzę metaboksu. czy potrzebne są kroki, aby działało to na innych typach postów? ..Zmieniłem nazwę podatku na moją niestandardową taksonomię, używając go tylko do jednego podatku, a nie wielu, jak pierwotna osoba, o którą prosiłem
shawn