کد جاوا اسکریپت سیستم امتیازدهی
قبل از هر چیز ما به واسطه ای نیاز داریم که بتواند بدون رفرش شدن صفحه، درخواست کاربر را به سرور منتقل کرده و پاسخ سرور را دریافت، پردازش و در صورت نیاز خروجی دهد، این واسطه در اکثر موارد چیزی نیست به جزء آژاکس و جاوا اسکریپت (یا فریم ورک های مبتنی بر آن مانند جی کئوری) که در زیر یک نمونه از آن را ملاحظه می کنید.
<script type="text/javascript">
//<![CDATA[
function voting(action,id){
var up_point_id = "up_point_" + id;
var down_point_id = "down_point_" + id;
var loading_id = "loading_img_" + id;
var loading = <img src="loading.gif" alt="loading" height="16" width="16" border="0" />;
if (action == up){
var user_point = document.getElementById(up_point_id).innerHTML;
}
else if (action == down){
var user_point = document.getElementById(down_point_id).innerHTML;
}
var xmlhttp;
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
else{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState > 0 && xmlhttp.readyState < 4){
document.getElementById(loading_id).innerHTML=loading;
}
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById(loading_id).innerHTML=;
var response = xmlhttp.responseText;
var splited_response = response.split("||");
var status = splited_response[0];
var new_point = splited_response[1];
if (action == up && status == ok){
document.getElementById(up_point_id).innerHTML=new_point;
}
else if (action == down && status == ok){
document.getElementById(down_point_id).innerHTML=new_point;
}
}
}
var req = "vote.php?do=" + action + "&user=" + id + "&point=" + user_point;
xmlhttp.open("GET",req,true);
xmlhttp.send();
}
//]]>
</script>
توضیح:
- در کد بالا ما صرفا از برنامه نویسی ساده جاوا اسکریپت و آژاکس استفاده کرده ایم که این کار موجب کاهش چشمگیر حجم نهایی صفحات وب می شود.
- تابعی که از آن استفاده کرده ایم، voting نام دارد که البته یک نام دلخواه و فرضی است، این تابع از دو آرگومان استفاده می کند، آرگومان اول (action) مشخص می کند که آیا کاربر قصد دادن امتیاز منفی را دارد یا اینکه می خواهد امتیاز مثبت بدهد، مقادیر آرگومان در هنگام فراخوانی تابع با عبارات up یا down مشخص می شوند.
- آرگومان دوم برای این است که کاربران مختلف را در صفحه از هم متمایز کنیم، در اینجا می توان از تکنیک های زیادی بسته به سلیقه استفاده کرد، به طور مثال ما از نام کاربران برای آرگومان دوم استفاده کرده ایم و برای هر کاربر نیز، نام او را به انتهای عنوان آی دی بلاک ها اضافه نموده ایم، به این ترتیب سیستم ما قادر خواهد بود که هر کاربر را به طور مجزا شناسایی کند، البته در عمل برای ایجاد چنین مواردی می توان در هنگام خروجی گرفتن، لیست کاربران را از دیتابیس استخراج و در حلقه foreach یا for به صورت داینامیک چاپ کرد.
- در قسمت اول تابع voting چند متغیر تعریف می کنیم که در ادامه به آنها نیاز خواهیم داشت، به فرض متغیر up_point_id از پیوستن پیش عبارت _up_point به آرگومان id برای هر کاربر به صورت داینامیک، آی دی اختصاصی بلاک او را برای امتیازات مثبت تعریف می کند، یا متغیر loading_id به همین ترتیب مشخص می کند که تصویر کوچک نمایش در حال بارگذاری باید برای کدام کاربر به نمایش درآید.
- در گام بعدی چون در اینجا ما از دیتابیس استفاده نمی کنیم، ناچاریم امتیازات فعلی را از صفحه حاضر دریافت کنیم، لذا یک متغیر با نام user_point تعریف می کنیم که وظیفه اش گرفتن محتوای درون بلاک up_point_id یا down_point_id است، این مقدار به سرور ارسال شده و (در این مثال) با عدد 1 جمع می شود، نهایتا نیز حاصل با xmlhttp.responseText بازگشت داده می شود.
- همان طور که در آموزش های مقدماتی آژاکس (Ajax) گفته ایم، پس از ارسال درخواست آژاکسی، xmlhttp.readyState در چند وضعیت قرار می گیرد که با اعداد 0 تا 4 دریافت می شوند، بدین شرح:
عدد 0 به معنی حالت عادی و عدم درخواست آژاکس است.
عدد 1 به معنی شروع درخواست آژاکس است.
عدد 2 به معنی دریافت درخواست آژاکس توسط سرور است.
عدد 3 به معنی در حال پردازش بودن درخواست آژاکس است.
عدد 4 به معنی تکمیل درخواست و آماده بودن پاسخ آن است.
لذا بین عدد 0 تا 4 می توان یک تصویر کوچک به عنوان در حال بارگذاری نمایش داد.
- برای اینکه بتوانیم پاسخ سرور را به درستی مدیریت کنیم، آن را با split به آرایه هایی تجزیه می کنیم، در اینجا از علامت || به عنوان جدا کننده، برای قسمت کردن پاسخ و تجزیه آن در چند متغیر مجزا استفاده کرده ایم، حال متغیر status بخش اول پاسخ سرور و متغیر new_point قسمت دوم آن را در خود دارد.
- ملاحظه می کنید که از متد GET برای ارسال و دریافت متغیرها و مقادیر آنها به سرور استفاده شده است.
فراخوانی تابع voting
برای فراخوانی تابع کافی است آن را به صورت a و href به همراه رویداد onclick تعریف کنید، این کار را در نمونه زیر برای دو کاربر انجام داده ایم.
<div class="user">
<a href="#" onclick="voting(up,user1);"><img src="plus.png" height="16" width="16" alt="up" title="امتیاز مثبت" border="0" /></a>
<span id="up_point_user1">0</span>
<a href="#" onclick="voting(down,user1);"><img src="minus.png" height="16" width="16" alt="down" title="امتیاز منفی" border="0" /></a>
<span id="down_point_user1" dir="ltr">0</span>
<span id="loading_img_user1"></span>
</div>
<div class="user">
<a href="#" onclick="voting(up,user2);"><img src="plus.png" height="16" width="16" alt="up" title="امتیاز مثبت" border="0" /></a>
<span id="up_point_user2">0</span>
<a href="#" onclick="voting(down,user2);"><img src="minus.png" height="16" width="16" alt="down" title="امتیاز منفی" border="0" /></a>
<span id="down_point_user2" dir="ltr">0</span>
<span id="loading_img_user2"></span>
</div>
توضیح:
- در مثال بالا برای هر کاربر یک بلاک با کلاس فرضی user در نظر گرفته ایم.
- اگر به آی دی به کار رفته شده برای تگ های span دقت کنید، ملاحظه می کنید که نام هر کاربر برای تفکیک، به انتهای آنها اضافه شده است.
کد php برای سیستم امتیازدهی
برنامه هنوز تکمیل نشده است، گذشته از سمت کاربر و اسکریپت نویسی آن، بخش عمده کار مربوط می شود به سمت سرور و پردازش های آن، به طور مثال پس از ارسال درخواست، ابتدا باید ببینیم کاربر به چه کسی قصد امتیاز دادن دارد و امتیاز فعلی آن فرد چقدر است، اگر قصد کاربر امتیاز مثبت بود، امتیازات فعلی را به اضافه مقادیر جدید کنیم، یا برعکس اگر کاربر امتیاز منفی داد، امتیازات فرد را از مقادیر جدید کم و سپس نتایج جدید را هم در دیتابیس به روز کرده و هم به صفحه مرورگر ارسال کنیم، لذا بخش اصلی کار ما در کنار کدها و برنامه نویسی php کار با دیتابیس و پرس و جوهای mysql خواهد بود، اما به جهت اینکه آموزش حاضر صرفا برای این است که یک نمونه باشد، از مباحث مربوط به mysql آن می گذریم و برای درک مطلب با یک تکه کد php ساده کار را ادامه می دهیم.
<?php
$do = $_GET[do];
$point = $_GET[point];
if ($do == up){
$new_point = $point + 1;
}
elseif($do == down){
$new_point = $point - 1;
}
echo ok.||.$new_point;
?>
توضیح:
- این کد را با نام vote.php در یک فایل ذخیره کنید، فایل حاضر و صفحه html که کد آژاکس را در آن قرار داده ایم باید در یک فولدر قرار گیرند یا اینکه آدرس قسمت var req به درستی تنظیم شود.
- در کد بالا تنها با یک دستور شرطی ساده امتیاز فعلی کاربر را یک واحد افزایش یا کاهش می دهیم.
- خروجی ما با علامت || از هم تفکیک شده است، همان طور که پیش تر گفتیم، در سمت کاربر و در کد آژاکس، پاسخ سرور را با این علامت و دستور split تجزیه می کنیم.
کد نهایی و پیش نمایش آنلاین
برای ملاحظه یک نمونه آزمایشی و اولیه از سیستم امتیازدهی می توانید از کد و پیش نمایش آنلاین زیر استفاده کنید.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>وبگو | ایجاد امکان امتیازدهی در سایت</title>
<!-- http://webgoo.ir -->
<style type="text/css">
body{
font-family:Tahoma, Geneva, sans-serif;
font-size:12px;
direction:rtl;
}
.user{
display:block;
border:#666 1px dashed;
height:30px;
width:120px;
padding:4px;
margin:4px;
}
</style>
<script type="text/javascript">
//<![CDATA[
function voting(action,id){
var up_point_id = "up_point_" + id;
var down_point_id = "down_point_" + id;
var loading_id = "loading_img_" + id;
var loading = <img src="loading.gif" alt="loading" height="16" width="16" border="0" />;
if (action == up){
var user_point = document.getElementById(up_point_id).innerHTML;
}
else if (action == down){
var user_point = document.getElementById(down_point_id).innerHTML;
}
var xmlhttp;
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
else{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState > 0 && xmlhttp.readyState < 4){
document.getElementById(loading_id).innerHTML=loading;
}
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById(loading_id).innerHTML=;
var response = xmlhttp.responseText;
var splited_response = response.split("||");
var status = splited_response[0];
var new_point = splited_response[1];
if (action == up && status == ok){
document.getElementById(up_point_id).innerHTML=new_point;
}
else if (action == down && status == ok){
document.getElementById(down_point_id).innerHTML=new_point;
}
}
}
var req = "vote.php?do=" + action + "&user=" + id + "&point=" + user_point;
xmlhttp.open("GET",req,true);
xmlhttp.send();
}
//]]>
</script>
</head>
<body>
<noscript>
جاوا اسکریپت در مرورگر شما غیر فعال است یا پشتیبانی نمی شود! <br />
</noscript>
<div class="user">
<a href="#" onclick="voting(up,user1);"><img src="plus.png" height="16" width="16" alt="up" title="امتیاز مثبت" border="0" /></a>
<span id="up_point_user1">0</span>
<a href="#" onclick="voting(down,user1);"><img src="minus.png" height="16" width="16" alt="down" title="امتیاز منفی" border="0" /></a>
<span id="down_point_user1" dir="ltr">0</span>
<span id="loading_img_user1"></span>
</div>
<div class="user">
<a href="#" onclick="voting(up,user2);"><img src="plus.png" height="16" width="16" alt="up" title="امتیاز مثبت" border="0" /></a>
<span id="up_point_user2">0</span>
<a href="#" onclick="voting(down,user2);"><img src="minus.png" height="16" width="16" alt="down" title="امتیاز منفی" border="0" /></a>
<span id="down_point_user2" dir="ltr">0</span>
<span id="loading_img_user2"></span>
</div>
<hr />
سیستم امتیازدهی بالا جهت تست و بدون استفاده از دیتابیس کار می کند؛ لذا امتیازات بعد از بستن یا رفرش صفحه به حالت پیش فرض بر می گردند، برای ساخت یک سیستم امتیازدهی کامل باید علاوه بر آژاکس و php از mysql نیز استفاده کنید.
</body>
</html>