Search code examples
advanced-custom-fieldsacfpro

ACF acf_form on admin page works, but when it is loaded in via ajax it breaks


I'm using acf_form() to embed a form in a metabox on the admin page using this code (simplified):

$submitted_user_id = 'user_3';

$form_settings = array(

    'fields' => ['field_625008b509dca'],

    'form_attributes' => array(
        'method' => 'POST',
        'action' => admin_url("admin-post.php"),
    ),

    'post_id' => $submitted_user_id,

);

acf_form( $form_settings );

..and calling the requisite acf_form_head() in admin_init as such:

function append_acf_form_head() {

   acf_form_head();

}
add_action( 'admin_init', 'append_acf_form_head', 1 );

This works fine, and updates the values on submit. However I want to pull this form in via ajax, in order to pass the user_id from a select filter above.

The ajax is also working perfectly, and pulling in the form with the passed user_id, however on submission the form does not save the data, and redirects to 'wp-admin/admin-post.php'.

This is the php code for the ajax functionality in functions.php:

add_action( 'wp_ajax_test_action', 'test_action' );
function test_action() {

    // Same acf_form() function as above

    wp_die()

}

And finally the JS:

$('button#support-ticket-user-filter').on('click', function(e) {

    e.preventDefault();

    var data = {
        'action': 'test_action',
        'user_id': $('select#get_user_id').val()
    };

    $.post(ajaxurl, data, function(response) {

        $('#listings-result').append( response );

    });

});

Any ideas why it would work perfectly in the first case, but not in the second? Perhaps it's related to the ajaxurl?

Many thanks!


Solution

  • For anyone looking for the solution; I've found a slightly hacky approach which does the trick for now. The ACF Support team mentioned this wasn't out the box functionality but has now been included as a feature request. For those trying to achieve this the trick is to permanently embed a 'dummy form' which loads the necessary stuff to make it all work - then kind of hook this into the form pulled in via ajax:

    So, in the meta box a permanent dummy form is embedded:

    // This dummy form is required to load all the acf stuff for the ajax version 
    
    $dummy_form_settings = array(
    
         // Do not declare any fields
    
        'post_id' => $submitted_user_id, // Make sure the ID corresponds ( for users in my case )
    
        'form' => true,
    
    );
    
    acf_form( $dummy_form_settings );
    

    All we want from this dummy form is the 'update' button - which is the one that actually works, as opposed to the one in the form pulled in via ajax. So that function will remove the submit button like this:

    $form_settings = array(
    
        'fields' => ['field_625008b509dca'],
    
        'form_attributes' => array(
            'method' => 'POST',
        ),
    
        'html_before_fields' => sprintf(
            '<input type="hidden" name="user_id" value="' . $submitted_user_id . '">',
        ),
    
        'post_id' => $submitted_user_id,
    
        'form' => true,
    
        'html_submit_button' => '', // The important bit
    
    );
    
    acf_form( $form_settings );
    
    wp_die();
    

    Now your essentially left with a single form that submits properly.