If anyone is interested in a simple fix to this other than @christian-denatorange-fr ‘s, I found a useful hook in the ACF JS API:
https://www.advancedcustomfields.com/resources/javascript-api/#actions-select2_init
Here, the configuration args that were passed to select2() in the initialization process are passed to the hook. This allows you to store them in order to re-use them when you need to re-initialize the field.
Here’s how I modify the html of dropdown items for example:
acf.addAction('select2_init', function( $select, args, settings, field ){
console.log("Select2 initialized with args: ", args);
args['templateResult'] = function (state) {
if (!state.id) {
return state.text;
} else {
//Note that this html will not be escaped further on. If you need to escape, do it here!
let $state = "<div class='item'>" + state.text + "<span class='label'>Add</span></div>";
return jQuery($state);
}
};
//Reinit
$select.select2(args);
});
Here’s an example of how we solved this problem:
1. Pass Selected Parent Terms In AJAX
You need a JS hook to filter the AJAX request of the child field, and add a new argument that contains the chosen parent term(s):
<?php
add_action('acf/input/admin_footer', 'support_acf_152814_filter_child_ajax');
function support_acf_152814_filter_child_ajax()
{
global $post;
//areas where this functionality is needed
if (!$post || !isset($post->ID) || get_post_type($post->ID) != 'my_posy_type')
return;
?>
<script type="text/javascript">
(function($){
$(document).ready( function() {
acf.add_filter('select2_ajax_data', function( data, args, $input, field, instance ){
let parent_field_key = '<parent_field_key>'; // Parent Field
let target_field_key = '<child_field_key>'; // Child Field
if( data.field_key == target_field_key ){
let parent = acf.getField(parent_field_key);
if (parent) {
data['parent_terms'] = parent.val(); //This is an array if the parent field is multiselect
}
}
return data;
});
});
})(jQuery);
</script>
<?php
}
2. Filter Taxonomy Query of the Child Terms
Here, you need to catch the argument we introduced above, and modify the query accordingly.
What I do here, is that I get the ids of all children of the selected parents, and I use put them in the ‘include’ option of the terms query:
add_filter('acf/fields/taxonomy/query/key=child_field_key', 'support_acf_152814_child_terms_filter', 10, 3);
function support_acf_152814_child_terms_filter( $args, $field, $post_id ) {
// Check if this is an ajax call
$children_ids = [];
if (wp_doing_ajax()) {
if (isset($_POST['parent_terms'])) {
$parent_terms = $_POST['parent_terms'];
if (is_array($parent_terms) && !empty($parent_terms)) {
foreach ($parent_terms as $parent_id) {
$new_children = get_term_children($parent_id, 'disease_categories');
if (!is_wp_error( $new_children )) {
$children_ids = array_merge($children_ids, $new_children);
}
}
}
$args['include'] = $children_ids;
}
}
return $args;
}
I tested the code above and it works in my case. Please @hube2 let me know if this can be improved further.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.