Autor Zpráva
Medo
Profil
Dobrý deň, skúšal som podľa návodu na www.smitka.org/programovani/ajax-chat spraviť chat v AJAXe... Chat ako taký funguje, len pri odoslaní príspevku vypíše to, že sa správu nepodarilo odoslať, ale odošle ju... A taktiež sa nerefreshuje... Tu je živá ukážka...

Všetko je to tak ako v návode, až na to, že som pomenoval databázu ajax_chat namiesto chat.


Skript
<style>
 .hlavicka{
  border:1px solid black; 
  width:500px;
  color:black;
  background-color:grey;
 }
 .text{
  border:1px solid black; 
  width:500px;
 }
</style>
<form name="form0" action="chat.php?action=poslat" method="POST"> 
<input type="text" size="8" name="name" value="Meno"> 
<input type="text" size="20" name="text" value="text"> 
<input onclick="return posli();" type="submit" value="poslat"> 
</form> 
<div id="chtext"></div>
<div style="display:none;"><endora></div>
<?php
include("connect.php");
$lastid=isset($_GET["id"])?$_GET["id"]:0;  //získání id, defaultně 0
$action=isset($_GET["action"])?$_GET["action"]:"aktualizovat"; //zjištění akce (aktualizovat/poslat), defaultně aktualizovat
switch($action){
  case "aktualizovat":
    if ($lastid<=0) {//pokud id=0 tak se vybere z databáze 30 nejnovějších příspěvků
      $result = mysql_query("SELECT id, ip, name, timestamp, text  FROM ajax_chat ORDER BY timestamp DESC LIMIT 30"); 
    }else{//jinak příspěvky s id větším než zadaným
      $result = mysql_query("SELECT id, ip, name, timestamp, text  FROM ajax_chat WHERE ajax_chat.id > {$_GET['id']} ORDER BY timestamp DESC");
    }
    while ($zaznam = mysql_fetch_array($result)){ //pro každý příspěvek se vygeneruje HTML kód
      echo "<div title=\"{$zaznam['ip']}\" class=\"hlavicka\">".date("d.m H:i:s",$zaznam['timestamp'])." - <strong>{$zaznam['name']}</strong> napsal(a):</div><div class=\"text\">{$zaznam['text']}</div><br>";
      $lastid=($lastid>$zaznam['id'])?$lastid:$zaznam['id'];//do proměnné lastid se bude ukládat nejvyšší id
    }
  break;
  case "poslat":
    if (isset($_POST["text"]) and isset($_POST["name"]) and $_POST["text"]!=''){//pokud jsou vloženy potřebné údaje, je příspěvek vložen do databáze
      if (mysql_query("INSERT INTO ajax_chat VALUES(0,'". $_SERVER["REMOTE_ADDR"]."','".$_POST["name"]."',".strtotime("now").", '".nl2br(htmlspecialchars($_POST["text"]))."')" )) 
        echo "ok";//odpověď pokud se zápis do databáze povedl
      }
  break;
} 
?>

<script type="text/javascript">
var id=0; //id příspěvku
var timer=5000; //čas obnovování
//čtecí a zapisovací objekt
var ajax1 = (window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : false));
var ajax2 = (window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : false));

//čtení zpráv
function zpravy(){
  if(!ajax1){
    alert("Tady AJAX neběží...");
    return true;
  }
  ajax1.onreadystatechange= function () {text(); } ;
  ajax1.open("GET", "chat.php?action=aktualizovat&id="+id, true);//požadavek na čtené nových příspěvků
  ajax1.send(null);
  return false;
}

//zápis zpráv
function posli(){
  if(!ajax2){
    alert("Tady AJAX neběží...");
    return true;
  }
  ajax2.onreadystatechange= function () {poslano(); } ;
  ajax2.open("POST", "chat.php?action=poslat", true);
  ajax2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  ajax2.send("text="+document.form0.text.value+"&name="+document.form0.name.value); //poslání hodnot z formuláře
  return false;
}

