I made a star rating system for a school project and need some help improving it a bit. It's a fairly simple setup: index.php contains list-items (content is fetched from a DB) with an image and a div holding the stars for rating. Each star is a link that triggers a function which saves the rating in a database.
Here's the link! for starters.
If you click on any star, the first click will result in a green check mark on the first list-item. The idea is that this check mark will appear on each list-item when rated. That's where I need you guys to point me in the right direction. First of all I know I can't echo out multiple divs with the same id, but I had to in order for the ajax function to work (document.getElementById("rated")). Any ideas on how to solve this?
CODE
insert_receive.php:
<?php
session_start();
$sess = session_id();
$mysqli = new mysqli("", "", "", "");
if (mysqli_connect_errno()) {
printf("Connect failed: %s
", mysqli_connect_error());
exit();
}
$stmt = $mysqli->prepare("REPLACE INTO Ratings (projId_fkey, sessionId, rvalue) VALUES ('".$_GET['projId']."','".$sess."','".$_GET['rating']."')");
$stmt->execute();
printf("✔");
?>
ajax_framework.js:
function saveClick(rating,projId)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("rated").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","insert_receive.php?rating=" + rating + "&projId=" + projId,true);
xmlhttp.send("");
}
index.php: (the part that matters)
<?php
$select = "SELECT id, projName, location FROM Projects";
if($result = $mysqli->query($select))
{
while($row = $result->fetch_assoc())
{
echo '<li id="'.$row['id'].'">';
echo '<h1 class="header">'.$row['projName']."</h1>";
echo '<img src="'.$row['location'].'" alt=""/>';
echo '<div class="rating">';
echo '<a href="#" onclick="saveClick(5, '.$row['id'].')">'.★★★★★."</a>";
echo '<a href="#" onclick="saveClick(4, '.$row['id'].')">'.★★★★."</a>";
echo '<a href="#" onclick="saveClick(3, '.$row['id'].')">'.★★★."</a>";
echo '<a href="#" onclick="saveClick(2, '.$row['id'].')">'.★★."</a>";
echo '<a href="#" onclick="saveClick(1, '.$row['id'].')">'.★."</a>";
echo '<div id="rated">'.""."</div>";
echo "</div>";
echo "</li>";
}
}
?>
First, use a class instead, obviously.
echo '<div class="rated">'.""."</div>";
Second, in your JavaScript, instead of this line
document.getElementById("rated").innerHTML=xmlhttp.responseText;
Use this
var proj = document.getElementById(projId);
var rated = proj.getElementsByClassName('rated')[0];
rated.innerHTML=xmlhttp.responseText;
What we're doing here is that we find the element with an id matching projId
. Then we find the elements with the class rated
INSIDE the projID
we found earlier. Now notice that getElementsByClassName
returns an array regardless of the number of elements, but since we only have a single one here we just select the item at the first index [0]
.
You can use an iterator to give each element a different ID, after that, you can indeed dynamically get the element by the correct ID. For example:
echo '<div id="rated'.$row['id'].'">
and then:
document.getElementById("rated"+projId).innerHTML=xmlhttp.responseText;
This will dynamically select the element you want.
Regarding your code in general, I simply must point you in the direction of http://jquery.com/ It will make element selection much simpler, and will also normalize your use of ajax.
Change your php to:
while($row = $result->fetch_assoc())
{
echo '<li id="'.$row['id'].'">';
echo '<h1 class="header">'.$row['projName']."</h1>";
echo '<img src="'.$row['location'].'" alt=""/>';
echo '<div class="rating">';
echo '<a href="#" onclick="saveClick(5, '.$row['id'].')">'.★★★★★."</a>";
echo '<a href="#" onclick="saveClick(4, '.$row['id'].')">'.★★★★."</a>";
echo '<a href="#" onclick="saveClick(3, '.$row['id'].')">'.★★★."</a>";
echo '<a href="#" onclick="saveClick(2, '.$row['id'].')">'.★★."</a>";
echo '<a href="#" onclick="saveClick(1, '.$row['id'].')">'.★."</a>";
echo '<div id="rated'.$row['id'].'">'.""."</div>";//updated this line
echo "</div>";
echo "</li>";
}
And the line in your javascript to:
document.getElementById("rated"+projId).innerHTML=xmlhttp.responseText;
Use a counter$id
to increment li id
<?php
$select = "SELECT id, projName, location FROM Projects";
if($result = $mysqli->query($select))
{
$id = 0;
while($row = $result->fetch_assoc())
{
echo '<li id="'.$id.'">';
echo '<h1 class="header">'.$row['projName']."</h1>";
echo '<img src="'.$row['location'].'" alt=""/>';
echo '<div class="rating">';
echo '<a href="#" onclick="saveClick(5, '.$row['id'].')">'.★★★★★."</a>";
echo '<a href="#" onclick="saveClick(4, '.$row['id'].')">'.★★★★."</a>";
echo '<a href="#" onclick="saveClick(3, '.$row['id'].')">'.★★★."</a>";
echo '<a href="#" onclick="saveClick(2, '.$row['id'].')">'.★★."</a>";
echo '<a href="#" onclick="saveClick(1, '.$row['id'].')">'.★."</a>";
echo '<div id="rated">'.""."</div>";
echo "</div>";
echo "</li>";
$id++;
}
}
?>