IFrame problem, PLEASE HELP!

Hi, I am building a chat/messenger application using PHP and Javascript.

I currently have two iframes, one has the chat, the other the users in the database and their status, which is set to default ‘offline’ and updated to ‘online’ when logging in.There is also an option to change colour of both iframes like so:

function change_background_pink() {		document.frames.chatContents.document.body.style.backgroundColor="pink";  

and then this code to call the function:

<BUTTON onclick=change_background_pink()>Pink</BUTTON>

The problem is, that when the frames refresh, the background of the users frame goes back to the default white colour (the text does change to show newly logged users), yet the chat one stays the newly selected colour as intended (again the text changes as required).
Here is the code of the iframe as it stands now:

<?php
	include("connect.php");
		$query=mysql_query("SELECT * FROM users;");	
		echo "<table style='font-family:arial;font-size:14px;'>";
					//
					echo "<th align=left>Username:" . "<th align=left>Status:";
					//while loop for rows					       
                    	while($rows=mysql_fetch_array($query)){
                            echo "<tr>";			
								//show member deatils
                            	echo "<td>" . $rows['username'] . "</td>" . "<td>" . $rows['status'] . "</td>";   
                            echo "</tr>";							
                        }
?><script type="text/javascript"><!--
	setTimeout("refreshiframe()", 10000); //poll server        	
function refreshiframe(){
            document.location.reload();
		} //-->
</script> 

What I am asking is if anybody knows how i can just refresh the actual text part of the frame from the database rather than the entire frame?

Many, many thanks in advance for any advice i may recieve and sorry if it sounds confusing i cannot think of a simpler way of explaining it.

You could take a look at AJAX instead of reloading the iframe each time.
Here is a tutorial on how to do that: http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=9

Also, when you use that you could (if you want) get rid of the iframes and use normal div’s with CSS overlow: auto :slight_smile:

Tahnks ScallioXTX ive followed the tutorial and it works a treat :slight_smile: I was just wondering though how do I get rid of the IFrames using CSS overflow? Using CSS would give me the option to fully customise is (user-side), i.e. change background colour/font etc. Thanks again for the link, that is EXACTLY what I was looking for, I am very, very greatful…

As a very crude example of how I would use a <div> and overflow: auto; for a chat


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>AJAX Chat with a <div></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <style type="text/css">
      html,body {
        margin: 0;
        padding: 0;
        background: #fff;
        color: #000;
      }
      #page {
        width: 700px;
        margin: 20px auto 0;
      }
      #chat {
        background: #fff;
        color: #000;
        border: 2px solid #000;
        height: 500px;
        overflow: auto;
      }
    </style>
    <script type="text/javascript">/* <![CDATA[ */
      function updateChatBox()
      {
        // This function would normally get new chats with AJAX
        // But I'll just simulate it using some gibberish

        // This generates some random gibberish
        var chars='aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789 ';
        var l=5+Math.floor(Math.random() * 15);
        var str='';
        for (var i=0; i<l; i++) {
          str += chars.substr(Math.floor(Math.random()*chars.length), 1);
        }
				
        // Put the gibberish in the chat -- normally here you would put any new messages obtained through AJAX in the text
        document.getElementById('chat').innerHTML += '<strong>User' + (Math.floor(Math.random()*5)+1) + '</strong>: '+str+'<br />';

        // Make sure the div scrolls to the bottom so users don't have to scroll manually
        // Note: I haven't tested this cross-browser, but it works in FF and you should get the idea :)
        document.getElementById('chat').scrollTop = document.getElementById('chat').scrollHeight;

        // Fire this function again.
        // Here I used a random time out to make the chat look more realistic
        // But in a real world setting with AJAX you would use a fixed value, like 1000
        setTimeout(updateChatBox, Math.floor(Math.random()*750)+250);
      }
      window.onload = updateChatBox;
    /* ]]> */</script>
  </head>
  <body>
    <div id="page">
      <div id="chat">
      </div>
    </div>
  </body>
</html>

If you want multiple themes, just put them in the <head> of your HTML as alternate stylesheet. For example:


<link rel="alternate stylesheet" title="yellow" type="text/css" href="/styles/themes/yellow.css" />

And then use a simple JavaScript stylesheet switcher (tutorial) to change enable/disable the stylesheet of your liking when a user clicks a button for a certain theme. The tutorial I linked to above uses cookies, so when the user reloads the page they will still see the theme they selected earlier (though they might see a flash of the default theme first, just a few ms).

Note: I use inline CSS and inline Javascript for this example, but if you use this it would be better to turn them into external versions (a .css file and a .js file)

