آموزش ساخت سیستم رتبه دهی ستاره ای در js و php
رتبه دهی ستاره ای در js و php – خیلی از مطالب و محصولات اینترنتی دارای بخشی هستند که می توان به محصول و مطلب رتبه دهید تا دیگر کاربران از میزان کیفیت آن مطلب مطلع شوند .
در این آموزش از html , css , js , php , mysql استفاده می کنیم .
فایل index.php
<!DOCTYPE html> <html lang="fa"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>RapidCode.IR - ساخت جستجوی پیشرفته AJAX با PHP و Javascript</title> <link rel="stylesheet" href="static/css/style.css"> </head> <body> <a id="introduce" target="_blank" href="https://rapidcode.ir">رپید کد - کتابخانه مجازی برنامه نویسان</a> <div class="container"> <?php require_once "posts.php"; $posts = get_posts(); ?> <?php foreach ($posts as $row): ?> <article id="post-<?php echo $row['id'] ?>"> <img src="<?php echo $row['thumbnail'] ?>" alt="<?php echo $row['title'] ?>"> <h2><?php echo $row['title'] ?></h2> <p><?php echo $row['content'] ?></p> <?php $stars = $row['rstar']; $reviewer_number = $row['rstar_user']; $score = $stars == 0 && $reviewer_number == 0 ? 0 : $stars / $reviewer_number; $integer_score = ceil($score); ?> <div class="stars-wrapper"> <?php if($stars != 0 && $reviewer_number != 0): ?> <span id="stars-number"><i id="rate"><?php echo round($score , 1) ?></i> از <i id="avg-count"><?php echo $reviewer_number ?></i> رای</span> <?php endif; ?> <span class="stars-shape" id="post_star_<?php echo $row['id'] ?>" data-post-id="<?php echo $row['id'] ?>"> <?php for($i=1;$i<=5;$i++): $offset_svg = 0; if($integer_score == 1){ $offset_svg = $score; }else if(1 < $integer_score){ $offset_svg = 1; } $integer_score--; $score--; $offset_svg = round($offset_svg , 1); $offset_svg *= 100; ?> <svg fill="url(#filler-<?php echo "pid-{$row['id']}-{$i}" ?>)" id="star<?php echo $i ?>" data-item-number="<?php echo $i ?>" class="star" height="511pt" viewBox="0 -10 511.98685 511" width="511pt" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="filler-<?php echo "pid-{$row['id']}-{$i}" ?>"><stop id="half-stp-1" offset="<?php echo $offset_svg ?>%"/><stop offset="0"/></linearGradient></defs><path d="m510.652344 185.902344c-3.351563-10.367188-12.546875-17.730469-23.425782-18.710938l-147.773437-13.417968-58.433594-136.769532c-4.308593-10.023437-14.121093-16.511718-25.023437-16.511718s-20.714844 6.488281-25.023438 16.535156l-58.433594 136.746094-147.796874 13.417968c-10.859376 1.003906-20.03125 8.34375-23.402344 18.710938-3.371094 10.367187-.257813 21.738281 7.957031 28.90625l111.699219 97.960937-32.9375 145.089844c-2.410156 10.667969 1.730468 21.695313 10.582031 28.09375 4.757813 3.4375 10.324219 5.1875 15.9375 5.1875 4.839844 0 9.640625-1.304687 13.949219-3.882813l127.46875-76.183593 127.421875 76.183593c9.324219 5.609376 21.078125 5.097657 29.910156-1.304687 8.855469-6.417969 12.992187-17.449219 10.582031-28.09375l-32.9375-145.089844 111.699219-97.941406c8.214844-7.1875 11.351563-18.539063 7.980469-28.925781zm0 0"/></svg> <?php endfor; ?> </span> </div><br> <a href="<?php echo $row['link'] ?>" target="_blank">ادامه مطلب</a> </article> <?php endforeach;?> </div> <script src="static/js/app.js"></script> </body> </html>
فایل posts.php برای دسترسی به توابع مورد نیاز جهت تعامل با mysql
فایل posts.php
<?php $table = "articles"; $mysqli = new mysqli("localhost", "root", "", "posts"); $mysqli->set_charset("utf8"); $stmt = $mysqli->stmt_init(); function get_posts($id = false) { global $table; global $mysqli; global $stmt; $where_statment = ""; $rows = []; if (!empty($id)) { if (is_row_exits($id)) { $where_statment = "WHERE id=?"; } else return $rows; } $query = "SELECT * FROM `{$table}` {$where_statment} ORDER BY id DESC"; $stmt->prepare($query); if (!empty($where_statment)) { $stmt->bind_param("i", $id); } if ($stmt->execute() && $res = $stmt->get_result()) { if ($stmt->affected_rows || $res->num_rows) { while ($row_loop = $res->fetch_assoc()) { $rows[] = $row_loop; } } } return $rows; } function is_row_exits($id) { global $table; global $mysqli; global $stmt; $query = "SELECT id FROM {$table} WHERE id=?"; $stmt->prepare($query); $stmt->bind_param('i', $id); $is_found = 0; if ($stmt->execute() && $stmt->store_result()) { $is_found = $stmt->affected_rows; $stmt->free_result(); } return $is_found; } function set_post_stars($post_id, $score) { global $table; global $stmt; $row_updated = false; $query = "UPDATE {$table} SET `rstar` = `rstar` + ? , `rstar_user` = `rstar_user` + 1 WHERE `id`=?"; $stmt->prepare($query); $stmt->bind_param('ii', $score, $post_id); if ($stmt->execute()) { $row_updated = $stmt->affected_rows ? $stmt->affected_rows : 1; } return $row_updated; } function set_post_stars_cookie(&$user_review_content_cookie, &$response_list) { $res = set_post_stars($_POST['post_id'], $_POST['post_score']); if (!$res) die(["msg" => "خطایی در ارتباط با پایگاه داده رخ داده است", "status" => 0]); $post = get_posts($_POST['post_id']); $post = end($post); $post = ["star"=> ($post['rstar'] / $post['rstar_user']) , "user"=> $post['rstar_user'] , "id" => $post['id']]; $response_list["data"] = $post; $response_list["msg"] = "امتیاز {$_POST['post_score']} با موفقیت ثبت گردید"; $response_list["status"] = 1; array_push($user_review_content_cookie['post_id'], $_POST['post_id']); setcookie("post_review_stars", json_encode($user_review_content_cookie), time() + 86400); // تا 1 روز آینده }
فایل review-api.php جهت ساخت api لازم برای ثبت رتبه کاربران .
فایل review-api.php
<?php header("Content-Type: application/json"); require_once "posts.php"; if (empty($_POST['post_id'])) { die(json_encode(["msg" => "پست آیدی ارسال نشد", "status" => 0])); } if (!is_row_exits($_POST['post_id'])) { die(json_encode(["msg" => "پست مورد نظر یافت نشد", "status" => 0])); } if (empty($_POST['post_score'])) { die(json_encode(["msg" => "امتیاز ارسال نشد", "status" => 0])); } $response_list = [ "msg" => "", "status" => 0 ]; $user_review_content_cookie = @$_COOKIE["post_review_stars"] ? $_COOKIE["post_review_stars"] : ["post_id" => []]; if (!empty($user_review_content_cookie)) { if(!is_array($user_review_content_cookie)) $user_review_content_cookie = json_decode($user_review_content_cookie, true); if (in_array($_POST['post_id'], $user_review_content_cookie['post_id'])) { $response_list['msg'] = "شما از قبل به این پست امتیاز داده بودید"; } else { set_post_stars_cookie($user_review_content_cookie, $response_list); } } else { set_post_stars_cookie($user_review_content_cookie, $response_list); } die(json_encode($response_list));
style.css جهت دادن استایل به برنامه
استایل برنامه با style.css
article { width: 25%; border: 2px solid skyblue; padding: 10px; float: right; margin-left: 15px; } article img { width: 200px; } article h2{ height: 82px; } article p{ height: 56px; overflow: hidden; } article a { text-decoration: none; font-weight: bold; background-color: #FF9800; color: white; width: 100%; padding: 10px 0; display: block; } .stars-wrapper{ direction: ltr; } .stars-wrapper #stars-number{ float: left; direction: rtl; } .stars-wrapper .stars-shape { cursor: pointer; transition: all 0.3s; } .stars-wrapper .stars-shape svg{ overflow: initial; width: 15px; height: 15px; stroke-width: 55px; stroke: #ffc107; margin-left: 1px; } .stars-wrapper .stars-shape svg:hover{ fill: #ffc107; } stop{ stop-opacity: 1; stop-color: rgba(0, 0, 0, 0); } stop#half-stp-1{ stop-color: #ffc107; }
فایل app.js
document.addEventListener("DOMContentLoaded", function () { const starElmentDOM = document.getElementsByClassName("stars-shape"); let requestLock = false; const starDOM = document.getElementsByClassName("star"); for (var i = 0; i < starDOM.length; i++) { const currentElement = starDOM[i]; currentElement.addEventListener("mouseover", handlerFillStars) currentElement.addEventListener("click", function (event) { const currentElementParent = currentElement.parentElement; const postID = currentElementParent.getAttribute("data-post-id"); const score = parseInt(currentElement.getAttribute("data-item-number")); reviewRequest(postID, score); }) } for (var i = 0; i < starElmentDOM.length; i++) { const currentElement = starElmentDOM[i]; currentElement.addEventListener("mouseleave", handlerEmptyStars) } // handlers function handlerFillStars(event) { handlerEmptyStars(); const currentElement = this; const currentElementParent = currentElement.parentElement; const currentElementItemNumber = currentElement.getAttribute("data-item-number"); for (var i = 0; i < currentElementItemNumber; i++) { const currentElement = currentElementParent.querySelector("#star" + (i + 1)); if (currentElement == null) continue; currentElement.style.fill = "#bc8f07"; } } function handlerEmptyStars(event) { for (var j = 0; j < starDOM.length; j++) { const currentElement = starDOM[j]; currentElement.removeAttribute("style"); } } // ajax Request function reviewRequest(postID, postScore, currentElement) { if (requestLock) return; const xhr = new XMLHttpRequest(); xhr.responseType = "json"; requestLock = true; const params = new FormData; params.append("post_id", postID); params.append("post_score", postScore); xhr.open("POST", location.href + "/review-api.php"); xhr.onload = function () { requestLock = false; const response = this.response; if (response.status == 1) { let starsNumber = response.data.star; const reviewerNumber = response.data.user; const postID = response.data.id; const starWrapper = document.querySelector("article#post-" + postID + " .stars-shape") let parentElementPreviousElement = starWrapper.previousElementSibling; if(!parentElementPreviousElement){ parentElementPreviousElement = document.createElement("span"); parentElementPreviousElement.id = "stars-number"; parentElementPreviousElement.innerHTML = '<i id="rate">x1</i> از <i id="avg-count">x2</i> رای'; starWrapper.parentElement.insertBefore(parentElementPreviousElement , starWrapper); } // مقداردهی نوشته رای parentElementPreviousElement.querySelector("#rate").textContent = starsNumber.toFixed(1); parentElementPreviousElement.querySelector("#avg-count").textContent = reviewerNumber; // پرکردن مجدد ستاره ها const svgStar = starWrapper.querySelectorAll("svg"); var starTempValue = 0; var currentElement = null; for(var i=0;i<svgStar.length;i++){ currentElement = svgStar[i]; starTempValue = 1 < starsNumber ? 1 : starsNumber.toFixed(1); starTempValue *= 100; currentElement.querySelector("#half-stp-1").setAttribute("offset" , starTempValue + "%"); starsNumber--; } } alert(response.msg); } xhr.onerror = function () { requestLock = false; console.warn("[XHR Error]"); } xhr.send(params); } });
دموی برنامه رتبه دهی ستاره ای
قبل از اجرای برنامه وارد پوشه posts DATABASE to import شده دیتابیس را import کنید
ارسال نظر