Ajax Contact Form with an Attachment (jQuery & PHP)
Today let's create an Ajax based contact form, that will allow users to send attachments in email message. This tutorial has been updated recently and is based on my recent post here. I've added Ajax part to the the example here, it will send form data without refreshing the page.Mark Up
In order to send file as an attachment, first we must allow users to upload file using contact form. As you can see I have added file input field called file_attach[] to our form, you can add as many file input field with same name for multiple attachments.HTML
- 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
<div id="contact_results"></div>
<form id="contact_form" method="post" action="contact_me.php">
<label for="name"><span>Name <span class="required">*</span></span>
<input type="text" name="name" data-required="true"/>
</label>
<label for="email"><span>Email <span class="required">*</span></span>
<input type="email" name="email" data-required="true"/>
</label>
<label><span>Phone <span class="required">*</span></span>
<input type="number" name="phone1" maxlength="3" placeholder="+91" />—
<input type="number" name="phone2" maxlength="15" data-required="true"/>
</label>
<label><span>Attachment</span>
<input type="file" name="file_attach[]" multiple/>
</label>
<label for="subject"><span>Regarding</span>
<select name="subject">
<option value="General Question">General Question</option>
<option value="Advertise">Advertisement</option>
<option value="Partnership">Partnership Oppertunity</option>
</select>
</label>
<label for="message"><span>Message <span class="required">*</span></span>
<textarea name="message" data-required="true"></textarea>
</label>
<label><span> </span>
<button type="submit">Submit</button>
</label>
</form>
jQuery Ajax Form Submit
Before we submit our form data to server using Ajax, we need to make sure input fields are not empty, and file type is allowable, and its size is not too big. For that we use HTML5 File API to read file data and validate it with our jQuery code. Once we validate our input fields, we can then send form data using jQuery $.ajax(). You can check-out my other post for more info about Ajax form submit.JQUERY
- 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
var allowed_file_size = "1048576"; //1 MB allowed file size
var allowed_file_types = [ 'image/png', 'image/gif', 'image/jpeg', 'image/pjpeg',
'application/x-zip-compressed', 'application/pdf', 'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
]; //Allowed file types
var border_color = "#C2C2C2"; //initial input border color
var maximum_files = 2; //Maximum number of files allowed
$("#contact_form").submit(function(e){
e.preventDefault(); //prevent default action
proceed = true;
//simple input validation
$($(this).find("input[data-required=true], textarea[data-required=true]")).each(function(){
if(!$.trim($(this).val())){ //if this field is empty
$(this).css('border-color','red'); //change border color to red
proceed = false; //set do not proceed flag
}
//check invalid email
var email_reg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
if($(this).attr("type")=="email" && !email_reg.test($.trim($(this).val()))){
$(this).css('border-color','red'); //change border color to red
proceed = false; //set do not proceed flag
}
}).on("input", function(){ //change border color to original
$(this).css('border-color', border_color);
});
//check file size and type before upload, works in all modern browsers
if(window.File && window.FileReader && window.FileList && window.Blob){
var total_files_size = 0;
if(this.elements['file_attach[]'].files.length > maximum_files){
alert( "Can not select more than "+maximum_files+" file(s)");
proceed = false;
}
$(this.elements['file_attach[]'].files).each(function(i, ifile){
if(ifile.value !== ""){ //continue only if file(s) are selected
if(allowed_file_types.indexOf(ifile.type) === -1){ //check unsupported file
alert( ifile.name + " is not allowed!");
proceed = false;
}
total_files_size = total_files_size + ifile.size; //add file size to total size
}
});
if(total_files_size > allowed_file_size){
alert( "Make sure total file size is less than 1 MB!");
proceed = false;
}
}
var post_url = $(this).attr("action"); //get form action url
var request_method = $(this).attr("method"); //get form GET/POST method
var form_data = new FormData(this); //Creates new FormData object
//if everything's ok, continue with Ajax form submit
if(proceed){
$.ajax({ //ajax form submit
url : post_url,
type: request_method,
data : form_data,
dataType : "json",
contentType: false,
cache: false,
processData:false
}).done(function(res){ //fetch server "json" messages when done
if(res.type == "error"){
$("#contact_results").html('<div class="error">'+ res.text +"</div>");
}
if(res.type == "done"){
$("#contact_results").html('<div class="success">'+ res.text +"</div>");
}
});
}
});
</script>
PHP mail
Below is the complete PHP code that sends mail with attachments, taken from my other post PHP mail with Multiple Attachments. We will do simple server-side validation and play with PHP $_FILES before attaching file to mail header. If there's no file uploaded for the attachment, we will simply switch to plain email.PHP
- 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
[email protected]"; //recepient
$from_email = "info@your_domain.com"; //from email using site domain.
if($_POST){
$sender_name = filter_var($_POST["name"], FILTER_SANITIZE_STRING); //capture sender name
$sender_email = filter_var($_POST["email"], FILTER_SANITIZE_STRING); //capture sender email
$country_code = filter_var($_POST["phone1"], FILTER_SANITIZE_NUMBER_INT);
$phone_number = filter_var($_POST["phone2"], FILTER_SANITIZE_NUMBER_INT);
$subject = filter_var($_POST["subject"], FILTER_SANITIZE_STRING);
$message = filter_var($_POST["message"], FILTER_SANITIZE_STRING); //capture message
$attachments = $_FILES['file_attach'];
//php validation, exit outputting json string
if(strlen($sender_name)<4){
print json_encode(array('type'=>'error', 'text' => 'Name is too short or empty!'));
exit;
}
if(!filter_var($sender_email, FILTER_VALIDATE_EMAIL)){ //email validation
print json_encode(array('type'=>'error', 'text' => 'Please enter a valid email!'));
exit;
}
if(!$phone_number){ //check for valid numbers in phone number field
print json_encode(array('type'=>'error', 'text' => 'Enter only digits in phone number'));
exit;
}
if(strlen($subject)<3){ //check emtpy subject
print json_encode(array('type'=>'error', 'text' => 'Subject is required'));
exit;
}
if(strlen($message)<3){ //check emtpy message
print json_encode(array('type'=>'error', 'text' => 'Too short message! Please enter something.'));
exit;
}
$file_count = count($attachments['name']); //count total files attached
$boundary = md5("sanwebe.com");
//construct a message body to be sent to recipient
$message_body = "Message from $sender_name\n";
$message_body .= "------------------------------\n";
$message_body .= "$message\n";
$message_body .= "------------------------------\n";
$message_body .= "$sender_name\n";
$message_body .= "$sender_email\n";
$message_body .= "$country_code$phone_number\n";
if($file_count > 0){ //if attachment exists
//header
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From:".$from_email."\r\n";
$headers .= "Reply-To: ".$sender_email."" . "\r\n";
$headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";
//message text
$body = "--$boundary\r\n";
$body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n\r\n";
$body .= chunk_split(base64_encode($message_body));
//attachments
for ($x = 0; $x < $file_count; $x++){
if(!empty($attachments['name'][$x])){
if($attachments['error'][$x]>0) //exit script and output error if we encounter any
{
$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" );
print json_encode( array('type'=>'error',$mymsg[$attachments['error'][$x]]) );
exit;
}
//get file info
$file_name = $attachments['name'][$x];
$file_size = $attachments['size'][$x];
$file_type = $attachments['type'][$x];
//read file
$handle = fopen($attachments['tmp_name'][$x], "r");
$content = fread($handle, $file_size);
fclose($handle);
$encoded_content = chunk_split(base64_encode($content)); //split into smaller chunks (RFC 2045)
$body .= "--$boundary\r\n";
$body .="Content-Type: $file_type; name=".$file_name."\r\n";
$body .="Content-Disposition: attachment; filename=".$file_name."\r\n";
$body .="Content-Transfer-Encoding: base64\r\n";
$body .="X-Attachment-Id: ".rand(1000,99999)."\r\n\r\n";
$body .= $encoded_content;
}
}
}else{ //send plain email otherwise
$headers = "From:".$from_email."\r\n".
"Reply-To: ".$sender_email. "\n" .
"X-Mailer: PHP/" . phpversion();
$body = $message_body;
}
$sentMail = mail($recipient_email, $subject, $body, $headers);
if($sentMail) //output success or failure messages
{
print json_encode(array('type'=>'done', 'text' => 'Thank you for your email'));
exit;
}else{
print json_encode(array('type'=>'error', 'text' => 'Could not send mail! Please check your PHP mail configuration.'));
exit;
}
}
<?php
$recipient_email = "