Hi! Xin chào các bạn, mình là Mr.Nav, hôm nay mình sẽ hướng dẫn các bạn cách tạo một Contact Form với Jquery AJAX + PHP. Đây là tuts đầu tiên do mình viết nếu có thiếu sót gì các bạn góp ý để mình hoàn thiện hơn trong các bài sau. Mình sẽ cố gắng viết rõ ràng để các bạn tiện theo dỗi và nắm bắt được code trong bài.

Để tiện cho việc tiếp thu bài này, các bạn cần biết PHP căn bản và các bạn hãy xem thêm các tuts AJAX đầu tiên do bạn KytoSai viết.

Mọi thắc mắc các bạn có thể gửi mail cho mình: mr.nav90@gmail.com hoặc các bạn comment ở dưới mình sẽ support cho các bạn nhanh nhất có thể, nào chúng ta cùng bắt đầu ^^

#Step 1 – Setup HTML

<?php session_start(); ?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>Jquery AJAX Contact Form With PHP</title>
	<link rel="stylesheet" type="text/css" href="css/reset.css" media="all">
	<link rel="stylesheet" type="text/css" href="css/style.css" media="all">
	<script type="text/javascript" src="js/jquery.1.7.2.min.js"></script>
	<script type="text/javascript" src="js/AJAX.js"></script> 
</head>
<body>
	<div id="wrapper">
		<div id="container">
			<h1>Jquery AJAX Contact Form With PHP<span class="arrow"></span></h1>
			<div id="loading"></div>
			<form action="" method="POST">
				<div id="success">Thanks your contact me !!!</div>
				<div id="error">Error !!! Can not sending Email.</div>
				<p>
				<input type="text" id="name" name="name" placeholder="Please insert your Name" required="">
				<div class="warning" id="nameError">Vui lòng nhập tên của bạn</div>
				</p>

				<p>
				<input type="email" id="email" name="email" placeholder="Please insert your Email" required="">
				<div class="warning" id="emailError">Email không hợp lệ</div>
				</p>

				<p>
				<input type="url" id="website" name="website" placeholder="Please insert your Website" required="">
				<div class="warning" id="websiteError">Vui lòng nhập Website của bạn</div>
				</p>

				<p>
				<input type="text" id="subject" name="subject" placeholder="Please insert your Subject" required="">
				<div class="warning" id="subjectError">Vui lòng nhập tiêu đề</div>
				</p>

				<p>
				<textarea id="content" name="content" placeholder="Please insert your Message" required="" ></textarea>
				<div class="warning" id="contentError">Vui lòng nhập nội dung</div>
				</p>

				<p>
				<input type="text" id="captcha" name="captcha" placeholder="Please insert Captcha" required="" alt="Security Code">
				<img src="captcha.php" id="img_captcha">
				<img src="images/load.png" id="load_captcha">
				<div class="warning" id="captchaError">Vui lòng nhập Captcha</div>
				</p>

				<p>
				<input type="submit" id="SendMail" value="Send Mail">
				</p>

			</form>
		</div><!-- End #container -->
	</div><!-- End #wrapper -->
</body>
</html>

Các thuộc tính HTML5 mình dùng trong bài mình sẽ giới thiệu lại cho các bạn nào mới làm quen với HTML5.

  • Required => Bắt buộc bạn nhập vào hộp thoại input trước khi submit
  • Placeholder => Tạo một đoạn text mờ trong input
  • Type: Email => Định dạng input nhập vào phải là một Email hợp lệ
  • Type:Url => Định dạng input nhập vào phải là một đường dẫn hợp lệ

#Step 2 – CSS

html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent;margin:0;padding:0;}body{line-height:1;}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block;}nav ul{list-style:none;}blockquote,q{quotes:none;}blockquote:before,blockquote:after,q:before,q:after{content:none;}a{font-size:100%;vertical-align:baseline;background:transparent;margin:0;padding:0;}ins{background-color:#ff9;color:#000;text-decoration:none;}mark{background-color:#ff9;color:#000;font-style:italic;font-weight:700;}del{text-decoration:line-through;}abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help;}table{border-collapse:collapse;border-spacing:0;}hr{ /* display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0; */}input,select{vertical-align:middle;}

*{margin:0; padding:0;}

@font-face { 
	font-family: 'UTM Avo';
	src:url('../font/UTM-Avo.ttf') format('truetype')
}

#wrapper {
		width: 1000px;
		margin: 0 auto; 
}

#container {
  	width: 450px;
  	background: #ebebeb;
  	border: 1px solid #d4d4d4;
		margin-left: 300px;
    margin-top: 10px;
    position: relative;
}

