Automatically check parent checkbox if child is selected in WordPress

To keep all posts in WordPress organized in terms of categorization, it helps to make sure that when a user selects a category that’s three levels down i.e. has two parents, that all the corresponding parents get checked.

What follows is a short and sweet JavaScript solution to help the user do this.

Here is how it works:

  1. Find all the checkboxes within in the #categorychecklist container
  2. Bind a change event to each of the checkboxes
  3. If a checkbox is checked, find all the parents and check their immediate child
  4. If a checkbox is unchecked, find all the children and uncheck them
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
jQuery(document).ready(function($){
  synchronize_child_and_parent_category($);
});
 
function synchronize_child_and_parent_category($) {
  $('#categorychecklist').find('input').each(function(index, input) {
    $(input).bind('change', function() {
      var checkbox = $(this);
      var is_checked = $(checkbox).is(':checked');
      if(is_checked) {
        $(checkbox).parents('li').children('label').children('input').attr('checked', 'checked');
      } else {
        $(checkbox).parentsUntil('ul').find('input').removeAttr('checked');
      }
    });
  });
}
jQuery(document).ready(function($){
  synchronize_child_and_parent_category($);
});

function synchronize_child_and_parent_category($) {
  $('#categorychecklist').find('input').each(function(index, input) {
    $(input).bind('change', function() {
      var checkbox = $(this);
      var is_checked = $(checkbox).is(':checked');
      if(is_checked) {
        $(checkbox).parents('li').children('label').children('input').attr('checked', 'checked');
      } else {
        $(checkbox).parentsUntil('ul').find('input').removeAttr('checked');
      }
    });
  });
}

I have a generic admin.js file in WordPress where I keep little back-end snippets like this.

I then register the script:

1
2
3
4
5
wp_register_script(
  PS . '-admin',
  plugins_url('_scripts/admin.js', dirname(dirname(__FILE__))),
  array('jquery')
);
wp_register_script(
  PS . '-admin',
  plugins_url('_scripts/admin.js', dirname(dirname(__FILE__))),
  array('jquery')
);

And enqueue it where needed:

1
2
3
wp_enqueue_style(
  PS . '-admin'
);
wp_enqueue_style(
  PS . '-admin'
);

If you’re curious, the PS (plugin slug) is a constant I define and use infront of many things where I can’t use a PHP namespace, like script and field names, to prevent them from potentially interfering with other plugins.

Lastly, if you’re thinking about using the code above, keep in mind that you’ll also have to prevent checked checkboxes from bubbling to the top, because when a user edits a post with previously checked checkboxes, there’s a good chance the hierarchy will be broken.

4 thoughts on “Automatically check parent checkbox if child is selected in WordPress

    1. Ryan Post author

      Thanks for sharing the alternative solution. In terms of namespace, you don’t have to use namespaces or constants, so you could replace PS . '-admin' with something static like 'my-admin', then this would work for you, too.

      Reply
  1. Greg Montaño

    Thanks Ryan for this awesome solution and the wp_terms_checklist_args checked_ontop filter! I’ve used it on 2 sites now. Is there a way to prevent checking the parent category if there are sub terms of that term? If the term does not have sub terms, allow checking it. Any help is greatly appreciated!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *