Taxonomy dropdown metabox in the back-end

I’ve created custom taxonomy called Brands and made it hierarchical so I can add Car brands and models there and keep their relations, like this:

  • Ford
    • Mustang
    • Mondeo
    • Focus

Problem is, this list might get pretty long and only one brand and one model is needed per post, so checkboxes are misleading.

I’m thinking to split that metabox in to two (one for brand and one for model) and make them dropdowns. So when brand is selected in the first dropdown, second dropdown would show only models related to that brand. But i have no idea how to code it. Maybe anyone could show me an example?

1
1

Here is an example. I have also created a Gist with more generic code.

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();
}

Leave a Comment