thanbk you scalio that is brilliant, i will try it later…thank you very, very much for the advice :slight_smile:

You’re welcome :slight_smile:

If you have any more questions feel free to ask :slight_smile:

Hi Scalio thanks for the advice you have given me, i have studied the AJAX tutorial, and it works much, much better.
I started doing it in Javascript/PHP with iIFrames. There was a simple chat IFrame with another IFrame which says all the users in the database and their status (table attribute offline default which changes to online when a user logs in). The problem with this was I set a timer for 10 seconds so it will check/refresh for changes in the database (i.e. somebody logs in/out) but it flickered when it refreshed.

This is on the parent page:

<iframe id="users" name="users" src="users.php">
            </iframe>

and this on the page it refers to:

<?php
	include("connect.php");
		$query=mysql_query("SELECT * FROM users;");	
		echo "<table style='font-family:arial;font-size:12px;'>";
					//
					echo "<th align=left>Username:" . "<th align=left>Status:";
					//while loop for rows					       
                    	while($rows=mysql_fetch_array($query)){
                            echo "<tr>";			
								//show member deatils
                            	echo "<td>" . $rows['username'] . "</td>" . "<td>" . $rows['status'] . "</td>";   
                            echo "</tr>";							
                        }
?>
<script type="text/javascript"><!--
	setTimeout("refreshiframe()", 10000); //poll server
       	function refreshiframe(){
            document.location.reload();
		} //-->
</script>

I was wondering if you know of a way to do this with AJAX, preferably without using IFrames?
Again thank you for sharing your expertise, it is appreciated immensely :slight_smile:

This can certainly be done via AJAX also, but it’s a bit more complicated than the main chat box (well, you could make it as easy as the main chat box, but that would be inefficient, and I don’t like inefficient :)).

The first thing to do is ditch the iframe (yay!) and create a div in its place. Again with overflow auto as their may be more users logged in than the height of the div can accommodate for.

Next, in your main script (the one that shows the chat div and the online div) show all people who are online the “online” div, just like you are showing them no in the iframe (though I would personally prefer <divs> in stead of tables, but I’ll leave that up to you).

So now you have all users on the page, and behind their name there is the text whether they are online or offline.

What is interesting here is that all you have to do is change text online/offline if that ever changes. What I would do is create some php file like checkOnline.php and let that return and XML much like the XMLs created for the messages in the tutorial I showed you.
Something like this:


<members>
 <member>
  <id>1</id>
  <status>1</status>
 </member>
 <member>
  <id>2</id>
  <status>0</status>
 </member>
 ...
</members>

So you get for every member their id, and whether they are online (status 1) or offline (status 0).
Note that we could have also used “online” and “offline” for the status, but 0 and 1 is just as clear and saves a few bytes. In the javascript side of things you can then show “online” of the status is 1 and “offline” if the status is zero.

Now, in the member list you’ve created (the one that’s showing in the div now), incorporate the id of the user in the id of the element that shows online/offline for each user. i.e.


<div>User1</div><div id="status_1">online</div>
<div>User1</div><div id="status_2">offline</div>
...

That way you can easily find the <div> that describes if a user is online or offline given their user id, and the javascript can be something very simple, like


function handleReceiveOnlineStates() {
if (receiveReq2.readyState == 4) {
var xmldoc = receiveReq2.responseXML;
var member_nodes = xmldoc.getElementsByTagName("member");
var n_members = member_nodes.length
for (i = 0; i < n_members; i++) {
var userid_node = member_nodes[i].getElementsByTagName("id");
var status_node = member_nodes[i].getElementsByTagName("status");
document.getElementById('status_' + userid_node[0].firstChild.nodeValue).innerHTML=status_node[0].firstChild.nodeValue ? 'online' : 'offline';
}
mTimer = setTimeout('getOnlineStates();',2000);
}

Note that I’ve used receiveReq2 here, because if you were to use receiveReq for this as well then two (receive chats and receive online list) might cross paths and that would screw everything up.

The handleReceiveOnlineStates is similar to the handleReceiveChat function in the tutorial I gave earlier, and needs a function making the request to the server to initialize it: getOnlineStates().
Given the tutorial and my text above I’m sure you’ll know how that function would go :slight_smile:

As an aside, I wouldn’t use the text “online” / “offline”, but something like a green light for people who are online, and a red light (or no light) for people who are offline (like the SitePoint forum has, check out the images on the bottom left corner of each post). IMO that looks a lot clearer than text “online”/“offline”. Mostly because these texts are so similar :slight_smile:

Once again thank you ScallioXTX, that is superb…thank you so much for your time :slight_smile: