I am running ACF PRO 5.3.9.2, but I think this pertains to any version with nested repeaters. I am hoping to add rows to a nested repeater (that is a repeater inside a repeater) using the update_field()
or update_sub_field()
function.
The update_field()
function works great for first-level repeater rows, i.e.:
update_field( $field_key, $value, $postID );
but I am uncertain about how to use this for nested repeaters. This is the ACF Fields structure:
CUSTOM POST TYPE
Repeater Field - "Media"
Repeater Field - "Notes"
So, here is the code I am attempting:
$field_key = "field_xxxxxxxxxxxxx"; //NOTES FIELD KEY
$value = get_field($field_key, 12); //GET FIELDS OF POST ID 12, NOTES
$value[] = array("note" => "Here is a new note");
update_field( $field_key, $value, 12 );
But this does nothing. There is no way to determine WHICH "Media" repeater I am wishing to add a "note" to.
I can successfully "update" the nested repeater field using update_sub_field() like the code below IF and only IF there is a row in the nested repeater field, but it overwrites just the one row and cannot add to it. It also will not work if there isn't currently a row in the repeater.
update_sub_field( array('media', 1, 'notes', 2, 'note'), 'Here is a new note!', $postID );
What can I do to add rows to a nested repeater whether there is a row already or not?
I was able to accomplish this with both a combination of ACF's functions and regular good old PHP. I can't find another method, but I read other posts where people allude to this method, although they do not elaborate or show code, so here were my long-winded steps to accomplish this:
array_push()
update_field()
To help illustrate the parent/child relation, remember I have a repeater field called media
and a nested repeater within that called notes
, which only has the 1 sub-field note
. So if I use get_field('media')
this is the array it would return:
Array
(
[0] => Array
(
[media_title] => 'title 1',
[notes] => Array
(
[0] => Array
(
[note] => 'HERE IS THE NOTE ADDED'
)
[1] => Array
(
[note] => 'Here is another note added!'
)
)
)
[1] => Array
(
[media_title] => 'title 2',
[notes] =>
)
)
So, in this example, I have 2 elements in the parent repeater, one of which has 2 elements in the nested repeater, one that has no elements in the nested repeater. This is important because you will need to determine if there is already an array established in the nested repeater before you can add to it.
//LOOP THROUGH PARENT REPEATER
if( have_rows('media_item', $postID) ):
//SET YOUR ROW COUNTER
$i = 0;
//MAKE YOUR NEW ARRAY
$media_item = get_field('media_item', $postID);
while( have_rows('media_item', $postID) ) : the_row();
if($i == $arrayRowID) { //IF THIS IS THE ROW WE WANT TO EDIT IN PARENT REPEATER
//FIND OUT IF IT IS AN ARRAY ALREADY OR NOT
if( !is_array($media_item[$i]['notes']) ) { //WE DONT HAVE ANY NOTES
$media_item[$i]['notes'] = array();
}
$addRow = array( //SET YOUR NEW ROW HERE
'note' => 'This is my new note added!';
);
//ADD TO ARRAY
array_push($media_item[$i]['notes'], $addRow);
}
$i++;
endwhile;
endif;
So, I use $i
as a counter to determine which row in the parent repeater I want. If it was the second item in the array, $i = 1
, since the array starts at 0
. You also have to feed it your post ID in this function, but hopefully it makes sense. Be careful if you have many rows for your parent or child repeaters, as to save it, you have to overwrite the entire parent repeater array with the new one you just created:
$field_key = "field_xxxxxxxxxxxxx" //FIELD KEY OF PARENT REPEATER 'media'
update_field($field_key, $media_item, $postID);
This will save the new array with the rows you appended to your child repeater. I hope this helps someone as I couldn't find any examples covering this method. I would love to a function added to ACF like add_row()
which works for nested repeaters!