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:
- Find all the checkboxes within in the
#categorychecklist
container - Bind a
change
event to each of the checkboxes - If a checkbox is checked, find all the parents and check their immediate child
- 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.
Hello.
Thanks for tackling this issue. I tried to follow your steps, but found a simpler solution before I could re-create the php namespace and enqueue it.
http://wordpress.org/plugins/parent-category-toggler/
This does not provide the uncheck options yours does, but it provides the functionality we need.
cheers
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.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!
Hi Greg! You could probably loop through each checkbox, and if it has children, disable the parent by setting the HTML attribute to
disabled
on it.Thank you so much for snippet! Exactly what I was looking for and works like charm.
(I only changed ‘#categorychecklist’ to ‘.cat-checklist’ since in the quick-edit form there is no id attached to the list – plus I have multiple taxonomies and now it works on all of them in both the quick editor and in the main editor)