1

I have created a plugin that creates a custom Post Type called smm_newsletter, and used that Post Type to create newsletter template and send a newsletter email. Then, I made a meta-box for sending button include in that Post Type's post-new.php/post.php.

The script for wp_localize_script is this

function smm_admin_scripts() {
    wp_register_script( 'smm-js-priv-script', plugins_url( '/js/private/smm-builder.js', __FILE__ ), array( 'jquery' ), '', true );
    // localize admin URL
    $php_localized_priv_script = array( 'admin_url' => admin_url() );
    wp_localize_script( 'smm-js-priv-script', 'smm_priv_script', $php_localized_priv_script );
    wp_enqueue_script( 'smm-js-priv-script' );
}
add_action( 'admin_enqueue_scripts', 'smm_admin_scripts' );

*I added exactly same localized admin URL to my public scripts function and it work fine in input submit button. This code too, it work fine in input submit button.

This is code for that button

// I do not use type="submit" because publish/update button use it.
<input id="smm_newsletter_send" name="smm_newsletter_send" type="button" value="Send Newsletter">

and ajax

jQuery( document ).ready( function($) {
    /* Newsletter Section */
    // I did localized script for path to wp-admin here
    var wpajax_url = smm_priv_script.admin_url + 'admin-ajax.php';
    var sendingNewsletter_url = wpajax_url + '?action=smm_newsletter_sender';
    // out put form console: http://localhost/wordpressProject/wordpress/wp-admin/admin-ajax.php?action=smm_newsletter_sender
    console.log(sendingNewsletter_url);
    $( '#smm_newsletter_send' ).on( 'click', function( e ){
        e.preventDefault();
        $form = $( 'form#post' );
        // setup our form data for ajax post
        var form_data = $form.serialize();
        console.log( form_data ); // here it work find
        // submit form data with ajax post
        $.ajax({
            'method' : 'post',
            'url' : sendingNewsletter_url,
            'data' : form_data,
            'dataType' : 'json',
            'catch' : false,
            'success' : function( data, textStatus ){
                if( data.status == 1 ) {
                    // success
                    // notify the user of success
                    window.location.reload( true );
                    console.log( data.status + '\n' );
                    console.log( data.message + '\n' + '——————————' );
                } else {
                    // error
                    // begin building our error message text
                    console.log( data.status + ' ' + 'error' + '\n' );
                    console.log( data.message + '\n' + '——————————' );
                }
            },
            'error' : function( jqXHR, textStatus, errorThrown ) {
                // ajax didn't work
                console.log('A jQuery Ajax error has occurred! See details below...');
                console.log(textStatus);
                console.log(errorThrown);
            }
        });
        // stop the form from submitting nornally
        return false;
    });
});

But, after I clicked that button ajax() only console.log undefined for me

undefined error
undefined
——————————

So, I tried another method to test my sending newsletter function [smm_newsletter_sender()] to make sure that function works, by changing $_POST to $_GET. And simply placed URL that look like this http://localhost/wordpressProject/wordpress/wp-admin/admin-ajax.php?action=smm_newsletter_sender?post_ID=123. It worked perfectly, by sending all of newsletter emails and returning the proper JSON. My email sending function is working fine, but the button for send not, why?.

At first, I had suspected about ajax(), may I did something wrong about it? But I did not found anything wrong. So, may be It about WordPress itself that prevent something that I don't know.

brasofilo
  • 25,496
  • 15
  • 91
  • 179
Dedd
  • 13
  • 5

3 Answers3

0

Looks like your ajax url displaying undefined. You need to localize your script first like:

wp_register_script('myscript', get_stylesheet_directory_uri() . '/js/myscript.js', array('jquery'), '1.0.1', TRUE);

$protocol = !empty($_SERVER['HTTPS']) ? 'https://' : 'http://';

wp_localize_script('myscript', 'ajax_obj', array('admin_ajax' =>admin_url('admin-ajax.php',$protocol)));
// Enqueued script with localized data.
wp_enqueue_script('myscript');

Then in your .js file read admin URL like :ajax_obj.admin_ajax.

mokiSRB
  • 1,132
  • 7
  • 16
  • On code above, I had already did it. `smm_priv_script.admin_url` received localized script form the PHP file. but thank. – Dedd May 15 '17 at 14:13
0

