Thanks, John. I tried that but it didn’t seem to affect the Ajax validation, only the fields appearance. The JS solution is working well though so I’m going to run with that having now added in a check to see if the targeted for is being validated and ‘passing’ it if so:
acf.add_filter('validation_complete', function( json ){
var match = false,
val = "acf[field_123xyz]";
$.each( json.errors, function( index, value ){
if( value.input == val ) match = true;
} )
return match ? { valid: 1 } : json;
});
Thanks, John. Sadly this solution didn’t work for me. My best guess is it’s because wp_doing_ajax()
returns true both on the front end-submit and in the block editor.
I’ve got around it though by using ACF JS and just returning return { valid: 1 };
JSON response for all forms and just loading that script in WP Admin.
acf.add_filter('validation_complete', function( json, $form ){
// return
return { valid: 1 };
});
Thanks, John. In hindsight, using the post object field wasn’t really necessary for this particular issue. I simplified it by switching to using the select field and populating it with the load_field filter.
Boom. Thanks, John. I arrived at the same method after testing changing about every other value in the $_POSTed array but still wasn’t sure if I was missing something. Thanks a lot for getting back to me.
Hi, ReHo20. Thanks for those pointers. After posting this question I found that I could pass a post_id
, or more specifically a **user id** to the acf_add_options_sub_page()
function which enabled me to effectively have an options page which works for editing user meta. The steps I used were:
– Sending the user to admin.php?page=crm-client&user=2 via a custom table of users on my plugin landing page in admin
– Creating an options page with acf_add_options_sub_page()
with post_id
set to $_GET
the user_id from the URL
– I set the position
to 99 and then hid that menu item with CSS so that my client wouldn’t find themselves on the Client Settings page without an id in the URL, i.e.: they can only get to it via the user table
And it works like a charm! This was always a more desirable solution than hacking the default WP user page in admin as it gives me much more control and means that we still have that more detailed user options page at our disposal.
Thanks again for taking the time to share your solution.
This was really useful. Thanks John and Vayu. Readers watch out for a small typo in John’s original answer on line 12 where it says
prepeare_field
which should, of course be prepare_field
.
It had me stumped for a short while.
Sweet, thanks for clarifying, John. That’s what I’m using. There’s a typo in your solution above (for the benefit of anyone finding and hoping this) in the form of an extra closing parentheses. Should be…
if( ! is_admin() && did_action( 'acf/submit_form' ) == 0 ) {
acf_form_head();
}
Thank you, John. I’ve used your code and the duplication is no longer happening. However, I think that on this occasion the solution was to prevent it loading twice in the front and admin as described in this post: https://support.advancedcustomfields.com/forums/topic/acf_form-always-creates-two-posts/#post-53099
Thanks again
Posting my workaround here in case it’s of use to anyone stumbling across this issue. First I use acf/load_field
to move the instructions to a new item in the array and empty the instructions item, checking first to see if this is a child of my repeater field. Then I filter the output of all fields using acf/render_field
to see if there’s an ‘instructions_below’ item in the array and output it after the input.
add_filter( 'acf/load_field', 'tweak_repeater_instructions' );
function tweak_repeater_instructions( $field ) {
if( 'group_123xyz' !== $field['parent'] ) return $field;
$field['instructions_below'] = $field['instructions'];
$field['instructions'] = '';
return $field;
}
add_filter( 'acf/render_field', 'position_repeater_instructions' );
function position_repeater_instructions( $field ) {
if( ! isset( $field['instructions_below'] ) ) return;
echo '<p class="description">'.$field['instructions_below'].'</p>';
}
+1 from me. Thank you.
Thanks, @rootid – this turned out to totally be my problem too. I was echoing the content straight from the $post object like $post->post_content
. What fixed it was switching to echo apply_filters( 'the_content', $post->post_content );
.
The slightly misleading thing I found was that other blocks were appearing in post_content
, just not my ACF custom blocks – I guess because of the order in which they are added – this hindered my diagnosis of the issue though, which I had assumed was a problem with my render_template
path as the blocks were appearing correctly in the block editor.
With a nudge in the right direction from ACF support, I was able to achieve exactly what I wanted, namely removing some controls from my acf_form front-end Google Map inputs, via the ‘new’ JavaScript API’s google_map_args
filter found at https://www.advancedcustomfields.com/resources/javascript-api/#filters-google_map_args
acf.add_filter('google_map_args', function( args, field ){
args[ 'mapTypeControl' ] = false;
args[ 'streetViewControl' ] = false;
args[ 'fullscreenControl' ] = false;
return args;
})
Thanks for the quick reply, John. Actually, I solved my problem. The $post_id
var was ‘new_post’ but my filter was being fired after the post had been created and was thus returning the created post ID. I changed the priority to 1 and everything fell into place.
I’m using the pre_save_post
filter because I need to get the values from my fields in order to structure the new post (including meta and tax) and I don’t believe that I could do that with the new_post
argument – unless I’ve missed something.
Hi, John. I think this might be the root of a problem that I’m experiencing with my pre_save_post filter. If I comment out the
if( $post_id != 'new_post' ) {
return $post_id;
}
bit then it works. Your comment above suggests that I should change it to new new_{$custom_post_type}
, my post type is ‘role’ but $post_id != 'new_role'
doesn’t do the trick. What am I missing?
NB the documentation says $post_id != 'new'
but that doesn’t work either.
Thanks
Thanks again for your help on this, John. I didn’t get it working in the end and instead reverted to using WooCommerce hooks to append fields to the registration form.
I’ve not ruled out revisiting your proposed solution at a later date though as I’m using an ACF form on the user’s account page and would ideally like to be using the same one on the register form, rather than maintaining two sets of fields. If I do eventually get it to work I’ll update this thread with my results.
Never mind. This totally works with the key/slug and pulls the form directly from the json. I was using a shortcode which was wrapping my slug in intval() thus returning 0.
I’m also coming against this same issue. I’ve tried passing the group ‘slug’ (group_5b44c8acacd2c) instead of the post ID but that doesn’t seem to work. Is there any way to call an acf_form without syncing the fields on my live site?
Hi everyone. I’ve just worked in a solution for this issue thanks to a reply from James on a different question. I’ve created a set of custom fields on an options page where my user can create a custom header/footer to appear before/after a post type and had manually created a list of post types for them to choose from. This wasn’t great as the list would include assumed and potentially unused post types (like ‘product’) and not include post types added by plugins beyond my control.
I now hijack that select field and populate it with only active (and ‘public) post types with the following function:
function acf_load_post_type_choices( $field ) {
$field[‘choices’] = array();
$choices = get_post_types( array(‘public’ => true) );
if( is_array($choices) ) {
foreach( $choices as $choice ) {
$field[‘choices’][ $choice ] = $choice;
}
}
return $field;
}
add_filter(‘acf/load_field/name=post_types’, ‘acf_load_post_type_choices’);
Hope someone finds that useful.
+1 for this feature.
Bump!
I’ve just implemented a page layup on a site today where the user enters the page content in three different languages that then also appear in tabs on the live site. It would be really cool to be able to click a little ‘+’ tab at the end to add a new language.
Tabbed repeaters or repeating tabs would be awesome.
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 Privacy Policy. If you continue to use this site, you consent to our use of cookies.