Ik probeer een systeem te maken voor mijn project, waarmee je net als in Gmail bijvoorbeeld, bepaalde items met een ster kan markeren.
Het gaat hier om een lijst met gebruikers. Elk van die gebruikers moet je met een ster kunnen markeren om ze zo zeg maar tussen je favorieten te zetten.

Dit script is onder te verdelen in drie elementen:
- De HTML code die het javascript oproept (in dit voorbeeld wordt dat gegenereerd door een stukje PHP, die alle users uit een database moet ophalen):

   echo "<div id=\"star$uid\" style=\"width:30px; height:30px; cursor:pointer;";
$uid = $row['id'];
$star = mysql_query("SELECT * FROM stars WHERE (myip = '$myip') AND (userid='$uid')")
or die(mysql_error());
$row2 = mysql_fetch_array($star);
if ($row2['starred'] == 1) { echo " background-image:url(static/images/star_on.gif);"; } else { echo " background-image:url(static/images/star_off.gif);"; }
   echo " background-repeat:no-repeat; background-position:center \" onclick=\"ajaxAddStar('$uid','star$uid')\">&nbsp;</div>";
   echo "</td><td>"; 

- De AJAX functie die vervolgens het uit te voeren stuk PHP oproept:

function ajaxAddStar(str,x)   {
   
   
if (str.length==0)
{
document.getElementById(x).innerHTML=""
return
}
xmlHttp=GetXmlHttpObject2()
if (xmlHttp==null)
{
alert ("Browser does not support HTTP Request")
return
}
var url="sheets/default/addStar.php"
url=url+"?uid="+str
xmlHttp.onreadystatechange=stateChanged2
xmlHttp.open("GET",url,true)
xmlHttp.send(null)
}

function stateChanged2()
{
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{
document.getElementById(x).innerHTML=xmlHttp.responseText
}
}

function GetXmlHttpObject2()
{
var objXMLHttp=null
if (window.XMLHttpRequest)
{
objXMLHttp=new XMLHttpRequest()
}
else if (window.ActiveXObject)
{
objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
}
return objXMLHttp

} 

- En uiteindelijk, het stuk php dat ervoor zorgt dat er een ster tevoorschijn komt wanneer deze er nog niet staat en andersom:


<?php

$uid=$_GET['uid'];
$myip=GetHostByName($REMOTE_ADDR);

// Make a MySQL Connection
mysql_connect("localhost", "login", "password") or die(mysql_error());
mysql_select_db("board") or die(mysql_error());

// Get all the data from the "example" table
$result = mysql_query("SELECT * FROM stars WHERE (myip='$myip') AND (userid='$uid')") or die(mysql_error());
$match = mysql_num_rows($result);
$row = mysql_fetch_array($result);

if ($match == 1) {
if ($row['starred'] == 1) {
mysql_query("UPDATE stars SET starred='0' WHERE (myip='$myip') AND (userid='$uid')");
}
elseif ($row['starred'] == 0) {
mysql_query("UPDATE stars SET starred='1' WHERE (myip='$myip') AND (userid='$uid')");
}
} elseif ($match == 0) {
$insert = mysql_query("INSERT INTO stars
(myip, userid, starred) VALUES('$myip', '$uid' ,'1' ) ");
}

$result2 = mysql_query("SELECT * FROM stars WHERE (myip='$myip') AND (userid='$uid')");
$row2 = mysql_fetch_array($result2);
if ($row2['starred'] == 1) { echo "<div style=\"width:30px; height:30px; cursor:pointer; background-image:url(static/images/star_on.gif); background-repeat:no-repeat; background-position:center; \">&nbsp;</div> "; } else { echo "<div style=\"width:30px; height:30px; cursor:pointer; background-image:url(static/images/star_off.gif); background-repeat:no-repeat; background-position:center; \">&nbsp;</div>"; }

mysql_close();

?>


- Het script op zich werkt, maar met een aantal vreemde problemen:
In firefox doet het script zijn werk, maar veranderd de ster pas wanneer je de pagina vernieuwd.
- In internet explorer moet je eerst je cache legen voordat de afbeelding veranderd wordt. Ik heb al <META HTTP-EQUIV="pragma" CONTENT="no-cache"> geprobeerd te gebruiken, maar tevergeefs.
Daarnaast geeft internet explorer een fout en zegt het volgende:

Regel: 173
Teken: 1
Fout: 'x' is niet gedefinieerd
Code: 0

Hij zegt dus dat de variabele x in de functie ajaxAddStar(str,x) niet gedefinieerd is, maar dat is toch wel zo?? Als ik de functie oproep, geef ik toch keurig twee variabelen mee??

Ik snap het probleem dus niet bepaald, weten jullie het op te lossen?

Alvast bedankt!
Die dat hij niet geüpdate wordt, en IE die de fout geeft heeft te maken met deze functie:

function stateChanged2()
{
    if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
        document.getElementById(x).innerHTML=xmlHttp.responseText
    }
}

Binnen deze functie is x inderdaad onbekend, omdat je niet meer binnen de scope van ajaxAddStar zit. Ik had eigenlijk ook veracht dat je nog wel een fout voor xmlHttp kreeg, want daar geldt hetzelfde voor.


Een voorbeeldoplossing (zo delen ze elkaars scope):

function ajaxAddStar(str,x)
{
    if (str.length==0) {
        document.getElementById(x).innerHTML="";
        return;
    }

    /* 
     * let op: ik heb hier 'var' voor xmlHttp gezet, zodat deze variabele niet naar 
     * de global-scope gaat. Zou je dat wel doen, dan zouden ze door elkaar kunnen
     * gaan lopen, waardoor de ene aanvraag de ander overschijft. En geloof me,
     * dat wil je echt niet!
     */
     
    var xmlHttp=GetXmlHttpObject2();

    if (xmlHttp==null) {
        alert ("Browser does not support HTTP Request");
        return;
    }

    var url="sheets/default/addStar.php?uid="+str;
    xmlHttp.onreadystatechange = function() 
    {
        if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
            document.getElementById(x).innerHTML=xmlHttp.responseText;
        }
    }

    xmlHttp.open("GET", url, true);
    xmlHttp.send(null);
}


Verder is het nog een goed idee om ervoor te zorgen dat de URL altijd anders is, zodat deze niet gecached wordt. Je kan ook ingewikkeld gaan doen met headers, maar deze simpele aanpak werkt gewoon altijd, vandaar dat ik hier de voorkeur aan geef:
Vervang:

    var url="sheets/default/addStar.php?uid="+str;

eens door:

    var d = new Date();
    var url="sheets/default/addStar.php?uid=" + str + "&dummy="+d.getTime();

Reageren