I’ve used Ajax with WordPress before and got it working. However this particular case (file upload) has proven difficult. The problem seems to be that the action is not calling the php function even though I’ve set the action in AJAX formData.append( 'action', 'uc_user_image' ); the same as my function name in PHP function uc_user_image()

I know that Ajax is working, as I had some checks (that I didn’t include here) within success: function(data) {} and I’m not getting any errors in the console.

My end goal is to allow users to change their profile images dynamically through their account page. I’ve read through a lot of tutorials and SE questions but can’t seem to figure it out. I appreciate any feedback.

functions.php

<?php

// includes
include( get_theme_file_path( '/includes/enqueue.php' ) );
include( get_theme_file_path( '/includes/process/profile-picture.php' ) );

// hooks
add_action( 'wp_enqueue_scripts', 'include_scripts' );
add_action( 'wp_ajax_uc_user_image', 'uc_user_image' );

update: I’m not including the nopriv action as this should only work for logged in users. I’ve also been testing only while logged in.

enqueue.php

<?php

function include_scripts() {

  $uri              =     get_theme_file_uri();
  $ver              =     UC_DEV_MODE ? time() : false;

wp_register_script( 'ajax-account', $uri . '/assets/js/account/userimg-ajax.js', array('jquery'), $ver, true);
wp_localize_script( 'ajax-account', 'userimg', array( 'ajaxurl' => admin_url( 'admin-ajax.php', 'relataive' )));
wp_enqueue_script( 'ajax-account' );

}

profile-picture.php

<?php

function uc_user_image() {
// I know (assume) this isn't firing because I've done some checks like below.
// I'm omitting the file upload code to focus on calling the function.

  $output = ['status'  => 'func_fired'];
  wp_send_json($output);

}

userimg-ajax.js

jQuery(document).ready(function( $ ) {

  $('#user-image-form').submit(function(e) {
    e.preventDefault();

    var formData = new FormData()
    var file = $('#user-image-file')[0].files[0];
    formData.append( 'action', 'uc_user_image' );
    formData.append( 'file', file );

    $.ajax({
        url: userimg.ajax_url,
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
        success: function(data) {
              if ( data.status == 'func_fired' ) {
                $(".dev-updates").html('Function Fired');
              } else {
                $(".dev-updates").html('Function NOT Fired');
              }
        }

    });

  });

});

form html

            <form id="user-image-form">

              <label id="user-image-upload">
                 <input type="file" name="user-image-file" id="user-image-file" accept="image/*" />
                 + Upload Picture
              </label>
              <button type="submit" id="user-image-save"/>Save</button>

            </form>

If you’re questioning why I’ve wrapped the input in the label, it’s for styling purposes.

1 Answer
1

The problem is with the AJAX endpoint URL, i.e. url: userimg.ajax_url, which is not actually defined in your JS/PHP code.

More specifically, you did define the correct URL, but in the JS object, the property name is ajaxurl and not ajax_url:

// wrapped for brevity
wp_localize_script( 'ajax-account', 'userimg', array(
  'ajaxurl' => admin_url( 'admin-ajax.php', 'relataive' )
));

So in your $.ajax() args, just make sure you use the correct property name — ajaxurl. Or change the one in your PHP to ajax_url.

And then the problem would be gone.

Leave a Reply

Your email address will not be published. Required fields are marked *