Support

Account

Home Forums Gutenberg Dynamically populate an ACF Gutenberg Block field based on other field value.

Solving

Dynamically populate an ACF Gutenberg Block field based on other field value.

  • Hi!

    I am trying to dynamically populate a select options fields based on the value of another select option within the scope a Gutenberg block in real time.

    I’ve read everything mentioned here: https://www.advancedcustomfields.com/resources/dynamically-populate-a-select-fields-choices/, however in the examples the they are fetching the external field from an option setting, not from a group/Gutenberg block itself.

    Basically I want to have a first dropdown with A, B, C options and based on that show another dropdown with different choices based on that previous selection in real time.

    Right now, the filters available don’t expose me to the whole group/block nor does it provide me the ID of the block.

    I would appreciate any help regarding this.

    Regards,

    A.

  • This reply has been marked as private.
  • This is an example of populating one acf select field bases on another acf select field without the block editor.

    However, I have no idea what changes would need to be make to get this to work in a block. https://github.com/Hube2/acf-dynamic-ajax-select-example/tree/master/dynamic-select-example

  • Did you make any progress with this? I want to do something similar, but pull the data from other ACF blocks on the same page. An option to select a “parent” block…

  • I’ve figured out a way to do this; I doubt it’s the most efficient method, but it works and that was my main objective. My code and explanation are for dynamically populating a post_object ACF field, but I think it would be a similar process for an ACF select field.

    I enqueue this Javascript code with the custom block to only load in the Admin:

    (function($){
    
        // the post_object ACF field in the custom ACF block that I want to filter
        let post_object_field_key = 'field_624f5d2c6b97c'; 
    
        // the ACF select field in the custom ACF block that I want to use to dynamically filter the ACF field above
        let region_selector_field_key = 'field_6259a73fcf5ef';
        let region_selector_field_name = 'my_region_selector';
    
        // Callback for the ACF select fields
        let selectFieldCallback = function( select_field ){
    
            // get the field name for the ACF field that was changed (I found this by using the Web Inspector and noticed that the ACF field name was saved as data attribute)
            let fieldName = select_field.$el[0].getAttribute('data-name');
    
            // clear the manually selected posts if the "my_region_selector" select field is changed
            if (fieldName === region_selector_field_name) {
    
                select_field.on('change', function() {
    
                    // the ID is in the form of the current ACF block instance ID + ACF field_key (eg 'acf-block_624f300b806d1-field_624f5d2c6b97c')
                    let this_el_id = select_field.$el.find('select')[0].id; 
    
                    // grab the first part of the ID which denotes the specific ACF block instance that this custom field is associated with
                    let block_el_id = this_el_id.split('-field_')[0];
    
                    // grab the post_object ACF field that is associated with the same ACF block instance
                    let adjacent_post_object_selector = document.getElementById(<code>${block_el_id}-${post_object_field_key}</code>);
                    
                    // calls a custom function that I wrote to clear the existing values that were selected in the post_object ACF field
                    clearSelectFieldValue(adjacent_post_object_selector);
    
                });
    
            }
    
        };
    
        // Set ACF actions for the block (I have multiple ACF select fields that I am using to filter one post_object field which is why I use new_field/type=select, but you could use a more specific filter)
        if ( window.acf ) {
            window.acf.addAction( 'new_field/type=select', selectFieldCallback );
        }
        
        // Create an ACF filter to dynamically populate the post_object ACF field with the appropriate posts based on what is selected in the relevant ACF Select fields
        acf.add_filter('select2_ajax_data', function( data, args, $input, field, instance ) {
    
            // since the 'select2_ajax_data' ACF filter can't be set for a specfic field, use this conditional to only filter the field we care about
            if ( data.field_key === post_object_field_key ) {
    
                // the ID is in the form of the current ACF block instance ID + ACF field_key (eg 'acf-block_624f300b806d1-field_624f5d2c6b97c')
                let this_el_id = instance.$el[0].id;
    
                // grab the first part of the ID which denotes the specific ACF block instance that this custom field is associated with
                let block_el_id = this_el_id.split('-field_')[0];
    
                // grab the ACF select field in the custom ACF block that I want to use to dynamically filter the post_object field
                let adjacent_region_selector = document.getElementById(<code>${block_el_id}-${region_selector_field_key}</code>);
                if (adjacent_region_selector) {
                    // My field allows multi-select so I use a custom function to grab the currently selected values of this multi-select field
                    let selectedRegions = getSelectedOptions(adjacent_region_selector);
                    if (selectedRegions.length) {
                        data.regions = selectedRegions; // send the currently selected post_type to the AJAX WP_Query when fetching results to populate the post_object custom field
                    }
                }
    
                // You can add more ACF fields that you want to use to filter the post_object field here using a similar format above
    
            }
            
            // 
            return data;
    
        });
    
    })(jQuery);
    

    Then I set up a PHP filter for the post_object field that I want to dynamically populate:
    add_filter( 'acf/fields/post_object/query/key=field_624f5d2c6b97c', 'dynamically_set_acf_post_object_query', 10, 3 );

    And here’s the corresponding function for the filter:

    <?php
    function dynamically_set_acf_post_object_query( $args, $field, $post_id ) {
    
        // if the AJAX request sends regions use them for a taxonomy query
        if (!empty($_POST['regions']) && is_array($_POST['regions'])) {
    
    		// if there are still region terms remaining in the array add a tax_query to the WP_Query arguments
    		if (count($filtered_regions) > 0) {
    			$args['tax_query'] = array(
    				'relation' => 'OR',
    				array(
    					'taxonomy'  => 'my_regions_taxonomy',
    		            'field'		=> 'slug',
    		            'terms'     => $_POST['regions'],
    				)
    			);
    		}
    
        }
        
        return $args;
    
    }
    
Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.