Ajax Form Validation in PHP – PHP – SitePoint Forums

I am trying to create ajax with php authentication, let’s explain with screenshots. While validating the form I get all errors at the same place…

What I want to get is separate validation for fields like

After submitting the form, I want to display a success message at the top of the form, but I get the success message on all fields

html form data (index.php)

<form id="first_form" method="POST" action="form.php">
    <p class="form-message"></p>
    <div class="mb-3">
        <input type="text" class="form-control" id="name" name="name" placeholder="Name:">
        <p class="form-message"></p>
    </div>
    <div class="mb-3">
        <input type="tex" class="form-control" id="email" name="email" placeholder="Email:">
        <p class="form-message"></p>
    </div>
    <div class="mb-3">
        <input type="text" class="form-control" id="phone" name="phone" placeholder="Phone:">
    </div>
    <div class="mb-3">
        <input type="text" class="form-control" id="address" name="address" placeholder="Address:">
    </div>
    <div class="mb-3">
        <input type="text" class="form-control" id="subject" name="subject" placeholder="Subject:">
    </div>
    <div class="mb-3">
        <input type="text" class="form-control" id="services" name="services" placeholder="Services:">
    </div>
    <div class="mb-3">
        <textarea class="form-control" rows="5" id="message" name="message" placeholder="Leave Your Message..."></textarea>
    </div>
    <button type="submit" name="submit" id="submit" class="btn btn-primary">Submit</button>
</form>

js code:

  $(document).ready(function() {
    $("#first_form").submit(function(event) {
        event.preventDefault();
        
            name     = $("#name").val();
            email    = $("#email").val();
            phone    = $("#phone").val();
            address  = $("#address").val();
            subject  = $("#subject").val();
            services = $("#services").val();
            message  = $("#message").val();
            submit   = $("#submit").val();

            $(".form-message").load("form.php", {
                name: name,
                email: email,
                phone: phone,
                address: address,
                subject: subject,
                services: services,
                message: message,
                submit: 'submitted'
            });

    });
});

form.php data

if (isset($_POST['submit'])){
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $subject = "Contact Form";
    $mailTo = "[email protected]";
    $headers = "From: ".$email;
    $txt = "You have received a message from ".$name.
        ".nn".$message;
    
    $errorEmptyname = false;
    $errorEmptyemail = false;
    $errorEmptymessage = false;
    $errorEmail = false;
    
    if (empty($name)) {
        echo "<span class="form-error">Name Field cannot be empty</span> ";
        //$errorEmptyName = true;
    }  
    
    if (empty($email)) {
        echo "<span class="form-error">Email Field cannot be empty</span>";
        //$errorEmptyemail = true;
    }    
    
    if (empty($message)) {
        //$errorEmptymessage = true;
    }
    elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        echo "<span class="form-error">
        Write a valid e-mail addres </span>";
        $errorEmail = true;
    }
    else {
        echo "<span class="form-success">
        Thank you for your message!<br>
        I'll get back to you as soon as I can.</span>";
        
        mail($mailTo, $subject, $body, $headers);
    }
}
else{
    echo "There was an error!";
}

All I understand is that I’m not getting a single validation error in a single field bcz the class is the same, how do I attach the error to the related field

I haven’t validated using js yet bcz I want to do some validation for spammers to prevent spam, as we know when viewing source code we can easily see validation code too, so validate in php

In order to allow you to display success messages or individual error messages, you must create elements with unique IDs. The server-side code must then output (json) data that has these IDs as keys and the desired content as values.

