WordPress-Plugin-Boilerplate icon indicating copy to clipboard operation
WordPress-Plugin-Boilerplate copied to clipboard

Where do I put ajax function?

Open lwoods opened this issue 8 years ago • 15 comments

I am calling an ajax function from JS in my admin menu page. If I put the add_action( wp_ajax...) and function in my base plugin file then all works fine. BUT since this code is only being used on the admin side I would really like to put the code in a separate module and only load it on the admin side. I can't figure out what is in memory and not in memory when I have classes loading classes loading classes....ad nauseam. Where can I put the add_action and the function so that it is in memory when needed---and not in memory all of the time?

Thanks in advance

lwoods avatar Mar 06 '16 18:03 lwoods

Heyo,

Couldn't you simply check is_admin() around the action hook?

jonathan-dejong avatar Mar 20 '16 10:03 jonathan-dejong

@lwoods If I understand correctly you should be able to add the action within the define_admin_hooks function inside your \includes\class-your-plugin.php file.

private function define_admin_hooks() {
    $plugin_admin = new your_plugin_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_nopriv_your_action', $plugin_public, 'your_action_cb' );
    $this->loader->add_action( 'wp_ajax_your_action', $plugin_public, 'your_action_cb' );
}

LeoFNaN avatar Mar 26 '16 11:03 LeoFNaN

I've tried a bunch of different places to register ajax calls, but the only way I've been able to register ajax calls is in the base plugin file your-plugin.php before run_your_plugin(); is called at the end of the file. @LeoFNaN You're right. This should work, but it isn't working on my end here. Have you had success on your end?

nhobi avatar Mar 31 '16 17:03 nhobi

Here's the code for the end of my base plugin file. I'd really like a better way of doing this.

/**
 * Begins execution of the plugin.
 *
 * Since everything within the plugin is registered via hooks,
 * then kicking off the plugin from this point in the file does
 * not affect the page life cycle.
 *
 * @since    1.0.0
 */
function run_wp_data_append() {

    $plugin = new Wp_Data_Append();
    $plugin->run();

}

function register_ajax_calls(){
    add_action( 'wp_ajax_get_gf_form_object', 'get_form_object' );  
}

function get_form_object() {
    header('Content-Type: application/json');
    echo json_encode(GFAPI::get_form($_POST['form_id']));
    wp_die();
}

register_ajax_calls();
run_wp_data_append();

nhobi avatar Mar 31 '16 17:03 nhobi

Hey @gr33k01, I'm using the technique described by @LeoFNaN in my plugin Simple Sharing. Works just fine for me, but I'm doing really simple stuff there.

https://github.com/slushman/simple-sharing

slushman avatar Mar 31 '16 21:03 slushman

I have a similar problem. I'm trying to do a search tag box similar to that of the backend, but for the frontend. I'm using AJAX to get tag suggestions as user types. I've used AJAX in Wordpress in the past with no problem in themes and such, but I can't get it working using the boilerplate. The AJAX call works, but success:function(data) always returns 0 when it should return 'testing' which makes me think my function never gets called. I've been hours at it and I can't spot the mistake.

UPDATED: My mistake was missing putting action: 'tags_autofill_function' in my AJAX function as someone kindly pointed out in Stack Exchange. I'm leaving the corrected code here in case someone finds it useful.

This is my code:

/public/js/my-plugin-public.js

$('#my_plugin_tags').keyup(function() {

    var user_input = $(this).val();
    var user_input_last = $.trim(user_input.split(',').pop());

    $.ajax({
        url: my-plugin.ajax_url,
        type: 'POST',
        data: {
            'action': tags_autofill_function,
            'user_input': user_input_last
        },
        success:function(data) {
            console.log(data);
        },
        error: function(errorThrown){
            console.log(errorThrown);
        }
    });

});

/public/class-my-plugin-public.php

/**
 * Register the JavaScript for the public-facing side of the site.
 *
 * @since    1.0.0
 */
public function enqueue_scripts() {
    wp_enqueue_script( 'my-plugin-public', plugin_dir_url( __FILE__)  . 'js/my-plugin-public.js', array( 'jquery' , $this->plugin_name ), $this->version, false );          
    wp_localize_script( 'my-plugin-public', 'my-plugin' , array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );

}

/public/class-my-plugin-class-public.php

/**
  * Get tag suggestions from while user writes
  *
  * @since      1.0.0
  */

public function tags_autofill_function() {
    echo('Testing');
    exit();
}

/includes/class-my-plugin.php

/**
 * Register all of the hooks related to the public-facing functionality
 * of the plugin.
 *
 * @since    1.0.0
 * @access   private
 */
