2

I am using an AJAX script to submit a basic contact form at the bottom of my HTML that uses Google reCAPTCHA. The html code is:

<div class="col-md-6">
  <form role="form" id="form" action="form.php" method="post">
    <div class="form-group">
      <label for="name">Your Name</label>
      <input type="text" class="form-control" id="name" name="name" placeholder="Enter name">

      <span class="help-block" style="display: none;">Please enter your name.</span>

      <label for="exampleInputEmail1">Email address</label>
      <input type="email" class="form-control" id="email" name="email" placeholder="Enter email">
      <span class="help-block" style="display: none;">Please enter a valid e-mail address.</span>

      <label for="exampleInputText1">Message</label>
      <textarea class="form-control" rows="3" id="message" name="message" placeholder="Enter message"></textarea>

      <span class="help-block" style="display: none;">Please enter a message.</span>
    </div>
    <div class="form-group">
      <div class="g-recaptcha" data-sitekey="I HAVE REMOVED MY SITE KEY"></div>
      <span class="help-block" style="display: none;">Please check that you are not a robot.</span>
    </div>
    <button type="submit" id="Submit" data-loading-text="Sending..." class="btn btn-default">Submit</button>
  </form>

</div>
<!-- Placed at the end of the document so the pages load faster -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.2/modernizr.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript" src="slick/slick.min.js"></script>
<script src="assets/js/smoothscroll.js"></script>
<script src="assets/js/jquery.stellar.min.js"></script>
<script src="assets/js/fancybox/jquery.fancybox.js"></script>
<script src="assets/js/main.js"></script>
<script src="alert/sweetalert2.min.js"></script>
<script src='https://www.google.com/recaptcha/api.js'></script>

I have created a very basic php to email me the data entered into the form.

<?php

 //include CSS Style Sheet
   echo "<link rel='stylesheet' type='text/css' href='alert/sweetalert2.css' />";

   //include a javascript file
   echo "<script type='text/javascript' src='alert/sweetalert2.min.js'></script>";

   // Define some constants
define( "RECIPIENT_NAME", "Paul O'Shea" );
define( "RECIPIENT_EMAIL", "I HAVE REMOVED MY EMAIL" );
define( "EMAIL_SUBJECT", "Website Enquiry" );
   
    $full_name;$email;$subject;$message;$captcha;
        if(isset($_POST['name'])){
            $name=$_POST['name'];
        }if(isset($_POST['email'])){
            $email=$_POST['email'];
        }if(isset($_POST['message'])){
            $message=$_POST['message'];
        }if(isset($_POST['g-recaptcha-response'])){
            $captcha=$_POST['g-recaptcha-response'];
        }
        if(!$captcha){
         echo '<script type="text/javascript">';
  echo 'setTimeout(function () { swal("ERROR!","In order to avoid SPAM mail, you must confirm you are human. Please select IM NOT A ROBOT and complete the simple challenge","error");';
  echo '}, 1000); </script>';
            exit;
   
        }
        $response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?I HAVE REMOVED MY SECRET KEYresponse=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
        if($response.success==false)
        {
            echo "<script type=\"text/javascript\">alert('Message Failed. Please try again'); location.href='index.html#contact';</script>";
        }else
        {
           // If all values exist, send the email
if ( $name && $email && $message ) {
  $recipient = RECIPIENT_NAME . " <" . RECIPIENT_EMAIL . ">";
  $headers = "From: " . $name . " <" . $email . ">";
  $success = mail( $recipient, EMAIL_SUBJECT, $message, $headers );
}

        echo "<script type=\"text/javascript\">alert('Thanks for your enquiry! Your message has been sent to Paul and he will be in touch within 48hrs'); location.href='index.html#contact';</script>"; 
        }
  
  
?>

The PHP has 3 alerts within it:

  1. reCAPTCHA has not been run.

  2. If reCAPTCHA fails.

  3. Success message.

These PHP alerts work if i bypass the AJAX script, (however open a blank form.php) but don't work at all when I use the AJAX script. Therefore I get a success alert from the AJAX script - even if the reCAPTCHA has not been completed - and the form data has not been emailed.

This is my AJAX script:

<script type="text/javascript">
    var frm = $('#form');
    frm.submit(function (ev) {
        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                swal(
            'Thanks for your enquiry!',
            'Your message has been sent. Paul will be in contact soon.',
            'success'
        );
            }
        });

        ev.preventDefault();
  
    });
</script>

This gives the desired result, the email is sent, and the nice alert is shown over the original page, and when closed returns to original page. However, none of the alerts referenced in form.PHP are displayed. If user forgets to run reCaptcha - the same success alert is shown - even though there message will not be emailed.

Can anyone help me add the PHP alerts to the AJAX javascript? I tried copy and paste the same code - but am a little unsure of the appropriate way to format the code. Any help greatly appreciated! Thanks!

Paul O'Shea
  • 69
  • 10
  • First of all, you don't invoke SweetAlert by using alert(). You should either use sweetAlert or swal. Check the documentation [SweetAlert](http://t4t5.github.io/sweetalert/) – Manu Aug 12 '15 at 04:56
  • Alert shows up in a blank page because form.php is actually a blank page. You submit your form, then you are redirected to post.php (which is blank - does not have any actual HTML representation), which outputs an alert, and then possibly redirects back to index.html. – Manu Aug 12 '15 at 05:00
  • Thanks Manos. I have edited the above form.php. I've added the sweetalert css and js to the php file. I found on another post how to use sweetalert with echo - so have duplicated that code in the form.php. This does work. However, as you mentioned - the sweetalert is displaying ontop of the blank php file. So, my question is - what is the best way to process the form.php WITHOUT leaving the original html so the alerts show up on top of original page - and when closed return you to exactly where you were. Javascript or can i embed the form.php inside my index.html? – Paul O'Shea Aug 12 '15 at 07:29

1 Answers1

0

I would remove the <script> responses from your php script and instead use plain text, then I'd go with an AJAX approach of form submission.

There are plenty of examples using this (recommended in my opinion) approach, check the following two:

Using just jQuery: jQuery Ajax POST example with PHP

jQuery AJAX submit form

Another approach is to create one file with both your HTML and php in it, and don't redirect your form post to another page but to itself. However, this would invoke a page refresh.

Check the following example:

Refresh page after form submitting - Check 1st Answer

Keywords for further searching: post form, ajax, php, jquery, jquery form plugin malsup

EDIT 1 - Code

HTML/JS:

    <div class="col-md-6">
      <form role="form" id="form" action="form.php" method="post">
        <div class="form-group">
          <label for="name">Your Name</label>
          <input type="text" class="form-control" id="name" name="name" placeholder="Enter name">

          <span class="help-block" style="display: none;">Please enter your name.</span>

          <label for="exampleInputEmail1">Email address</label>
          <input type="email" class="form-control" id="email" name="email" placeholder="Enter email">
          <span class="help-block" style="display: none;">Please enter a valid e-mail address.</span>

          <label for="exampleInputText1">Message</label>
          <textarea class="form-control" rows="3" id="message" name="message" placeholder="Enter message"></textarea>

          <span class="help-block" style="display: none;">Please enter a message.</span>
        </div>
        <div class="form-group">
          <div class="g-recaptcha" data-sitekey="I HAVE REMOVED MY SITE KEY"></div>
          <span class="help-block" style="display: none;">Please check that you are not a robot.</span>
        </div>
        <button type="submit" id="Submit" data-loading-text="Sending..." class="btn btn-default">Submit</button>
      </form>

    </div>
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.2/modernizr.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script type="text/javascript" src="slick/slick.min.js"></script>
    <script src="assets/js/smoothscroll.js"></script>
    <script src="assets/js/jquery.stellar.min.js"></script>
    <script src="assets/js/fancybox/jquery.fancybox.js"></script>
    <script src="assets/js/main.js"></script>
    <script src="alert/sweetalert2.min.js"></script>
    <script src='https://www.google.com/recaptcha/api.js'></script>
    <script type="text/javascript">

    $(document).ready(function(e) {
        var frm = $('#form');
        frm.submit(function (ev) {
            $.ajax({
                type: frm.attr('method'),
                url: frm.attr('action'),
                data: frm.serialize(),
                success: function (data) {
                    if (data == "error")
                    {
                        swal("ERROR!","In order to avoid SPAM mail, you must confirm you are human. Please select IM NOT A ROBOT and complete the simple challenge","error");
                    }
                    else if (data == "fail")
                    {
                        swal("Failed", "Message Failed. Please try again!", "error");                       
                        location.href='index.html#contact';
                    }
                    else if (data == "success")
                    {
                        swal("Thanks for your enquiry!", "Your message has been sent to Paul and he will be in touch within 48hrs", "success"); 
                        location.href='index.html#contact';
                    }
                    else
                    {
                        swal("Something went wrong!", data, "error");
                    }
                }
            });

            ev.preventDefault();
        });
    });
</script>

Your php script:

<?php
// Define some constants
define( "RECIPIENT_NAME", "Paul O'Shea" );
define( "RECIPIENT_EMAIL", "I HAVE REMOVED MY EMAIL" );
define( "EMAIL_SUBJECT", "Website Enquiry" );

$full_name;$email;$subject;$message;$captcha;
if(isset($_POST['name']))
{
    $name=$_POST['name'];
    if($name != filter_var($name, FILTER_SANITIZE_STRING))
    {
        echo "Name is not valid!";
        exit(); // or exit w/e you please
    }
}
else
{
    echo "Name field is required!";
    exit(); // or exit w/e you please
}
if(isset($_POST['email']))
{
    $email=$_POST['email'];
    if(! filter_var($email, FILTER_VALIDATE_EMAIL))
    {
        echo "Email is not valid!";
        exit(); // or exit w/e you please
    }
}
else
{
    echo "Email field is required!";
    exit(); // or exit w/e you please
}

if(isset($_POST['message']))
{
    $message=$_POST['message'];
    if($message != filter_var($message, FILTER_SANITIZE_STRING))
    {
        echo "Name is not valid!";
        exit(); // or exit w/e you please
    }
}
else
{
    echo "Message field is required!";
    exit(); // or exit w/e you please
}

if(isset($_POST['g-recaptcha-response']))
{
    $captcha=$_POST['g-recaptcha-response'];
}

if(!$captcha)
{
    echo 'error';
    exit();
}

$response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?I HAVE REMOVED MY SECRET KEYresponse=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);

if($response.success==false)
{
    echo 'fail';
    // No need to exit() here, code ends after this anyway
}
else
{
    // If all values exist, send the email
    if ( $name && $email && $message ) 
    {
        $recipient = RECIPIENT_NAME . " <" . RECIPIENT_EMAIL . ">";
        $headers = "From: " . $name . " <" . $email . ">";
        $success = mail( $recipient, EMAIL_SUBJECT, $message, $headers );
        echo "success";
    }
    else
    {
        echo "Name, email and message are required!";
    }
    // No need to exit() here, code ends after this anyway
}
?>

EDIT 2 - Validation (Added in code as well)

You can use php's filter_var function with the available filters to validate your input. Likewise, if a validation fails you can echo and exit accordingly with a message like echo 'other' which would invoke the last if case at the JS above (just fix the title perhaps to something like "Input error" or "Invalid input").

Community
  • 1
  • 1
Manu
  • 185
  • 4
  • 11
  • Thanks again Manos. Have added an AJAX script for form submission. See above. It sends, but the alerts written into the PHP do not apply - only the alert in the script. Do I need to create new alert code in the javascript. Not sure how to do that :/ – Paul O'Shea Aug 12 '15 at 10:38
  • You should just echo the text, not the javascript. e.g. not `echo "swal("This is a message")"` but `echo "This is a message"` – Manu Aug 12 '15 at 10:49
  • I'd primarily need an alert if the recaptcha was not completed. The current script shows the same success alert if recaptcha is complete or not - but only actually sends the email if recaptcha is complete. – Paul O'Shea Aug 12 '15 at 10:59
  • if i just echo the alert in the new ajax script - i get the same result (but with crappy alerts) - the alert written into the script shows both when recaptcha is successful or not. None of the alerts in the form.php seem to run. But the email does send (ONLY if recaptcha was successful) – Paul O'Shea Aug 12 '15 at 11:12
  • I did try simple echo "This is a message" code in the PHP also - but it still only shows the success sweet alert generated by the AJAX script – Paul O'Shea Aug 12 '15 at 23:43
  • You should put `data` (which is what you echo from your php script) in : `swal('Thanks for your enquiry!', data, 'success');` at the action upon a successful AJAX call. – Manu Aug 13 '15 at 12:17
  • Try the example code that I added and post your observations. – Manu Aug 13 '15 at 20:31
  • Thanks Manos. I originally tried just replacing `swal('Thanks for your enquiry!', data, 'success');` in my ajax script - and changed my php to standard text echos with different messages. This worked - but the error message would still use the sweet alert success tick. Your code above resolves this! Thanks so much. I'm running out the door - so will test more thoroughly when I get home - but seems to be working perfectly. Your awesome :) – Paul O'Shea Aug 13 '15 at 21:15
  • Yes. Your amendments to the code seem to work very well. I get an error message( with sweet allert !) if the user forgets to run reCaptcha - and a success message(with sweet alert tick) when message is sent. I tested on Firefox, chrome and safari on mac - and iPad iOS. I guess the only improvement that could be made is better validation. I currently get some browser specific popup on the email field if it is invalid (no @) - but it is possible to submit a blank form (all fields blank) and still receive a 'Success! Message Sent' alert. – Paul O'Shea Aug 14 '15 at 00:33
  • ...or likewise, if I fill the Name and eMail field, run reCaptcha and accidentally post without filling in message - it alerts that message has been sent - even though the PHP will not send unless there is something in all fields. – Paul O'Shea Aug 14 '15 at 00:36
  • One problem. reCaptcha works across all browsers I tested - except an old macbook. The latest version of safari it can run is Version 5.1.10. With your amended code, when I click on 'I'm not a robot', it would auto approve - with NO user input!!? No pictures would come up at all. I changed `exit();` back to `exit;` and it worked again on safari version 5. Whats the purpose of the `()`? – Paul O'Shea Aug 14 '15 at 01:10
  • That should not make a difference, `exit`, `exit()` and `exit(0)` are all identical (its just that I'm used to type `exit()` sorry :) ). I'm curious how that made a difference, as it's php and it's run on the server not the browser. – Manu Aug 14 '15 at 04:36
  • Thanks Manos. I think you've nailed it. I did have to remove all `()` from the exit code. This was causing the reCapture to auto approve without user solving the picture challenge. Even on firefox this time!? Strange but true. All validation alerts now working perfectly. Thankyou! I'll upvote your solution once I get enough rep points. – Paul O'Shea Aug 14 '15 at 12:33
  • If you have time to have a look. I'm trying to solve this problem on the same website: [link](http://stackoverflow.com/questions/31977378/stellar-parallax-to-run-on-desktop-static-image-on-mobile-device) – Paul O'Shea Aug 14 '15 at 12:35
  • I also just remove the two `location.href='index.html#contact';` from the AJAX script - as we are never actually redirected away from the original page - no need to redirect back. – Paul O'Shea Aug 14 '15 at 12:45
  • Hey #Manos Forsaken. This form has been working fine for me, but I've had a few others test the form... And most emails never make it to my gmail - even though they get the success alert. Not sure if there is some loophole in the code, or would I be better to try and implement phpmailer instead of mail() so I can use gmails SMTP? Strange thing is, the server I'm hosted on seems to support mail(), it's always worked when I test... And I have received messages from some others using different ISPs... But many messages are going missing?? Any thoughts? – Paul O'Shea Sep 18 '15 at 04:23