In my WP 4.4 Twenty Sixteen child theme I want to delete post image attachments from a front end form created by a plugin. To achieve this I followed this answer, but the delete links doesn't delete anything (they link me to the top of the page). What is wrong here?


With the commenters help and after fixing some errors I solved my problem. Thank you! Below is the fixed code.

In my front end form created by a plugin I get the post ID and display its image attachments together with the delete links:

<!-- Display item thumbnails -->
<?php if( 'POST' == $_SERVER['REQUEST_METHOD'] && isset( $_POST['postid'] ) ) {
    $images = get_children( array ( 'post_parent' => $_POST['postid'], 'post_type' => 'attachment', 'post_mime_type' => 'image' ));
    if ( empty( $images ) ) {
        // no attachments here
    } else {
        echo '<label for="item_thumbnails">Post thumbnails</label>';
        echo '<div class="item_thumbnails">';
        foreach ( $images as $attachment_id => $attachment ) {
            echo wp_get_attachment_image( $attachment_id, 'thumbnail' ) . '<br>'; ?>
            <!-- add a 'Delete' link -->
            <a class="remImage" name="<?php echo $attachment_id; ?>" href="#"><?php _e('delete');?></a>
            <input type="hidden" id="att_remove" name="att_remove[]" value="<?php echo $attachment_id; ?>" />
            <input type="hidden" name="nonce" id="nonce" value="<?php echo wp_create_nonce( 'delete_attachment' ); ?>" />
        <?php }
        echo '</div>';

In a 'js' subdirectory of my plugin I created a jQuery script named 'delete_attachment.js':

// this is for jQuery 1.7+
//jQuery('.remImage').on('click', function(event) {

// this is for jQuery 1.4.3+
jQuery(document).delegate('.remImage', 'click', function(event) {

// this is for jQuery 1.3+ (deprecated)
//jQuery('.remImage').live('click', function(event) {

    var attID = jQuery(this).attr('name');
        type: 'post',
        url: MyAjax.ajaxurl,
        data: {
            action: 'delete_attachment',
            attID: jQuery(this).attr('name'),
            _ajax_nonce: jQuery('#nonce').val(),
            post_type: 'attachment'
        success: function() {

I enqueued it in the plugin file:

function the_plugin_scripts() {
    wp_enqueue_script( 'delete-attachment', plugins_url( 'js/delete_attachment.js' , __FILE__ ), array('jquery') );
    wp_localize_script( 'delete-attachment', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
add_action( 'wp_enqueue_scripts', 'the_plugin_scripts' );

and in the same plugin file I added a function that handles the AJAX request:

add_action( 'wp_ajax_delete_attachment', 'delete_attachment' );
function delete_attachment( $post ) {
    //echo $_POST['attID'];
    $msg = 'Attachment ID [' . $_POST['attID'] . '] has been deleted!';
    if( wp_delete_attachment( $_POST['attID'], true )) {
        echo $msg;

Now you need to handle the AJAX call in PHP.

add_action( 'wp_ajax_delete_attachment', 'delete_attachment' );
function delete_attachment( $post ) {
//echo $_POST['att_ID'];
$msg = 'Attachment ID [' . $_POST['att_ID'] . '] has been deleted!';
if( wp_delete_attachment( $_POST['att_ID'], true )) {
    echo $msg;

As for your event, just add it to the click function then everything inside will know what you're talking about.

jQuery('.remImage').on('click', function(event) {


Copy and paste this into your functions. It will automatically run and should output a response from the AJAX in an alert and also the console.

function ajax_delete_attachment_handler() {

    $data = json_encode(array('message' => 'THIS IS AJAX WORKING', '$_POST' => $_POST));

$action_name = 'delete_attachment';
add_action("wp_ajax_nopriv_$action_name", 'ajax_delete_attachment_handler');
add_action("wp_ajax_$action_name", 'ajax_delete_attachment_handler');
add_action('wp_footer', function() {
            type: 'POST',
            cache: false,
            dataType: 'json',
            url: "/wp-admin/admin-ajax.php",
            data: {
                action: 'delete_attachment',
                ID: 'some ID here',
                'foo': 'bar'
            success: function (response) {

                // we encoded the data, so let's decode it first
                var json = JSON.parse(response.data);

                console.log('response: ', response);
                console.log('json parsed: ', json);

            fail: function (response) {
                console.log('FAILED: ' + response);
  • Your answer helped me to solve my problem, so I will mark it as accepted, but please fix the code line fjQuery('.remImage').on('click', function(event) { as in my updated question, because the on('click' doesn't work. Thank you! Dec 21 '15 at 22:04
  • 1
    Well, if it's working then just roll with it. Cheers!
    – jgraup
    Dec 21 '15 at 22:30
  • Changed .live() with .delegate() - jQuery( document ).delegate('.remImage', 'click', function(event) { as suggested on api.jquery.com/live. Dec 21 '15 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.