private function define_public_hooks() {

    // Load CSS & Scripts
    $plugin_public = new My_Plugin_Public( $this->get_plugin_name(), $this->get_version() );

    $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
    $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );

    // Custom Class from My Plugin
    $plugin_class_public = new My_Plugin_Class_Public();

    $this->loader->add_action( 'wp_ajax_tags_autofill_function', $plugin_class_public , 'tags_autofill_function' );
    $this->loader->add_action( 'wp_ajax_nopriv_tags_autofill_function', $plugin_class_public , 'tags_autofill_function' );

}

sandra-sanz avatar Apr 11 '16 11:04 sandra-sanz

@sandra-sanz - Your response helped me a lot. I'm still not 100% through it. Could you please share the code for your form that needs the AJAX?

Also, could you please explain why did you add: $plugin_class_public = new My_Plugin_Class_Public()? instead of using $plugin_public?

TheBigK avatar May 06 '16 14:05 TheBigK

@sandra-sanz You should do an exit(); after echoing your value back to your ajax function.

jonathan-dejong avatar May 06 '16 22:05 jonathan-dejong

@sandra-sanz This is great! Thanks! I also (as @TheBigK) would love to see the form code. Thanks!

thecodetemple avatar Sep 03 '17 20:09 thecodetemple

This may help other too.

private function define_admin_hooks() {

	$plugin_admin = new VTC_Name_Admin( $this->get_vtc_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( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_ajax_response' );
	$this->loader->add_action( 'wp_ajax_save_button_order', $plugin_admin, 'save_button_order' );


}

public function enqueue_ajax_response() {

wp_localize_script( $this->vtc_name, 'vtc_name' , array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );

}

public function save_button_order() { echo "welcome ajax"; die();- } // save_button_order()

ayrasys avatar Jan 20 '19 19:01 ayrasys

$.ajax({ url: vtc_name.ajax_url, type: 'POST', data: { 'user_input': 'user_input_last', 'action': 'save_button_order' }, success:function(data) { console.log(data); }, error: function(errorThrown){ console.log(errorThrown); } });

ayrasys avatar Jan 20 '19 19:01 ayrasys

its works fine

ayrasys avatar Jan 20 '19 19:01 ayrasys

Hey everyone. Probably, my remark would help someone... I'm just learning WP and faced with the same problem: how to call JS functions and pass data back and forth (for further plugin development). Copied the entire code from the example above to my plugin's files. But keep receiveng '0' in AJAX instead of response from PHP handler function.

I was facing with this until I changed the following:

/public/js/my-plugin-public.js

$.ajax({
        url: my-plugin.ajax_url,
        type: 'POST',
        data: {
            'action': tags_autofill_function,
            'user_input': user_input_last
        },
        success:function(data) {
            console.log(data);
        },
        error: function(errorThrown){
            console.log(errorThrown);
        }
    });

to

$.ajax({
        url: my-plugin.ajax_url,
        type: 'POST',
        data: {
            'action': 'tags_autofill_function',
            'user_input': user_input_last
        },
        success:function(data) {
            console.log(data);
        },
        error: function(errorThrown){
            console.log(errorThrown);
        }
    });

I.e. I wrapped action name to single quotes so that it's passed as a string not as URL that comes up instead, if use this not as a string.

Sorry in advance, probably, I did something wrong, would be appreciated if someone explain this to me. But now it does work.

sPITf1re-dev avatar Mar 11 '19 16:03 sPITf1re-dev

@lwoods If I understand correctly you should be able to add the action within the define_admin_hooks function inside your \includes\class-your-plugin.php file.

private function define_admin_hooks() {
    $plugin_admin = new your_plugin_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_nopriv_your_action', $plugin_public, 'your_action_cb' );
    $this->loader->add_action( 'wp_ajax_your_action', $plugin_public, 'your_action_cb' );
}

why $plugin_public?? shouldn't be $plugin_admin?

dont understand about this when i use $plugin_admin not working still. whats happen.?

encoderit-arman avatar Apr 26 '21 20:04 encoderit-arman

@lwoods If I understand correctly you should be able to add the action within the define_admin_hooks function inside your \includes\class-your-plugin.php file.

private function define_admin_hooks() {
    $plugin_admin = new your_plugin_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_nopriv_your_action', $plugin_public, 'your_action_cb' );
    $this->loader->add_action( 'wp_ajax_your_action', $plugin_public, 'your_action_cb' );
}

why $plugin_public?? shouldn't be $plugin_admin?

dont understand about this when i use $plugin_admin not working still. whats happen.?

Does reading this help?

https://codex.wordpress.org/AJAX_in_Plugins

TonyKnibb-MakaraHealth avatar Sep 01 '21 15:09 TonyKnibb-MakaraHealth