0
votes

This is for a live commercial project so any help is greatly appreciated.

I am relatively new to PHP and jQuery/Javascript so forgive me if most of what I have already is what you experts would deem... crap :)

  • My website is HTML only with a contact form that uses a PHP mail form (the contact form is on an HTML document still).
  • Using jQuery Validate, I have implemented client-side validation which works to a level that I am happy with.
  • I have also implemented server side validation and sanitization within the PHP form script.

While client and server side validations appear to be working together correctly, I'm suffering a mental block in how to display error messages generated by the server side PHP script.

Client slide jQuery validation works fine - I have an error message container DIV on the contact.html page which displays the correct error messages; however, for server side - when I hit submit, it goes loads contact-form.php in the browser and displays the error messages (or success message) - on a blank page.

What I want is any output error messages from the contact-form.php file to be displayed in the same error container DIV as the jQuery, without actually leaving the page.

The reason I am trying to do this is - if the user does not have javascript enabled, jQuery validator is obviously not going to work - but I still need the PHP error handling to be just as elegant as the jQuery handling.

Thank you for taking the time to read and advise.

Here is my code as it stands:

contact-form.php

<?php

$formType           = $_POST['formType'] ;

$sender_name            = $_POST['name'] ;
$sender_company     = $_POST['company'] ;
$sender_email           = $_POST['email'] ;
$sender_telephone       = $_POST['telephone'] ;
$sender_message     = $_POST['message'] ;

// Server Side Validation
// Error Messages
// Name
$errorMsg_Name_Empty            = "Please enter your name (cannot be empty). <br />" ; // isEmpty
$errorMsg_Name_Invalid          = "Please your name using valid characters only. <br />" ; // Contains illegal characters only
// Email
$errorMsg_Email_Invalid         = "Please enter a valid e-mail address. <br />" ;
$errorMsg_Email_Empty           = "Please enter your e-mail address (cannot be empty). <br />" ;
// Telephone
$errorMsg_Telephone_Invalid     = "Please enter a valid telephone number." ;
$errorMsg_Telephone_Empty       = "Please enter your telephone number (cannot be empty). <br />" ;
// Message
$errorMsg_Message               = "Please enter a message. Your message should be at least 30 and no more than 3000 characters in length. <br />" ;
// Human
$errorMsg_Human_Incorrect       = "You have not answered the simple maths question correctly! <br />" ;
// Callback Date
$errorMsg_callbackDate          = "Please enter a valid date for us to call you back on, formatted as dd/mm/yyyy (for example: 31/01/2103). <br />" ;
// Callback Time
$errorMsg_callbackTime          = "Please specify a time you would like us to call you back. <br />" ;



// Input: Name
if ( $sender_name != "") {
    $sender_name = substr(filter_var( $sender_name, FILTER_SANITIZE_STRING), 0,49) ;  
    if ( $sender_name == "" ) {  
        $errors .= $errorMsg_Name_Invalid ;
    }
} else {
    $errors .= $errorMsg_Name_Empty ;
} 

// Input: Company
if ( $sender_company != "") { 
    $sender_company = substr(filter_var( $sender_company, FILTER_SANITIZE_STRING),0,49);
}



// Input: Email
if ( $sender_email != "") {  
    $email_temp = filter_var( $sender_email, FILTER_SANITIZE_EMAIL); 
    if (!filter_var( $email_temp, FILTER_VALIDATE_EMAIL )) {  
        $errors .= $errorMsg_Email_Invalid ;
    }  
} else {  
    $errors .= $errorMsg_Email_Empty ;
}  


// Input: Telephone
if ( $sender_telephone != "") {
    $sender_telephone = filter_var($sender_telephone, FILTER_SANITIZE_NUMBER_INT);
    if ( strlen ( $sender_telephone ) < 11 || strlen ( $sender_telephone ) > 12 ) {
        $errors .= $errorMsg_Telephone_Invalid ;
    }
} else {
    $errors .= $errorMsg_Telephone_Empty ;
} 

// Input: Message
if ( $sender_message != "") {  
   $sender_message = filter_var($sender_message, FILTER_SANITIZE_STRING);  
    if ($sender_message == "") {  
        $errors .= $errorMsg_Message ;
    } elseif ( strlen ($sender_message) < 30 || strlen ($sender_message) > 3000 ) {
        $errors .= $errorMsg_Message ;
    }
} else {  
    $errors .= $errorMsg_Message ;
}

 // Human
if ($formType == "Message") { 
    $human = $_POST['human_message'] ; 
} elseif ( $formType == "Callback") {
    $human = $_POST['human_callback'] ;
} ;
$human_correctAnswer = '12' ;

