I found a chatroom script online and have heavily modified it so that the data is stored in a database instead of text files and so that the only messages that the PHP file would return are the new messages. Every time the AJAX function is called (every 5 secs) it adds "[object Document] to the div box I want the messages in. I am not a very good JavaScript/AJAX programmer, so I came here for some help. Original Script: http://robertdot.org/2006/06/23/how-to-make-an-ajax-chat-room/ Affected Function in the JS File: function loadXMLDoc(url,query_string,callback) { xml_obj = false; if(window.XMLHttpRequest) { try { xml_obj = new XMLHttpRequest(); } catch(e) { xml_obj = false; } } else if(window.ActiveXObject) { try { xml_obj = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { xml_obj = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { xml_obj = false; } } } if(xml_obj) { xml_obj.onreadystatechange = callback; xml_obj.open("POST", url, true); xml_obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xml_obj.send(query_string); } else{ alert("Failed to create XMLHttpRequest!"); } } function messagesRetrieved(){ if (xml_obj.readyState == 4){ if (xml_obj.status == 200 && xml_obj.responseXML){ output = xml_obj.responseXML; var current_messages = document.getElementById("chat_area").innerHTML; document.getElementById("chat_area").innerHTML = current_messages+output; } } } Code (markup): Affected Part of PHP File: $time = time(); $time2 = $time - 30; session_start(); $blank = ""; function tsv_to_xml(){ if(isset($_SESSION['lastquery'])){ $lastquery = $_SESSION['lastquery']; if($lastquery > $time2){ $select = mysql_query("SELECT * FROM chatroom_messages WHERE time>$lastquery ORDER BY time"); $return = "<br />"; while($row = mysql_fetch_array($select)) { $return .= "<b>"; $return .= htmlentities($row['uname']); $return .= ":</b> "; $return .= htmlentities($row['message']); } $_SESSION['lastquery'] = $time; $return .= "</messages>"; return $return; } else { $_SESSION['lastquery'] = $time; return $blank; } } else { $_SESSION['lastquery'] = $time; return $blank; } } PHP: So do I need to do anything special with the data with JS, or am I doing something wrong with my PHP? I was using the PHP to do XML, but it wasn't working so I decided to do it this way. I would really appreciate it if you guys could help me out here. Thanks.
erm, xml_obj.responseXML is an object. you can iterate the children/properties an d output html accordingly. or you can output responseText as a string direct. can't output the object automatically though, one or the other. you'd have to change the response to a non xml one and just output html formatted strings instead - probably the best solution.
Thanks dimitar_christoff, but it still isn't working. The PHP is outputting HTML (I assume?). I changed the JavaScript to: if (xml_obj.status == 200 && xml_obj.responseXML){ output = xml_obj.responseText; Code (markup):
There is many things wrong with this. The php is outputting poorly formatted xml, I don't know php but as far as I can see it is specifying the end of a block with </messages> but I can't see the start of it. And even so the javascript is not reading the response as xml but just displaying it. Also, including html within an xml response is not a good idea, because it stuffs it all up.. you want to use tags like (for bold) etc and convert them to html with the javascript. BTW, I wouldn't rely on a script that has been originally coded using text-files to store data...
I did not notice that I was outputting </messages> as well. I had decided not to do XML if I could help it, but apparently I forgot to erase that line. So it's not outputting poorly formatted XML, but I guess it's outputting HTML with the excess </messages> tag (trying to make myself feel better ). That's what I want, but is it possible without using XML and doing stuff to it with JavaScript? In other words, can I output HTML with the PHP and just use the response text with the JavaScript?
Yeah, just output the response text... output = xml_obj.responseText; var current_messages = document.getElementById("chat_area").innerHTML; document.getElementById("chat_area").innerHTML = current_messages+output; Code (markup): although this could be, much shorter: document.getElementById("chat_area").innerHTML += xml_obj.responseText; Code (markup): What is this returning? Can you provide a link to an active example?
It isn't returning anything. I added an alert after where it is supposed to enter the text and a blank message box pops up. I shortened the response output as you suggested. So, I'm assuming that the PHP isn't sending anything? Sorry, I can't give an example.
If so, wouldn't it mess up the script when I'm trying to add a message? The messages are inserted into the database just fine.
Well i'm stumped, i can't see the problem.. I take it that you do realise that it will return blank if no new messages have been added since last checked. The only other thing I can think of is this> WHERE time>$lastquery part of the query string may not work properly, but I don't have any knowledge of php... If the time field is a date/time field then aren't time/date values normally surrounded with ## ? E.g WHERE time>#$lastquery#
Oh yes of course. I even tried to get it to select all of the messages with no luck. Thanks for the help.
By the way, I didn't see your edit to your post. The suggestion didn't work, but I've ruled that out as a problem now. It's working halfway, but it's not quite there. What I have now: function tsv_to_xml(){ if(isset($_SESSION['lastquery']) && time() - $_SESSION['lastquery'] < 60){ $lastquery = $_SESSION['lastquery']; $select = mysql_query("SELECT * FROM chatroom_messages WHERE time>$lastquery ORDER BY time"); $data = ""; while($row = mysql_fetch_array($select)) { $data += "<b>"; $data += htmlentities($row['uname']); $data += ":</b> "; $data += htmlentities($row['message']); $data += "<br />"; } $_SESSION['lastquery'] = time(); echo $data; } else { $_SESSION['lastquery'] = time(); return $blank; } } PHP: This is outputting numbers correctly, but with text it's outputting "0". What do I need to do to output text as well? EDIT: Don't really know what happened there, but it's outputting everything fine now. The only problem I'm having is Chrome isn't doing anything with the JavaScript. I know the AJAX works because the function I made to get the list of online users is working. JavaScript is below. function loadXMLDoc(url,query_string,callback) { xml_obj = false; if(window.XMLHttpRequest) { try { xml_obj = new XMLHttpRequest(); } catch(e) { xml_obj = false; } } else if(window.ActiveXObject) { try { xml_obj = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { xml_obj = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { xml_obj = false; } } } if(xml_obj) { xml_obj.onreadystatechange = callback; xml_obj.open("POST", url, true); xml_obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xml_obj.send(query_string); } else{ alert("Failed to create XMLHttpRequest!"); } } function messagesRetrieved(){ if (xml_obj.readyState == 4){ if (xml_obj.status == 200 && xml_obj.responseXML){ document.getElementById("chat_area").innerHTML += xml_obj.responseText; } } } function get_xml(){ loadXMLDoc("request.php","action=get_xml",messagesRetrieved); setTimeout("get_xml()",5000); } Code (markup):
Is Chrome giving you an error message? I know that chrome supports XMLHttpRequest.. Another thing: Try changing: if (xml_obj.status == 200 && xml_obj.responseXML) to responseText.. just in case, becasuse it isn't really XML that you are retrieving. Also, maybe try using GET instead of POST considering that you are not sending a great deal of information, just (action=get_xml).. so try changing: xml_obj.onreadystatechange = callback; xml_obj.open("POST", url, true); xml_obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xml_obj.send(query_string); to: xml_obj.onreadystatechange = callback; xml_obj.open("GET", url + "&" + query_string, true); xml_obj.send(query_string); Also, on another note, you will want to make sure the page isn't cached. I'm not sure about PHP but in ASP you do this by using: Response.Expires = -1 on the server side, or alternatively you can add a random number to the querystring in javascript e.g: r = Math.floor(Math.random()*20001); xml_obj.onreadystatechange = callback; xml_obj.open("GET", url + "&" + query_string + "?r=" + r, true); xml_obj.send(query_string);
this is why people invented frameworks as an abstraction layer that takes care of incompatibilities - so you dont have to worry about what browser supports what. just issue the xhr request and enjoy the results - it will work if it does support it. period.
I have never had a problem with chrome and ajax... maybe because the Content-Length parameter isn't set? xml_obj.onreadystatechange = callback; xml_obj.open("POST", url, true); xml_obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xml_obj.setRequestHeader("Content-length", query_string.length); xml_obj.send(query_string); Code (markup): I'm unsure of whether it is necessary but normally I do it regardless... and it must be there for a reason/
erm, not as if a problem described as 'does not work in chrome' means anything. chrome has an error console, after all...
Never really noticed, i'm not a big fan of chrome, I like to have a menu system at the top of any app, which is why I don't like office 07 (i installed the add-in to bring back the menu's)... but then again chrome is still in its early years.