Today we are going to create an Ajax based contact
form, which will allow visitors to upload and attach a file to the
e-mail message. This example is based on my previous post (Simple Ajax Contact form), but here I have modified few things so that visitors can upload and attach file to email using contact form.
Take a look at the picture below, this is how our Ajax contact form is going to appear on the browser. Only difference here is the extra file input field, rest is exactly the same as previous example.
Take a look at the picture below, this is how our Ajax contact form is going to appear on the browser. Only difference here is the extra file input field, rest is exactly the same as previous example.
Mark Up
In order to send file as an attachment, first we must allow users to upload file using contact form. Let’s add file input field called “file_attach” to our markup along with other inputs. Notice we have <form> tag missing from the code? don’t worry we don’t need typical HTML form setting here, we can just collect fields value using jQuery .val() and files.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<fieldset id="contact_form">
<legend>My Contact Form</legend> <div id="result"></div> <label for="name"><span>Name</span> <input type="text" name="name" id="name" placeholder="Enter Your Name" /> </label> <label for="email"><span>Email Address</span> <input type="email" name="email" id="email" placeholder="Enter Your Email" /> </label> <label for="phone"><span>Phone</span> <input type="text" name="phone" id="phone" placeholder="Phone Number" /> </label> <label for="phone"><span>Attachment</span> <input type="file" name="file_attach" id="file_attach" /> </label> <label for="message"><span>Message</span> <textarea name="message" id="message" placeholder="Enter Your Name"></textarea> </label> <label><span> </span> <button class="submit_btn" id="submit_btn">Submit</button> <img src="ajax-loader.gif" class="loading-img" style="display:none"> </label> </fieldset> |
jQuery and Ajax
Let’s write some jQuery code for our contact form. The code below is similar to Simple Ajax Contact form, the difference is $.ajax(), we will be using jQuery $.ajax() instead of $.post(), simply because it has more options, and allows us to have more control while uploading file to the server.
1
2 3 4 5 6 7 8 9 10 11 |
$.ajax({
url: 'contact_me.php', data: post_data, contentType: false, processData: false, type: 'POST', dataType:'json', success: function(data){ //do stuff } }); |
But before sending data to the server using XMLHttpRequest, we need to build a FormData object appending fields to it by calling append() method. The transmitted data is sent in the same format that the form’s submit() method would use to send the data if the form’s encoding type were set to “multipart/form-data”.
1
2 3 4 5 6 7 |
//data to be sent to server
var post_data = new FormData(); post_data.append( 'userName', user_name ); post_data.append( 'userEmail', user_email ); post_data.append( 'userPhone', user_phone ); post_data.append( 'userMessage',user_message); post_data.append( 'file_attach', attach_file ); |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
$(document).ready(function() {
$("#submit_btn").click(function() { //get input field values var user_name = $('input[name=name]').val(); var user_email = $('input[name=email]').val(); var user_phone = $('input[name=phone]').val(); var attach_file = $('input[name=file_attach]')[0].files[0]; var user_message = $('textarea[name=message]').val(); //simple validation at client's end //we simply change border color to red if empty field using .css() var proceed = true; if(user_name==""){ $('input[name=name]').css('border-color','red'); proceed = false; } if(user_email==""){ $('input[name=email]').css('border-color','red'); proceed = false; } if(user_phone=="") { $('input[name=phone]').css('border-color','red'); proceed = false; } if(user_message=="") { $('textarea[name=message]').css('border-color','red'); proceed = false; } //everything looks good! proceed... if(proceed) { $(".loading-img").show(); //show loading image $(".submit_btn").hide(); //hide submit button //data to be sent to server var post_data = new FormData(); post_data.append( 'userName', user_name ); post_data.append( 'userEmail', user_email ); post_data.append( 'userPhone', user_phone ); post_data.append( 'userMessage',user_message); post_data.append( 'file_attach', attach_file ); //instead of $.post() we are using $.ajax() //that's because $.ajax() has more options and can be used more flexibly. $.ajax({ url: 'contact_me.php', data: post_data, processData: false, contentType: false, type: 'POST', dataType:'json', success: function(data){ //load json data from server and output message if(data.type == 'error') { output = '<div class="error">'+data.text+'</div>'; }else{ output = '<div class="success">'+data.text+'</div>'; //reset values in all input fields $('#contact_form input').val(''); $('#contact_form textarea').val(''); } $("#result").hide().html(output).slideDown(); //show results from server $(".loading-img").hide(); //hide loading image $(".submit_btn").show(); //show submit button } }); } }); //reset previously set border colors and hide all message on .keyup() $("#contact_form input, #contact_form textarea").keyup(function() { $("#contact_form input, #contact_form textarea").css('border-color',''); $("#result").slideUp(); }); }); |
PHP Email
In our PHP page which is contact_me.php, the most tricky part could be the Mail header, because while writing this tutorial I realized that most mail header examples (with attachment) just don’t work with most client. So I looked inside a working Gmail message source and borrowed it’s mail header for this tutorial. Here’s what I came up with.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php
# Mail headers should work with most clients (including thunderbird) $headers = "MIME-Version: 1.0\r\n"; $headers = "X-Mailer: PHP/" . phpversion()."\r\n"; $headers .= "From: SENDER_EMAIL@domain.com\r\n"; $headers .= "Subject: Email subject\r\n"; $headers .= "Reply-To: RECIPIENT_EMAIL@domain.com" . "\r\n"; $headers .= "Content-Type: multipart/mixed; boundary=".md5('boundary1')."\r\n\r\n"; $headers .= "--".md5('boundary1')."\r\n"; $headers .= "Content-Type: multipart/alternative; boundary=".md5('boundary2')."\r\n\r\n"; $headers .= "--".md5('boundary2')."\r\n"; $headers .= "Content-Type: text/plain; charset=ISO-8859-1\r\n\r\n"; $headers .= $user_Message."\r\n\r\n"; $headers .= "--".md5('boundary2')."--\r\n"; $headers .= "--".md5('boundary1')."\r\n"; $headers .= "Content-Type: ".$file_type."; "; $headers .= "name=\"".$file_name."\"\r\n"; $headers .= "Content-Transfer-Encoding:base64\r\n"; $headers .= "Content-Disposition:attachment; "; $headers .= "filename=\"".$file_name."\"\r\n"; $headers .= "X-Attachment-Id:".rand(1000,9000)."\r\n\r\n"; $headers .= $encoded_content."\r\n"; $headers .= "--".md5('boundary1')."--"; |
So here’s complete code of contact_me.php, we will do simple server-side validation and play with PHP $_FILES (HTTP File Upload variable) before attaching file to mail header. Since attachment may not be mandatory in most cases, we will just switch to plain email header if we do not find $_FILES['file_attach'] variable.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
<?php
if($_POST) { $to_Email = "recipient_email@example.com"; //Replace with recipient email address $subject = 'Ah!! My email from Somebody out there...'; //Subject line for emails //check if its an ajax request, exit if not if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') { //exit script outputting json data $output = json_encode( array( 'type'=>'error', 'text' => 'Request must come from Ajax' )); die($output); } //check $_POST vars are set, exit if any missing if(!isset($_POST["userName"]) || !isset($_POST["userEmail"]) || !isset($_POST["userPhone"]) || !isset($_POST["userMessage"])) { $output = json_encode(array('type'=>'error', 'text' => 'Input fields are empty!')); die($output); } //Sanitize input data using PHP filter_var(). $user_Name = filter_var($_POST["userName"], FILTER_SANITIZE_STRING); $user_Email = filter_var($_POST["userEmail"], FILTER_SANITIZE_EMAIL); $user_Phone = filter_var($_POST["userPhone"], FILTER_SANITIZE_STRING); $user_Message = filter_var($_POST["userMessage"], FILTER_SANITIZE_STRING); //additional php validation if(strlen($user_Name)<4) // If length is less than 4 it will throw an HTTP error. { $output = json_encode(array('type'=>'error', 'text' => 'Name is too short or empty!')); die($output); } if(!filter_var($user_Email, FILTER_VALIDATE_EMAIL)) //email validation { $output = json_encode(array('type'=>'error', 'text' => 'Please enter a valid email!')); die($output); } if(!is_numeric($user_Phone)) //check entered data is numbers { $output = json_encode(array('type'=>'error', 'text' => 'Only numbers allowed in phone field')); die($output); } if(strlen($user_Message)<5) //check emtpy message { $output = json_encode(array('type'=>'error', 'text' => 'Too short message! Please enter something.')); die($output); } ### Attachment Preparation ### $file_attached = false; //initially file is not attached if(isset($_FILES['file_attach'])) //check uploaded file { //get file details we need $file_tmp_name = $_FILES['file_attach']['tmp_name']; $file_name = $_FILES['file_attach']['name']; $file_size = $_FILES['file_attach']['size']; $file_type = $_FILES['file_attach']['type']; $file_error = $_FILES['file_attach']['error']; //exit script and output error if we encounter any if($file_error>0) { $mymsg = array( 1=>"The uploaded file exceeds the upload_max_filesize directive in php.ini", 2=>"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form", 3=>"The uploaded file was only partially uploaded", 4=>"No file was uploaded", 6=>"Missing a temporary folder" ); $output = json_encode(array('type'=>'error', 'text' => $mymsg[$file_error])); die($output); } //read from the uploaded file & base64_encode content for the mail $handle = fopen($file_tmp_name, "r"); $content = fread($handle, $file_size); fclose($handle); $encoded_content = chunk_split(base64_encode($content)); //now we know we have the file for attachment, set $file_attached to true $file_attached = true; } if($file_attached) //continue if we have the file { # Mail headers should work with most clients (including thunderbird) $headers = "MIME-Version: 1.0\r\n"; $headers .= "X-Mailer: PHP/" . phpversion()."\r\n"; $headers .= "From:".$user_Email."\r\n"; $headers .= "Subject:".$subject."\r\n"; $headers .= "Reply-To: ".$user_Email."" . "\r\n"; $headers .= "Content-Type: multipart/mixed; boundary=".md5('boundary1')."\r\n\r\n"; $headers .= "--".md5('boundary1')."\r\n"; $headers .= "Content-Type: multipart/alternative; boundary=".md5('boundary2')."\r\n\r\n"; $headers .= "--".md5('boundary2')."\r\n"; $headers .= "Content-Type: text/plain; charset=ISO-8859-1\r\n\r\n"; $headers .= $user_Message."\r\n\r\n"; $headers .= "--".md5('boundary2')."--\r\n"; $headers .= "--".md5('boundary1')."\r\n"; $headers .= "Content-Type: ".$file_type."; "; $headers .= "name=\"".$file_name."\"\r\n"; $headers .= "Content-Transfer-Encoding:base64\r\n"; $headers .= "Content-Disposition:attachment; "; $headers .= "filename=\"".$file_name."\"\r\n"; $headers .= "X-Attachment-Id:".rand(1000,9000)."\r\n\r\n"; $headers .= $encoded_content."\r\n"; $headers .= "--".md5('boundary1')."--"; }else{ # Mail headers for plain text mail $headers = 'From: '.$user_Email.'' . "\r\n" . 'Reply-To: '.$user_Email.'' . "\r\n" . 'X-Mailer: PHP/' . phpversion(); } //send the mail $sentMail = @mail($to_Email, $subject, $user_Message, $headers); if(!$sentMail) //output success or failure messages { $output = json_encode(array('type'=>'error', 'text' => 'Could not send mail! Please check your PHP mail configuration.')); die($output); }else{ $output = json_encode(array('type'=>'message', 'text' => 'Hi '.$user_Name .' Thank you for your email')); die($output); } } |
Download Script
0 comments:
Post a Comment