I think what makes it especially complex IMO is that you’re trying to do a bunch at once, and when you throw in Ajax (for the last one), then it’s getting even worse. For that matter, seems to me the majority of what you want would have to be dynamic, and that’s Ajax, not PHP, so I can’t really help you there.
The simplest approach is to edit the CSS a little, which I’d been doing myself in the functions.php — but for some reason, this has stopped working with 2.8.2., so instead I edit the core css file and make note to redo with next update (it’s pretty harmless change, overall). On lines 1852 and 1860, change the height to 100% (both should be for #categorydiv and variants). That, at least, will open the category list box wide so you’re not looking at only seven options at a time, if none of the rest works for you.
To force single-choices for each, you need radio boxes, not checkboxes. Hmm. I would suggest perhaps starting with the notion of metaboxes — but not exactly. Instead, disable the category box (via screen options) and re-introduce the same variables as a metabox, which will mean some funkiness at the end to add those selected categories back in, but still has to be easier than writing Ajax to do it dynamically after it’s loaded.
Just of the top of my head, I’d first try to call up the categories into radio boxes so the user’s forced to pick only one per. Then collect those when the post is saved, and compile as array and update the post categories. Maybe something like the following (with apologies for the radiobox html, since I can’t remember precisely how it goes):
function new_meta_box() {
global $post;
//$catlist = ((( insert query to list all categories that are children of X parent )))
echo (((parent))).'<br />';?>
foreach ($catlist as $cat) {
$catID = $cat->ID;
<input type=radio name="category_1" value="<?php echo $catID; ?>"><?php echo $cat->name; ?><br />
<?php }
// repeat for next set, if you want all categories in same meta-box area
} ?>
Do action/filter etc per usual metabox, something like:
function create_new_meta_box() {
global $post, $theme_name; add_meta_box( 'box2', 'City', 'meta_box', 'post', 'normal', 'low' );}
function save_meta_postdata( $post_id ) { global $post, $new_meta_box;
$data1 = $_POST['category_1'];
$data2 = $_POST['category_2'];
$data3 = $_POST['category_3'];
wp_set_post_categories($postId, array($data1, $data2, $data3 …));
Alternately, you could set up the $data intake as a loop and use array_push to create an array automatically. Whatever way gets it in, via the form needed, and that might be a decent hack to at least prevent multiple-choices w/in a sub-category.
Though one tip about metaboxes: sometimes it won’t take for some reason. Check the $post_id format — at some points, it’s $post_id that’s carrying the ID as variable, other times, it’s $post->ID that will get you the right value. I have no idea why it’ll be one, then the other. I just fiddle with them until it does what I want.
Good luck, sorry I can’t be of more help.
wp_set_post_categories($postId, array(cat1ID, cat2ID, …)),