Support

Account

Home Forums Backend Issues (wp-admin) Getting Local Fields at Load_Field filter.

Solved

Getting Local Fields at Load_Field filter.

  • Hi all. I’ve got a question and I hope someone could answer it.

    My setup is basically a Flexibel Content field. Some layouts have a select field which I would like to fill with choices using the 'acf/load_field/name=' filter. The choices are values based on a set of local fields (which are added on a ACF Options Page) that I’ve generated with PHP using the layouts in the Flexibel Content field I’ve mentioned earlier. To generate the local fields I’m using the 'acf/init' action and I am getting the layout data from the Flexibel Content field correctly. And I am able to generate the local fields I need (On the ACF Options Page). The only thing that doesn’t work is populating the select field I mentioned earlier. At the 'acf/load_field/name=' filter it somehow can’t get the generated local fields to be able to populate the select field with it’s values.

    Is it possible that this doesn’t work because by the time the 'acf/load_field/name=' filter is fired the local fields aren’t loaded yet? Or might there be a different issue?

    This is my basic setup for this

    
        class defaults2 {
            public function initialize(){
                add_action('acf/include_fields', [$this, 'getDefaults'], 99);
            }
    
            public function getDefaults(){
    
                $layouts = acf_get_fields('group_5f33b50973315')[0]['layouts'];
    
                $blocks = array_filter($layouts, function($layout){
                    return in_array('source', array_column($layout['sub_fields'], 'name'));
                });
    
                $blocks = array_column($blocks, 'name');
    
                acf_add_local_field_group([
                    'key' => 'group_defaults',
                    'title' => 'My Group',
                    'fields' => [],
                    'location' => [
                        [
                            [
                                'param' => 'options_page',
                                'operator' => '==',
                                'value' => 'default-blocks',
                            ],
                        ],
                    ],
                    'menu_order' => 0,
                    'position' => 'normal',
                    'style' => 'seamless',
                    'label_placement' => 'top',
                    'instruction_placement' => 'label',
                    'hide_on_screen' => '',
                ]);
    
                foreach ($blocks as $block) {
    
                    acf_add_local_field([
                        'key' => 'field_' . $block . '_tab',
                        'label' => $block,
                        'type' => 'tab',
                        'placement' => 'left',
                        'parent' => 'group_defaults'
                    ]);
    
                    acf_add_local_field([
                        'key' => 'field_' . $block . '_group',
                        'label' => $block,
                        'name' => $block,
                        'type' => 'repeater',
                        'parent' => 'group_defaults',
                        'button_label' => '+ Nieuwe groep',
                        'layout' => 'block'
                    ]);
    
                    acf_add_local_field([
                        'key' => 'field_' . $block . '_group_name',
                        'label' => 'Groepsnaam',
                        'name' => 'name',
                        'type' => 'text',
                        'required' => true,
                        'parent' => 'field_' . $block . '_group',
                        'wrapper' => [
                            'width' => 50
                        ]
                    ]);
    
                    acf_add_local_field([
                        'key' => 'field_' . $block . '_group_id',
                        'label' => 'Groep ID',
                        'name' => 'groupID',
                        'type' => 'text',
                        'required' => true,
                        'parent' => 'field_' . $block . '_group',
                        'wrapper' => [
                            'width' => 50
                        ]
                    ]);
    
                    add_filter('acf/load_field/name=select' . ucfirst($block), function($field) use ($block) {
    
                        // reset choices
                        $field['choices'] = [];
    
                        // if has rows
                        if (have_rows($block, 'options')) {
                            while (have_rows($block, 'options')) {
                                the_row();
    
                                if (get_sub_field('group')) {
                                    foreach (get_sub_field('group') as $key => &$item) {
                                        $value = $item['groupID'];
                                        $label = $item['name'];
                                        $field['choices'][$value] = $label;
                                    }
                                }
                            }
                        }
    
                        return $field;
                    }, 99);
                }
            }
    
            public static function get_blocks(): array {
    
                $layouts = acf_get_fields('group_5f33b50973315')[0]['layouts'];
    
                $blocks = array_filter($layouts, function($layout){
                    return in_array('source', array_column($layout['sub_fields'], 'name'));
                });
    
                return array_column($blocks, 'name');
            }
        }
    
        $defaults2 = new defaults2();
        $defaults2->initialize();
    
  • I think that the issue is that it is a sub field. Try using the field key variant of the filter instead of the field name.

  • Well, I looked closer at your fields and the field key is dynamic.

    What you need to do is create a filter that runs on all fields. Then inside of your filter you need to look at the field key to see if it matches your pattern for the select field.

  • Hi John,

    Thanks for your response. And you definitly pointed me in the right direction. Using a filter that runs on all fields was the solution I was looking for. I now basically removed the whole filter that had the dynamic part and moved it all to the initialize method. I only had a nesting level issue so I switched to a the ‘afc/prepare_field’ filter instead.

    Just for your reference here’s my adjusted code (I only need to do a minor cleanup). And thanks again!

    
    add_filter('acf/prepare_field', function($field) {
    
        $fieldObject = get_field_object($field['key']);
    
        if(!str_starts_with($fieldObject['name'], 'select')){
            return $field;
        }
    
        $layouts = acf_get_fields('group_5f33b50973315')[0]['layouts'];
    
        $blocks = array_filter($layouts, function($layout){
            return in_array('source', array_column($layout['sub_fields'], 'name'));
        });
    
        foreach ($blocks as $block) {
            if($fieldObject['name'] !== 'select' . ucfirst($block['name'])){
                continue;
            }
    
            $field['choices'] = [];
    
            $groups = get_field($block['name'], 'options');
    
            foreach($groups as $group){
                $field['choices'][$group['groupID']] = $group['name'];
            }
        }
    
        return $field;
    });
    
Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.