Here at Studio Simpatico, we love Advanced Custom Fields. Recently we’ve been using ACF Forms to allow users on the frontend of a WordPress site to create and edit posts, something that usually can only be done when logged into the backend.

However, if you let users create their own posts, you need to let them delete their posts as well. ACF Forms is not as well set up to allow you to delete posts, but we’ve got a workaround that will allow you to add a delete button to your post-editing form using jQuery.

Here’s the strategy. There’s no way to get an ACF form to delete a post natively. So instead, we’ll write a filter in functions.php to check for a delete field when a post is saved. We’ll add an invisible true/false field to the ACF group the form uses. Then we use JavaScript to append a “delete” button to the form. When that button is clicked, set the invisible true/false field to true and trigger a click on the form’s submit button. Now our filter will see that the field is true, and delete the post instead of saving.

Simple, right?

First, let’s write out filter function. Add the following code in functions.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
add_filter('acf/save_post', 'delete_project');
 
function delete_project($post_id) {
    $post_type = get_post_type($post_id);
 
    // change to post type you want them to be able to delete
    if ($post_type != 'projects') {
        return;
    }
 
    if (get_field('delete_post', $post_id)) {
        $force_delete = false; // move to trash
        // change above to true to permanently delete
        wp_delete_post($post_id, $force_delete);
        header("Refresh:0");
        exit;
    }
}

In our example, the post type that we want to delete is “projects,” but switch that out for whatever is appropriate in your case.

Now that we have our filter checking for the “delete_post” field, we need to add that to our ACF field group. For me, that looked like this:

Screenshot of ACF field group

Use CSS to make that field display: none; since the user won’t be interacting directly with it. Make a note of the field’s key, as we’ll be using it later.

Next, we’ll use JS to create a delete button variable and append it to our form. We’re targeting our form using a parent wrapper with the “edit-proj-form” class, but substitute whatever targeting works for your form:

1
2
3
4
5
let editForms = $('.edit-proj-form form');
const deleteBtn = '<button class="delete-btn js-delete-proj" type="button">Delete this project</button>';
editForms.each(function() {
    $(this).append(deleteBtn);
});

Once we have our button added, we need to listen for clicks. We’ll write a listener that will prompt the user to confirm the deletion, then check off the hidden true/false field, and trigger a click event on our form’s submit button.

1
2
3
4
5
6
7
8
9
10
11
12
13
$(document).on('click', '.js-delete-proj', function() {
    const confirmDelete = window.confirm('This will permanently delete the project. Are you certain you wish to proceed?');
    const deleteCheck = $(this).siblings('.acf-form-fields').find('input[name="acf[your_field_key]"]');
    const submitDiv = $(this).siblings('.acf-form-submit')[0];
    const submitBtn = $(submitDiv).find('.acf-button');
 
    if (confirmDelete) {
        deleteCheck.each(function() {
            $(this).val(1);
        });
        submitBtn.click();
    }
});

Here you’ll want to sub out your_field_key for the key name of your delete_post field.

Now users will be able to click the delete button on your form, confirm that they want to delete the corresponding form, and remove the post all from the front end!