// Input: Human
if ( $human != $human_correctAnswer) {
    $errors .= $errorMsg_Human_Incorrect ;
}
// Callback Specific
// If form type is "Callback", collect time/date input fields.
if ( $formType == "Callback" ) {
    $callback_date      = $_POST['callback_date'] ;
    $callback_time      = $_POST['callback_time'] ;

    //Callback date
    if ( $callback_date != "" ) {
        list ($day,$month,$year) = explode ("/" ,$callback_date );
        if ( (is_numeric($day)) || (is_numeric($month)) || (is_numeric($year)) ) {
            if (!checkdate($month, $day, $year))
                $errors .= $errorMsg_callbackDate ;
        } else {
            $errors .= $errorMsg_callbackDate ;
        }
    } else {
        $errors .= $errorMsg_callbackDate ;
    } ;

    //Callback Time
    if ( $callback_time == "" ) {
        $errors .= $errorMsg_callbackTime ;
    }

} 
// END Callback Specific


// If there are no errors - send the form.
if (!$errors) {

    $sender_ipAddress   = $_SERVER['REMOTE_ADDR'];
    $sender_browser     = $_SERVER['HTTP_USER_AGENT'];

    // E-mail headers
    $recipient_email    = "[email protected]" ;
    $headers            = "MIME-Version: 1.0" . "\r\n";
    $headers            .= "Content-type:text/html; charset: utf8" . "\r\n";
    $headers            .= "From: My Website\r\n"; 
    $headers            .= 'Reply-To: [email protected]' . "\r\n" ;

    // Setting the e-mail subject
    if ( $formType == "Message" ) {
        $subject            = "Message from the My website." ;
    } else {
        $subject            = "Callback request from the My website." ;
    };

    // For database scripting - replace new-line html with carriage return character - Array
    // Placeholders for array
    $sender_message_placeholders = array("\n") ;
    //Replace Values for array
    $sender_message_replaceValues = array("¶") ;
    // $sender_message stripped of new-lines, and replaced with nc-characters.
    $sender_message_stripped = str_replace($sender_message_placeholders, $sender_message_replaceValues, $sender_message) ;

    // Writing the e-mail body.
    if ( $formType == "Message") {
        $emailBody  = "

        <style type \"text/css\">
        body                            { font-family: Helvetica, Arial ; font-size: 16px ; line-height: 20px ; color: #5e5e5e }
        h1                              { font-size: 42px ; line-height: 42px ; color: #c1c1c1 }
        div.section                     { padding: 12px ; margin-bottom: 8px ; background-color: #f7f7f7 ; border: 1px solid #c8c8c8 }
        div.part                        { margin-bottom: 8px ; 1border: 1px solid blue }
        div.part:last-child             { margin-bottom: 0 }

        label                           { margin: 0 ; font-size: 13px ; line-height: 20px ; font-weight: bold ; color: #80a553  }
        p                               { margin: 0  }
        p.input-field#sender-message    { white-space: pre-line }

        div#dbImport                    { color: #a1a1a1!important  }
        div#dbImport p                  { font-size: 12px!important ; line-height: 14px ; white-space: normal!important }
        </style>
        </head> 

        <body>
        <html>

        <h1>Message</h1>

        <p class=\"input-field\" style=\"margin-bottom:12px\">A message has been sent from Mywebsite.  The message is as follows:</p>

        <div class=\"section\">     
            <div class=\"part\">
                <label>Contact Form Type:</label>
                <p class=\"input-field\">$formType</p>
            </div>
        </div>

        <div class=\"section\">     
            <div class=\"part\">
                <label>Name:</label>
                <p class=\"input-field\">$sender_name</p>
            </div><!-- !.part -->
            <div class=\"part\">
                <label>Company:</label>
                <p class=\"input-field\">$sender_company</p>
            </div><!-- !.part -->
            <div class=\"part\">
                <label>E-mail:</label>
                <p class=\"input-field\">$sender_email</p>
            </div><!-- !.part -->
            <div class=\"part\">        
                <label>Telephone:</label>
                <p class=\"input-field\">$sender_telephone</p>
            </div><!-- !.part -->
        </div><!-- !.section -->

        <div class=\"section\">     
            <div class=\"part\">
                <label>Message:</label>
                <p class=\"input-field\" id=\"sender-message\">$sender_message</p>
            </div><!-- !.part -->
        </div><!-- !.section -->

        <div class=\"section\" id=\"visitor-info\">
            <div class=\"part\">
                <label>Sender IP Address:</label>
                <p class=\"input-field\"><a href=\"http://network-tools.com/default.asp?prog=express&host=$sender_ipAddress\">$sender_ipAddress</a></p>
            </div><!-- !.part -->
            <div class=\"part\">
                <label>Sender Web Browser:</label>
                <p class=\"input-field\">$sender_browser</p>
            </div><!-- !.part -->
        </div><!-- !.section -->

        <div id=\"dbImport\">
            <p style=\"font-weight:bold\">IMPORTDB DATA</p>
            <p>NAME/COMPANY/EMAIL/TELEPHONE/MESSAGE/CALLBACK-DATE/CALLBACK-TIME</p>
            <p>#begin#$sender_name#$sender_company#$sender_email#$sender_telephone#$sender_message_stripped#end</p>
        </div>

        </body>
        </html>
    " ;
    } else { 
        $emailBody  = "

        <head>
        <style type \"text/css\">
        body                                { font-family: Helvetica, Arial ; font-size: 16px ; line-height: 20px ; color: #5e5e5e }
        h1                                  { font-size: 42px ; line-height: 42px ; color: #c1c1c1 }
        div.section                         { padding: 12px ; margin-bottom: 8px ; background-color: #f7f7f7 ; border: 1px solid #c8c8c8 }
        div.section#callback-details        { background-color: #f8e0e0 }
        div.section#callback-details label  { color: #df5c5c }
        div.part                            { margin-bottom: 8px }
        div.part:last-child                 { margin-bottom: 0 }

        label                               { margin: 0 ; font-size: 13px ; line-height: 20px ; font-weight: bold ; color: #80a553  }
        p                                   { margin: 0  }
        p.input-field#sender-message        { white-space: pre-line }

        div#dbImport                        { color: #a1a1a1!important  }
        div#dbImport p                      { font-size: 12px!important ; line-height: 19px ; white-space: normal!important }
        </style>
        </head> 

        <body>
        <html>

        <h1>Callback Request</h1>

        <p class=\"input-field\" style=\"margin-bottom:12px\">A callback request has been sent from mywebsite.  The callback details are as follows:</p>

        <div class=\"section\">     
            <div class=\"part\">
                <label>Contact Form Type:</label>
                <p class=\"input-field\">$formType</p>
            </div>
        </div>

        <div class=\"section\" id=\"callback-details\">     
            <div class=\"part\">
                <label>Callback Date:</label>
                <p class=\"input-field\">$callback_date</p>
            </div><!-- !.part -->
            <div class=\"part\">
                <label>Callback Time:</label>
                <p class=\"input-field\">$callback_time</p>
            </div><!-- !.part -->
        </div><!-- !.section -->

        <div class=\"section\">     
            <div class=\"part\">
                <label>Name:</label>
                <p class=\"input-field\">$sender_name</p>
            </div><!-- !.part -->
            <div class=\"part\">
                <label>Company:</label>
                <p class=\"input-field\">$sender_company</p>
            </div><!-- !.part -->
            <div class=\"part\">
                <label>E-mail:</label>
                <p class=\"input-field\">$sender_email</p>
            </div><!-- !.part -->
            <div class=\"part\">        
                <label>Telephone:</label>
                <p class=\"input-field\">$sender_telephone</p>
            </div><!-- !.part -->
        </div><!-- !.section -->

        <div class=\"section\">     
            <div class=\"part\">
                <label>Message:</label>
                <p class=\"input-field\" id=\"sender-message\">$sender_message</p>
            </div><!-- !.part -->
        </div><!-- !.section -->

        <div class=\"section\" id=\"visitor-info\">
            <div class=\"part\">
                <label>Sender IP Address:</label>
                <p class=\"input-field\"><a href=\"http://network-tools.com/default.asp?prog=express&host=$sender_ipAddress\">$sender_ipAddress</a></p>
            </div><!-- !.part -->
            <div class=\"part\">
                <label>Sender Web Browser:</label>
                <p class=\"input-field\">$sender_browser</p>
            </div><!-- !.part -->
        </div><!-- !.section -->

        <div id=\"dbImport\">
            <p style=\"font-weight:bold\">IMPORTDB DATA</p>
            <p>NAME/COMPANY/EMAIL/TELEPHONE/MESSAGE/CALLBACK-DATE/CALLBACK-TIME</p>
            <p>#begin#$sender_name#$sender_company#$sender_email#$sender_telephone#$sender_message_stripped#$callback_date#$callback_time#end</p>
        </div>

        </body>
        </html>

        " ;
    } ;
    // End e-mail bodies


    /* Send the message using mail() function */
    mail($recipient_email, $subject, $emailBody, $headers) ;

    // The message to display in the contact form success div
    if ( $formType == "Message") {
        print "
        <h4>Your message has been sent.  Thank you.</h4>
        <hr>
        <p>Someone will get back to you very shortly.  We aim to respond to all messages within 24 hours.  If your enquiry is super-duper-urgent, why not give us a ring?</p>
        " ;
    } else {
        print "
        <h4>Your request has been sent.  Thank you.</h4>
        <hr>
        <h5>A note about our callback service.</h5>
        <p>Sometimes life throws you a curve-ball that really mucks up your plans.</p>

        <p>In the event that we encounter one of said curve-balls and we're unable to callback when you requested, we will, where possible, get in touch and make arrangements for us
        to call back at another time convenient to you.</p>" ;
    } ;
    // end 'if there are no errors'

} else {  // if there are errors with the users inputs

    echo '
    There was a problem with the information you have tried to submit:
    <div style="color: red ; font-size: 22px ; line-height: 28px">' . $errors . '<br/></div>
    Please go back, check the information and try again.';  
}  
?>

the contact.html file Please note: there are actually 2 forms on the same page - one is a message form and one is a callback request form - they are on jQuery tabs. I have included HTML markup for just one form.

As you can see there is an errorContainer DIV which is where jQuery validation error messages appear, and where I would like the error messages generated from the PHP script to display.

<form id="form-callback" method="post" action="contact-form.php" class="clearfix">
                        <input name="formType" id="formType" value="Callback">
                        <div id="errorContainer-callback" class="errorContainer">
                            <b>Oops... it looks like there is a problem with the data you have entered into the form.  Please correct the following errors:</b>
                            <ul />
                        </div><!--  !#errorContainer-callback  -->
                        <!--  BEGIN 4 INPUT FIELDS  -->
                        <div id="input-fields">
                            <div id="name-company">
                                <label>Name</label>
                                    <input name="name" tabindex="1">
                                <label>Company</label>
                                    <input name="company" tabindex="2">
                            </div><!--  ! #name-company -->
                            <div id="email-telephone">
                                <label>Email</label>
                                    <input name="email" tabindex="3">
                                <label>Telephone</label>
                                    <input name="telephone" tabindex="4">
                            </div><!--  ! #email-telephone  -->
                        </div><!--  ! #input-fields  -->
                        <!--  BEGIN MESSAGE CELL  -->
                        <div id="message">
                            <label>Tell us a little about what you'd like talk about when we call you back.</label>
                            <textarea name="message" tabindex="5"></textarea>
                        </div><!--  ! #message  -->
                        <div class="clearfix"></div>
                        <!-- BEGIN Bottom of Form (Date/Time/Human/Button)  -->
                        <div id="end">
                            <!-- BEGIN DATE  -->
                            <div id="cell1" class="cell">
                                <label>When would you like us to get back to you?</label>
                                <div>
                                    <input placeholder="Date" name="callback_date" type="date" id="callback-date" tabindex="6">
                                </div><!--  ! date input container  -->
                                <!-- BEGIN CELL-TIME  -->
                                <div>
                                    Time
                                    <select id="callback-time" name="callback_time" tabindex="7">
                                        <option value="" selected="selected"></option>
                                        <option value="0900-1100">09:00-11:00</option>
                                        <option value="1100-1300">11:00-13:00</option>
                                        <option value="1300-1500">13:00-15:00</option>
                                        <option value="1500-1700">15:00-17:00</option>
                                    </select>
                                </div><!--  ! subcell -->

                            </div><!-- ! #cell1 -->
                            <!-- BEGIN CELL-HUMANCHECK  -->
                            <div id="cell2" class="cell human-check">
                                <label><b> What is 3 + 9</b></label>
                                <input id="human-result-callback" class="human" name="human_callback" type="number" maxlength="2" tabindex="8" />
                            </div><!-- ! #cell2 .cell -->
                            <!-- BEGIN CELL-BUTTON  -->
                            <div id="cell3" class="cell">
                                <input class="button" id="submit" name="submit" type="submit" value="Send Your Request">
                            </div><!-- ! #cell3 .cell -->
                        </div><!--  ! #end  -->                     
                    </form><!--  ! form#form-callback  -->
1
Are the html form and the php code in the same file contact-form.php?MaveRick
No, the contact form is on an HTML file, separate from the contact-form.php. The PHP file is basically just doing the donkey work.user2705521
So if you need to return the error message to the same html page to be outputted in the same container that your jquery using then you have to include some php code in your html page. the proper thing to do is to use ajax to submit your form and return php outputs to the same results container in your html page but you are saying you need a page that works with no java and return the results to the same container which impossible with 2 files and no java!MaveRick
Agh. So do i need to be looking at including the html and php code on the same page? Would that then become a php file? i.e. would contact.html become contact.php? Sorry - as I said I am still learning a lot about all this.user2705521
Out of interest - does anyone have any comment on the code I have in place, i.e. is it largely ok? Or could it be done so much better?user2705521

1 Answers

0
votes

What I normally do is:

  1. Validate on client side
  2. If everything is ok check on server. I include server validation script before the form in generated on same page.
  3. Have a boolean flag start with may be true.
  4. If error is encountered change boolean flag to false.
  5. Now if boolean flag is true it will redirect to appropriate page or it will show the form again.
  6. If on success or or fail both will show the form, depending upon the boolean flag, I set the error div to not display with css property that can be later changed from javscript while doing validation.

This is just a simple general idea.