#container h1 {
		margin-top: 20px;
		background: -moz-linear-gradient(top,#E3654C,#B85140);
    background: -webkit-linear-gradient(top,#E3654C,#B85140);
  	padding: 10px 20px;
  	margin-left: -20px;
  	width: 70%;
  	color: #fff;
		font-family: UTM Avo;
  	position: relative;
  	box-shadow: 1px 1px 1px #292929;
  	-moz-box-shadow: 1px 1px 1px #292929;
  	-webkit-box-shadow: 1px 1px 1px #292929;
    text-shadow: 0px 1px 0px #333;
}

.arrow {
		width: 0; height: 0;
  	line-height: 0;
  	border-left: 20px solid transparent;
  	border-top: 10px solid #ac0202;
  	position: absolute;
  	top: 100%;
  	left: 0px;
}

#container form {
		margin: 20px 20px 0px 20px;  
}

#container div#loading {
    position: absolute;
    top: 130px;
    right: 40px;
}

#container form div#success {
    border: 1px solid green;
    color: green;
    padding: 5px;
    width: 170px;
    margin-bottom: 10px;
    display: none;
}

#container form div#error {
    border: 1px solid red;
    color: #333;
    padding: 5px;
    width: 200px;
    margin-bottom: 10px;
    display: none;
}

#container form p {
		padding-bottom: 10px;  
}

#container form input {
		width: 250px;
		height: 30px;
		font-family: UTM Avo;
  	padding: 0px 10px;
}

#container form div.warning {
    border: 1px solid #777;
    padding: 5px;
    width: 200px;
    color: red;
    display: none;
}

#container form input#captcha {
		width: 205px;
		float: left; 
}

#container form img {
		margin: 0px 10px;
		border: 1px solid #A7A6AA;  
}

#container form img#img_captcha {
		float: left;  
}

#container form img#load_captcha {
		background: #fff;
		padding: 4px;  
  	margin: 0px;
    cursor: pointer;
}

#container form textarea {
		resize: none;
		width: 385px;
		height: 120px; 
  	padding: 10px;
  	font-family: UTM Avo;
  	font-size: 14px;
}

