0
votes

I'm trying to create a contact form in Wordpress using wp_mail and Ajax

The email works but I'm having problems with the Ajax success response.

After the email is sent I need to show the user a message that the email was sent.

The Javascript to validate the form and show the success message:

    $atj(function(){
      $atj('#training-submit').click(function(e) {
        e.preventDefault();
        e.stopPropagation();
        if(verfiyFields()) {
            alert('here');
            requestData = {
              'action' : 'myajax-submit',
              'firstName' : $atj("#name").val(), 
              'email' : $atj("#email").val(), 
          }
          $atj.post(MyAjax.ajaxurl, requestData).done(function(result){        
            result = jQuery.parseJSON( result );
            console.log(result);
            if(result == 'success'){
              $atj('.training-form [type=text]').val('');
              $atj('.training-form-message').append('<p class="training-form-complete-message">Thank you for the  email</p>');
            }
          });
        }
      });
    })



    //Verfiy 
    function verfiyTrainingFields() {
      var flag = true;

      var name =        $atj('#name');
      var email =       $atj('#email');

      if(name.val().indexOf(' ') === -1 ){
        name.parent().prepend('<p class="form-error">Please enter name, first space last</p>');
        errorMessage($atj('.form-error'));
        flag = false;
      }
      if(!IsEmail(email.val())){
        email.parent().prepend('<p class="form-error">Please enter valid email address</p>');
        errorMessage($atj('.form-error'));
        flag = false;
      }
      return flag;
    }

The functions.php file to send the email and send the ajax response.

    function myajax_submit() {

        $name = sanitize_text_field($_POST['firstName']);
        $email = sanitize_text_field($_POST['email']);

        $headers[] = 'From: ' . $name . ' <' . $email . '>' . "\r\n";
        $headers[] = 'Content-type: text/html' . "\r\n"; //Enables HTML ContentType. Remove it for Plain Text Messages

        $to = '[email protected]';

        $message = 'Name: ' . $name . "\r\n" . 'email: ' . $email;

        add_filter( 'wp_mail_content_type', 'set_html_content_type' );
        wp_mail( $to, 'Email Test', $message );
        remove_filter( 'wp_mail_content_type', 'set_html_content_type' ); 

        echo 'email sent';

        // generate the response
        $response = json_encode( array( 'success') );

        // response output
        header( "Content-Type: application/json" );
        echo $response;

        exit;
    }

The email is sent and the 'email sent' echo fires but the if(result == 'success'){ in the js doesn't work.

The console.log(result) in the js file gives the following.

<br />
<b>Warning</b>:  call_user_func_array() expects parameter 1 to be a valid callback, function 'set_html_content_type' not found or invalid function name in <b>/Users/user.name/Desktop/MAMP-DocRoot/appname/src/php/wp-includes/plugin.php</b> on line <b>192</b><br />
email sent<br />
<b>Warning</b>:  Cannot modify header information - headers already sent by (output started at /Users/user.name/Desktop/MAMP-DocRoot/appname/src/php/wp-includes/plugin.php:192) in <b>/Users/user.name/Desktop/MAMP-DocRoot/appname/src/php/wp-content/themes/sitename/functions.php</b> on line <b>66</b><br />
["success"] 
2
Move this — header( "Content-Type: application/json" ); to the top of your PHP file. You're getting an error because you're trying to send HTTP headers after you've already started outputting the body of your AJAX response (echo 'email sent';). - r3mainer

2 Answers

0
votes

You can't set headers after echo'in a response. Remove the echo 'email sent';

0
votes

First, remove the echo statement as it's sending headers prematurely.

Then, you need to explicitly tell jQuery post to expect json back:

$atj.post(MyAjax.ajaxurl, requestData).done(function(result){
    result = jQuery.parseJSON( result );
    console.log(result);
    if(result == 'success'){
        $atj('.training-form [type=text]').val('');
        $atj('.training-form-message').append('<p class="training-form-complete-message">Thank you for the  email</p>');
    }
}, 'json' );

Finally, your json encoded response will not give you your expected response == success. Instead, use json_encode( array( 'success' => 1' ) ); and change your javascript to:

if( 1 == result.success ) ){
}

Here's a complete example:

$.post( url, data, function( response ){
    if( 1 == response.success ){
      // Success - do something
    } else {
      // Failure
    }
}, 'json' );

<?php
function myAjaxFunction(){
    $result = array(
        'success' => 0 // Assume failure first
    );
    if( $_POST[ 'whatever' ] == 'what i want' ){
        $result[ 'success' ] = 1;
    }
    print json_encode( $result );
    exit();
}