Some points about the existing code –

  1. Don’t write code for every field. Operate on data as a collection. You can use jquery .serialize() method to get all form data at once.
  2. You need to use the jquery $.ajax method so you have more control over what it does.
  3. Don’t copy variables to variables for no reason. It’s just a waste of typing.
  4. Save the form data as a collection in a php array variable and then operate on the elements in that array variable throughout the rest of the code.
  5. Don’t create variables for every possible error. Instead, use an array to handle user/authentication errors.
  6. These emails were not sent from the email address entered in the form. They are sent from the mail server on your web hosting. The From: header must be an email address corresponding to your outgoing mail server. You can put the email address you entered into the Reply-to: message header, after verifying that it’s just a properly formatted email address.
  7. Any dynamic values ​​used in the message body should have htmlentities() applied to help prevent manipulating any html, css, javascript in the value when reading the message with a browser.

See the following examples −

<p class="response" id="success_message"></p>

<form id="first_form" method="POST" action="form.php">
    <div class="mb-3">
        <input type="text" class="form-control" id="name" name="name" placeholder="Name:">
        <p class="response" id="name_error"></p>
    </div>
    <div class="mb-3">
        <input type="text" class="form-control" id="email" name="email" placeholder="Email:">
        <p class="response" id="email_error"></p>
    </div>
    <div class="mb-3">
        <textarea class="form-control" rows="5" id="message" name="message" placeholder="Leave Your Message..."></textarea>
        <p class="response" id="message_error"></p>
    </div>
    <button type="submit" name="submit" id="submit" class="btn btn-primary">Submit</button>
</form>
<script>
  $(document).ready(function() {
    $("#first_form").submit(function(event) {
        event.preventDefault();
        
		$.ajax({
			type: "POST",
			url: "form.php",
			dataType: 'json',
			data: $(this).closest("form").serialize(),
			success: function(response){
				// clear any existing class="response" html
				$(".response").empty();
				// loop over the keys/values in the response
				$.each(response, function(key, value){
					// set the html of the id corresponding to the key to the value
					$('#'+key).html(value);
				});
			}
		});
    });
});
</script>
<?php

// initialization

$subject = "Contact Form";
$mailTo = "[email protected]";
// the From: mail header must be an address that corresponds to your sending mail server
$mailFrom = "[email protected]";

$post = []; // array to hold a trimmed working copy of the form data
$errors = []; // array to hold user/validation errors

// post method form processing
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
	// inputs - name, email, message
	
	// trim all the data at once
	$post = array_map('trim',$_POST); // if any input is an array, use a recursive trim call-back function here instead of php's trim
	
	// validate inputs
	if($post['name'] === '')
	{
		$errors['name'] = "Name is required.";
	}

	if($post['email'] === '')
	{
		$errors['email'] = "Email is required.";
	}
	else if(!filter_var($post['email'], FILTER_VALIDATE_EMAIL))
	{
		$errors['email'] = "Email format is not valid.";
	}
	
	if($post['message'] === '')
	{
		$errors['message'] = "Message is required.";
	}	
	
	// if no errors, use the form data
	if(empty($errors))
	{
		// use the form data in $post here...
		
	    $headers = "From: ".$mailFrom;
		
		// you would use a call-back function with array_map() to apply htmlentities() to all the elements in $post, rather than writing out a line of code for each element
		$post['name'] = htmlentities($post['name'],ENT_QUOTES);
		$post['message'] = htmlentities($post['message'],ENT_QUOTES);
		
		$body = "You have received a message from {$post['name']}nn{$post['message']}";

		// you must test the returned value from the mail() call
		// if it is a false value, setup a message in the $errors array
		mail($mailTo, $subject, $body, $headers);
	}
	
	$response = [];
	if(empty($errors))
	{
		$response['success_message'] = "Thank you for your message!<br>I'll get back to you as soon as I can.";
	}
	else
	{
		foreach($errors as $key=>$value)
		{
			$response[$key.'_error'] = $value;
		}
	}
	echo json_encode($response);
}

Thanks a lot sir, this is what I’ve been trying to do now, I can get individual errors but the success message doesn’t show up on the form submission…

What did you do to debug? How can I check the browser’s developer tools network response tab to see what the server is outputting?

Leave a Reply

Your email address will not be published. Required fields are marked *