0

I know questions like this have been asked before, but none of them have helped me solve this problem. If it is something stupid I have overlooked then I apologize in advance. I have set up a contact form in a bootstrap modal. The html for the form is below:

<div class="modal-body">
    <form id="contactForm" action="contact.php" method="post">
        <div class='form-group'>
            <label class='sr-only' for="name" sr-only="Name">Name</label>
            <input id="name" type="text" name="name" class="form-control" placeholder="Name">
        </div>
        <div class='form-group'>
            <label class='sr-only' for="email" sr-only="Email address">Email</label>
            <input id="email" type="email" name="email" class="form-control" placeholder="Email address">
        </div>
        <div class='form-group'>
            <label class='sr-only' for="message" sr-only="Your Message"></label>
            <textarea id="message" type="text" name="message" rows='6' class="form-control" placeholder='Type your message here...'></textarea>
        </div>
        <br>
        <div class="form-group">
            <label class="control-label" for="human" sr-only="Prove you're human.  What is 3 + 2?">Prove you're human:  3 + 2 = ?</label>
            <input type="text" class="form-control" id="human" name="human" placeholder="Type the number here">
        </div>
        <br>
        <button id='contactFormSubmit' type='submit' name='submit' class='form-control btn btn-block btn-lg btn-info'>
            <i class='fa fa-send'></i>&nbsp;&nbsp;Send Message
        </button>
    </form>
</div>

Below is the ajax request. Note that there is some form validation; the ajax is about half way down the code:

$('form#contactForm').submit(function(e) {
    e.preventDefault();
    $('input.borderRed, textarea.borderRed').removeClass('borderRed');
    var name = $('#name');
    var email = $('#email');
    var message = $('#message');
    var human = $('#human');
    var vals = [name, email, message, human];
    var emptyVals = [];
    for(var i=0; i < vals.length; i++) {
        if (vals[i].val() == '') {
            vals[i].addClass('borderRed');
            emptyVals.push(vals[i]);
        }
    }
    if (emptyVals.length > 0) {
        $('#intro').append('<div class="alert alert-danger alert-dismissable fade show"><strong>Please fill in all fields to send a message.</strong><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
        return false;
    } else if(human.val() != 5) {
        $('#intro').append('<div class="alert alert-danger alert-dismissible fade show"> <strong>Try that math problem again!</strong><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
        human.addClass('borderRed');
        return false;
    } else {
        $.ajax({
            data: $(this).serialize(),
            type: "POST",
            url: "contact.php", 
            success:function(response) {
                if (response == 'success') {
                    $('#intro').append('<div class="alert alert-success alert-dismissible fade show"> <strong>Your message was sent successfully.</strong><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
                    $('.borderRed').removeClass('borderRed');
                } else {
                    $('#intro').append('<div class="alert alert-danger alert-dismissible fade show"> <strong>There was a problem with your submission.  Please try again.</strong><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
                }
            }
        });
    }
});

Finally, here is contact.php. Note that this is incomplete. At this point I am trying to confirm that I am getting $_POST data:

<?php
if( empty($_POST )) {
    echo "Post is empty.";
} elseif( !empty($_POST)) {
    echo "Post is not empty.";
}

print_r($_POST);

$to = '';
$subject = 'Contact Form Submission';
$header = "From: ".$name." <".$email.">";

$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
$message = filter_var($_POST['message'], FILTER_SANITIZE_STRING);
$message = wordwrap($message, 70);

$response = '';

if ($name && $email && $message) {
    $response = 'success';
    mail($to, $subject, $header, $message);
} else {
    $response = 'error';
}

echo $response;
?>

As the title of my question suggests, I am not getting the data. At contact.php I am getting the empty post message, and for print_r($_POST), I get Array (). The post data is not arriving, and I cannot figure out why.

EDIT: I should have mentioned that if I console.log($(this).serialize()); just before the ajax call, then I get the correct serialized data in the console window. So the data is there and ready to go just before the ajax call.

reveret
  • 3
  • 3
  • Have you checked `data` to make sure it contains what you expect? – Jay Blanchard Mar 11 '18 at 22:09
  • I haven't done PHP for donkey's years, but I thought if you're using Ajax to handle server request like POST. Why do you point the form itself to the same destination as Ajax calls? – Prav Mar 11 '18 at 22:14
  • add a ``console.log($(this).serialize());`` at the beginnin of the else and check the browser *console* (in the JS just before the ``$ajax`` call) – Ivan Buttinoni Mar 11 '18 at 22:21
  • 1
    @PraveenP that is fairly standard, especially when the AJAX is added later. – Jay Blanchard Mar 11 '18 at 22:24
  • How are you examining what you get back from `contact.php`? Your JavaScript doesn't report the output of it – Quentin Mar 11 '18 at 22:26
  • 1
    @PraveenP — https://en.wikipedia.org/wiki/Unobtrusive_JavaScript – Quentin Mar 11 '18 at 22:27
  • maybe this helps: https://stackoverflow.com/questions/42623577/cant-retrieve-jquery-serialized-form-data-with-php-post-variable –  Mar 11 '18 at 22:32
  • A check if $(this) refers to a form. Also check how the data are getting submitted poerhaps you may need to use teqniques mentioned in: https://stackoverflow.com/questions/8945879/how-to-get-body-of-a-post-in-php#8945912 – Dimitrios Desyllas Mar 11 '18 at 23:14
  • Also ensure that the http post is a form submit too. – Dimitrios Desyllas Mar 11 '18 at 23:14
  • I think the problem will be with this `$(this).serialize()` can you put `var self=this;` after `e.preventDefault();`, then replace `$(this).serialize()` with `$(self).serialize()` – Kerkouch Mar 11 '18 at 23:52
  • @Ivan Buttinoni -- I should have mentioned in my original post that this is one of the things I tried. I did exactly as you suggest and got the data exactly as I would expect in the console window. So prior to the ajax call, all the data is there ready to go. – reveret Mar 12 '18 at 01:20
  • @Quentin -- opening a browser window and pointing it at localhost/mysite/contact.php. That's where the "Post is empty" message is echoed and where I get the "Array ()" output from my print_r($_POST). – reveret Mar 12 '18 at 01:23
  • @Karkouch -- Thanks for the suggestion. I was wondering too if using $(this) might be the problem, but trying a variable in its place did not work. – reveret Mar 12 '18 at 01:32
  • I have tested this form and it works, except one problem `$('#intro').append(' – Kerkouch Mar 12 '18 at 07:03

1 Answers1

0

opening a browser window and pointing it at localhost/mysite/contact.php. That's where the "Post is empty" message is echoed and where I get the "Array ()" output from my print_r($_POST)

So this is what you are doing:

  1. Making a GET request to an HTML document by opening it in the browser window
  2. Letting JavaScript in the HTML document make a POST request to contact.php
  3. Not examining the response to that POST request
  4. Making a GET request to contact.php by opening it in the browser window
  5. Looking at the response to that GET request

Making a GET request to a URL you previously made a POST request to does not show you the response you got to that POST request.

You have two different requests and two different responses.

If you want to see the response to the request you triggered using Ajax then you have to look at that response. You can do this by examining the response variable in your success function or by looking at the Network tab of your browser's developer tools.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • This was helpful. Following your suggestion (the Network tab), I can now see that the ajax call was successful all along. I was just trying to "see" that success in the wrong way. Thanks for your help. – reveret Mar 12 '18 at 17:11