Michael Benjamin
Michael Benjamin

Reputation: 371331

AJAX form submission, solely to prevent page refresh and nothing else

I've built a simple HTML/PHP e-mail sign-up form to appear in the footer area of my website. There are only two fields: email and country.

The form works perfectly for my purposes. Data collection, validation, sanitization, error handling, clear fields, success notification, etc. -- ALL GOOD!

My final step is to implement AJAX to prevent a page refresh. This is all that is required from AJAX.

All tutorials, articles, and answers to related questions on this site I have found offer code that includes functions I've already handled with PHP.

I've gotten as far as the AJAX submission, which works. The page doesn't refresh, user input is inserted to the database, and I receive the confirmation e-mail.

I would appreciate some guidance (or a link to a tutorial) that can help me implement the PHP error logic and echo PHP success/error messages.

HTML

<form action="process_footer_form/" method="post" id="footer-form">

<ul>

<li>
<input type="email" name="email" id="email"
value="<?php if (isset($email)) {echo $email;} ?>">
</li>

<li>
<input type="text" name="country" id="country"
value="<?php if (isset($country)) {echo $country;} ?>">
</li>

<li>
<input type="submit" name="submit" id="submit">
</li>

</ul>

<?php if (isset($success_message)) {echo $success_message;} ?>
<?php if (isset($error_message)) {echo $error_message;} ?>

</form>

JQuery

$(function() {

    // identify form
    var form = $('#footer-form');

    // create event listener
    $(form).submit(function(event) {

        // disable html submit button
        event.preventDefault();

        // serialize form data
        var formData = $(form).serialize();

        // submit form using AJAX
        $.ajax({
            type: 'POST',
            url: $(form).attr('action'),
            data: formData
        })

        .done(function(response) {

            // 1. echo PHP success message
            // 2. fire PHP clear fields command

        })

        .fail(function(data) {

            // 3. execute PHP error logic here
            // 4. echo PHP error messages

        });  
    });
});

PHP

<?php

if ($_SERVER["REQUEST_METHOD"] == "POST") {

// Load PHPMailer
require 'PHPMailer/PHPMailerAutoload.php';

// Create PHPMailer session
$mail = new PHPMailer;
$mail->CharSet = "UTF-8";

// SMTP settings
$mail->isSMTP();                                      
$mail->Host = 'smtp.xxxxxxxxxx.com';
$mail->SMTPAuth = true;
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
$mail->Username = 'xxxxxxxxxxxxxxxxxx'; 
$mail->Password = 'xxxxxxxxxxxxxxxxxx';

$mail->setFrom('xxxxxxxxxxxxxxxxxx' , 'xxxxxxxxxxxxxxxxxx');
$mail->addAddress('xxxxxxxxxxxxxxxxxx');
$mail->isHTML(true);  

// Sanitize & Validate Input
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$country = trim(filter_input(INPUT_POST, 'country', FILTER_SANITIZE_SPECIAL_CHARS));

// set connection to mysql server
$connection = mysql_connect("localhost","xxxxxxxxxxxxxxxxxx","xxxxxxxxxxxxxxxxxx");

// connect to database
mysql_select_db("xxxxxxxxxxxxxxxxxx", $connection);

// insert user input to table
$sql = "INSERT INTO email_subscribers (email,country) VALUES ('$email','$country')";

if (!$connection) {

$error_message = <<<ERROR
<div>ERROR. Form not sent. Please try again or <a href="contact/">contact us</a>.</div>
ERROR;

// Send error notice to host
$mail->Subject = 'Website Error - Footer Form';
$mail->Body = ("Error Notice: A site user is having trouble on the footer form.");
$mail->send();

    } else {

    // run query
    mysql_query($sql, $connection);

$success_message = <<<CONFIRMATION
<div>Subscription complete. Thank you!</div>
CONFIRMATION;

    mysql_close($connection);

    // Send confirmation notice to host.
    $message = <<<HTML
    <span>E-mail: {$email}</span><br>
    <span>Country: {$country}</span>
HTML;

$mail->Subject = 'New E-mail Subscriber - Footer Form';
$mail->Body = $message;
$mail->send();

unset($email, $country);
}
} else {

header('Location: http://www.mywebsite.com/');
exit;

}
?>

Upvotes: 0

Views: 2000

Answers (3)

HeadCode
HeadCode

Reputation: 2828

You might try simplifying your life by using the FormData object. Then your code could look something like this. I have tested this out.

<form method="POST" id="subscription-form" enctype="multipart/form-data">
<input type="email" name="email" id="email" value="[email protected]">
<input type="text" name="country" id="country" value="Lilliput">
<input type="button" value="submit" id="form-submit">
</form>

Below this you could put in a div for displaying messages:

<div id="messages"></div>

Then your jquery/javascript would look something like this:

<script>
(function(){
    $("#form-submit").on("click", function(){ submitForm();});
})();


function submitForm(){
var form = document.getElementById("subscription-form");
var fd = new FormData(form);
    $.ajax({
        url: './PHPscript.php',
        data: fd,
        processData: false,
        contentType: false,
        type: 'POST',
        success: function(data){
            $("#messages").html(data);
       }
     });
   }
</script>

Regarding letting PHP "handle the messages" I think you're missing something about AJAX.

In your initial PHP page you are loading the html that PHP has generated and then PHPs part is finished. When you make the AJAX call you are asking the server to execute a different PHP script and then return the output of that script back to javascript.

At that point you need to put whatever message PHP has generated back into the current page, which has not and will not reload. That was the purpose of using AJAX in the first place. That is what the "messages" div is for.

As a way of completely understanding this create an extremely simple PHPscript.php file that looks like this and try it out:

<?php
print $_POST['email'] . ' ' . $_POST['country'];
?>

You will see your values returned in the current page inside that messages div.

Upvotes: 1

Cyrbil
Cyrbil

Reputation: 6478

Okay, first thing, var that = this is a trick when you loses context, but where you use it is not somewhere you can lose it .. so forget it :)

Then your find().each(), it's a good way of getting your values, but jquery offers a method which is $( this ).serializeArray() (it does kinda exactly what your want)

Also, you send your data with ajax, but you have no callback. Your ajax call need to have at least a function to call once everything went fine. This is done with done()

Finally, returning false does cancel the event in most cases but you will prefer preventDefault() as it disable default behavior, but still propagate event (for other handlers).

Sum it all:

$('form.ajax').submit( function(event) {
    var form = $(this);
    $.ajax({
        url: form.attr('action'),
        type: form.attr('method'),
        data: form.serializeArray()
    }).done(function(data) {
        alert("Ajax call successful");
        console.log("Server answer:" + data);
    });
    event.preventDefault();
});

Edit: Nvm my first remark, I understood lately your that = this stuff.

Upvotes: 0

Alex McMillan
Alex McMillan

Reputation: 17952

The first request to, for example www.mysite.com/something.php will run the PHP and dump the result into the page. Ajax doesn't work this way. You send a request to your PHP file, and it sends a response that you can then inspect and do something with.

If ajax responses dumped their content into the page like an initial load, mayhem would ensue.

Try something like this:

        $.ajax({
            url: url,
            type: type,
            data: data
        }).done(function (response) {
            console.log(response);
        }); 

then have a looksie in the console and see what goodness you're getting from the PHP script. Then build that .done callback up to process the results of your request and determine what to do.

Upvotes: 0

Related Questions