پروژه فروشگاه اینترنتی با جاوااسکریپت - سیستم نظرات کاربران


🎯 اهداف یادگیری

  • طراحی و پیاده‌سازی سیستم نظرات کاربران
  • اعتبارسنجی فرم نظردهی
  • ذخیره و نمایش نظرات
  • امتیازدهی ستاره‌ای
  • فیلتر و مرتب‌سازی نظرات

📌 طراحی فرم نظردهی

ابتدا فرم ساده‌ای برای دریافت نظرات کاربران طراحی می‌کنیم:

html
<form id="comment-form">
<div class="form-group">
<label for="name">نام شما:label>
<input type="text" id="name" required>
div>
<div class="form-group">
<label for="rating">امتیاز:label>
<div class="star-rating">
<span data-value="1">span>
<span data-value="2">span>
<span data-value="3">span>
<span data-value="4">span>
<span data-value="5">span>
div>
<input type="hidden" id="rating-value" value="0">
div>
<div class="form-group">
<label for="comment">نظر شما:label>
<textarea id="comment" required>textarea>
div>
<button type="submit">ثبت نظرbutton>
form>

استایل‌دهی به سیستم امتیازدهی ستاره‌ای:

css
.star-rating {
direction: rtl; /* برای نمایش ستاره‌ها از راست به چپ */
display: inline-block;
}
.star-rating > span {
font-size: 24px;
cursor: pointer;
color: #ccc;
transition: color 0.2s;
}
.star-rating > span:hover,
.star-rating > span:hover ~ span {
color: #ffc107; /* رنگ زرد برای ستاره‌های انتخاب شده */
}
.star-rating > span.active,
.star-rating > span.active ~ span {
color: #ffc107;
}

📌 پیاده‌سازی منطق نظرات با جاوااسکریپت

حالا با جاوااسکریپت سیستم نظرات را پیاده‌سازی می‌کنیم:

javascript
// مدیریت امتیازدهی ستاره‌ای
document.querySelectorAll('.star-rating span').forEach(function(star) {
star.addEventListener('click', function() {
// حذف کلاس active از همه ستاره‌ها
document.querySelectorAll('.star-rating span').forEach(function(s) {
s.classList.remove('active');
});
// اضافه کردن کلاس active به ستاره‌های انتخاب شده
const rating = parseInt(this.getAttribute('data-value'));
document.getElementById('rating-value').value = rating;
for (let i = 1; i <= rating; i++) {
document.querySelector(`.star-rating span[data-value="${i}"]`).classList.add('active');
}
});
});
// مدیریت ارسال فرم نظر
document.getElementById('comment-form').addEventListener('submit', function(e) {
e.preventDefault();
const name = document.getElementById('name').value;
const rating = document.getElementById('rating-value').value;
const comment = document.getElementById('comment').value;
// اعتبارسنجی فرم
if (!name || !comment || rating === '0') {
alert('لطفاً همه فیلدها را پر کنید');
return;
}
// ایجاد شیء نظر جدید
const newComment = {
id: Date.now(),
name: name,
rating: parseInt(rating),
comment: comment,
date: new Date().toLocaleDateString('fa-IR')
};
// ذخیره نظر در localStorage
let comments = JSON.parse(localStorage.getItem('product-comments')) || [];
comments.push(newComment);
localStorage.setItem('product-comments', JSON.stringify(comments));
// نمایش پیام موفقیت
alert('نظر شما با موفقیت ثبت شد. پس از تأیید نمایش داده خواهد شد.');
document.getElementById('comment-form').reset();
// ریست کردن ستاره‌ها
document.querySelectorAll('.star-rating span').forEach(function(s) {
s.classList.remove('active');
});
document.getElementById('rating-value').value = '0';
// بارگذاری مجدد نظرات
loadComments();
});

📌 نمایش نظرات کاربران

تابعی برای نمایش نظرات موجود در localStorage می‌نویسیم:

javascript
// تابع بارگذاری و نمایش نظرات
function loadComments() {
const commentsContainer = document.getElementById('comments-list');
const comments = JSON.parse(localStorage.getItem('product-comments')) || [];
// محاسبه میانگین امتیازات
const averageRating = comments.length > 0 ? comments.reduce((acc, curr) => acc + curr.rating, 0) / comments.length : 0;
document.getElementById('average-rating').textContent = averageRating.toFixed(1);
// نمایش نظرات
commentsContainer.innerHTML = comments.map(comment => `
<div class="comment-item">
<div class="comment-header">
<h4>${comment.name}</h4>
<div class="comment-rating">
${'★'.repeat(comment.rating)}${'☆'.repeat(5 - comment.rating)}
</div>
</div>
<div class="comment-date">${comment.date}</div>
<p class="comment-text">${comment.comment}</p>
</div>
`).join('');
}
// بارگذاری نظرات هنگام لود صفحه
document.addEventListener('DOMContentLoaded', loadComments);

📌 فیلتر و مرتب‌سازی نظرات

امکان فیلتر و مرتب‌سازی نظرات را اضافه می‌کنیم:

javascript
// فیلتر نظرات بر اساس امتیاز
document.getElementById('filter-rating').addEventListener('change', function(e) {
const rating = parseInt(e.target.value);
let comments = JSON.parse(localStorage.getItem('product-comments')) || [];
if (rating > 0) {
comments = comments.filter(c => c.rating === rating);
}
document.getElementById('comments-list').innerHTML = comments.map(comment => `
<div class="comment-item">
<div class="comment-header">
<h4>${comment.name}</h4>
<div class="comment-rating">
${'★'.repeat(comment.rating)}${'☆'.repeat(5 - comment.rating)}
</div>
</div>
<div class="comment-date">${comment.date}</div>
<p class="comment-text">${comment.comment}</p>
</div>
`).join('');
});
// مرتب‌سازی نظرات
document.getElementById('sort-comments').addEventListener('change', function(e) {
let comments = JSON.parse(localStorage.getItem('product-comments')) || [];
if (e.target.value === 'newest') {
comments.sort((a, b) => b.id - a.id);
} else if (e.target.value === 'highest') {
comments.sort((a, b) => b.rating - a.rating);
} else {
comments.sort((a, b) => a.id - b.id);
}
document.getElementById('comments-list').innerHTML = comments.map(comment => `
<div class="comment-item">
<div class="comment-header">
<h4>${comment.name}</h4>
<div class="comment-rating">
${'★'.repeat(comment.rating)}${'☆'.repeat(5 - comment.rating)}
</div>
</div>
<div class="comment-date">${comment.date}</div>
<p class="comment-text">${comment.comment}</p>
</div>
`).join('');
});

📌 نکات مهم پیاده‌سازی

  • اعتبارسنجی سمت کلاینت: همیشه اعتبارسنجی را هم در سمت سرور انجام دهید، اینجا فقط برای UX بهتر است
  • امنیت: قبل از نمایش نظرات، محتوای آنها را با DOMPurify یا similar پاکسازی کنید
  • پاسخگویی: سیستم را برای موبایل‌ها بهینه کنید

📌 تمرین عملی

ویژگی‌های زیر را به سیستم نظرات اضافه کنید:

  1. امکان پاسخ به نظرات دیگران
  2. امکان لایک کردن نظرات
  3. صفحه‌بندی نظرات (هر صفحه 5 نظر)
  4. جستجو در متن نظرات

📌 قدم بعدی

در بخش پنجم با سیستم پرداخت آنلاین آشنا خواهیم شد!