Home > Software engineering >  How to get an error about an unsent message
How to get an error about an unsent message

Time:01-08

I have a form that submits using AJAX and wp_mail(). I insert the form on the page using a shortcode. Now the problem is that even if the message is not sent, it still shows a message about successful sending. I wanted to bind to the response, but there I receive data in the form: Response data in console

How do I process my response so that the form about successful submission is not shown if there is an error during validation?

add_shortcode('contact-form', 'display_contact_form');

function display_contact_form()
{

    $validation_messages = [];

    if (isset($_POST['contact_form'])) {

        //Sanitize the data
        $full_name = isset($_POST['full_name']) ? sanitize_text_field($_POST['full_name']) : '';
        $email     = isset($_POST['email']) ? sanitize_text_field($_POST['email']) : '';
        $message   = isset($_POST['message']) ? sanitize_textarea_field($_POST['message']) : '';

        //Validate the data
        if (strlen($full_name) === 0) {
            $validation_messages[] = esc_html__('Please enter a valid name.');
        }

        if (
            strlen($email) === 0 or
            !is_email($email)
        ) {
            $validation_messages[] = esc_html__('Please enter a valid email address.');
        }

        if (strlen($message) === 0) {
            $validation_messages[] = esc_html__('Please enter a valid message.');
        }

        //Send an email to the WordPress administrator if there are no validation errors
        if (empty($validation_messages)) {

            $mail    = get_option('admin_email');
            $subject = 'New message from ' . $full_name;
            $message = $message . ' - The email address of the customer is: ' . $mail;

            wp_mail($mail, $subject, $message);
        }
    }

    //Display the validation errors
    if (!empty($validation_messages)) {
        foreach ($validation_messages as $validation_message) {
            echo '<div >' . esc_html($validation_message) . '</div>';
        }
    }
?>

    <!-- Echo a container used that will be used for the JavaScript validation -->
    <div id="validation-messages-container"></div>

    <form id="contact-form" action="<?php echo esc_url(get_permalink()); ?>" method="post">
        <input type="hidden" name="contact_form">
        <div >
            <input type="text" id="full-name" name="full_name" placeholder="Name">
        </div>
        <div >
            <input type="text" id="email" name="email" placeholder="Email">
        </div>
        <div >
            <textarea id="message" name="message" placeholder="Write something..."></textarea>
        </div>
        <button type="submit" id="contact-form-submit">
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path fill-rule="evenodd" clip-rule="evenodd" d="M1.81818 4.85279L9.39603 11.5887C9.74047 11.8948 10.2595 11.8948 10.604 11.5887L18.1818 4.85279V15.4547C18.1818 15.9567 17.7748 16.3637 17.2727 16.3637H2.72727C2.22519 16.3637 1.81818 15.9567 1.81818 15.4547V4.85279ZM3.1865 3.63647H16.8134L9.99995 9.69288L3.1865 3.63647Z" fill="white" />
            </svg>
            Submit Message
        </button>
    </form>

    <div id="success-messages-container"></div>
<?php

}

add_action('wp_ajax_display_contact_form', 'display_contact_form');
add_action('wp_ajax_nopriv_display_contact_form', 'display_contact_form');

$("#submit").click(function (event) {
    event.preventDefault();
    var userName = $("#full-name").val();
    var userEmail = $("#email").val();
    var userMessage = $("#message").val();
    var formData = $("#contact-form").val();
    $.ajax({
      type: "POST",
      dataType: "html",
      url: "/wp-admin/admin-ajax.php",
      data: {
        action: "display_contact_form",
        contact_form: formData,
        full_name: userName,
        email: userEmail,
        message: userMessage,
      },
      success: function (response) {
        console.log(response);
        $("#success-messages-container").append(
          "<p>Your message has been successfully delivered</p>"
        );
      },
    });
  });

CodePudding user response:

You can try these changes. I added some comments in php code.

Your php code:

add_shortcode('contact-form', 'display_contact_form');

function display_contact_form()
{

    $validation_messages = [];

    if (isset($_POST['contact_form'])) {

        //Sanitize the data
        $full_name = isset($_POST['full_name']) ? sanitize_text_field($_POST['full_name']) : '';
        $email     = isset($_POST['email']) ? sanitize_text_field($_POST['email']) : '';
        $message   = isset($_POST['message']) ? sanitize_textarea_field($_POST['message']) : '';

        // object with response data
        $response = (object) [
            'success' => false,
            'error' => ''
        ];

        //Validate the data
        if (strlen($full_name) === 0) {
            $validation_messages[] = esc_html__('Please enter a valid name.');
        }

        if (
            strlen($email) === 0 or
            !is_email($email)
        ) {
            $validation_messages[] = esc_html__('Please enter a valid email address.');
        }

        if (strlen($message) === 0) {
            $validation_messages[] = esc_html__('Please enter a valid message.');
        }

        //Send an email to the WordPress administrator if there are no validation errors
        if (empty($validation_messages)) {
            $mail    = get_option('admin_email');
            $subject = 'New message from ' . $full_name;
            $message = $message . ' - The email address of the customer is: ' . $mail;

            // if wp_mail returns true, then success
            if (wp_mail($mail, $subject, $message))
                $response->success = true;
            else
                $response->error = 'There was an error while sending email';
        } else {
            //Display the validation errors

            foreach ($validation_messages as $validation_message) {
                $response->error .= '<div >' . esc_html($validation_message) . '</div>';
            }
        }

        header('Content-Type: application/json; charset=utf-8');

        echo json_encode($response);

        exit;
    }
?>

    <!-- Echo a container used that will be used for the JavaScript validation -->
    <div id="validation-messages-container"></div>

    <form id="contact-form" action="<?php echo esc_url(get_permalink()); ?>" method="post">
        <input type="hidden" name="contact_form">
        <div >
            <input type="text" id="full-name" name="full_name" placeholder="Name">
        </div>
        <div >
            <input type="text" id="email" name="email" placeholder="Email">
        </div>
        <div >
            <textarea id="message" name="message" placeholder="Write something..."></textarea>
        </div>
        <button type="submit" id="contact-form-submit">
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path fill-rule="evenodd" clip-rule="evenodd" d="M1.81818 4.85279L9.39603 11.5887C9.74047 11.8948 10.2595 11.8948 10.604 11.5887L18.1818 4.85279V15.4547C18.1818 15.9567 17.7748 16.3637 17.2727 16.3637H2.72727C2.22519 16.3637 1.81818 15.9567 1.81818 15.4547V4.85279ZM3.1865 3.63647H16.8134L9.99995 9.69288L3.1865 3.63647Z" fill="white" />
            </svg>
            Submit Message
        </button>
    </form>

    <div id="success-messages-container"></div>
<?php

}

add_action('wp_ajax_display_contact_form', 'display_contact_form');
add_action('wp_ajax_nopriv_display_contact_form', 'display_contact_form');

And your js:

$("#submit").click(function (event) {
    event.preventDefault();
    var userName = $("#full-name").val();
    var userEmail = $("#email").val();
    var userMessage = $("#message").val();
    var formData = $("#contact-form").val();
    $.ajax({
      type: "POST",
      dataType: "html",
      url: "/wp-admin/admin-ajax.php",
      data: {
        action: "display_contact_form",
        contact_form: formData,
        full_name: userName,
        email: userEmail,
        message: userMessage,
      },
      success: function (response) {
          // maybe this line will be necessary
          //response = JSON.parse(response);

        if (response.success) {
            $("#success-messages-container").html(
              "<p>Your message has been successfully delivered</p>"
            );
        } else
            $("#validation-messages-container").html(response.error)
      },
    });
});
  • Related