Métabox de liste déroulante de taxonomie dans le back-end

9

J'ai créé une taxonomie personnalisée appelée Brandset rendue hiérarchique afin que je puisse y ajouter des marques et des modèles de voitures et conserver leurs relations, comme ceci:

  • Gué
    • Mustang
    • Mondeo
    • Concentrer

Le problème est que cette liste peut devenir assez longue et qu'une seule marque et un seul modèle sont nécessaires par poste, donc les cases à cocher sont trompeuses.

Je pense à diviser cette métabox en deux (une pour la marque et une pour le modèle) et en faire des listes déroulantes. Ainsi, lorsque la marque est sélectionnée dans la première liste déroulante, la seconde liste déroulante n'affichera que les modèles liés à cette marque. Mais je n'ai aucune idée de comment le coder. Peut-être que quelqu'un pourrait me montrer un exemple?

Kovas
la source

Réponses:

10

Voici un exemple. J'ai également créé un Gist avec un code plus générique.

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
la source
@Hameedullah trucs assez lourds hameedullah, excellent travail néanmoins. +1
VicePrez
@Hameedullah très sympa. Mais j'ai un problème avec ça. J'ai collé tout ce code dans mon functions.php et quand je vais au back-end du post, j'obtiens ceci: Attention: define () attend au moins 2 paramètres, 1 donné en (pointant vers cette ligne de code:) if ( define('DOING_AUTOSAVE') && DOING_AUTOSAVE ).
Kovas
veuillez modifier définir en défini par exempleif ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ))
Hameedullah Khan
@Hameedullah c'est super, merci pour la solution :)
Kovas
était ravi de trouver cet extrait de code et l'a essayé sur place. Je l'utilise sur un post-type personnalisé, pas sur des posts, mais je ne vois pas la metabox. y a-t-il des étapes nécessaires pour que cela fonctionne sur d'autres post-types? ..J'ai changé le nom de la taxe pour ma taxonomie personnalisée, en n'utilisant cela que pour une taxe unique, pas multi comme la personne d'origine demandée
Shaw