//úkony po poslání zprávy
function poslano(){
  if (ajax2.readyState == 4){
    if(ajax2.status == 200  || ajax2.status==0){
      if(ajax2.responseText=="ok"){ //pokud se zpráva uložila, dojde k vymazání prvku se zprávou
        document.form0.text.value="";
        zpravy();
      }else{
        alert("Bohužel se nepodařilo zprávu odeslat ");
      }
    }else{
      alert("Chyba: "+ ajax2.status +":"+ ajax2.statusText);
    }  
  }
}

//vypsání získaných příspěvků
function text(){
  var txt;
  var param= new Array();
  if (ajax1.readyState == 4){
    if(ajax1.status == 200  || ajax1.status==0){
      param=ajax1.responseText.split("|id=");//rozdělení textového řetězce na text a id
      document.getElementById("chtext").innerHTML = param[0]; //výpis do DIVu chtext
      // + document.getElementById("chtext").innerHTML
      id=param[param.length-1];//uložení id nejaktuálnějšího příspěvku
    }
    else alert("Chyba: "+ ajax1.status +":"+ ajax1.statusText);
  }
}

//aktualizace příspěvků
function aktualizovat(){
  window.setTimeout("aktualizovat()", timer);
  zpravy();
}

aktualizovat();
</script>
_es
Profil
Medo:
Nemáš tam element s id "chtext".
Ten kód na pohľad veľmi pekne nevyzerá, skús okopírovať niečo iné.
Medo
Profil
_es:
No v tom to nebolo, predtým tam ten div bol... Kód som upravil, tak je to takto snáď lepšie ;-)

Teraz to po menších úpravách ide, updatuje sa, ale do výpisu príspevkov to vložilo celú stránku, a nie len nové príspevky, preto je tam toto (riadky 100 a 101):

document.getElementById("chtext").innerHTML = param[0]; //výpis do DIVu chtext
// + document.getElementById("chtext").innerHTML


Vždy to tam znova a znova vkladalo celý súbor, a tak sa každých 5 sekúnd stránka predlžovala... Preto som to obmedzil takto, a to je zrejme dôvodom toho, že je tam pole na vkladanie príspevkov dva krát. To je jediná chyba, ktorú tam teraz vidím...
_es
Profil
Medo:
Nemáš definované kódovanie znakovej sady.
Ten kód je celý nejako chaoticky.
Pochybujem, že sa to niekomu bude chcieť lúštiť.
Asi sa budeš musieť posnažiť to viac pochopiť sám.
Kcko
Profil
Doporucil bych Ti stahnout nejaky normalni kod, napr. tento -> http://blog.rotten77.cz/jquery-chat
Chamurappi
Profil
Reaguji na Kcka:
Ten moc normální není. Pokud ho autor během posledního měsíce neopravil, blbne mu v některých prohlížečích čeština a trpí nepěknými memory leaky.
Jistě jde najít nějaké kvalitní hotové řešení, ale tohle mezi ně nepatří.
Kcko
Profil
Chamurappi:
No tak cestina se da opravit a memory leaku jsem si nevsiml. Nicmene oproti kodu z prvniho prispevku je to jak nebe a dudy. A aspon se tam dotycny nauci psat alespon prehledny a kratky kod.

PS. Memory leaky, kde / jak? Niceho jsem si nevsiml.
endora
Profil
Na Endora.cz je provoz chatu zakazan :)
Smíťa
Profil *
Problém je v tom, že stránka co má vrátit potvrzení že byl příspěvek vložen do databáze tím že napíše ok, je ta samá stránka, co vykresluje obsah. Takže místo samotného textu ok se vrátí spousty kódu a vyhodnotí se to, jako že se nepodařilo vložit příspěvek. To samé se děje při aktualizování zpráv. Doporučoval bych tedy dát obsluhu db do jiného souboru, nebo současný skript upravit tak, aby vracel při požadavku na db pouze odpověď bez okolního html.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0