I have a taxonomy name "City" . I have used "city" like this .

City 1
    Sub city 1
    Sub city 2
City 2 
    Sub city 3
    Sub city 4

Here the problem is if admin/user select City 1 , they can even select sub city 3 or sub city 4 , which is not under the City 1 . I want to restrict user that they can't select a child taxonomy till they have selected the parent taxonomy .

Or is there any other way , that child taxonomy will appear as drop down , upon selecting parent taxonomy .

  • This is a neat problem. You'll probably need both a Term Walker and probably some JS (Or you may be able to do it with JS exclusively). I'll see what I can find!
    – Howdy_McGee
    Sep 3, 2014 at 18:18

1 Answer 1


Really, you could probably refine this more and come up with better names, I just wanted to make it functional ^_^ !

First thing's first -> Let's include JQuery because I don't want to do this in vanilla JS.

function lets_include_jquery() {
    wp_enqueue_script( 'jquery' );
add_action( 'admin_enqueue_scripts', 'lets_include_jquery' );

Now let's throw a script into the footer of our admin panel to take care of the fun stuff.

function lets_add_our_js() {
    if(get_current_post_type() == 'POST_TYPE_HERE') : ?>
        <script type="text/javascript">
                $('#TAXONOMY_NAME_HEREchecklist li label > input:checkbox:not(:checked)')
                    .css('display', 'none');

                // The following is 100% optional since our children are hidden, I like it though.
                $('#TAXONOMY_NAME_HEREchecklist li label > input:checkbox:not(:checked)')
                    .attr('disabled', 'disabled');

                // This is required
                $('#TAXONOMY_NAME_HEREchecklist li label > input:checkbox').click(function(){
                        $(this).parent('label').next('.children').css('display', 'block');
                        $(this).parent('label').next('.children').find('input:checkbox').removeAttr('disabled'); // This line is really optional, I like it though.
                        $(this).parent('label').next('.children').css('display', 'none');
                        $(this).parent('label').next('.children').find('input:checkbox').attr('disabled', 'disabled'); // This line is really optional, I like it though.
  <?php endif; 
add_action('admin_footer', 'lets_add_our_js');

It's a pretty generic script, nothing fancy going on. Next we add a neat little function I found online!

function get_current_post_type() {
    global $post, $typenow, $current_screen;

    //we have a post so we can just get the post type from that
    if ( $post && $post->post_type )
    return $post->post_type;

    //check the global $typenow - set in admin.php
    elseif( $typenow )
    return $typenow;

    //check the global $current_screen object - set in sceen.php
    elseif( $current_screen && $current_screen->post_type )
    return $current_screen->post_type;

    //lastly check the post_type querystring
    elseif( isset( $_REQUEST['post_type'] ) )
    return sanitize_key( $_REQUEST['post_type'] );

    //we do not know the post type!
    return null;

Whew! Now there are a few things you need to change... Wherever you find POST_TYPE_HERE you'll need to replace that with whatever your post type is so the script will only appear on those admin pages. If you have multiple, is in_array(). Wherever you see TAXONOMY_NAME_HERE you'll want to replace that with the taxonomy name that the metabox holds. So if I create a taxonomy / category called "tax_news" my Jquery would read: '#tax_newschecklist' etc.

It's Up To You To rename and comment this code so that it makes sense to you and your scenario for future purposes! I highly suggest you do so!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.