#container form input[type="submit"] {
  	width: 120px;
  	font-weight: bold;
  	font-family: UTM Avo;
 		border: 1px solid #A7A6AA;
  	background: -moz-linear-gradient(top,#fff,#d4d4d4);
  	background: -webkit-linear-gradient(top,#fff,#d4d4d4);
}

Sau khi xong 2 phần HTML & CSS các bạn có thể xem demo bên dưới

#Step 3 – Create Captcha

<?php 
	session_start();
	$captcha = imagecreate(125, 32);
	$bg = imagecolorallocate($captcha, 255, 255, 255);
	$font_color = imagecolorallocate($captcha, 106, 189, 197);
	$font = "font/UTM-Avo.ttf";

	$string = md5(microtime() * mktime());
	$text = substr($string,0,7);
	$_SESSION['security_code'] = $text;

	imagettftext($captcha, 20, 0, 5, 25, $font_color, $font, $text);
	header("Content-type: image/png"); 
	imagepng($captcha);
	imagedestroy($captcha);
?>

Nếu các bạn xem chưa hiểu thì các bạn hãy xem lại video của anh Demon Warlock hướng dẫn cách tạo Captcha nhé Cách tạo captcha

#Step 4 – Send Mail

<?php 
	session_start();
	if($_SESSION['security_code'] == $_POST['captcha']) {
		$name = $_POST['name'];
		$email = $_POST['email'];
		$website = $_POST['website'];
		$subject = $_POST['subject'];
		$content = $_POST['content'];

		$to = "contact.email.example@gmail.com";

		$body = "Ngày: ". date('d/m/Y')."n";
		$body .= $name . "- Email:" . $email . "n";
		$body .= "Website: $websiten";
		$body .= "Send a Email with content:n".nl2br($content);
		$headers = "From: $email n";

		mail($to, $subject, $body, $headers);
		echo "true";

	} else {
		echo "false";
	}

?>

Tớ giải thích một chút trong này nhé, ban đầu mình sẽ kiểm tra xem captcha đã nhập đúng hay chưa, đoạn text trong cái hình captcha chúng ta đã lưu nó lại vào một SESSION có tên là: security_code và input của mình sẽ là: captcha. Nếu hai cái này bằng nhau thì mình sẽ thực hiện công việc ở trong này.

– Lấy giá trị các input được nhập, và cho vào nội dung, trong này mình có sử dụng “n” nghĩa là xuống một hàng và hàm nl2br dùng để tự động xuống hàng khi trong nội dung họ gõ text xuống hàng.

Sau đó chúng ta thực hiện send mail với nội dung trên và lưu ý điểm quan trọng cuối cùng đó là kết quả trả về để chúng ta sử dụng AJAX.

Sau khi send mail xong sẽ echo “true” và ngược lại của hàm If sẽ echo “false”
Chuỗi “true” và “false” chính là kết quả trả về.

Sau khi xong phần PHP cho form chúng ta có thể xem kết quả ở dưới

#Step 5 – Jquery

Bây giờ chúng ta sẽ áp dụng jQuery vào cho Form

$(document).ready(function() {
            $("#SendMail").click(function() {
                    var name = $("#name").val();
                    var email = $("#email").val();
                    var website = $("#website").val();
                    var subject = $("#subject").val();
                    var content = $("#content").val();
                    var captcha = $("#captcha").val();
                    var email_regex = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/;
                   var data_string = 'name=' + name + '&email=' + email + '&website=' + website + '&subject=' + subject + '&content=' + content + '&captcha=' + captcha;
	});
});

Giải thích đoạn code trên có ý nghĩa thế này, khi Form được submit thì chúng ta sẽ lấy giá trị của Form bằng Jquery, chúng ta lấy giá trị của nó thông qua id của input các bạn có thể xem trong phần HTML.
Sau đó ta có 1 biến kiểm tra Email, thì cái này là một chuỗi check định dạng Email, đoạn này các bạn copy vào luôn cũng được, giải thích thì khó hiểu lắm.

Tiếp đến chúng ta sẽ lưu tất cả các giá trị mà mình lấy được vào biến data_string. Lưu ý ở đây là các chuỗi trong cặp dấu ‘ ‘ là name của input trong Form nhé, trong Jquery muốn nối một chuỗi thì mình dùng dấu ‘+’
Tiếp theo chúng ta sẽ dùng Jquery để kiểm tra giá trị trong Form xem người dùng nhập đầy đủ hay chưa.

if(name == "") {
	$("#nameError").slideDown('slow').delay(1000).slideUp('slow');
	$("#name").focus();
	return false;
       }
        if(!email_regex.test(email) || email == "") {
               $("#emailError").slideDown('slow').delay(1000).slideUp('slow');
              $("#email").focus()
              return false;
        }
       if(website == "") {
               $("#websiteError").slideDown('slow').delay(1000).slideUp('slow');
               $("#website").focus()
              return false;
       }

        if(subject == "") {
               $("#subjectError").slideDown('slow').delay(1000).slideUp('slow');
               $("#subject").focus();
               return false;
        }
        if(content == "") {
                $("#contentError").slideDown('slow').delay(1000).slideUp('slow');
               $("#content").focus()
               return false;
       }
        if(captcha == "") {
                $("#captchaError").slideDown('slow').delay(1000).slideUp('slow');
               $("#captcha").focus()
              return false;
       }        

Trong đoạn Jquery trên, chúng ta sẽ kiểm tra xem nếu các input rỗng thì sẽ dùng Jquery để hiển thị lỗi của nó ra. Ở trong phần HTML mình đã đặt một div ngay ở dưới mỗi input có id tương ứng với mỗi input, trong CSS mình đã cho nó display: none. Mình sử dụng hàm slideDown để show lỗi của input ra, tham số ‘slow’ => chậm, các bạn có thể đổi thành ‘fast’ => nhanh hay các con số 400, 500 hay 800 thì tùy ý các bạn.

Delay(1000) tức là nó sẽ dừng lại trong 1s, nó tính thế này: 1000 => 1s, 60000 => 1p .. thì chúng ta sẽ cho nó slideUp ẩn nó đi và đồng thời trỏ con chuột vào ô input chưa nhập và return false nó luôn.
Tiếp theo chúng ta sẽ viết thêm 2 Function nữa đó là:

Clear Form => Xóa các giá trị vừa nhập khi gửi mail thành công

function clear_form() {
            $("#name").val('');
            $("#email").val('');
            $("#website").val('');
           $("#subject").val('');
           $("#content").val('');
           $("#captcha").val('');
}

Change Captcha => Thay đổi hình ảnh Captcha

function change_captcha() {
	document.getElementById('img_captcha').src="captcha.php?rnd=" + Math.random();
}

Giải thích một chút ở đây có nghĩa là cái hình Captcha của chúng ta sẽ có id là img_captcha mình sẽ hướng tới nó thông qua id và trỏ nó tới đường dẫn file captcha với tham số rnd là ngẫu nhiên nối với hàm Math.random để tạo một chuỗi mới.

Trong Form chúng ta có một cái hình để load Captcha mới với id là #load_captcha thì chúng ta sẽ xử lý nó khi được click thì chúng ta sẽ gọi hàm change_captcha(); mình vừa viết ở trên.

$("#load_captcha").click(function() {
	change_captcha();
});

#Step 6 – AJAX

$("#loading").html("<img src='images/loading.gif'/>").fadeIn('fast');
$.ajax({
	type: "POST",
	url: "sendmail.php",
	data: data_string,
	success: function(data_form) {
	         if(data_form == "true") {
	        $('#loading').fadeOut('fast');
                       $("#success").slideDown('slow').delay(3000).slideUp('slow');
                       clear_form();
                       change_captcha();
                       } else {
	        $('#loading').fadeOut('fast');
                      $("#error").slideDown('slow').delay(3000).slideUp('slow');
                     }
               }
 });
return false;

Khi Form được nhập đầy đủ và được submit thì mình sẽ cho hiển thị cái hình dạng load dữ liệu ra. Và sau đó gọi AJAX để thực hiện công việc chính của Form như sau:

  • Type: “POST” => Phương thức mình sử dụng ở đây là POST
  • Url: “sendmail.php” => Đường dẫn tới file sendmail.php
  • Data: data_string => Lúc ở đoạn Jquery ở trên kia chúng ta đã lấy giá trị của Form và lưu vào biến này, bây giờ mình sẽ sử dụng biến này để gửi giá trị tới file sendmail.php để xử lý.
  • Success: function(data_form) => Khi Form được gửi thành công thì chúng ta sẽ thực hiện hàm data_form.

Ở đây chính là bước quan trọng, các bạn còn nhớ trong file sendmail.php chúng ta đã trả về kết quả là gì không ? Đó chính là 2 chuỗi “true” và “false”

Bây giờ chúng ta sẽ thực hiện so sánh nó, nếu nó là “true” tức là bạn đã gữi được mail thì chúng ta sẽ ẩn cái trạng thái Loading đi và đồng thời show ra thông báo gửi mail thành công và gọi hàm clear_form(); để xóa dữ liệu trên Form + hàm change_captcha(); để thay đổi captcha cho Form để có thể bắt đầu gửi một Email mới. Và ngược lại thì kết quả trả về của chúng ta chính là “false” thì mình sẽ ẩn trạng thái Loading và show lỗi ra thôi và return false nó luôn.

Các bạn có thể xem Code đầy đủ của file js đầy đủ ở đây.

$(document).ready(function() {
	$("#SendMail").click(function() {
		var name = $("#name").val();
		var email = $("#email").val();
		var website = $("#website").val();
		var subject = $("#subject").val();
		var content = $("#content").val();
		var captcha = $("#captcha").val();
		var email_regex = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/;
		var data_string = 'name=' + name + '&email=' + email + '&website=' + website + '&subject=' + subject + '&content=' + content + '&captcha=' + captcha; 
		
		if(name == "") {
           $("#nameError").slideDown('slow').delay(1000).slideUp('slow');
           $("#name").focus();
           return false;
        }

        if(!email_regex.test(email) || email == "") {
           $("#emailError").slideDown('slow').delay(1000).slideUp('slow');
           $("#email").focus()
           return false;
        }

        if(website == "") {
           $("#websiteError").slideDown('slow').delay(1000).slideUp('slow');
           $("#website").focus()
           return false;
        }

        if(subject == "") {
           $("#subjectError").slideDown('slow').delay(1000).slideUp('slow');
           $("#subject").focus();
           return false;
        }

        if(content == "") {
           $("#contentError").slideDown('slow').delay(1000).slideUp('slow');
           $("#content").focus()
           return false;
        }

        if(captcha == "") {
           $("#captchaError").slideDown('slow').delay(1000).slideUp('slow');
           $("#captcha").focus()
           return false;
        }

        $("#loading").html("<img src='images/loading.gif'/>").fadeIn('fast');
            $.ajax({
                type: "POST",
                url: "sendmail.php",
                data: data_string,
                success: function(data_form) {
                    if(data_form == "true") {
                        $('#loading').fadeOut('fast');
                        $("#success").slideDown('slow').delay(3000).slideUp('slow');
                            clear_form();
                            change_captcha();
                    } else {
                        $('#loading').fadeOut('fast');
                        $("#error").slideDown('slow').delay(3000).slideUp('slow');
                        }
                    }
                });
        return false;

	});

	function clear_form() {
        $("#name").val('');
        $("#email").val('');
        $("#website").val('');
        $("#subject").val('');
        $("#content").val('');
        $("#captcha").val('');
    }

    $("#load_captcha").click(function() {
        change_captcha();
    });

    function change_captcha() {
        document.getElementById('img_captcha').src="captcha.php?rnd=" + Math.random();
    }
});

Vậy là chúng ta đã hoàn thành một Contact Form sử dụng Jquery AJAX + PHP rồi ^^. Tớ mong các bạn có thể áp dụng được nó vào project của chính mình.