完善星级评定系统

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++;
}
}
?>