I had tried in many ways to solve this problem. OK, I don't know why, but this make it work. At first, I changed method form POST to GET and input button to a.

This is happen in custom meta-box.

// I created nonce url for security thing
$nonce_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=smm_newsletter_sender&post_ID=' . $post->ID ), basename( __FILE__ ), 'smm_send_newsletter_nonce' );
// and changed inupt to a tag
echo( '<div><a href="' . $nonce_url . '" id="smm_newsletter_send" class="button button-primary button-large">Send Newsletter</a>' );

and in jQuery ajax()

jQuery( document ).ready( function($) {
    $( '#smm_newsletter_send' ).on( 'click', function( e ){
        $.ajax({
            'method' : 'GET',
            'url' : $( this ).attr( 'href' ),
            'dataType' : 'json',
            'catch' : false,
            'success' : function( data, textStatus ){
                if( data.status == 1 ) {
                    // success
                    // notify the user of success
                    window.location.reload( true );
                    console.log( data.status + '\n' );
                    console.log( data.message + '\n' + '——————————' );
                } else {
                    // error
                    // begin building our error message text
                    console.log( data.status + 'error' + '\n' );
                    console.log( data.message + '\n' + '——————————' );
                }
            },
            'error' : function( jqXHR, textStatus, errorThrown ) {
                // ajax didn't work
                console.log('A jQuery Ajax error has occurred! See details below...');
                console.log(textStatus);
                console.log(errorThrown);
            }

        });
        e.preventDefault();

        // stop the form from submitting nornally
        return false;
    });
});

As I said above, I don't know why this work and, in case of input button, why ajax() can not sent the request URL to sending action. So, this is only a practical way.

If someone can explain, please do it.

Thank.

Dedd
  • 13
  • 5
0

The first thing is to print our scripts only on the pages we need. This is important because we don't want our styles/scripts printing all over wp-admin.

add_action( 'admin_print_scripts-post.php', 'smm_admin_script');
add_action( 'admin_print_scripts-post-new.php', 'smm_admin_script');

Also:

  • check if it's the correct Post Type before printing the scripts:
  • localize the full admin-ajax URL
  • localize the security nonce
function smm_admin_script() {
    global $typenow;
    if( 'smm_newsletter' !== $typenow )
        return;

    wp_enqueue_script('my-ajax', plugins_url( '/my-ajax.js', __FILE__ ), array('jquery') );
    wp_localize_script( 
        'my-ajax', 
        'my_plugin',
        array( 
            'ajaxnonce' => wp_create_nonce( 'nonce_smm' ),
            'ajaxurl' => admin_url( 'admin-ajax.php' )
        ) 
    );
}

The file my-ajax.js will use the localized values my_plugin.ajaxnonce and my_plugin.ajaxurl. The action is defined on the Ajax PHP function.

For testing I used button#send-ajax and div#aresponse.

jQuery(document).ready(function($) { 
    $( '#send-ajax' ).click( function(e) {
        e.preventDefault();
        var data = {
            action: 'sendform_smm',
            security: my_plugin.ajaxnonce,
            form_smm: { 'input1': 'value1', 'input2': 'value2' }
        };
        /* 
           You can send the full form as an object using:
           form_smm: $form.serializeArray()
        */ 
        $.post( 
            my_plugin.ajaxurl, 
            data,                   
            function( response ){
                // ERROR HANDLING
                if( !response.success ) {
                    // No data came back, maybe a server error
                    if( !response.data )
                        $( '#aresponse' ).html( 'AJAX ERROR: no response' );
                    else
                        $( '#aresponse' ).html( response.data.error );
                }
                else
                    $( '#aresponse' ).html( response.data );
            }
        ); 
    });
});

The Ajax function checks the nonce, you make your thing and return Error or Success:

add_action( 'wp_ajax_sendform_smm', 'sendform_smm_callback' );
function sendform_smm_callback() {
    check_ajax_referer( 'nonce_smm', 'security' );

    # Form values sent by JS
    $received_data = $_POST['form_smm']; 
    # Read the data sent and send it back just for testing purposes.
    $text = 'Input Field: ' . $received_data['input1'];
    # Your form actions
    $do_your_thing = true;
    if( !$do_your_thing )
        wp_send_json_error( array( 'error' => __( 'Error message.' ) ) );
    else
        wp_send_json_success( $text );
} 
brasofilo
  • 25,496
  • 15
  • 91
  • 179