Home › Forums › Add-ons › Repeater Field › Create New Repeater Row from Front End Form
I have done a bit of researching and have not found anything clear. I know that acf_form() can be used but for this I am looking for something different or a way to hook into acf_form().
I have a custom post type that contains a repeater field with multiple fields including a Google Map field. On the front-end I am using the repeater rows to put pins on a front-end Google Map. I am looking to create a front-end form that would allow someone to fill out a form and hit submit to add a new marker on the map.
When the person submits a form it will add a new repeater row to the post with the submitted data then show the new marker on the page. If I use acf_form() it shows the entire repeater field. I don’t want anyone on the front to change existing rows all I want is for someone to be be able to fill out a form to create a new row.
Any ideas or if anyone has a doc or form on this that would be great.
Hi Joe,
Do I understand you correctly if I think you have a larger field group which contains amongst else a repeater field? And the repeater field in term contains multiple fields including a google map field.
I think the easiest way for you to do this would be to create another field group for your CPT. In it you’ll put just a single google maps field. Then set the field_groups
parameter of acf_form()
to the new group so that a visitor only see this single google maps field.
Then you hook into the save_post
action. Make the necessary checks to make sure it’s your CPT and a value has been set to the new google maps field.
Here’s the tricky part. There is no easy way to add a new row programmatically to ACF. There’s only the update_sub_field function which are capable of updating an existing subfield value.
So what you need to do is first fetch the repeater fields value directly from the DB (which is a number corresponding to how many rows there are). Update it with +1 and then you can use update_sub_field.
I’ve done this myself in a project recently and it works 🙂
Here’s some sample code for how to create a new row and add values to it from within functions.php
//Our single google maps field
$temp_map = get_field('field_name');
//Repeater field
$repeater = get_post_meta($post_id, 'field_name', true);
//If there are no rows yet just set to 1, otherwise +1
$new_repeater_count = ( !$repeater ? 1 : $repeater + 1 );
update_post_meta($post_id, 'field_name', $new_repeater_count);
//Now we can start adding our sub field values. However the update_sub_field function takes 0 as base so we actually need to subtract 1 from our $new_repeater_count
$index = $new_repeater_count -1;
//Update the map sun field
update_sub_field( array( 'repeaterfieldkey', $index, 'subfieldkey' ), $temp_map), $post_id );
//And now we want to clear the single google maps field since there shouldn't be any preset address for the next person!
update_field('fieldkey', '', $post_id);
Let me know how that works out!
Hi @jonathan I really appreciate the input. You solution/work around makes sense but I am a little concerned because I feel like I may be putting a bandaid on the submit to repeater since it’s not truly supported.
I may handle this a little different than I originally planned since there are going to be 1000s of posts each with up to 20 repeater rows per-post. I think I may create a post type to store the actual location data (what I am calling sightings). I can then create a relationship between the listings post type and the sightings post type. I should be able to then query everything as needed. Thanks for the help.
Alright that’s another way to go 🙂
For me it was just 8 rows in each post (thousands of posts tho). It works like a charm but would of course break if elliot ever decides to change the actual DB value of the repeater field. I’ll save that for a rainy day.
Hello old thread!
FYI, this is now easier using the update_row function
instead of:
update_sub_field( array( ‘repeaterfieldkey’, $index, ‘subfieldkey’ ), $temp_map), $post_id );
Do this:
$row = array(
'repeater_child_fieldname' => $temp_map,
'repeater_child_fieldname2' => etc....,
);
update_row( 'repeater_name_or_key', $index, $row, $post_id );
Hi Jonathan,
I think there is an update/change to the code that make the minus 1 to $new_repeater_count unnecessary.
looking in .//advanced-custom-fields-pro/api/api-template.php for ACF Pro v 5.4.2 – on line 1607 there is this.
if( is_numeric($s) ) {
// get row index
$row_i = intval($s) - 1;
// add to name
$name .= "_{$row_i}";
} else {
So it seems like the -1 is now built in the code.
I’m not too thrilled with this, as now I have to remember yet another hidden functionality to the update_sub_field() function.
I would update Jonathan’s code to something like this.
$repeater = get_post_meta($orgPost, 'org_users', true);
$index = (!$repeater) ? 1 : $repeater + 1;
update_field(ORG_USERS_FIELD_KEY, $index, $orgPost);
update_sub_field(array(ORG_USERS_FIELD_KEY, $index, ORG_USER_SUB_FIELD_KEY), $user_id, $orgPost);
I believe you’re right, because I’m using the below code and not having to do any weird math like that.
//Add a row with the user's info as an admin to the Staff repeater field
//There are no rows yet, so we update the value of the repeater field to 1 to make a new row
//The value of the repeater field is simply a number representing the number of existing row
//If ACF ever changes the value of the repeater field in the database, this will need adjusting
if (get_post_meta($post_id, 'choose_tps_members')) {
$existingRows = get_post_meta($post_id, 'choose_tps_members', true);
if (have_rows('choose_tps_members', $post_id)) {
$selectedMembers = array();
while(have_rows('choose_tps_members', $post_id)) {
the_row();
$selectedMembers[] = get_sub_field('choose_member'); //user array
}
}
}
//Add a row to the repeater
update_post_meta($post_id, 'choose_tps_members', $existingRows+1);
//Update repeater row we just created with the Creator's info
$setUser = get_user_by('id',$creator);
$row = array(
'choose_member' => $setUser, //Creator
'make_admin' => array('Admin'), //Check the "make admin" box
);
//Update the repeater row
update_row( 'choose_tps_members', $existingRows+1, $row, $post_id );
//Once all fields validate, we can finally publish it
wp_update_post(array('ID'=>$post_id, 'post_status'=>'publish'));
arcanipsyche –
aren’t these three lines doing the same thing?
$repeater = get_post_meta($post_id, 'choose_tps_members', true);
if (get_post_meta($post_id, 'choose_tps_members')) {
$existingRows = get_post_meta($post_id, 'choose_tps_members', true);
Yes, that first line looks like a leftover from a previous attempt or something. It can be remove and everything works the same. I’ve done so. Good eye.
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
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.