Skip to content

Instantly share code, notes, and snippets.

@MogulChris
Forked from ChrisWebbNZ/hierearchical-select-acf.php
Last active August 7, 2023 06:25
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MogulChris/0e8e383d600e43190ad0dc2be4a5d6c9 to your computer and use it in GitHub Desktop.
Save MogulChris/0e8e383d600e43190ad0dc2be4a5d6c9 to your computer and use it in GitHub Desktop.
Hierarchical select for native Advanced Custom Fields taxonomy fields.
jQuery(document).ready(function($){
//Modify select2 ajax request to include a parent_id parameter, used by custom_acf_taxonomy_hierarchy()
acf.add_filter('select2_ajax_data', function( data, args, $input, field, instance ){
var target_field_key = 'field_5c7634ca3413f'; //YOUR TARGET FIELD KEY HERE
if(data.field_key == target_field_key){
var parent_id = 0; //by default we want terms with parent of 0 (top level)
if($input.val() != '' && $input.val() != null){ //if we have chosen one or more terms already
var values = $input.val();
parent_id = values.pop(); //get last selected term to use as the parent for the next query
}
data.parent = parent_id;
}
return data;
});
});
<?php
//Modifies ajax requests from our select2 dropdown, $args = WP_Term_Query arguments
function custom_acf_taxonomy_hierarchy( $args, $field, $post_id ){
//default to 0 (top-level terms only) unless we get a different parent with the request
$args['parent'] = empty($_POST['parent']) ? 0 : $_POST['parent'];
//To allow multiple top-level selections, we can go back to the top of the taxonomy tree after we reach the end of a branch
/*
if(!empty($args['parent'])){
$child_terms = get_term_children($args['parent'],'YOUR_TAXONOMY_SLUG'); //change to your taxonomy slug
if(empty($child_terms) || is_wp_error($child_terms)) $args['parent'] = 0;
}
*/
return $args;
}
add_filter('acf/fields/taxonomy/query/key=field_5c7634ca3413f', 'custom_acf_taxonomy_hierarchy',10,3);
//Make the javascript available in the admin when editing a post with ACF
function custom_admin_enqueue_scripts(){
wp_enqueue_script('custom-acf-admin-js', get_stylesheet_directory_uri() . '/js/custom-acf-admin.js',['jquery']);
}
add_action('acf/input/admin_enqueue_scripts','custom_admin_enqueue_scripts');
@gb3000
Copy link

gb3000 commented Aug 20, 2019

Hi Chris, many thanks for sharing your code.
I have a 3 level hierarchical taxonomy which have countrys, states/ provinces and cities. I have set your code up in my site, but when trying to use it I can only select the first level terms, I can also select more than one top level term. I am missing something? Does the field or taxonomy need any particular setting?
Best,
Gustavo

@MogulChris
Copy link
Author

Hey Gustavo,
difficult to say without seeing your implementation, but it sounds like the JS is not finding the correct parent id after you have made your first top-level selection. If parent_id is always 0, then you would always see the top-level terms only.

I suggest looking at lines 8-10 of the JS and seeing why parent_id is not being set to the last term you chose. It needs to find the value of the hidden <select> element for your taxonomy field. No special taxonomy configuration is needed.

Cheers
Chris

@ramonfincken
Copy link

ramonfincken commented Oct 3, 2019

To get ALL selected values use this:
data.all_selected = Object.values( collections ); // Get all selected options

@MogulChris
Copy link
Author

Updated the JS with a simpler way to get the value(s) you already selected.

$input is the taxonomy field you are working with, so $input.val() will give you a simple array of selected term ids. From there you can pop() the most recent value off to use as your parent.

@HobbyAlchemist
Copy link

Any updates on this one? I also have the same problem as @gb3000..

@MogulChris
Copy link
Author

@HobbyAlchemist I have updated the code since then, but have not tested it extremely recently. You'll need to debug your own javascript and see what's going on, there's not too many moving parts there. Make sure you are targeting the correct field (use your own field key on line 5 of the JS)

@HobbyAlchemist
Copy link

Ok! Thank you! Found another way using fields with child taxonomy and conditional logic setup againts a choice select box. A bit more work, but gets the job done.

@ArneSaknussemm
Copy link

This is helpful. I was in the same issue with @HobbyAlchemist and @gb3000. I solved replacing
add_action('admin_enqueue_scripts','custom_admin_enqueue_scripts');
with
add_action('acf/input/admin_enqueue_scripts','custom_admin_enqueue_scripts');
I would really love this if it allows me to do the multiple select. When I reach the end of the hierachy it shows "no results found" and doesnt come back to ask for parent anymore. Is there a way?
Thanks!

@MogulChris
Copy link
Author

Thanks for the better Javascript hook @ArneSaknussemm - updated.

In case you didn't work out how to allow multiple values, just add a check to custom_acf_taxonomy_hierarchy() to see if the given parent id has any child terms (get_term_children()) and override it with 0 if not. This makes you follow a branch of the taxonomy tree to the end, then go back to the top.

@albertvisuals
Copy link

Thanks so much for sharing this! It is a lifesaver!
Regarding allowing multiple terms, → aka going to the top level if it runs out of children.
Would it be possible that you add the lines you have mentioned in the last post.
I am pretty new to PHP & JS, so your help would be highly appreciated.

@MogulChris
Copy link
Author

@albertvisuals Sure thing, done. Just uncomment it and change the taxonomy slug to your own, tested and working for me.

@albertvisuals
Copy link

@MogulChris Thanks very much for your help!!!! You've saved my day :)

@ocunex
Copy link

ocunex commented Nov 17, 2021

Hello everyone, I've been looking for this solution for the past two days, Great I've found it but am not good at PHP and jQuery.

Am using ACF Frontend to allow users to submit their products via a frontend form.

after reading some articles on how to use jQuery in WP, I create a js folder in my child theme directory and uploaded the jQuery file. (customized the field key and also I didn't change the naming of the js file.)

I added the PHP code to the functions.php of my child theme but there is no change.

I'd request you guys to help me out on how to make it work. Thank you

@albertvisuals
Copy link

Is it possible not working anymore under ACF Version 6.0.5 and/or PHP 8.1? Has somebody an idea why?
Thanks a lot!

@dizplayy
Copy link

albertvisuals

FOund some workaround/fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment