HI guys, as mentioned not too long ago here https://www.daniweb.com/programming/web-development/threads/501668/contact-form-building-my-own-or-already-made I'm building my own php script that is supposed to validate and submit form fields to an email address provided. The problem is that I have no real experience of php so I' just doing some readings, getting bits and bobs from different places and add my own code - probably wrong anyway.
In terms of functionality, this is what I would like to build:
-Each field has its own error message displayed if empty or in case of bad input;
-When the form is submitted I need a message somewhere around the form to say something like "Thank you, form submitted" but I need the form to remain visible
-When I press the submit button, since this is a 1 page site, it will scroll back to the top, as you would expect. Normally I'd address this with one line of jquery

$(".contactForm .button input[type='submit']").click(function(e){
        e.preventDefault();
    });

but that wouldn't work here as I need the form to submit. Any other idea?

So, one way or another I've produced something that partially works but there are quite a lot of problems still. What would be great is if somebody could give me a hand to build this and get it to work: if you glance at the code and tell me that needs a completely rebuild, it's fine, at the end of the day, like I said, I'm not really that good with php.
So, let's get to the code. Here is what I've produced so far (if you want to see this code in action, you can find it here http://antonioborrillo.co.uk/agency_test/test/en/index.php and then click on "get in touch"):

<!-- form validation -->
            <?php
            //create variables for validation
            $titleError = "";
            $firstNameError = "";
            $lastNameError = "";
            $emailAddressError = "";
            $messageError = "";
            $websiteError = "";
            $titleError = "";

            $title = "";
            $firstName = "";
            $lastName = "";
            $emailAddress = "";
            $message = "";
            $website = "";

            //mail variables
            $to = "bassabasso@gmail.com";
            $subject = "New request";
            $currentTitle = $_POST["title"];
            $currentFirstName = $_POST["firstName"];
            $currentdLastname = $_POST["lastName"];
            $currentEmail = $_POST["emailAddress"];
            $currentWebsite = $_POST["website"];
            $currentMessage = $_POST["message"];
            $headers  = 'MIME-Version: 1.0' . "\r\n";
            $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";         
            mail($to,$subject,$currentMessage,$headers);

            if($_SERVER["REQUEST_METHOD"] == "POST"){
                //validate title
                if($_POST["title"] == "0"){
                    $titleError = "Select a title";
                }

                //validate firstName
                if (empty($_POST["firstName"])){//if empty
                    $firstNameError = "First name is required";
                }
                else{
                    $firstName = test_input($_POST["firstName"]);
                    // check if firstName only contains letters and whitespace
                    if(!preg_match("/^[a-zA-Z ]*$/",$firstName)){
                        $firstNameError = "Only letters and white space allowed"; 
                    }
                }
                if (empty($_POST["lastName"])){//if empty
                    $lastNameError = "Last name is required";
                }
                else{
                    $lastName = test_input($_POST["lastName"]);
                    // check if lastName only contains letters and whitespace
                    if(!preg_match("/^[a-zA-Z ]*$/",$lastNameError)){
                        $lastNameError = "Only letters and white space allowed"; 
                    }
                }
                if(empty($_POST["emailAddress"])){
                    $emailAddressError = "Email is required";
                }
                else{
                    $emailAddress = test_input($_POST["emailAddress"]);
                    // check if e-mail address is well-formed
                    if(!filter_var($emailAddress, FILTER_VALIDATE_EMAIL)){
                        $emailAddressError = "Invalid email format"; 
                    }
                }
                if(empty($_POST["website"])){
                    $website = "";
                }
                else{
                    $website = test_input($_POST["website"]);
                    // check if URL address syntax is valid (this regular expression also allows dashes in the URL)
                    if(!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {
                        $websiteError = "Invalid URL"; 
                    }
                }
                if(empty($_POST["comment"])){
                    $messageError = "Message required";
                }
                else{
                    $message = test_input($_POST["comment"]);                   
                }               
            }
            function test_input($data){
               $data = trim($data);
               $data = stripslashes($data);
               $data = htmlspecialchars($data);
               return $data;
            }
            ?>
            <div class="pseudoPage contact" data-item="contact">
                <h2>Contact us</h2>   
                    <p>We're always excited to work on a new project, so give us a shout!</p>
                    <p>Fill in the form or drop us a line at <a href="mailto:info@webdevsolutions.xxx">info@webdevsolutions.xxx</a></p>
                <div class="contactForm">                    
                    <div class="contactFormPanel">   
                        <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
                            <div class="control-group">
                                <label class="control-label" for="title">Title*</label>
                                <div class="controls">
                                    <select id="title" name="title">
                                        <option value="0">Please select</option>
                                        <option value="1">Mr </option>
                                        <option value="2">Mrs</option>
                                        <option value="3">Ms</option>
                                        <option value="4">Sir</option>
                                    </select>
                                    <span class="error"><?php echo $titleError;?></span>
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="firstName">First name*</label>
                                <div class="controls">
                                    <input id="firstName" type="text" name="firstName" value="<?php echo $firstName;?>">
                                    <span class="error"><?php echo $firstNameError;?></span>
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="lastName">Last name*</label>
                                <div class="controls">
                                    <input id="lastName" type="text" name="lastName" value="<?php echo $lastName;?>">
                                    <span class="error"><?php echo $lastNameError;?></span>
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="emailAddress">Email address*</label>
                                <div class="controls">
                                    <input id="emailAddress" type="text" name="emailAddress" value="<?php echo $emailAddress;?>">
                                    <span class="error"><?php echo $emailAddressError;?></span>
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="website">Website</label>
                                <div class="controls">
                                    <input id="website" type="text" name="website" value="<?php echo $website;?>">
                                    <span class="error"><?php echo $websiteError;?></span>
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="message">Enter your message*</label>
                                <div class="controls">
                                    <textarea id="message" name="message"><?php echo $message;?></textarea>
                                    <span class="error"><?php echo $messageError;?></span>
                                </div>
                            </div>                           
                            <div class="control-group">
                                <div class="controls">
                                    <div class="button">
                                        <!-- <a href="#">Submit</a> -->
                                        <input type="submit" name="submit" value="Submit">
                                    </div>
                                </div>
                            </div>

                        </form>
                    </div>
                </div>

            </div>

Here is what it works:
First Name, Last Name, email address and website seem to validate correctly. Title is a bit strange: say I select Mr and then hit the submit button: if there is an error (perhaps because I didn't fill in the email address), the title field resets itself to "Please select": how do I make sure that whatever selection I've made stays there?
Message: that's another one, and same as title: if I type something, then submit, and again, say there is an error somewhere else in the form, the message in the textarea disappears and the error "message required" appears (but I did type the message in!) I thought I sorted it out by doing this <textarea id="message" name="message"><?php echo $message;?></textarea> but obviously I was wrong. How do I retain the message?
As far as sending the form to the email address specified, well, what to say, I'm a bit lost there. Looking on the net, I noticed that mail() needs a few parameters, so I have come up with this:

//mail variables
            $to = "bassabasso@gmail.com";
            $subject = "New request";
            $currentTitle = $_POST["title"];
            $currentFirstName = $_POST["firstName"];
            $currentdLastname = $_POST["lastName"];
            $currentEmail = $_POST["emailAddress"];
            $currentWebsite = $_POST["website"];
            $currentMessage = $_POST["message"];
            $headers  = 'MIME-Version: 1.0' . "\r\n";
            $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";         
            mail($to,$subject,$currentMessage,$headers);

Trouble is that I need to send also other things like, title, Name, email etc, and the manual says taht you can have additional parameters but I don't quite understand how:
is it something like this: mail($to,$subject,$currentMessage,$headers,$currentTitle,$currentFirstName,$currentdLastname,$currentEmail,$currentWebsite,);?

Finally, how do I get the email to be sent only if the validation has been successful? Currently everytime I press submit I get about 3 empty emails coming through
Any help will be much appreciated
thanks

Recommended Answers

All 14 Replies

Edit: ignore the issue with the "message" problem, I sorted it out. It wasn't working because I made a schoolboy error

Right, I've made some more changes now:
I added some conditions to allow the form to be submitted or not depending on the error. I've created a variable $errors = 0; to keep an eye at the errors and if there is an error I change the value to 1 if there isn't, it goes back to 0. This allows me to say:

if($errors == 0){
    mail($to,$subject,$currentMessage,$headers);
}

and so I can choose when to submit and when not. No idea if it's good or not, but it seems to work.

Outstanding issues.
1)title: I still can't maintain the selection of the title option after I pressed submit with an error in the form: the form reloads and the selection reverst back to "Please select"
2)When I click submit the page jumps up to the top - as we know and as mentioned in the previous post - but if I add e.preventDefault() in the javascript the form, of course, doesn't submit anymore.
3)After the form has been submitted the data is still there: shouldn't that disappear?

Here is an updated version of the form and the php code:

<?php
//create variables for validation
$titleError = "";
$firstNameError = "";
$lastNameError = "";
$emailAddressError = "";
$messageError = "";
$websiteError = "";
$titleError = "";

$title = "";
$firstName = "";
$lastName = "";
$emailAddress = "";
$message = "";
$website = "";

//mail variables
$to = "bassabasso@gmail.com";
$subject = "New request";
$currentTitle = $_POST["title"];            
$currentMessage .= "Title: " . $_POST["title"] . "\r\n";
$currentMessage = "First Name: " . $_POST["firstName"] . "\r\n";
$currentMessage .= "Last Name: " . $_POST["lastName"] . "\r\n";
$currentMessage .= "Email address: " . $_POST["emailAddress"] . "\r\n";
$currentMessage .= "Website: " . $_POST["website"] . "\r\n";
$currentMessage .= "Message: " . $_POST["message"] . "\r\n";            
//keep track of how many errors
$errors = 0;
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";         
//mail($to,$subject,$currentMessage,$headers);

if($_SERVER["REQUEST_METHOD"] == "POST"){//has the form been submitted?
    //validate title

    if($_POST["title"] == "0"){
        $titleError = "Select a title";
        $errors = 1;
    }
    else{
        $title = $_POST["title"];                   
        $errors = 0;
    }
    /* if( 0 != $_POST['title'] ) {
    $title = $_POST['title'];
        }
    else
    {
        $titleError = "required";
    } */

    //validate firstName
    if (empty($_POST["firstName"])){//if empty
        $firstNameError = "First name is required";
        $errors = 1;
    }
    else{
        $firstName = test_input($_POST["firstName"]);
        // check if firstName only contains letters and whitespace
        if(!preg_match("/^[a-zA-Z ]*$/",$firstName)){
            $firstNameError = "Only letters and white space allowed"; 
            $errors = 1;
        }
        else{
            $errors = 0;                        
        }                   
    }
    if (empty($_POST["lastName"])){//if empty
        $lastNameError = "Last name is required";
        $errors = 1;
    }
    else{
        $lastName = test_input($_POST["lastName"]);
        // check if lastName only contains letters and whitespace
        if(!preg_match("/^[a-zA-Z ]*$/",$lastNameError)){
            $lastNameError = "Only letters and white space allowed"; 
            $errors = 1;
        }
        else{
            $errors = 0;                        
        }
    }
    if(empty($_POST["emailAddress"])){
        $emailAddressError = "Email is required";
        $errors = 1;
    }
    else{
        $emailAddress = test_input($_POST["emailAddress"]);
        // check if e-mail address is well-formed
        if(!filter_var($emailAddress, FILTER_VALIDATE_EMAIL)){
            $emailAddressError = "Invalid email format"; 
            $errors = 1;
        }
        else{
            $errors = 0;                        
        }

    }
    if(empty($_POST["website"])){
        $website = "";
        $errors = 0;
    }
    else{
        $website = test_input($_POST["website"]);
        // check if URL address syntax is valid (this regular expression also allows dashes in the URL)
        if(!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {
            $websiteError = "Invalid URL"; 
            $errors = 1;
        }
        else{
            $errors = 0;                        
        }
    }
    if(empty($_POST["message"])){
        $messageError = "Message required";
        $errors = 1;
    }
    else{
        $message = test_input($_POST["message"]);
        $errors = 0;
    }
    if($errors == 0){
        mail($to,$subject,$currentMessage,$headers);
    }
    /* else{
        return false;                   
    } */
}
function test_input($data){
   $data = trim($data); 
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   return $data;
}
?>
<div class="pseudoPage contact" data-item="contact">
    <h2>Contact us</h2>   
        <p>We're always excited to work on a new project, so give us a shout!</p>
        <p>Fill in the form or drop us a line at <a href="mailto:info@webdevsolutions.xxx">info@webdevsolutions.xxx</a></p>
    <div class="contactForm">                    
        <div class="contactFormPanel">   
            <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
                <div class="control-group">
                    <label class="control-label" for="title">Title*</label>
                    <div class="controls">
                        <select id="title" name="title">
                            <option value="0">Please select</option>
                            <option value="1">Mr </option>
                            <option value="2">Mrs</option>
                            <option value="3">Ms</option>
                            <option value="4">Sir</option>
                        </select>
                        <span class="error"><?php echo $titleError;?></span>
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="firstName">First name*</label>
                    <div class="controls">
                        <input id="firstName" type="text" name="firstName" value="<?php echo $firstName;?>">
                        <span class="error"><?php echo $firstNameError;?></span>
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="lastName">Last name*</label>
                    <div class="controls">
                        <input id="lastName" type="text" name="lastName" value="<?php echo $lastName;?>">
                        <span class="error"><?php echo $lastNameError;?></span>
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="emailAddress">Email address*</label>
                    <div class="controls">
                        <input id="emailAddress" type="text" name="emailAddress" value="<?php echo $emailAddress;?>">
                        <span class="error"><?php echo $emailAddressError;?></span>
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="website">Website</label>
                    <div class="controls">
                        <input id="website" type="text" name="website" value="<?php echo $website;?>">
                        <span class="error"><?php echo $websiteError;?></span>
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="message">Enter your message*</label>
                    <div class="controls">
                        <textarea id="message" name="message"><?php echo $message;?></textarea>
                        <span class="error"><?php echo $messageError;?></span>
                    </div>
                </div>                           
                <div class="control-group">
                    <div class="controls">
                        <div class="button">
                            <!-- <a href="#">Submit</a> -->
                            <input type="submit" name="submit" value="Submit">
                        </div>
                    </div>
                </div>

            </form>
        </div>
    </div>

</div>

Does anybody have any idea about the above? I'm relly not into php and I'm a bit lost. I suppose I using ajax will be the best way to submit the form so that the page doesn't jump up to the top and then I could combine this with the php validation? Any idea?

well seems like I've made some progress, but I don't seem to be able to submit the form. I've got the ajax and the validation up but something isn't right and the form hangs for a while and then it doesn't submit. Here is the form inside index.php:

<div class="pseudoPage contact" data-item="contact">
    <h2>Contact us</h2>   
        <p>We're always excited to work on a new project, so give us a shout!</p>
        <p>Fill in the form or drop us a line at <a href="mailto:info@webdevsolutions.xxx">info@webdevsolutions.xxx</a></p>
    <div class="contactForm">
        <!-- <div class="successMsg"><p>Thank you. The form has been submitted.</p></div> -->
        <div class="contactFormPanel">   
            <form id="contactForm">
                <div class="control-group">
                    <label class="control-label" for="title">Title*</label>
                    <div class="controls">
                        <select id="title" name="title" required>
                            <option value="0">Please select</option>
                            <option value="1">Mr </option>
                            <option value="2">Mrs</option>
                            <option value="3">Ms</option>
                            <option value="4">Sir</option>
                        </select>                                    
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="firstName">First name*</label>
                    <div class="controls">
                        <input id="firstName" type="text" name="firstName" value="" required>                                    
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="lastName">Last name*</label>
                    <div class="controls">
                        <input id="lastName" type="text" name="lastName" value="" required>                                  
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="emailAddress">Email address*</label>
                    <div class="controls">
                        <input id="emailAddress" type="text" name="emailAddress" value="" required>                                  
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="website">Website</label>
                    <div class="controls">
                        <input id="website" type="text" name="website" value="">                                 
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="message">Enter your message*</label>
                    <div class="controls">
                        <textarea id="message" name="message" required></textarea>                                    
                    </div>
                </div>                           
                <div class="control-group">
                    <div class="controls">
                        <div class="button">
                            <!-- <a href="#">Submit</a> -->
                            <input type="submit" name="submit" value="Submit">
                        </div>
                    </div>
                </div>
                <span class="success"></span>
                <span class="error"></span>
            </form>
        </div>
    </div>

</div>

Script form_en.js:

 $(function(){
      $(document).on("submit", "#contactForm", function(e){
          e.preventDefault();

          $form = $(this);

          $.post("../formhandler.php", $form.serialize())
          .then(function (msg){
              $form[0].reset();
             $("span.success").html(msg).show().delay(2500);
         })
         .fail(function (jqXHR) {
             var errors = JSON.parse(jqXHR.responseText);
             $("span.error").html(errors.join('<br>')).show().delay(2500);
         });
     });
 });

And formhandler.php

 <?php
  //require 'PHPMailer-master/PHPMailerAutoload.php';
  //header('Content-Type: application/json');

  $errors = array();

  $title = (isset($_POST['title']) && ($_POST['title'] != '0')) ?  $_POST['title'] : null;
  $firstName = (isset($_POST['firstName']) && !(empty($_POST["firstName"]))) ? $_POST['firstName'] : null;
  $lastName = (isset($_POST['lastName']) && !(empty($_POST["lastName"]))) ? $_POST['lastName'] : null;  
  $emailAddress = (isset($_POST['emailAddress']) && !(empty($_POST["emailAddress"]))) ? $_POST['emailAddress'] : null;
 $website = isset($_POST['website']) ? $_POST['website'] : '';
 $message = (isset($_POST['message']) && !(empty($_POST["message"]))) ? $_POST['message'] : null;

 if ($title === null) {
     $errors[] = 'You must select a title';
 }

 if ($firstName === null) {
     $errors[] = 'You must enter a first name';
 }

 if ($lastName === null) {
     $errors[] = 'You must enter a last name';
 }

 if ($emailAddress === null || filter_var($emailAddress, FILTER_VALIDATE_EMAIL) === false) {
     $errors[] = 'You must enter a valid email address';
 }

 if ($website !== '') {
     if(strpos($website, '://') === false) {
         $website = 'http://' . $website;
     }

     if (filter_var($website, FILTER_VALIDATE_URL, array('flags' => null)) === false) {
         $errors[] = 'You must enter a valid website address';
     }    
 }

 if ($message === null) {
     $errors[] = 'You must enter a message';
 }

 if (empty($errors)) {
     require __DIR__ . '/PHPMailer-master/PHPMailerAutoload.php';

     //SMTP needs accurate times, and the PHP time zone MUST be set
     //This should be done in your php.ini, but this is how to do it if you don't have access to that
     date_default_timezone_set('Etc/UTC');

     /* $mail = new PHPMailer;
     $mail->isSMTP();
     $mail->Host = 'smtp.gmail.com';
     $mail->Port = 587;
     $mail->SMTPSecure = 'tls';
     $mail->SMTPAuth = true;
     $mail->Username = "bassabasso@gmail.com";
     $mail->Password = "xxxxxxxxxxx";

     $mail->setFrom($emailAddress, $firstName . ' ' . $lastName);
     $mail->addAddress('bassabasso@gmail.com', 'Bassa Basso');
     $mail->Subject = 'New request';
     $mail->Body = $message . "\r\n\r\nWebsite: " . $website; */

    $mail = new PHPMailer;
    $mail->Timeout       =   30; // set the timeout (seconds)
    $mail->isSMTP();
    $mail->SMTPAuth   = true;                   // enable SMTP authentication
    $mail->SMTPSecure = "tls";                  // sets the prefix to the servier
    $mail->Host       = "smtp.live.com";        // sets hotmil as the SMTP server
    $mail->Port       = 587;                    // set the SMTP port for the hotmail server
    $mail->Username   = "jasonattin@hotmail.co.uk";      // hotmail username
    $mail->Password   = "xxxxxxxx";           // hotmail password
    $mail->setFrom($emailAddress, $firstName . ' ' . $lastName);
     $mail->addAddress('jasonattin@hotmail.co.uk', 'Bassa Basso');
     $mail->Subject = 'New request';
     $mail->Body = $message . "\r\n\r\nWebsite: " . $website; 


     if ($mail->send()) {
         echo json_encode('Form submitted successfully!');
         exit();
     }

     // You may want to log this somewhere
     // $mail->ErrorInfo;

     $errors[] = 'Could not send email, please try again later';    
 }

 http_response_code(400);
 echo json_encode($errors);

You can see the form in action here antonioborrillo.co.uk/agency_test/test/en/index.php under get in touch. Basically when I submit it, the form hangs - in the console you can see the formhandler.php loading and then returns an error
["Could not send email, please try again later"]
Does anybody know why it doesn't work? I'm using php mailer to send the form field via email to a hotmail address (tried with two gmail accounts with the same result)

I've managed to send an email finally, here is the working php script:

 <?php
  //require 'PHPMailer-master/PHPMailerAutoload.php';
  //header('Content-Type: application/json');

  $errors = array();



  $title = (isset($_POST['title']) && ($_POST['title'] != '0')) ?  $_POST['title'] : null;
  $firstName = (isset($_POST['firstName']) && !(empty($_POST["firstName"]))) ? $_POST['firstName'] : null;
  $lastName = (isset($_POST['lastName']) && !(empty($_POST["lastName"]))) ? $_POST['lastName'] : null;  
  $emailAddress = (isset($_POST['emailAddress']) && !(empty($_POST["emailAddress"]))) ? $_POST['emailAddress'] : null;
 $website = isset($_POST['website']) ? $_POST['website'] : '';
 $message = (isset($_POST['message']) && !(empty($_POST["message"]))) ? $_POST['message'] : null;

 if ($title === null) {
     $errors[] = 'You must select a title';
 }

 if ($firstName === null) {
     $errors[] = 'You must enter a first name';
     $firstNameError = "You must enter a first name";
 }

 if ($lastName === null) {
     $errors[] = 'You must enter a last name';
 }

 if ($emailAddress === null || filter_var($emailAddress, FILTER_VALIDATE_EMAIL) === false) {
     $errors[] = 'You must enter a valid email address';
 }

 if ($website !== '') {
     if(strpos($website, '://') === false) {
         $website = 'http://' . $website;
     }

     if (filter_var($website, FILTER_VALIDATE_URL, array('flags' => null)) === false) {
         $errors[] = 'You must enter a valid website address';
     }    
 }

 if ($message === null) {
     $errors[] = 'You must enter a message';
 }

 if (empty($errors)) {
     require __DIR__ . '/PHPMailer-master/PHPMailerAutoload.php';

     //SMTP needs accurate times, and the PHP time zone MUST be set
     //This should be done in your php.ini, but this is how to do it if you don't have access to that
     date_default_timezone_set('Etc/UTC');

     /* $mail = new PHPMailer;
     $mail->isSMTP();
     $mail->Host = 'smtp.gmail.com';
     $mail->Port = 587;
     $mail->SMTPSecure = 'tls';
     $mail->SMTPAuth = true;
     $mail->Username = "bassabasso@gmail.com";
     $mail->Password = "xxxxxxxxxxx";

     $mail->setFrom($emailAddress, $firstName . ' ' . $lastName);
     $mail->addAddress('bassabasso@gmail.com', 'Bassa Basso');
     $mail->Subject = 'New request';
     $mail->Body = $message . "\r\n\r\nWebsite: " . $website; */

    $mail = new PHPMailer;
    $mail->Timeout       =   30; // set the timeout (seconds)
   // $mail->isSMTP();
    $mail->SMTPAuth   = true;                   // enable SMTP authentication
    $mail->SMTPSecure = "tls";                  // sets the prefix to the servier
    $mail->Host       = "smtp.live.com";        // sets hotmail as the SMTP server
    $mail->Port       = 587;                    // set the SMTP port for the hotmail server
    $mail->Username   = "example@hotmail.co.uk";      // hotmail username
    $mail->Password   = "xxx";           // hotmail password
    $mail->setFrom($emailAddress, $firstName . ' ' . $lastName);
     $mail->addAddress('example@hotmail.co.uk', 'Giasone Attinio');
     $mail->Subject = 'New request';
     //$mail->Body = $message . "\r\n\r\nWebsite: " . $website; 
    $mail->Body = "Title: " . $title . "\r\n\r\nFirst Name: " .$firstName . "\r\n\r\nLast Name: " . $lastName . "\r\n\r\nEmail address: " .$emailAddress . "\r\n\r\nMessage: " . $message . "\r\n\r\nWebsite: " . $website; 

    /* $mail = new PHPMailer;
    $mail->isSMTP();
    $mail->SMTPAuth   = true;                   // enable SMTP authentication
    $mail->SMTPSecure = "tls";                  // sets the prefix to the servier
    $mail->Host       = "mail.example.com";        // sets hotmil as the SMTP server
    $mail->Port       = 465;                    // set the SMTP port for the hotmail server
    $mail->Username   = "info@example.co.uk";      // hotmail username
    $mail->Password   = "xxx";           // hotmail password
    //$mail->SetFrom('yourname@yourdomain.com', 'First Last');
    //$mail->AddReplyTo("name@yourdomain.com","First Last");
    //$mail->Subject    = "PHPMailer Test Subject via smtp (hotmail), basic";
    //$mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
    $mail->Body = "Title: " . $title . "\r\n\r\nFirst Name: " .$firstName . "\r\n\r\nLast Name: " . $lastName . "\r\n\r\nEmail address: " .$emailAddress . "\r\n\r\nMessage: " . $message . "\r\n\r\nWebsite: " . $website;   
           */
     if ($mail->send()) {
         echo json_encode('Thank you! The form has been submitted!');
         exit();
     }

     // You may want to log this somewhere
     // $mail->ErrorInfo;

     $errors[] = 'Could not send email, please try again later';    
 }

 http_response_code(400);
 echo json_encode($errors);

And this is the jquery that goes with it:

 $(function(){
      $(document).on("submit", "#contactForm", function(e){
          e.preventDefault();

          $form = $(this);

          $.post("../formhandler.php", $form.serialize())
          .then(function (msg){
              $form[0].reset();
              console.log("inside then " + msg + " type of msg " + jQuery.type(msg));
             $("span.success").html(msg).show().delay(2500);//fadeOut(1000)
         })
         .done(function(e){
            console.log("inside done " + e);
         })
         .fail(function (jqXHR) {
             var errors = JSON.parse(jqXHR.responseText);
             $("span.error").html(errors.join('<br>')).show().delay(2500);
             console.log("inside fail " + e);
         });
     });
 });

Now, in the form rather than using the attribute "required" that generate its own errors, I'd like to have customized ones appearing in a span below the input field they're referring to.
this is the form by the way:

<div class="contactForm">
                    <!-- <div class="successMsg"><p>Thank you. The form has been submitted.</p></div> -->
                    <div class="contactFormPanel">   
                        <form id="contactForm">
                            <span class="success"></span>
                            <span class="error"></span>
                            <div class="control-group">
                                <label class="control-label" for="title">Title*</label>
                                <div class="controls">
                                    <select id="title" name="title">
                                        <option value="0">Please select</option>
                                        <option value="1">Mr </option>
                                        <option value="2">Mrs</option>
                                        <option value="3">Ms</option>
                                        <option value="4">Sir</option>
                                    </select>                                    
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="firstName">First name*</label>
                                <div class="controls">
                                    <input id="firstName" type="text" name="firstName" value="" >                                        
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="lastName">Last name*</label>
                                <div class="controls">
                                    <input id="lastName" type="text" name="lastName" value="" >                                      
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="emailAddress">Email address*</label>
                                <div class="controls">
                                    <input id="emailAddress" type="text" name="emailAddress" value="" >                                  
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="website">Website</label>
                                <div class="controls">
                                    <input id="website" type="text" name="website" value="">                                 
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="message">Enter your message*</label>
                                <div class="controls">
                                    <textarea id="message" name="message" ></textarea>                                    
                                </div>
                            </div>                           
                            <div class="control-group">
                                <div class="controls">
                                    <div class="button">
                                        <!-- <a href="#">Submit</a> -->
                                        <input type="submit" name="submit" value="Submit">
                                    </div>
                                </div>
                            </div>

                        </form>
                    </div>
                </div>

Currently, if you look at the live site http://antonioborrillo.co.uk/agency_test/test/en/index.php the errors are displayed in a yellow box at the top of the form: that should be reserved to the success message, which you get when you submit the form. Somehow, even the errors are ending up there and that shouldn't be the case. You will notice that in th php file there is an array
$errors = array();
that depending on the error, gets more string errors inserted as a string. What I'd like to do in the js file, is to loop through the form elements and the errors and display, when necessary, those errors in span tags (teh span tags can be hardcoded I don't really care). What would be the best way to go about this?

Right, I reconsidered the whole thing, as I'm clearly not really good with php and I didn't get any solution from anywhere.
I've refactored the code, and, for simplicity, mocked up a simpler form here http://antonioborrillo.co.uk/formTest/test.php (no styles or fancy animations, just a crude form). And here is what I've decided to do.
As I needed only some basic validation, I've done it clientside, and I've validated only the mandatory fields. If there is an error, meaning merely that the input field is empty as I'm not validating the email address, an error message appears at the top, the same general error message for all the fields. I used to have a customized error address for each field, but to be honest, there is probably no need for that. When the form gets submitted you get a submission message at the top of the form that disappears after 2 seconds.
Let's quickly look at the code.
HTML Form (test.php):

<!DOCTYPE html>
<html>
    <head>
        <script src="jquery-1.11.3.min.js"></script>
        <script src="form_en.js"></script>
        <link rel="stylesheet" type="text/css" href="style.css">
        <title></title>
    </head>
    <body>
        <form id="contactForm" target="_blank" method="POST" action="formhandler.php">    
            <!-- <div class="control-group">
                <label class="control-label" for="title">Title*</label>
                <div class="controls">
                    <select id="title" name="title">
                        <option value="0">Please select</option>
                        <option value="1">Mr </option>
                        <option value="2">Mrs</option>
                        <option value="3">Ms</option>
                        <option value="4">Sir</option>
                    </select>
                    <span class="error"></span>
                </div>
            </div> -->
            <div class="control-group">
                <label class="control-label" for="firstName">First name*</label>
                <div class="controls">
                    <input id="firstName" type="text" name="firstName" value="" class="mandatory">
                    <!-- <span class="error"></span>-->
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="lastName">Last name*</label>
                <div class="controls">
                    <input id="lastName" type="text" name="lastName" value="" class="mandatory">
                    <!-- <span class="error"></span>-->
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="emailAddress">Email address*</label>
                <div class="controls">
                    <input id="emailAddress" type="text" name="emailAddress" value="" class="mandatory">
                    <!-- <span class="error"></span>-->
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="website">Website</label>
                <div class="controls">
                    <input id="website" type="text" name="website" value="">
                    <!-- <span class="error"></span>-->
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="message">Enter your message*</label>
                <div class="controls">
                    <textarea id="message" name="message" class="mandatory"></textarea>
                    <!-- <span class="error"></span>-->
                </div>
            </div>                           
            <div class="control-group">
                <div class="controls">
                    <div class="button">
                        <!-- <a href="#">Submit</a> -->
                        <input type="submit" name="submit" value="Submit">
                    </div>
                </div>
            </div>                           
        </form>
    </body>
</html>

Script (form_en.js) doing the ajax call, the validation, the success message, error message and resetting form fields

$(document).ready(function(){
    $("#contactForm").find("input[type='submit']").click(function(e){
        doValidation(e);
    });

});

function doValidation(e){
    e.preventDefault();//prevent form submission
    //console.log("inside doValidation");
    if(isValidation()){
        sendForm($("#contactForm"));

    }

}

function sendForm($currentForm){
    var $form = $currentForm;
    var formAction = $form.attr('action');
    var hasFormData = Boolean(window.FormData !== undefined);
    var formData = hasFormData ? new FormData(document.forms[0]) : $form.serialize();
    $.ajax({
            url: formAction,
            data: formData,
            contentType: hasFormData ? false : 'application/x-www-form-urlencoded; charset=UTF-8',
            processData: hasFormData ? false : true,
            type: "POST",
            success: function(data, textStatus, jqXHR){
                    //hideForm($currentForm,data);
                    $(".form-error").remove();//remove error first thing
                    clearFields();//clear fields
                    addSuccessMsg();//add a success message
                },
            error: function(jqXHR, textStatus, errorThrown){
                    //hideForm($currentForm,textStatus);
                }
        });
}

function isValidation(){
    var $fieldsToCheck = $("#contactForm .mandatory");//selection of mandatory fields
    var is_empty = isEmpty($fieldsToCheck);
    if(is_empty){
        throw_general_error();//display error
        return false;//don't submit form    
    }
    else if(!(is_empty)){
        return true;//submit        
    }   
}

function isEmpty($fieldsToCheck){//check if it is empty 
    for(var i=0; i<$fieldsToCheck.length; i++){
        if(!($fieldsToCheck.eq(i).val())){//if not empty
            return true;
        }
    }
    return false;//if empty
}
function throw_general_error(){//create and display general error   
    $(".form-error").remove(errorStringHTML);//remove error first thing
    var errorStringHTML = '<div class="form-error general"><p>Please make sure all mandatory fields are completed correctly.</p></div>';
    $("#contactForm").prepend(errorStringHTML);
}

function addSuccessMsg(){//creates and adds the success message
    var successMsgHTML = '<div class="form-success general"><p>Thank you, form submitted.</p></div>';
    $("#contactForm").prepend(successMsgHTML).find(".form-success").fadeOut(2000);
}

function clearFields(){
    console.log("inside clearFields");  
    var $fields = $("#contactForm").find(":input").not(":submit");
    for(var i=0; i<$fields.length; i++){
        $fields.eq(i).val("");
    }   
}

And the php file (formhandler.php) which uses PHPmailer for email submission

<?php
    require 'PHPMailer-master/PHPMailerAutoload.php';
    //header('Content-Type: application/json');


    //SMTP needs accurate times, and the PHP time zone MUST be set
    //This should be done in your php.ini, but this is how to do it if you don't have access to that
    date_default_timezone_set('Etc/UTC');


    $firstName = $_POST['firstName'];
    $lastName = $_POST['lastName'];
    $emailAddress = $_POST['emailAddress'];
    $message = $_POST['message'];
    $website = $_POST['website'];



    $mail = new PHPMailer(true);
    $mail->Timeout       =   30; // set the timeout (seconds)
    //$mail->isSMTP();
    $mail->SMTPAuth   = true;                   // enable SMTP authentication
    $mail->SMTPSecure = "tls";                  // sets the prefix to the servier
    $mail->Host       = "smtp.live.com";        // sets hotmail as the SMTP server
    $mail->Port       = 587;                    // set the SMTP port for the hotmail server
    $mail->Username   = "jasonattin@hotmail.co.uk";      // hotmail username
    $mail->Password   = "xxxxxx";           // hotmail password
    //$mail->setFrom($emailAddress, $firstName . ' ' . $lastName);  
    $mail->setFrom("test@gmail.com", "No reply");       
    $mail->addAddress('jasonattin@hotmail.co.uk', 'Giasone Attinio');
    $mail->Subject = 'New request';
    //$mail->Body = $message . "\r\n\r\nWebsite: " . $website; 
    $mail->Body = "First Name: " .$firstName . "\r\n\r\nLast Name: " . $lastName . "\r\n\r\nEmail address: " .$emailAddress . "\r\n\r\nMessage: " . $message . "\r\n\r\nWebsite: " . $website; 


    if(!$mail->send()){
        echo "Mailer Error: " . $mail->ErrorInfo;
    }
    else{
        echo "success";
    }

 ?>

That's all. That works pretty well.

Keep in mind that your server side script is not safe: an attacker could send a request directly to the formhandler.php script and this will execute without control.

Also the script should check the request method, for example by clicking (i.e. executing a GET request) on:

it should lead to unexpected results, because the $_POST array is not set. I did it and you will probably received a mail with some PHP warnings. It's worth to fix this, because scanners always target form actions in search of errors. You should check each index key of the $_POST array that you want to use. So, you should do something like this:

if($_SERVER['REQUEST_METHOD'] == 'POST')
{
    $firstName = filter_input('POST', 'firstname', FILTER_SANITIZE_STRING);
    $lastName = filter_input('POST', 'lastname', FILTER_SANITIZE_STRING);
    $emailAddress = filter_input('POST', 'emailAddress', FILTER_SANITIZE_EMAIL);
    $message = filter_input('POST', 'message', FILTER_SANITIZE_STRING);
    $website = filter_input('POST', 'website', FILTER_SANITIZE_URL);

    # all other code here
}

About return values of filter_input():

Value of the requested variable on success, FALSE if the filter fails, or NULL if the variable_name variable is not set. If the flag FILTER_NULL_ON_FAILURE is used, it returns FALSE if the variable is not set and NULL if the filter fails.

Check: http://php.net/filter-input

