Creating Chatroom: AJAX Returning [object Document]

Discussion in 'JavaScript' started by wierdo, Nov 21, 2009.

  1. #1
    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. :eek:

    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.
     
    wierdo, Nov 21, 2009 IP
  2. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #2
    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.
     
    dimitar christoff, Nov 22, 2009 IP
    wierdo likes this.
  3. wierdo

    wierdo Well-Known Member

    Messages:
    1,646
    Likes Received:
    45
    Best Answers:
    0
    Trophy Points:
    140
    #3
    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):
     
    wierdo, Nov 22, 2009 IP
  4. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #4
    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...
     
    Last edited: Nov 23, 2009
    camjohnson95, Nov 23, 2009 IP
  5. wierdo

    wierdo Well-Known Member

    Messages:
    1,646
    Likes Received:
    45
    Best Answers:
    0
    Trophy Points:
    140
    #5
    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 :eek:).

    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?
     
    wierdo, Nov 23, 2009 IP
  6. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #6
    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?
     
    camjohnson95, Nov 23, 2009 IP
  7. wierdo

    wierdo Well-Known Member

    Messages:
    1,646
    Likes Received:
    45
    Best Answers:
    0
    Trophy Points:
    140
    #7
    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.
     
    wierdo, Nov 23, 2009 IP
  8. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #8
    Yeh, Could it be that 'Time' (one of your database fields) could be reserved word in SQL?
     
    camjohnson95, Nov 24, 2009 IP
  9. wierdo

    wierdo Well-Known Member

    Messages:
    1,646
    Likes Received:
    45
    Best Answers:
    0
    Trophy Points:
    140
    #9
    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.
     
    wierdo, Nov 24, 2009 IP
  10. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #10
    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#
     
    Last edited: Nov 24, 2009
    camjohnson95, Nov 24, 2009 IP
  11. wierdo

    wierdo Well-Known Member

    Messages:
    1,646
    Likes Received:
    45
    Best Answers:
    0
    Trophy Points:
    140
    #11
    Oh yes of course. I even tried to get it to select all of the messages with no luck.

    Thanks for the help.
     
    wierdo, Nov 24, 2009 IP
  12. wierdo

    wierdo Well-Known Member

    Messages:
    1,646
    Likes Received:
    45
    Best Answers:
    0
    Trophy Points:
    140
    #12
    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):
     
    Last edited: Nov 24, 2009
    wierdo, Nov 24, 2009 IP
  13. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #13
    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);
     
    camjohnson95, Nov 25, 2009 IP
  14. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #14
    That way you can be sure that the browser is not loading a cached version of the page.
     
    camjohnson95, Nov 25, 2009 IP
  15. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #15
    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.
     
    dimitar christoff, Nov 25, 2009 IP
  16. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #16
    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/
     
    camjohnson95, Nov 25, 2009 IP
  17. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #17
    erm, not as if a problem described as 'does not work in chrome' means anything. chrome has an error console, after all...
     
    dimitar christoff, Nov 25, 2009 IP
  18. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #18
    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.
     
    camjohnson95, Nov 25, 2009 IP