Support

Account

Home Forums Add-ons Repeater Field Get row index inside add_filter( 'acf/load_field' )

Solved

Get row index inside add_filter( 'acf/load_field' )

  • Hi.
    Is there any way of getting the row index inside the load_field filter:
    add_filter( 'acf/load_field' ) )
    I’m using a repeater field and I’m trying to pre-populate the subfield, based on the value of a sibling field, after that field value is saved to the database.

    How could I get the row_index the “current” for the field.
    get_user_meta( 2, 'product_data_' . $row_index . '_product', true ));

  • You cannot populate different rows of a repeater with different row values using an acf/load_field filter. The reason is that the sub field is only “loaded” once so the field will have the same values for all rows.

    This can be accomplished using the acf/prepare_field filter. I actually just did this yesterday 🙂

    In order to do this you need to keep track of the row index yourself. I did this by encapsulating the filter in a class. This is how I set up all my filters. Basically I set up a class where I add all my ACF filters. Here is a basic example of what you want to do.

    Also, note that when filtering sub fields of a repeater it is usually best to use the field key the field name will not be what you expect it to be. For example, the field name being used by ACF for my filter looks something like this

    
    acf[field_602be12e89017][row-2][field_602be2818901b][field_602be3658901c][row-0][field_602d11a1de2fd][row-0][field_602d10bd5cc06]
    

    the field that I am filtering is a sub field in repeater that is nested in another repeater that is then nested in a group field that is nested in another repeater. It may work with the name, but it is more likely that a sub field will share it’s name with a sub field of other repeaters. For example, the name of this field is “value” and I use this sub field name often. Anyway, on to the example.

    
    class MY_PROJECT_NAME_acf_filters {
      
      // variable for row index
      private $my_field_name_index = 0;
      
      public function __construct() {
        // add a filter when preparing repeater
        // I also tend to always use field keys when coding
        add_filter('acf/prepare_field/key=field_XXXXX', array($this, 'init_my_field_name_index'));
        
        // add filter for ths sub field that you want to filter
        add_filter('acf/prepeare_field/key=field_YYYYY', array($this, 'filter_my_sub_field_name'));
      }
      
      public function init_my_field_name_index($field) {
        $this->my_field_name_index = 0;
        return $field;
      }
      
      public function filter_my_sub_field_name($field) {
        $row_index = $this->my_field_name_index;
        
        // do your filtering for this row index
        
        // after filtering increment the field index
        $this->my_field_name_index++;
        
        // return the field;
        return $field;
        
      }
      
    }
    
  • Thank you so much @hube2! 🙂 I really appreciate your feedback and for sharing your code. Here is what I ended up using. I kept your naming convention for convenience.

    
    class MY_PROJECT_NAME_acf_filters {
    	  
    	// variable for row index
    	private $my_field_name_index = 0;
    	
    	public function __construct() {
    		// add a filter when preparing repeater
    		add_filter( 'acf/prepare_field/key=field_601cf9424f9da', array( $this, 'init_my_field_name_index' ), 10, 1 );
    		
    		add_filter( 'acf/prepare_field/key=field_6023ad409d89d', array( $this, 'filter_my_sub_field_name' ), 10, 1 );
    		
    		// add filter for ths sub field that you want to filter
    		add_filter( 'acf/prepare_field/key=field_602e8a8821e89', array( $this, 'filter_my_sub_sub_field_name' ), 10, 1 );
    	}
    	  
    	public function init_my_field_name_index( $field ) {
    		$this->my_field_name_index = 0;
    		return $field;
    	}
    	
    	public function filter_my_sub_field_name( $field ) {
    		// after filtering increment the field index
    		$this->my_field_name_index++;
    		
    		// return the field;
    		return $field;
    	}
    	  
    	public function filter_my_sub_sub_field_name( $field ) {
    		$field['choices'] = [];
    		
    		$row_index = $this->my_field_name_index - 2;
    		
    		$product_id = (int) get_user_meta( 2, 'add_products_' . $row_index . '_produkt', true );
    		
    		if ( ! empty( $product_id ) ) {
    			
    			$pewc_group = new WP_Query( [
    				'posts_per_page => ' -1,
    				'post_type' => 'pewc_group',
    				'post_parent' => $product_id,
    				'post_status' => 'publish'
    			] );
    			if ( $pewc_group->have_posts() ) {
    				while( $pewc_group->have_posts() ) { $pewc_group->the_post();
    					
    					$field['choices'] = [];
    					
    					$group_title = get_the_title();
    					$group_id = get_the_ID();
    					
    					$pewc_field = new WP_Query( [
    						'posts_per_page => ' -1,
    						'post_type' => 'pewc_field',
    						'post_parent' => get_the_ID(),
    						'post_status' => 'publish',
    						'order' => 'ASC'
    					] );
    					if ( $pewc_field->have_posts() ) {
    						while( $pewc_field->have_posts() ) { $pewc_field->the_post();
    							$field_label = get_post_meta( get_the_ID(), 'field_label', true );
    							if ( ! empty( $field_label ) ) {
    								$field['choices'][get_the_ID()] = $field_label . ' (' . get_the_ID() . ')';
    							}
    						}
    						wp_reset_postdata();
    					}
    					
    				}
    				wp_reset_postdata();
    			}
    		}
    
    		// return the field;
    		return $field;
    	}
    	  
    }
    new MY_PROJECT_NAME_acf_filters();
    
  • I had a similar issue where i needed to add the ACF fields meta_id. Below is my solution to the same problem

    function build_meta_key($field){
        // Loop over parents.
        $return_name = $field["_name"];
    
        if(empty($field["prefix"])){
            return $return_name;
        }
    
        $is_row = preg_match("/row-(\d)+/", $field["prefix"], $matches);
    
        if(!$is_row){
            return $return_name;
        }
    
        //now figure out the row number from the field name
    
        $return_name = $matches[1]."_".$return_name;
        
        while ( $field['parent'] && $field = acf_get_field( $field['parent'] ) ) {
            if(isset($field["_name"])){
                $return_name = $field["_name"]."_".$return_name;
            }
        }
    
        return $return_name;
    }
    
    function get_all_meta_info_by_key($post_id,  $meta_key, $meta_type = "post"){
    	global $wpdb;
    	if ( ! $meta_type || ! $post_id || trim($meta_key) == "") {
    		return false;
    	}
    
    	$table = _get_meta_table( $meta_type );
    	if ( ! $table ) {
    		return false;
    	}
    
    	$meta = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$table} WHERE post_id = %d AND meta_key = %s", $post_id, $meta_key) );
    
    	if ( empty( $meta ) ) {
    		return false;
    	}
    
    	if ( isset( $meta->meta_value ) ) {
    		$meta->meta_value = maybe_unserialize( $meta->meta_value );
    	}
    
    	return $meta;
    }
    
    /**
     * Add in the ACF fields meta id to the field itself. so we can build the download links
     * @param $field
     *
     * @return mixed
     */
    function prepare_field( $field ) {
        global $post;
    
        $acf_meta_key = $this->build_meta_key($field);
    
        $meta_information = $this->get_all_meta_info_by_key($post->ID,  $acf_meta_key);
    
        if(!empty($meta_information->meta_id)){
            $field["post_meta_id"] = $meta_information->meta_id;
        }
    
        return $field;
    }
Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.

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 Cookie Policy. If you continue to use this site, you consent to our use of cookies.