Support

Account

Home Forums Add-ons Repeater Field Repeater load_value()

Solved

Repeater load_value()

  • I was hoping someone could give me some help with the repeater field.

    bit of background

    if you add_filter(‘acf/load_value/type=repeater’, ‘repeater_load_value’, 5, 3) it 5. The $value is an Int (total number of rows for this repeater). You have to return an int. As if you return anything else the native load_value function returns false.

    if you apply filter later like add_filter(‘acf/load_value/type=repeater’, ‘repeater_load_value’, 20, 3). The $value is an array ($rows).

    If I want to modify the to value like in the native load_value function and the return it as an array. Once the native load_value function is run it checks that the value is an int and returns false if it isn’t.

    My problem is. What if i want to build the rows a little differently? would it be possible to include an additional check on the native “load_value” (class-acf-field-repeater.php file line 486) function that doesn’t return false? Or is there another way to complete this?

  • Not 100% sure what your asking. If you want to alter the values of a repeater when they are loaded then you just have to have the priority > 10 to run after the acf function runs. At this point you can do whatever you want and return the value.

  • Hi John,

    Thanks for the response. What i need is to be able to add some variables to the sub field (specifically the repeater’s total rows and the sub field’s row count) before it is rendered.

    I need the value passed the field before the sub field runs it’s load_value function. As I’m using these values to do a seperate DB query for additional information.

    If i set the priority > 10 the sub field has already run through its load_value function and i would have to loop through everything a second time. Which will be fine if i only had a few rows. But i am anticipating over time there will be quite a few rows and i think this will impact in load times.

  • What you describe is the only way to do it. If you want to add rows to the repeater then you must add each row after ACF completes the initialization. Otherwise, you would be asking ACF to do what you don’t want to do. If you are doing a DB query then make sure you get all of your data in one query. Multiple queries will slow things down more than a loop that has to loop through more data.

  • Think i have found a way to achieve what i need.

    I ended up using the pre_load_value filter. which if you hook into and return a value. is then skipped when the repeater field goes to load its value.

    This way i can mimic the load_value function and the acf_get_value function just returns my value as opposed to the system value.

    incase anyone ever needs this in the future here is the code i used.

    add_filter('acf/pre_load_value',   array($this, 'pre_load_value'), 3, 3);
    function pre_load_value( $value, $post_id, $field  ){
    
        if($field['type'] != 'repeater'){
            return $value;
        }
    
        if(!$this->search_sub_fields_for_type($field['sub_fields'], $this->name)){
            return $value;
        }
    
        // Get field name.
        $field_name = $field['name'];
    
        // Check store.
        $store = acf_get_store( 'values' );
        if( $store->has( "$post_id:$field_name" ) ) {
            return $store->get( "$post_id:$field_name" );
        }
    
        // Load value from database.
        $value = acf_get_metadata( $post_id, $field_name );
    
        // Use field's default_value if no meta was found.
        if( $value === null && isset($field['default_value']) ) {
            $value = $field['default_value'];
        }
        //User our own load_value filter to add additional information to subfields
        $value = apply_filters( "ttc_repeater_load_value", $value, $post_id, $field );
    
        // Update store.
        $store->set( "$post_id:$field_name", $value );
    
        // Return value.
        return $value;
    
    }
    
    add_filter('ttc_repeater_load_value',   array($this, 'try_add_grid_info'), 2, 3);
    function try_add_grid_info($value, $post_id, $field){
    
        // bail early if no sub fields
        if( empty($field['sub_fields']) ) return $value;
    
        // vars
        $value = intval($value);
        $rows = array();
    
        $field["total_rows"] = $value;
    
        // loop
        for( $i = 0; $i < $value; $i++ ) {
    
            // create empty array
            $rows[ $i ] = array();
    
            // loop through sub fields
            foreach( array_keys($field['sub_fields']) as $j ) {
    
                // get sub field
                $sub_field = $field['sub_fields'][ $j ];
    
                // bail ealry if no name (tab)
                if( acf_is_empty($sub_field['name']) ) continue;
    
                // update $sub_field name
                $sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}";
                $sub_field["original_order"] = $i;
                $sub_field["latest_row"] = (($field["total_rows"]-1) == $i);
                $sub_field["total_row_count"] = ($field["total_rows"]);
    
                // get value
                $sub_value = acf_get_value( $post_id, $sub_field );
    
                // add value
                $rows[ $i ][ $sub_field['key'] ] = $sub_value;
    
            }
    
        }
    
        return $rows;
    
    }
    
    /** function to loop through sub fields and look for a particular sub field type.
     * @param $sub_fields array of repeater sub fields
     * @param $field_type - Field type we are looking for
     * @return bool
     */
    function search_sub_fields_for_type($sub_fields, $field_type){
        if(!empty($sub_fields)){
    
            foreach($sub_fields as $sub_field){
    
                if(!empty($sub_field["type"]) && $sub_field["type"] == $field_type ){
                    return $sub_field;
                }
            }
    
        }
    
        return false;
    }
Viewing 5 posts - 1 through 5 (of 5 total)

The topic ‘Repeater load_value()’ is closed to new replies.