Thanks for looking at that cereal. Needless to say, I'm more than happy to fix the problems if you tell me how :-).
I'm currently integrating the various scripts onto the main website, just to make sure it works, and then I'll integrate your amendments.

an attacker could send a request directly to the formhandler.php script and this will execute without control.

Fair enough, how do I fix that?

You should check each index key of the $_POST array that you want to use. So, you should do something like this:

No problem at all, will get that done.

you will probably received a mail with some PHP warnings

Nope, I didn't get anything.

how do I fix that?

Define the allowed request method and sanitize the input, as in my previous example, that should limit improper submissions.

Nope, I didn't get anything.

Ok, I thought it worked because your page returned with success.

You can find more information about forms security here:

Thanks for that. So I've added what you've suggested, but I run into a problem, I'm sure it's something I've done :-): Now, when I receive the email, the fields are empty, so the values I input in the form are not coming through, this is what I get in the email (it ws definitely working before, I checked that):

First Name: 
Last Name: 
Email address: 
Message: 
Website: 

I'm thinking perhaps I haven't implemented your code correctly, here's how my script looks now - I've basically wrapped almost everyting inside if($_SERVER['REQUEST_METHOD'] == 'POST'){:

<?php
    require 'PHPMailer-master/PHPMailerAutoload.php';
    //header('Content-Type: application/json');    
    //SMTP needs accurate times, and the PHP time zone MUST be set
    //This should be done in your php.ini, but this is how to do it if you don't have access to that
    date_default_timezone_set('Etc/UTC');    
    if($_SERVER['REQUEST_METHOD'] == 'POST'){
        $firstName = filter_input('POST', 'firstName', FILTER_SANITIZE_STRING);
        $lastName = filter_input('POST', 'lastName', FILTER_SANITIZE_STRING);
        $emailAddress = filter_input('POST', 'emailAddress', FILTER_SANITIZE_EMAIL);
        $message = filter_input('POST', 'message', FILTER_SANITIZE_STRING);
        $website = filter_input('POST', 'website', FILTER_SANITIZE_URL);            
        $mail = new PHPMailer(true);
        $mail->Timeout       =   30; // set the timeout (seconds)
        //$mail->isSMTP();
        $mail->SMTPAuth   = true;                   // enable SMTP authentication
        $mail->SMTPSecure = "tls";                  // sets the prefix to the servier
        $mail->Host       = "smtp.live.com";        // sets hotmail as the SMTP server
        $mail->Port       = 587;                    // set the SMTP port for the hotmail server
        $mail->Username   = "jasonattin@hotmail.co.uk";      // hotmail username
        $mail->Password   = "xxxxx";           // hotmail password
        //$mail->setFrom($emailAddress, $firstName . ' ' . $lastName);  
        $mail->setFrom("test@gmail.com", "No reply");       
        $mail->addAddress('jasonattin@hotmail.co.uk', 'Giasone Attinio');
        $mail->Subject = 'New request';
        //$mail->Body = $message . "\r\n\r\nWebsite: " . $website; 
        $mail->Body = "First Name: " .$firstName . "\r\n\r\nLast Name: " . $lastName . "\r\n\r\nEmail address: " .$emailAddress . "\r\n\r\nMessage: " . $message . "\r\n\r\nWebsite: " . $website;     
        if(!$mail->send()){
            echo "Mailer Error: " . $mail->ErrorInfo;
        }
        else{
            echo "success";
        }
   }//end of if($_SERVER['REQUEST_METHOD'] == 'POST')
 ?>

Right, I think I might have found the problem. Reading through the php manual, it appears that when I use the filter_input method I shouldn't put the first parameter (type) in quotes like this
$website = filter_input('POST', 'website', FILTER_SANITIZE_URL); but it should instead be $website = filter_input(INPUT_POST, 'website', FILTER_SANITIZE_URL);.
I changed all of them to be

if($_SERVER['REQUEST_METHOD'] == 'POST'){
        $firstName = filter_input(INPUT_POST, 'firstName', FILTER_SANITIZE_STRING);
        $lastName = filter_input(INPUT_POST, 'lastName', FILTER_SANITIZE_STRING);
        $emailAddress = filter_input(INPUT_POST, 'emailAddress', FILTER_SANITIZE_EMAIL);
        $message = filter_input(INPUT_POST, 'message', FILTER_SANITIZE_STRING);
        $website = filter_input(INPUT_POST, 'website', FILTER_SANITIZE_URL);
        ...

And now the data in the email comes through OK, but please let me know if you think this amendment is right :-)
thanks

commented: it's ok! +14

Great! One thing though: at the moment I'm directing the emails to a hotmail email address, but that will change as soon as I get a new email address with the domain of the website - which will chage as well by the way. Everytime I get an email, it goes into the spam folder, even if I mark it to be "no spam": has this got something to do with this:
$mail->setFrom("test@gmail.com", "No reply");
thanks

Reading through the php manual, it appears that when I use the filter_input method I shouldn't put the first parameter (type) in quotes

My fault, sorry, I wrote it without checking the documentation and got confused with the syntax used in the Guzzle client... o_o'

Bye!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.