0

I'm in the process of building a plugin using the Boilerplate linked in the official WordPress documentation. In my plugin I want to make an AJAX call (on button click) that runs a function and in turn returns a value. This function only needs to run on the admin side, not publicly in the front-end.

My JS script (separate file) is being called correctly, but it seems that WP can't get to my PHP function that needs to return the callback. The results of data is always 0. Does this has something to do with my functions being inside classes? Below a breakdown of my code.

File: my-plugin/includes/class-myplugin.php

class Myplugin {

    private function define_admin_hooks() {

        $plugin_admin = new Myplugin_Admin( $this->get_plugin_name(), $this->get_version() );

        $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
        $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );

        $this->loader->add_action( 'wp_ajax_myplugin_ajax_function', 'wp_ajax', 'myplugin_ajax_function' );

    }

}

File: my-plugin/admin/class-myplugin-admin.php

class Myplugin_Admin {

    public function enqueue_scripts() {
    
        wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/myplugin-admin.js', array( 'jquery' ), $this->version, false );
    
        wp_enqueue_script( 'myplugin_ajax_script', plugin_dir_url( __FILE__ ) . 'js/myplugin_ajax_script.js', array( 'jquery' ), $this->version, false );
    
        wp_localize_script( $this->plugin_name, 'wp_ajax', array('ajaxurl' => admin_url('admin-ajax.php') ) );
    
    }

    public function myplugin_do_magic($url) {
    
        if ( !$url ) { return; }
    
        return $url . '?test';
    
    }
    
    /**
     * Register function to get data from ajax
     */
    public function myplugin_ajax_function() {
    
        $url = $_POST['my_form_field_name'];
        $result = myplugin_do_magic($url);
        echo json_encode( array('data_result' => $result) );
        die;
    
    }

}

File: my-plugin/admin/partials/settings.php

<div class="wrap">

    <h2><?php echo esc_html( get_admin_page_title() ); ?></h2>

    <form action="options.php" method="post">
        <?php
            settings_fields( $this->plugin_name );
            do_settings_sections( $this->plugin_name );
            submit_button();
        ?>
    </form>

    <h2><?php _e('Title here', 'myplugin'); ?></h2>

    <div class="myplugin_ajax_form">

        <input type="url" name="my_form_field_name" id="my_form_field_name" value="" />

        <button type="button" id="myplugin_ajax_button" class="button">
            <?php _e('Run function!', 'myplugin'); ?>
        </button>

    </div>

</div>

File: my-plugin/admin/js/myplugin_ajax_script.js

jQuery(function() {

    console.log('js file loaded...');

    jQuery('#myplugin_ajax_button').click(function() {

        var my_form_field_value = jQuery('#my_form_field_name').val();

        jQuery.ajax
        ({ 
            url: ajaxurl,
            data: {
                action: 'myplugin_ajax_function',
                my_form_field_name: my_form_field_value,
            },
            type: 'post',
            success: function(data) {
                console.log(data);
                if ( data['data_result'] == '' ) {
                    console.log('empty result');
                }
                else {
                    var parsed_data = JSON.parse(data);
                    console.log(parsed_data.data_result);
                }
            },
            error: function(errorThrown) {
                alert(errorThrown);
            }
        });

    });

});

I hope someone can help my out with this. Thanks in advance!

2
  • 1
    I posted an answer, but have you considered using the REST API instead of the old admin-ajax.php route? And if you have, why didn't you use it instead? You know, you could create a custom endpoint, or maybe there's an existing endpoint you could actually use.
    – Sally CJ
    Commented Jul 11, 2022 at 15:46
  • 1
    I've actually never thought of using the REST API for this. I will check that out, thanks!
    – DeltaG
    Commented Jul 12, 2022 at 12:18

1 Answer 1

2

So the AJAX action defined in Myplugin::define_admin_hooks() has been corrected (it's just a typo in the question).

But there's another issue in your code, also in the above function, where the second parameter for $this->loader->add_action() should actually be $plugin_admin (which is an object and an instance of the Myplugin_Admin class) and not wp_ajax:

  • Incorrect: $this->loader->add_action( 'wp_ajax_myplugin_ajax_function', 'wp_ajax', 'myplugin_ajax_function' );

  • Correct: $this->loader->add_action( 'wp_ajax_myplugin_ajax_function', $plugin_admin, 'myplugin_ajax_function' );

And I actually noticed another issue — in Myplugin_Admin::myplugin_ajax_function(), I believe you wanted to call the myplugin_do_magic() method/function in the Myplugin_Admin class, so you should use $result = $this->myplugin_do_magic($url); (note the $this->) because otherwise, then you would end up with a 500 internal server error!

Unless of course if for example there's a function named myplugin_do_magic defined in the global scope.

So make sure that you call a class method properly. =)

6
  • Yes, you are right about that mistake. Thanks for pointing it out. I think I've copied it wrongly in here, in my live code it was indeed the function name instead of the name of the script. I've updated my question with the correct action name.
    – DeltaG
    Commented Jul 12, 2022 at 12:16
  • Actually, there were 2 issues in your original code in question - 1) the AJAX action, and 2) the AJAX callback (the 3rd parameter for $this->loader->add_action()); and now you've corrected the 1st issue, but the 2nd one is still there - use array( $plugin_admin, 'myplugin_ajax_function' ) like in my answer, and not just 'myplugin_ajax_function'. Or was that also another typo in the question only? 🤔
    – Sally CJ
    Commented Jul 12, 2022 at 12:43
  • Or use $this->loader->add_action( 'wp_ajax_myplugin_ajax_function', $plugin_admin, 'myplugin_ajax_function' ); ? (note the 2nd parameter)
    – Sally CJ
    Commented Jul 12, 2022 at 13:04
  • When I use $this->loader->add_action( 'wp_ajax_myplugin_ajax_function', $plugin_admin, 'myplugin_ajax_function' ); I get a 500 error on the admin-ajax.php file in the console. When I use $this->loader->add_action( 'wp_ajax_myplugin_ajax_function, 'wp_ajax', array( $plugin_admin, 'myplugin_ajax_function' ) ); I get the same result (0) as I did before.
    – DeltaG
    Commented Jul 12, 2022 at 13:12
  • 1
    You are a real life saver here! I fixed both of the issues you've pointed out in your revised answer. It works correctly now! Also thank you for your explanation regarding the use of Classes and how to call the functions inside them. Again, you saved my day!
    – DeltaG
    Commented Jul 12, 2022 at 15:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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