The simplest AJAX/AJAJ/XHR/JHR between PHP contact form submission and submit acction

I have created a simple backend-frontend (HTML-JavaScript-CSS-PHP) contact form to transfer contact form inquiries to my local email client (i.e. local in the sense that it sits on the same web hosting provider environment of my website shared hosting environment).

The PHP pattern is:

<?php
	$contact_form_url="example.com/contact";

	$to = "example@example.com";
	$subject = "New email message";
	$message = "Message";

	mail($to, $subject, $message);

	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
 		header("Location: $contact_form_url");
		exit;
	}
?>

As can be understood from the code; after the form is submitted the user is supposed to stay on the same webpage (some kind of a “refresh webpage” action on the contact form’s URL).

What I desire to have is the user getting some AJAX/AJAJ/XHR/JHR alert() or popup/modal message like “Thanks! I should most likely get back to you as soon as possible!” between the form submission and the refreshing of the page.

How would you achieve that in vanilla JavaScript?

When the title of your post is as long as your code… :stuck_out_tongue_winking_eye:

The long and short of it is:
Add an event listener to the Submit event;
Have that Submit event stop the form’s default action.
Use AJAX to submit the form.
Throw an alert when the AJAX returns.
If desired, have Javascript reload the contact form page after the alert.

At no point does the browser ‘go to’ your PHP page, so the user doesnt see any change in their web experience.

2 Likes

With the following code, I can get an email in my inbox and in my browser I stay with the same webpage (i.e. there is no longer the redirection to the PHP blank file)

let contactForm = document.querySelector("#contact_form")
contactForm.addEventListener("submit", function(event){
	event.preventDefault()
	var xhr = new XMLHttpRequest();
	xhr.open(contactForm.method, contactForm.action, true);
	xhr.setRequestHeader('Accept', 'application/json; charset=utf-8');
	xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
	xhr.send();
});

But, the HTML structure sent to my inbox is empty — it doesn’t contain any of the data I filled in the form, so I get something like:

Name:
Email:

Instead

Name: SOME_NAME
Email: SOME_EMAIL

Any suggestion how to handle with that problem?

well you told it where to go, you told it what verb to use to communicate to the server, you told it what headers to give.

What you didnt do was give it any sort of payload to carry.
You made a very pretty box and put it in the mailbox, but you didnt put anything inside the box.

I think you meant that I don’t have anything to substitute the PHP $message string I currently send.

Well, the PHP $message string I currently send is an heredocument with this pattern:

$message = <<<LABEL
<html>
    <head>
        <style>
        * {
            font-size: 20px;
        }
        .form_output_col_1 {
            font-weight: bold;
        }
        .form_output_col_1:not(#form_output_topic):after {
            content:": "
        }
        </style>
    </head>
    <body dir="rtl" style="text-align: right;">
        <div><span class="form_output_col_1">שם</span><span class="form_output_col_2">$name</span></div>
        <div><span class="form_output_col_1">אימייל</span><span dir="ltr" class="form_output_col_2">$email</span></div>
        <div><span class="form_output_col_1">טלפון</span><span dir="ltr" class="form_output_col_2">$phone</span></div>
    </body>
</html>
LABEL;

As far as I know there is no heredocument syntax in JavaScript but perhaps something like the following pseudocode inside xhr.SOME_METHOD(message_variable) can be a substitute?

const message_variable = `
<html>
    <head>
        <style>
        * {
            font-size: 20px;
        }
        .form_output_col_1 {
            font-weight: bold;
        }
        .form_output_col_1:not(#form_output_topic):after {
            content:": "
        }
        </style>
    </head>
    <body dir="rtl" style="text-align: right;">
        <div><span class="form_output_col_1">שם</span><span class="form_output_col_2">$name</span></div>
        <div><span class="form_output_col_1">אימייל</span><span dir="ltr" class="form_output_col_2">$email</span></div>
        <div><span class="form_output_col_1">טלפון</span><span dir="ltr" class="form_output_col_2">$phone</span></div>
    </body>
</html>
`;

What i’m saying is your javascript is not sending the form data to the PHP page.

There should be either something in the .send() parameters or another line between those two. I’m spitballing here, as I have to head out in a minute, but inline it’d be something along the lines of

xhr.send(JSON.stringify(Object.fromEntries(new FormData(contactForm))));