1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

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