R
E
S
O
U
R
C
E
S
       Home      Products & Services      Contact Us      Links


WebHatchers will design & develop your site for you.
_______________________

Website Menu Heaven: menus, buttons, etc.
_______________________

Send us your questions.
_______________________

site search by freefind
_______________________

HOME
SEO, Google, Privacy
   and Anonymity
Browser Insanity
JavaScript
Popups and Tooltips
Free Website Search
HTML Form Creator
Animation
Buttons and Menus
Counters
Captchas
Image Uploading
CSS and HTML
PHP
AJAX
XPATH
Website Poll
IM and Texting
Databases—MySQL
   or Not MySQL
Personal Status Boards
Content Management
   Systems
Article Content
   Management Systems
Website Directory
   CMS Systems
Photo Gallery CMS
Forum CMS
Blog CMS
Customer Records
   Management CMS
Address Book CMS
Private Messaging CMS
Chat Room CMS
JavaScript Charts
   and Graphs




Free Personal Status Boards (PSB™)

Free Standard Free PSB

Free PSB Pro Version

Free Social PSB

Free Social PSB Plus (with Email)

Free Business PSB

Free Business PSB Plus (with Email)

PSB demo

Social PSB demo

Business PSB demo

So what's all this PSB stuff about?

Chart comparing business status boards

PSB hosting diagram

PSB Licence Agreement



Copyright © 2002 -
MCS Investments, Inc. sitemap

PSBs, social networking, social evolution, microcommunities, personal status boards
PSBs, social networking, business personal status boards
website design, ecommerce solutions
website menus, buttons, image rotators
Ez-Architect, home design software
the magic carpet and the cement wall, children's adventure book
the squirrel valley railroad, model railroad videos, model train dvds
the deep rock railroad, model railroad videos, model train dvds

Content Management System — Chat Room Home Page Tutorial



The above links go to other chat room script tutorials. Here is the chat room home page script tutorial. The chat room home page script below does many things. It has several AJAX functions that interface with various PHP scripts, therefore this page never reloads—its displayed content gets changed only when AJAX routines change the innerHTML on one div at a time. It gives users Public chat and Private chat options. It displays the most recent comments in the chat window every 8 seconds, which it does because a timer runs the running of a couple AJAX scripts. It offers a dropdown for users to use for selecting Private chat partners, and once the other user agrees to the Private chat the script displays only the comments of one person and his or her chat partner. It contains a form in which users can type in their chat comment, and they can add emoticons to any comment. It has instructions for using our custom tags so users can enjoy links, email links, bold, underline, or italics in their comments. We make them use OUR tag syntax for security reasons. It inserts a scroll bar in the chat window whenever the window has too many comments to fit its space and it scrolls the div contents upwards as needed. Finally, it dumps old chat content when the window is too full.

Here are the emoticons we use: http://www.aglasshalffull.org/emoticons/ which are on a different one of our sites since css-resources.com has restricted access except for the website pages. If you want them, center the cursor on each, below, and right click and select Save Image As in Firefox or Save Picture As in IE and put them into a folder called emoticons. Or use the link above and click on each gif link and save them that way. Then the code below will work right. This assumes you select and save all the bold code blocks from the pages whose links are above, plus the code below with the names recommended, have an available MySQL database, and you configure a config.php file with your server and database info, since without it, this MySQL-based app would not be viable. You cannot relate to a db without knowing the magic words.











The emoticons are from http://www.freewebstuff.be/ whose terms of use says that All graphics (it means animated gifs, arrows, avatars, backgrounds, banners, bullets, buttons, icons, lines, logos, shapes, smileys) on this site are available for public use in whichever way you like. Feel free to go to this site and grab whatever emoticons you feel you need. Don't forget to link to them like we're doing here as a way of thanking them for free use of their content! Aren't they cool? We got a bit carried away when we used 4 full rows of animated gif emoticons. You may find that users typing chat content experience a dropped character now and then. If this is a problem for you, don't dump the emoticons you save using the last paragraph's instructions. Instead, go to the most active of the gifs and load them into a graphics program and save one frame as the entire gif. One easy way to do this is do a PrintScreen (the PrtSc key) and load that result into a graphics program such as ImageForge by creating a new blank image 1024 x 768 pixels, then use Ctrl v to paste in the PrintScreen result. Use the scissors tool to select various gifs and save them with the correct name. You'll find that as soon as you relieve your chat home page of some of this lively—but processing-intensive—gif activity, the dropped character problem will go away.

The code starts with the JavaScript function textCounter(), which is set up to show a counter of the number of characters a user has typed as chat input and stop allowing input when the 252 allowable characters is exceeded. Then there's the fix() function which tweaks screen display depending on browser. Then we define lots of variables, including a couple of arrays, one of which we stick full of empty strings. Next is the timedout() function, which displays in the chat screen the fact that someone has timed out—which means no input for 320 seconds. Then there is the quit() function which runs a special PHP page when a users exits the script. You'll find that the body tag contains onunload="quit();". This runs the PHP file quit.php where his db table record fields are adjusted to indicate "logged out."

Then, the checkdb() AJAX function goes out to grab the newest chat entries, every 8 seconds, from the MySQL db table where they are stored. It sends the results to an offscreen div, using AJAX's xmlhttp.responseText for results holding. The results are processed and then stuck in the chat window's div using innerHTML, the choice made by most AJAX programming for displaying results. Let's look at our checkdb() AJAX function in more detail. The first line gets the time. But not to display it with chat results as you might think. Instead, it's to prevent the browser's annoying habit of using cached results rather than new AJAX xmlhttp results when you update your target div. Let us explain:

Browsers love to cache things to keep the Internet, the servers, and the browsers as efficient as possible. When you POST or GET to a PHP page and this reloads the page, the reloading prevents the browser from giving you old cached results since there's evidence you're after new results from the POSTs, GETs, and reloads. So you get the new result you're after. But with AJAX, there is no reloading of pages and the POSTs or GETs are done sneakily, under the radar, using xmlhttp, which AJAX, which is Asynchronous JavaScript and XML, uses to get results sneakily. AJAX is a technique for creating fast and dynamic web pages. AJAX allows web pages to be updated asynchronously by exchanging small amounts of data with the server behind the scenes. So, as we have been saying, this means that it is possible to update parts of a web page without reloading the whole page. Normal websites do not use AJAX, so they must reload the entire page to alter content. So a standard, and clever, way to avoid the caching dilemma is to stick the time in the URL query string used in the xmlhttp.open() function that sends values to PHP (or other languages) scripts on the server. The URL will be different every time you use this function, because the time will never be the same twice, so this will mean "new page coming" to the browser so it will make no attempt to lay old cached pages on you. Note the variable t and its time value in our xmlhttp.open() function. Problem solved.

The second line uses the getElementById() method to make a couple of divs easier to reference. Later in this AJAX function, b.innerHTML and jj.innerHTML will make sense to the function as a result of these referencing shortcuts. In the next 2 lines, a countem variable and a timeouts variable get incremented. The former will be used later in the function to limit how full the chat window gets. When the timeouts variable hits 40, the timedout() function already discussed will run. The next 4 lines declare the xmlhttp variable in one of 2 ways as a xml request object, depending on whether you're in the IE5 or IE6 browser, or in any other browser not those 2. The next 2 lines are the standard AJAX protocol for xmlhttp:

xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){


The idea is to wait until the server readiness has the correct code for an asynchronous interfacing with the PHP (or whatever) script. The next 2 lines get the results in the xmlhttp.responseText object, which we stick into an offscreen div so nothing unsightly happens onscreen, then we process it in the check() function which we'll peruse later, sticking the processing results in the v variable which we now display onscreen in the chat window. This one variable can contain several lines of chat from several different users, separated by <BR> tags. In the next 5 lines, we define the xmlhttp.open() function's task: what scripts to call on the server and what variables to send them. If the startup flag is set (which happens only once—after login), we run the start.php script; otherwise we run the checkdb.php script. The start script gets the last 64 seconds of results from all the chatters and sends it back to the AJAX script that called it, and it holds all this chatter in the xmlhttp.responseText which it quickly sticks in the empty chat window so this newcomer will have content to relate to. Finally, if the countem counter has reached 40, we zero it (restart it) and check the number of characters in the chat window. If it's 700 or more, we dump the first 500 characters, leaving only the newest comments. The statement h.substr(500) tells the script to get everything after the first 500 characters.

The logins() AJAX function is next, but to understand it, let's first look at the tiny function that comes after it:

function timer(){
logins();checkdb();
setTimeout('timer()',8000);}


The logins() function is run immediately prior to the checkdb() function EVERY 8 SECONDS while the chat room is going. The first function loads the Online Now right sidebar with AJAX results and the second one appends the chat window content with other AJAX results. This timer() function is started up by an onload in the body tag. The logins() function is run as synchronous AJAX, but the checkdb() function is run as asynchronous AJAX. It's better to avoid synchronous AJAX, since it stops all processing until the results return. But when we tried to run them both asynchronously, AJAX proceeded to demonstrate just how asynchronous it could get by mixing the results from these 2 AJAX scripts. To prevent mixing, we used synchronous AJAX first so that the second script was not allowed to run until the first script's results were neatly and safely tucked away in a different div.

The logins() function runs its xmlhttp variable declaration and browser-specific request object the same as the asynchronous AJAX function, but it skips the onreadystatechange state httpxml stuff because it does not care about the server's readiness—it just gives the server a task and waits until the results come back before proceeding. Like asynchronous AJAX scripts, we avoid the cache problems by sticking a time function in the URL query string. But unlike the asynchronous script, we use false, not true, as the last parameter in the xmlhttp.open() function. The word false indicates: "no asynchronous for me, thank you." We stick the xmlhttp.responseText result right into the innerHTML of the div, and process it afterwards. We check out the last 14 characters returned. If they are "(private chat)", then we change the user's status buttons so the Public one is no longer highlighted and the Private one is highlighted, using the button_private() function. Then we increment the priv_start variable. If this is the first time we've been in Private mode since the logins() function was run, the priv_start variable will be a 1 so we dump the chat room window contents, replacing them with "PRIVATE". If the last 14 characters returned from the AJAX routine are not "(private chat)", the button_public() function is run, and we change the user's status buttons so the Public one is highlighted and the Private one is no longer highlighted. If the last 14 characters are hyphens, we zero the priv_flag, set the priv_name variable to an empty string, change the mode to "public", and run the processing() function, which puts a "PROCESSING" notice in the chat window for 8 seconds. This is because the 14 hyphens are a signal to a user's chat page that their private chat partner has pressed the Public button, signalling the end of their private chat session, so his JavaScript variables needed updating so they'll match the statuses of the MySQL db table flags and status fields.

Next come the browser sniffers, needed because Firefox and Opera need a bit different CSS for display styling. These differences are handled from the body tag's onload function running the fix() function, which tweaks the display. The next function is from Eric Pascarello of radio.javaranch.com/pascarello/. It's run by putting divScroll.activeScroll() wherever you need it—in our case, that would be the checkdb() and ajax() functions. This script inserts a scroll bar in the chat window whenever the window has too many comments to fit its space and it scrolls the div contents upwards as needed. He's tested this on lots of browsers and we weren't too inclined to reinvent the wheel and conjure up a similar script and do all that testing, so we tried his script out, were pleased, and decided to use it, giving him credit and the courtesy of a link, the standard Internet "thank you" for utilizing other programmers' good works. (Hint hint.)

The next function is function no_enter(e), which stops users from submitting with the Enter key when they're typing comments. We need the submit button to do the submitting, for various technical reasons too boring to explain. The next function is pre_ajax(), and it checks when the user submits a comment whether or not he has timed out, and if he has not, the ajax() AJAX function is run. If he has, no submitting of content is allowed, although the user is welcome to watch others chat forever. Or s/he can log in again and be able to submit chatter.

Next comes the ajax() function, which sends user chatter to the MySQL db table to be stored (up to 5 comments from each user are stored, and as more comments arrive at the db, the oldest gets its oldest comment field's data replaced by the new comment and so on, so that only the most recent 5 comments are available in the db for the checkdb() script to find (by using the checkdb.php script) and display. Note that the first line of ajax() insists that empty form submissions are ignored. Looking at the next 2 lines, if the user has timed out, his/her chatter is ignored. But if he or she has not timed out, the script's timeout flag is zeroed since the flag represents time since the last submission and being in this function is usually about a submission is now occuring.

Flags that act as counters that go to 40 are not a mystery when you see that the incrementing happens once every 8 seconds and therefore letting them get to 40 means 320 seconds—over 5 minutes. That seems like a reasonable time period before one is timed out for nonactivity. Similarly, the countem flag going to 40 in the checkdb() function represents checking every 320 seconds to see if the chat window is filling up too much.

Back at the ajax() function, the next 6 lines that follow the document.getElementById() method do the following: escape the chatter content for safety in URL query string transporting, and escape the plus and forward slash separately because the escaping routine doesn't process these. (The chatter will be unescaped when it gets to its php.php destination.) Next, the chat form is emptied, and the character counter set back to 252, and the cursor made to stay in the chat input box via the focus() function.

The xmlhttp stuff has already been covered in the checkdb() script discussion. Next, we pretend to get xmlhttp.responseText from ajax(), but since the way one sends this response from PHP is to echo something, and the php.php script that ajax() runs has only data storage in the MySQL db table and no echo, this code is just a hangover from when we tried to have this be the only script needed for chat (php.php had echoes at first, until we learned better), but this was a nonstarter. So we left xmlhttp.responseText there to be cute and to preclude problems from not having it, but there are none. If you don't echo, there's no xmlhttp.responseText happening. Finally, the xmlhttp.open() function is needed to send the data to the MySQL db table for storage, and again the query string holds all the data to be stored. Again, to avoid cache problems we stick the time in the URL query string used in the xmlhttp.open() function that sends values.

Next comes the check() function which processes xmlhttp.responseText that the checkdb() AJAX routine returns. After processing it gets displayed on the screen by appending the chat window content. But the check() routine itself does the following: Splits a big long string with multiple comments separated by "|" characters into an array of comments without "|" characters anywhere. Whips through the array, dumping duplicate elements that it finds as it compares itself and a recent comments array. Sticks new comments into the recent comments array for later comparison purposes. Finally, concatenates all the comments together into one string variable: v. The first line takes the content that the checkdb() script stuck in the offscreen div jj and sticks it into the variable a. The second line dumps the first "|" character from the a variable. This character is just a useless remnant of the way the checkdb.php script added this to the beginning of each comment before concatenating all the comments together into one string variable to echo to the AJAX xmlhttp.responseText. The next line splits the a variable into an array called arr. The while loop is obvious stuff, with the if conditional if(recent[i]==arr[j]){arr.splice(j,1);} looking for matches between the recent[] and arr[] element values and, finding them, dumping this element from the arr array using the JavaScript splice function. Next a for loop sticks all its values into the recent[] array. Once the element number counter exceeds 18, we start back at element 0. Finally, the last loop concatenates all the comments together into one string variable: v.

The next function is sending(), which changes the label on the chat entry input box Submit button to "sending" and disables the button for 5 seconds, after which it runs the done() function, which changes the label on the Submit button back to "Submit" and re-enables the button.

Then comes the function private(), which fills the priv_name variable with the form value of the submitted dropdown form containing the screen names of those online now. The point of this dropdown is to give users a menu of screen names to select from to choose a private chat partner. Then the go_priv and priv_flag flags get zeroed. Next the user is shown a confirm dialog that asks him/her: "[screen name of selected user] will be asked if he or she wants to chat with you, [your screen name], and if s/he does, your Private Chat button will turn blue. OK?" If you press CANCEL to change your mind about sending this private chat request, the priv_name variable is emptied and the mode variable changes to 'public'. If you press OK to accept sending this request , the processing() function is run, displaying the word "PROCESSING". Then the mode variable is changed to 'private', the priv_flag variable gets a 1 dumped into it, the chat entry form value turns into '._..q...v_.z__._k_.', which is a code for "I will proceed with my process of offering that user a private chat". Next the go_priv variable is changed to 1, the ajax() function is run so the code is sent to the PHP scripts, and the priv_flag variable is changed to 2.

If you click either the Public or Private button, the modes(i) function is run with the new mode value in the i variable, the processing() function is run, displaying the word "PROCESSING", and the mode variable gets the i value. If you have selected the Private button, the variable priv_flag gets a 2 and the variable go_priv gets a 1, all of which means you have accepted a private chat offer from another user. If you have selected the Public button, the variable priv_flag gets a 0 and the variable go_priv gets a 9 and the priv_name variable gets an empty string and the button_public() function is run, turning the Public button blue, all of which means you have ended or refused a private chat with another user.

The function button_public() turns the Public button blue and the Private button grey. The function button_private() turns the Public button grey and the Private button blue. The function processing() moves the sign "PROCESSING" from offscreen to the middle of the chat window for 8 seconds, after which it runs the doner() function, which moves it back offscreen. Next come the CSS styles. Then comes the body tag, with an onunload event function that logs people out in the MySQL db table when they leave the chat site. It also has 2 onload events: the first tweaks the screen display according to browser quirks and the second starts up the timer that, every 8 seconds, runs both the logins() AJAX function that updates the right sidebar's Online Now display and the checkdb() AJAX function that updates the chat window display.

Next, there are 5 divs in a row. The first is the page title. The second is the chat window where the action is. The third is the right sidebar's content that tells who is Online Now. The fourth is the offscreen invisible div that gets the xmlhttp.responseText from 2 of the AJAX functions and processes it before displaying it in the chat window. The fifth is a sign, "PROCESSING", in large red letters, that is normally offscreen but gets stuck on top of the chat window when various changes are occuring that take 5 or 10 seconds to process, such as a person asking another person for a private chat, a person accepting a private chat, a person refusing a private chat, or a person deciding to leave a private chat and return to public chatting.

On to the PHP code. As usual, we start with config.php, since without it, the MySQL-based app would not be viable. You cannot relate to a db without knowing the magic words. Next we GET the username and startup flag from the PHP script that sent us to this script, which is the cms-chat-room.php script. The username and startup flag got sent to this script via the URL query string from the chat-room-login.php script, which is the user's login. Then if the user name is looked for in the db table and it's not there, the user is sent to the login script. Next the $gifs array is declared and the emoticons' names are gotten from a db table called emoticons and stuck, using PHP's array_push function, into the $gifs array. These 53 emoticons' gif names are used to display the emoticons in an onscreen table in 3 rows. The gif images themselves are in a chat room folder called emoticons. So you can see why the echoed image source code SRC='emoticons/".$gifs[$i]."' would work. The link attached to each gif is not much of a link—it doesn't even have an end tag. It's just a place to stick an onclick event that runs the emot() function. It sends the gif's name to that function as a parameter. This function sticks this gif name between 2 of our custom image tags and then appends all this to the chat input box's current chat comment in progress of being typed or just finished being entered. Feel free to stick emoticons anywhere in comments, or even have them BE the comment. Next the user's screen name is gotten from the chatroommembers db table—it will be used with any comment. Finally the custom tag info sidebar is echoed to the left side of the screen. It has instructions for using our custom tags so users can enjoy links, email links, bold, underline, or italics in their comments. We make them use OUR tag syntax for security reasons. Below that is echoed the Login and sign-up links and the Public and Private buttons.

Next comes the HTML chat entry box script. Since the submit button is type "button" and not type "submit," the form tag action is not relevant. The chat input is a textarea box since the 252 allowed character limit means multiple lines can happen. We stop the Enter key influence by use of an onkeypress event running "return no_enter(event)" which has already been mentioned. It returns false if Enter has been hit—otherwise true. The onkeydown event runs the textCounter() function which displays the number of characters still left in your allotment of 252. It also stops entry of characters once the 252 is used up. In the button's input tag, the sending() and pre_ajax() functions are run by the onclick event. You'll find explanations of the pre_ajax() function above and the sending() function above too.

Finally, there's a JavaScript script that grabs some PHP values and uses JSON (JavaScript Object Notation) to stick them into JavaScript variables since PHP variables won't convert into JavaScript variables without it, even though numbers will—as long as we're not talking numeric arrays, which also need JSON. We convert the username, screen name, and startup flag into JavaScript variables. This script had to be after the PHP codes on this page to work right—you can only convert what you know about, which wouldn't have happened if the PHP came after this block of JavaScript. The emot() function has been discussed above. Note that the last line of the script makes sure that the fact that the user is online gets announced to all chatters online, since this fact gets sent right to the chat window by sending this announcement to the ajax() AJAX function which will store it in the user's db table record for the checkdb() AJAX function to find using the checkdb.php script and returning it to the chat window via the xmlhttp.responseText route.

Save this file as cms-chat-room.php

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<TITLE>Chat Room—Content Management System (CMS)</TITLE>
<meta name="description" content="Chat Room—Content Management System (CMS)">
<meta name="keywords" content="Chat Room,Chat Rooms,Chatroom,Content Management System,Content Management System Articles,php,CMS,javascript, dhtml, DHTML">
<SCRIPT LANGUAGE="JavaScript">
<!--

function textCounter(field, countfield, maxlimit) {
if (field.value.length > maxlimit){field.value = field.value.substring(0, maxlimit);}
else{countfield.value = maxlimit - field.value.length;}}

function fix(){document.MyForm.chatter.focus();if(Netscape||is_opera){e=document.getElementById('top');e.style.marginTop='-10px';e=document.getElementById('info');e.style.width='158px';e=document.getElementById('online');e.style.width='158px';e=document.getElementById('entry');e.style.height='74px';}}

var o = 0;
var d = "0";
var f = "0";
var ft = "0";
var q = 0;
var g = "";
var c = "0";
var pic = 0;
var chatter = " is online";
var s= "";
var ss= "";
var countem = 0;
var timeouts = 0;
var gone = 0;
var el = 0;
var recent=new Array();
for (i=0;i<19;i++) {recent[i]="";}
var v = "";
var arr=new Array();
var z = 0;
var jj = "";
var j = 0;
var mode="";
var priv_name = "";
var priv_flag = 0;
var go_priv = 0;
var priv_start = 0;

function timedout(){document.MyForm.chatter.value='(i-)('+sn+' has timed out)(ii-)';gone=1;o=1;logins();ajax();}

function quit(){window.location="quit.php?u="+u;}

function checkdb(){
var t = new Date().getTime();go_priv=0;
b=document.getElementById("k");jj=document.getElementById("j");
countem=countem+1;timeouts=timeouts+1;if(timeouts==40){timedout();return;}
if (window.XMLHttpRequest){ // for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}else{ // for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
jj.innerHTML=xmlhttp.responseText;check();
b.innerHTML=b.innerHTML+v;divScroll.activeScroll();}}
if(startup==1){startup=0;xmlhttp.open("GET","start.php?u="+u+"&t="+t,true);xmlhttp.send();
}else{xmlhttp.open("GET","checkdb.php?
go_priv="+go_priv+"&sn="+sn+"&priv_name="+priv_name+"&priv_flag=
"+priv_flag+"&mode="+mode+"&u="+u+"&t="+t,true);xmlhttp.send();}
if(countem==40){countem=0;h=b.innerHTML;if(h.length>700){b.innerHTML=h.substr(500);}}}

function logins(){
if (window.XMLHttpRequest){ // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}else{ // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.open("GET","logged-in.php?go_priv="+go_priv+"&priv_flag="+priv_flag+"&u="+u+"&ms=" + new Date().getTime(),false);
xmlhttp.send();
document.getElementById("online").innerHTML="";document.getElementById("online").innerHTML=xmlhttp.responseText;h=document.getElementById("online").innerHTML;h=h.substr(h.length-14);if(h=="(private chat)"){button_private();priv_start++;if (priv_start==1){b=document.getElementById("k");b.innerHTML="PRIVATE<BR>";}}else{priv_start = 0;button_public();if(h=="--------------"){priv_flag=0;priv_name="";mode='public';processing();}}
}

function timer(){
logins();checkdb();
setTimeout('timer()',8000);}

mactest=(navigator.userAgent.indexOf("Mac")!=-1) //My browser sniffers
Netscape=(navigator.appName.indexOf("Netscape") != -1)
msafari=(navigator.userAgent.indexOf("Safari")!= -1)
wsafari=0; if(!mactest&&msafari){wsafari=1;msafari=0}
is_opera = 0; if(window.opera){is_opera=1}
is_ie_mac = 0; is_ie=0;if(document.all){is_ie=1}
if(is_ie&&mactest){is_ie_mac=1}

var chatscroll = new Object(); //thanks to Eric Pascarello of radio.javaranch.com/pascarello/
chatscroll.Pane = function(scrollContainerId){
this.bottomThreshold = 390;
this.scrollContainerId = scrollContainerId;
this._lastScrollPosition = 100000000;}
chatscroll.Pane.prototype.activeScroll = function(){
var _ref = this;var scrollDiv = document.getElementById(this.scrollContainerId);var currentHeight = 0;
var _getElementHeight = function(){
var intHt = 0;
if(scrollDiv.style.pixelHeight)intHt = scrollDiv.style.pixelHeight;
else intHt = scrollDiv.offsetHeight;
return parseInt(intHt);}
var _hasUserScrolled = function(){
if(_ref._lastScrollPosition == scrollDiv.scrollTop || _ref._lastScrollPosition == null){return false;}
return true;}
var _scrollIfInZone = function(){
if( !_hasUserScrolled || (currentHeight - scrollDiv.scrollTop - _getElementHeight() <= _ref.bottomThreshold)){
scrollDiv.scrollTop = currentHeight; _ref._isUserActive = false;}}
if (scrollDiv.scrollHeight > 0)currentHeight = scrollDiv.scrollHeight;
else if(scrollDiv.offsetHeight > 0)currentHeight = scrollDiv.offsetHeight;
_scrollIfInZone(); _ref = null;scrollDiv = null;}
var divScroll = new chatscroll.Pane('k');

function no_enter(e){
var key;
if(window.event){key = window.event.keyCode;}else{key = e.which;}
return (key != 13);}

function pre_ajax(){if(gone==0){ajax();}}

function ajax(){
chatter=document.MyForm.chatter.value;if (chatter == ""){return;}
if(timeouts>39 && o==0){return;}
if(timeouts<40 && o==0){timeouts=0;}
b=document.getElementById("k");jj=document.getElementById("j");
chatter=escape(chatter);
chatter=chatter.replace("+", "%2B");
chatter=chatter.replace("/", "%2F");
document.MyForm.chatter.value="";
document.MyForm.remLen.value="252";
document.MyForm.chatter.focus();
if (window.XMLHttpRequest){ // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}else{ // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
jj.innerHTML=xmlhttp.responseText;check();
b.innerHTML=b.innerHTML+v;divScroll.activeScroll();}}
xmlhttp.open("GET","php.php?go_priv="+go_priv+"&chatter="+chatter+"&u="+u+"&priv_name=
"+priv_name+"&priv_flag="+priv_flag+"&gone="+gone+"&ms="+new Date().getTime(),true);
xmlhttp.send();
}

function check(){

var a=jj.innerHTML;
if(a.substr(0,1)=="|"){a=a.substr(1);}
arr=a.split("|");
j=0;v="";

while(j<arr.length){
for (i=0;i<19;i++) {
if(recent[i]==arr[j]){arr.splice(j,1);}}
j++;}

for (j=0;j<arr.length;j++) {
el++;if(el>18){el=0;}
recent[el]=arr[j];}

for (j=0;j<arr.length;j++){v=v+arr[j];}
}

function sending(){document.MyForm.send.disabled = true;document.MyForm.send.value="sending";setTimeout('done()',5000);}

function done(){document.MyForm.send.disabled = false;document.MyForm.send.value="Submit";}

function private(){priv_name=document.form.priv.value;go_priv=0;priv_flag=0;
var answer = confirm(priv_name+" will be asked if he or she wants to chat with you, "+sn+",\n and if s/he does, your Private Chat button will turn blue. OK?");
if (!answer){priv_name="";mode='public';return;}
else{processing();mode='private';priv_flag=1;document.MyForm.chatter.value=
'._..q...v_.z__._k_.';go_priv=1;o=1;ajax();o=0;priv_flag=2;}}

function modes(i){processing();mode=i;if(mode=='private'){priv_flag=2;go_priv=1;}else{mode='public';priv_flag=0;priv_name="";go_priv=9;button_public()}}

function button_public(){e=document.getElementById('public');e.style.backgroundColor='#99f';e=document.getElementById('private');e.style.backgroundColor='#999';}

function button_private(){e=document.getElementById('public');e.style.backgroundColor='#999';e=document.getElementById('private');e.style.backgroundColor='#99f';}

function processing(){e=document.getElementById('m');e.style.left='400px';setTimeout('doner()',8000);}

function doner(){e=document.getElementById('m');e.style.left='-400px';}

// -->
</script>
<style type="text/css">
BODY {margin-left:0; margin-right:0; margin-top:0;text-align:left;background-color:#ddd;}
p, li {font:13px Verdana; color:black;text-align:left;margin-top:0.2em;margin-bottom:0}
h1 {font:bold 24px Verdana; color:black;text-align:center}
h2 {font:bold 24px Verdana;text-align:center}
textarea {overflow:hidden}
.emoticons {position:absolute;top:480px;left:200px;width:600px;border:2px solid black}
.entry {position:absolute;top:400px;left:200px;width:600px;border:2px solid black;height:64px;}
.chat {position:absolute;top:40px;left:200px;width:600px;height:350px;border:2px solid black; background-color:#fff;overflow:auto}
.info {position:absolute;top:40px;left:2px;width:170px;border:1px solid blue;padding:6px;background-color:#bbb}
.online {position:absolute;top:40px;right:10px;width:170px;border:1px solid blue;padding:6px;background-color:#bbb}
.j {position:absolute;top:0px;left:-3999px}
.q {width:130px;border:1px solid blue;padding:6px;background-color:#999}
#public {background-color:#99f}
#private {background-color:#999}
</style>
</head>

<body onunload="quit();" onLoad="fix(),timer();">

<div id='top'><h1>Chat Room—Content Management System (CMS)</h1></div>

<div class='chat' id='k'></div>

<div class='online' id='online'></div>

<div class='j' id='j'></div>

<DIV ID="m" style="position:absolute; top:320px; left:-400px; width:187px; height:24px;z-index:999"><FONT COLOR="red" size="+2" FACE="arial">PROCESSING</font>
</DIV>

<?php

include_once"config.php";

$startup=$_GET['st'];

$U=$_POST['username'];if (!isset($U)){$U=$_GET['username'];}
if (isset($U)&&preg_match("/[A-Za-z0-9_]{6,20}$/",$U)){$check_user_data = mysql_query("SELECT * FROM chatroommembers WHERE username='$U'") or die(mysql_error());if(mysql_num_rows($check_user_data)==0){unset($U);}}else{unset($U);}
if (!isset($U)){echo '<script language="javascript">alert("Please login.");window.location="chat-room-login.php"; </script>';}

$gifs=array();

$result = mysql_query("SELECT gif FROM emoticons order by gif") or die(mysql_error());
while($row = mysql_fetch_array($result)){
array_push ($gifs, $row[0]);}

$num_gifs_in_table=mysql_num_rows($result);

echo "<div class='emoticons'><table><tr>";
for ($i=0;$i<$num_gifs_in_table;$i++) {
echo "<td><a HREF='#' onclick='emot(\"".$gifs[$i]."\")'><IMG SRC='emoticons/".$gifs[$i]."' BORDER=0></td>";
if($i==17||$i==34){echo "</tr><tr>";}}
echo "</tr></table></div>";

$result = mysql_query("SELECT screen_name FROM chatroommembers WHERE username='$U'") or die(mysql_error());
$row = mysql_fetch_array($result);$name=$row['screen_name'];

echo "<div class='info' id='info'>For italics, starting and ending tags are (i-) and (ii-). For bold, use (b-) and (bb-). Underline is (u-) and (uu-). For links, use (l-) then domain <i>without http://</i>, then (ll-) then link text, then (lll-). For emails, use (e-) then email address <i>with (ee-) instead of @</i>, then (eee-) then subject, then (eeee-) then link text, then (eeeee-).<BR><BR><BR><center><div class='q'><a HREF='chat-room-login.php'>Log in here</a></div><BR><div class='q'><a HREF='chat-room-login.php'>Sign up here</a></div><BR><div class='q' id='public'><a HREF='#' onclick='modes(\"public\")'>Public Chat</a></div><BR><div class='q' id='private'><a HREF='#' onclick='modes(\"private\")'>Private Chat</a></div></center></div>";

mysql_close();

?>

<div class='entry' id='entry'>
<table><form id='form1' name="MyForm" method="POST" action=" ">
<tr><td><textarea name="chatter" cols="63" rows="4" id="chatter" onkeypress="return no_enter(event)" onKeyDown="textCounter(this.form.chatter,this.form.remLen,252)" onKeyUp="textCounter(this.form.chatter,this.form.remLen,252)"></textarea></td><td valign='top'>
<input readonly type='text' name='remLen' size='3' maxlength='3' value="252"><br><br>
<input name="send" type="button" value="submit" onclick="sending(),pre_ajax()"></td></tr></form></table>
</div>

<SCRIPT LANGUAGE="JavaScript">

function emot(a) {g="(p-)"+a+"(pp-)";document.MyForm.chatter.value=document.MyForm.chatter.value+g;}

var u = <?php echo json_encode($U); ?>;
var sn = <?php echo json_encode($name); ?>;
var startup = <?php echo json_encode($startup); ?>;
document.MyForm.chatter.value='(i-)('+sn+' is online)(ii-)';o=1;logins();ajax();o=0;

</script>

</body>
</html>