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


WebHatchers will design & develop your site for you.
_______________________

Website Menu Heaven: side or top popup menus, buttons, image rotators, navbars, tons more.
_______________________

Send us your questions and wittiest comments.
_______________________

Report errors on our site.
_______________________

Share your neatest DHTML examples with us; we may publish them.
_______________________


_______________________

      QUESTION INDEX      

Question Index
Browser Insanity
JavaScript
Animation
Buttons and Menus
CSS and HTML
PHP
Personal Status Boards
Content Management
   Systems
Article Content
   Management Systems
Website Directory
   CMS Systems
Photo Gallery CMS
Forum CMS

 INFORMATIVE ARTICLES 

Menus-and-Buttons-
Part-I.htm


Menus-and-Buttons-
Part-II.htm


Change-Div-Size-Color-
and-Location-with-the-
W3C-DOM.htm


Bouncing-Ball-Animation-
with-the-W3C-DOM.htm


Style-Changes-with-the-
W3C-DOM.htm


Animation-with-the-
W3C-DOM.htm


Window-Play-and-Some-
Important-DOM-Methods.htm


Using-getElementsByTagName
-and-getElementsByName.htm


The-CSS-Resources-Intro-
Page.htm


Convert-Word-Files-to-HTML-
and-Install-Editor2-to-
Use-Instead-of-NotePad.htm


CSS-Issues.htm

What Are Fifteen Simple Methods of Doing Web-Page Pop-ups?

Security levels from Javascript and PHP input filtering

What is a regular expression general input validator?

What is a regular expression user name validator?

What is a regular expression password validator?

What is a regular expression email validator?

What is a regular expression URL validator?

How can I convert a Javascript array to a PHP array?

How can I Dynamically Create Input Boxes with Validation?

How do I use JavaScript Object Notation (JSON) in PHP and JavaScript to convert strings and arrays from PHP to JavaScript?

How do I add html to a web page with JavaScript, PHP or ssi includes?

How do I add html to a web page with JavaScript includes?


PHP

How do you put PHP variables in URL and link text?

What is PHP Code for Multiple PSB Hosts?

What is Registration PHP Code for Multiple PSB Hosts?

What is Registration PHP Code for Multiple PSB Hosts with a captcha?

What is Administrator PHP Code for Multiple PSB Hosts?

What's the PHP code for a script for a PSB?

What's the PHP code for a script for PSB updating?

What's the PHP code for a script if you forgot your user name?

What's the PHP code for a script if you forgot your password?

What's the PHP code for a script to change a member's email address?

What's the PHP code for a script to connect to a MySQL database?

What's the PHP code for a script to close a member's account?

What's the PHP code for a script to edit group member?

What's the PHP code for a script to add group member?

What's the PHP code for a script to reset a MySQL table's data to its original?

What's the PHP code for a script to edit a MySQL table's data?

What's the PHP code for a script to change a username?

What's the PHP code for a script to change a password?

What's the PHP code for a script to delete group member?

What's the PHP code for a script to view membership data?

What's the PHP code for a script to change an administrator's password?

What's the PHP code for a script to logout?

What's the PHP code for a script to login?

Security levels from Javascript and PHP input filtering

Security levels and PHP

How can I convert a Javascript array to a PHP array?

What is PHP Code to Prevent Duplicate Data Input - Like User Names or Members?

What is PHP Code for PSB Status Update for Multiple PSB Hosts?

How do I sort 1 PHP array and have the other arrays sort in parallel to how the first array sorts?

How do I use JavaScript Object Notation (JSON) in PHP and JavaScript to convert strings and arrays from PHP to JavaScript?

How do you do PHP-to-JavaScript String Conversion with No JSON?

How do you Convert PHP String to JavaScript String?

How do you Post a JavaScript Array to a PHP Array?

How do you send a value to PHP using JavaScript?

Info on unwanted primary field auto-sorting

How can I do instant article font size, font family, and paragraph formatting with radio buttons?

How can I create custom HTML tags that are safer for MySQL databases?

How can I edit text from MySQL databases by using a textarea box?

How can I highlight matched search terms in a MySQL database table search?

How can I search using not only exact phrase matching but also a series of words to match in a MySQL database table search?

What's the code for an Ajax and PHP Based Input Filter?

Ajax and PHP Based Insult Auto-Completer

How can I use PHP and MySQL for Checking Key Codes to Allow Update to a New Software App Version?




Personal Status Boards (PSB™)

Standard Free PSB

PSB Pro Version

Social PSB

Social PSB Plus (with Email)

Business PSB

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




Article Content Management System

Content Management System Introduction

Content Management System—Article Navigation

Content Management System—Article Indexing

Content Management System—Article Editing

Content Management System—Article Searching

Content Management System—Article Deleting

Content Management System—Article Writing

Content Management System—Article Reading

What are the terms of use for our Article Content Management System?




Website Directory Content Management System

Website Directory Navigation

Website Directory—Delete Category

Website Directory—Delete URL

Website Directory—Add URL

Website Directory—Add Category

Website Directory—Directory Creating

Website Directory—View by Category (Demo Code)

Website Directory—View by URL (Demo Code)

Website Directory—View by Category (Demo)

Website Directory—View by URL (Demo)

Website Directory—View

Website Directory—View (Demo)




Photo Gallery Content Management System

Code for Photo Gallery Navigation

Code for Photo Gallery—View

Code for Photo Gallery—Create

Code for Photo Gallery—Add Category

Code for Photo Gallery—Delete Category

Code for Photo Gallery—Add Photo

Code for Photo Gallery—Delete Photo

Code for JavaScript Photo Gallery

JavaScript Photo Gallery




Forum Content Management System

Forum: home page

Forum: search

Forum: login

Forum: topic and replies viewing page

Forum: add topic to database

Forum: add reply to database

Forum: edit topic in database

Forum: create topic in database

Forum: delete topic in database

Forum: delete reply in database

Forum: delete user account in members table



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

PSB™ PHP Code for Multiple PSB™ Hosts

Multiple PSB™ Hosts, also called hosts of administrators, host the PSB™ administrators, each of which administers (manages) a PSB™. Administrators may choose to sign themselves up as a PSB™ user if they wish—this will include them on the PSB™ (personal status board) display. Here is a diagram named The Personal Status Board (PSB™) Hosting Diagram that will help you see how all the parts fit together: Servers, databases, MySQL, host of administrators, administrators, users, and PSB™s. Check it out.

This PHP code gets the login user name and password from a user, checks it with the data in the "members" table, and admits users with valid data into the PSB™ page whose script code is listed below. Note that everyone in a group uses the administrator's user name (which can be thought of as their group's name) and the users password to login. No one but the administrator has to sign up for a PSB™ on the host's Registration page, so there are no other user names in any one group, even though their group's MySQL PSB™ table includes all members' first names, their statuses, and their comments. Only the administrator can change the status code meanings for the 100 status codes, since only he has the required administrator password. But any user can login and change any status or comment of anyone—trust is implied. Users are represented, therefore, only by first names which may be nicknames or whatever as long as only 12 or less alphanumeric characters and underline are used—no spaces allowed. Using cryptic names would be counterproductive, since the idea of a PSB™ is to see everyone's status at a glance, and "Joan" is a lot easier to comprehend than "J_girl_yum1", so one can assume he'll Just enter Joan, or JoanG or Joan_G if there are 2 Joans. The administrator is the only one allowed to enter or edit or delete or add member names, and in order to be part of the PSB™ group, he has to enter his first name along with the others in the Registration script. Otherwise he is merely a nonparticipating manager.

When members change their statuses and comments, this utilizes a script called update_psb.php which updates the MySQL table containing the Personal Status Board (PSB™) statuses and comments for PSB™s, and, like other server-side scripts (PHP, CGI, ASP), can support many PSB™ users simultaneously. The code grabs the ID, status, comment, and table name that was posted to it by the main PSB™ page, psb.php, listed below. It uses this data to do the updating of statuses and comments. The table name will contain the user name of the administrator.

Users and administrators never see the file below—only the PSB™ host sees it, so he will have to replace the "yourusername", "yourpassword" and "yourdatabase" with legitimate names that will enable the MySQL connection to be made and the database to be chosen. Only one database will be used to host all PSB™s, and each administrator's data will be entered into the host's "members" table (that contains users password, administrator password, administrator user name, email address, date of joining, and IP of administrator). Each administrator gets 2 other tables as well that are for his group only. The first table contains his group's statuses and comments, which any group member may change, as well as all first names of group members, which only the administrator can edit. The second table contains the current meanings of the 100 status codes—which the administrator may change if his group wants it.

Note that the script below submits updated status and comment values to update_psb.php and does the updating immediately, and transparently to the users, and returns the action back to psb.php as soon as the table is edited and a couple of field values get posted back to psb.php. You can see this POSTing being received below. The flag set to "1" means "returning from updating the PSB™" and the table name gets sent because even though the psb.php script below just sent this value to the update script, the only way it will continue to have the correct table name is if we post it back with POST, send it as a cookie, send it with GET, or use session variables. By posting it back and forth, once a user signs in, his user name will not be subsequently forgotten, since it's now part of the table name. Note the need for JSON in json_encode($table) to convert the table name received in PHP to JavaScript so it could be stuck in the form's hidden field value for posting back and forth to the update script. There's no other convenient way to do this conversion, although there is a cheap and dirty way to pull off this string conversion. JSON is also used for converting the PHP arrays (pulled out of the two MySQL tables for this group) from PHP to JavaScript, as there is no other reasonable way to pull this stunt off. PHP's and JavaScript's data types are not compatible, and the only conversions not needing JSON are with simple numbers (integer or floating point), since numeric arrays, strings and string arrays are not compatible.

<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<TITLE>The Personal Status Board (PSB™)</TITLE>
<meta name="description" content="The Personal Status Board (PSB™) is our contribution to social connectedness, parenting, and ultimately social evolution.">
<meta name="keywords" content="Personal Status Board,PSB,PHP empowered communication,PHP and Javascript based web pages,parenting,social evolution,social connectedness,php,javascript, dhtml, DHTML">
<script language="javascript">
var sub_title=new Array("Alone","Nurturing","P.E.T. or Other Authoritative Parenting Activity","Talk or Play","Coordinate MC Activities","Coordinate Outside Activities","I Am Out","Want Ride","Study or Projects","Custom Codes or Mobile");
var member=-1;Status="";Comment="";
var memstatus=new Array();
var fname=new Array();
var psb=new Array();
var ids=new Array();

mactest=(navigator.userAgent.indexOf("Mac")!=-1) //My browser sniffers
is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1
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}

Above, we declare the subtitle array for the status code meanings chart, initialize a few arrays, and do browser sniffing because they will attempt to display this PSB™ page with slight but significant differences, and we had to adjust our parameters accordingly.

Below, we respond to a click of a "Change Status" button with the function newstatus(). First it finds the current status value of the member whose button was clicked and puts it into the status field of the form so users will be reminded of their current status code—which they may now change by entering 2 digits to replace the old code. Then the value of the group's PSB™ table name in the MySQL database is stuffed into the form's hidden field for POSTing to the update file. The ID value, also in a hidden field, is similarly readied for POSTing. Finally, the member's first name is stuck in the text next to the status update input box.

The function validate() is triggered when the form is submitted, using onSubmit. First, it checks to see that a button has been clicked—if the member number is -1 that's a flag for lack of a click, so it cancels the submit by use of "return false". Next, it looks at the status code. If it's not 2 digits it cancels the submit by use of "return false". The function isNaN() detects nondigit characters. The comment field is checked and its input parsed for nasties that could allow MySQL injections. The ' and + characters are especially bad, but ' is needed in contractions. We could have escaped it but chose to replace it with a ; instead because escaping would add a character to the string and increase the chance of the display being corrupted as well as the possibility that the last character would be dumped from the string, since the MySQL table is configured to allot only 55 characters to this field. The ; character used to be a nasty until PHP 3.2 or thereabouts decided to stop allowing multiple MySQL commands in queries. These used to be separated by ; characters but this is no longer allowed so ; is okay. Another very dangerous entity is 2 hyphens in a row. This got replaced twice with one space character and one hyphen. Why twice? Because an odd number of hyphens could still let "--" leak through. The other very dangerous entity is the = sign. Regular expressions allowed us to replace this, and any other questionable character with a space character. We could have disallowed the submit if they entered weird stuff but chose to do replacements instead to keep the flow going.

The function validatepassword() is a standard form validation script for passwords and user names. If unacceptable characters are entered, the regular expressions detect it, the function returns false, and the user gets a do-over.

function newstatus(){
document.PSBform.status.value=memstatus[member];
document.PSBform.table.value=tbl;
document.PSBform.ID.value=ids[member];
document.getElementById('newstatus').innerHTML = fname[member]+" ";}

function validate(){
if(member<0){alert("Please click a 'Change Status' button first.");return false}
d=document.PSBform;
Status=d.status.value;
if (Status.length!=2 || isNaN(Status)) {alert("Please input any two digits for the personal status code.");return false}

Comment=d.comment.value;
Comment=Comment.replace(/'/g,";");
Comment=Comment.replace(/--/g," -");
Comment=Comment.replace(/--/g," -");
Comment=Comment.replace(/[@#$%\^&\*\(\)\+\|\\=\{\}\[\]:"'\/><]/g," ");
d.comment.value=Comment;
return true;}

function validatepassword(){

var ck_password = /^[A-Za-z0-9!@#$%^&*()_]{4,20}$/;
if (document.formpw.txtPassword.value.search(ck_password)==-1)
{alert("Please only enter letters, numbers and these for password: !@#$%^&*()_");return false}

var ck_username = /^[A-Za-z0-9_]{1,20}$/;
if (document.formpw.txtUsername.value.search(ck_username)==-1)
{alert("Please only enter letters, numbers and underline for user name.");return false}

return true;}

</script>

<style type="text/css">
BODY {margin-left:0; margin-right:0; margin-top:0;text-align:left;background-color:#88f;}
p, li {font:13px Verdana; color:black;text-align:left;margin-top:0.2em;margin-bottom:0}
h1 {font:bold 28px Verdana; color:black;text-align:center}
.arrow {font:18px bold 'Arial Black'; color:black;}
.psb_info {padding:10px;border:1px solid black;width:350px;position:absolute;top:410px;left:0px;background-color:#ccc;}
input {background-color:#eee;}
th {background-color:#ccc;}
.f {background-color:#f88;}
.g {background-color:#666;color:white;}
#container {width:1024px;text-align:left;position:absolute;top:0px;left:50%;margin-left:-502px;}
#logo {width:118px;height:47px;position:absolute;top:3px;left:13%;}
#user {width:12%;height:14px;font-size:14px;font-weight:bold;position:absolute;top:16px;left:4px;}
</style>

</head>
<body>

<div id='container'>

<div id='logo'><IMG SRC="PSB_.jpg" WIDTH=118 HEIGHT=47 BORDER=0></div>

Above, we wrap the entire web page in a container with CSS styles: width:1024px;text-align:left;position:absolute;top:0px;left:50%; and margin-left:-502px. This has little effect on a 1024-pixel-wide screen, but on all wider screens, it centers the page content in the center in this 1024-wide div. The left:50% tries to stick the left edge of the div in the center of the screen, but then the margin-left:-502px takes half the width of the container div and brings the left edge of the div leftward by that much, which exactly centers the div. Well, we had to account for the width of the scrollbar by have margin-left: be 10 less than half the container div width.

Below, we grab the POSTed value entry, flag, username, password, and table. In truth, once the password and username have been entered, the form that solicits these values POSTs the page right back to itself. Next, we check if the $U variable that had the user name in it after the login still has a value, since if we have updated a status the value will have been lost when we go to the 'update_psb.php' script for MySQL table updating. But the $table variable will still have the user name plus '_psb' in it. So we use the PHP string replace function to replace '_psb' with nothing in $table, then store this result in $U. This gets echoed in the top left corner of the screen to let the user know we know him or her. The script then looks at whether this is the correct password (the "users password") and user name (the administrator's user name which is also this GROUP's user name), and even whether or not such a user name exists. If the user has submitted the form, the $Entry flag will be set and his group's administrator-entered data will be located in the "members" table as long as this administrator user name exists—a warning will pop up if it is not found, or if the username/password pair is invalid. Note that in checking through the "members" table for the record in which the user's group user name matches the one entered into the form, we use MySQL's SELECT statement in PHP. The $N flag is set if their entry attempt is NO GOOD—which returns them to try again. $Z temporarily gets the table's users password to compare with their input.

<?php
$Entry=$_POST['entry'];
$FLAG=$_POST['flag'];
$U=$_POST['username'];
$P=$_POST['password'];
$table=$_POST['table'];
$N=0;
$Z='';
$Q=0;

if(empty($U)){$U = str_replace("_psb", "", $table);}

// Make a MySQL Connection
mysql_connect("localhost", "yourusername", "yourpassword") or die(mysql_error());
mysql_select_db("yourdatabase") or die(mysql_error());

if($Entry==1){
$check_user_data = mysql_query("SELECT * FROM members WHERE username = '$U'") or die(mysql_error());
if(mysql_num_rows($check_user_data) == 0)
{echo '<script language="javascript">alert("This user name does not exist. Please try again.")</script>;';$N=1;}
else {$get_user_data = mysql_fetch_array($check_user_data);}
}

if($N==0 && $Entry==1){$Z=$get_user_data['users_password'];}

if($Z != $P && $Entry==1)
{echo '<script language="javascript">alert("Username/password pair is invalid. Please try again.")</script>;';$N=1;}

if(($N==1||$Entry==0) && empty($FLAG)){ ?>

<h1>Personal Status Board (PSB™)</h1>

<div id='pw' style='position:absolute;top:410px;left:200px;width:300px'><table style="background-color:#8aa;border-color:#00f" border='6' cellspacing=0 cellpadding=6><tr><td>
<form id='formpw' name="formpw" method="post" action="psb.php" onsubmit="return validatepassword()">
<label for="User Name"><b>User Name: </b><input type="text" name="username" size="20" maxlength="30" value=""></label>
<label for="Password"><b>Password:    </b><input type="password" name="password" size="20" maxlength="20" value=""></label><br><br>
<input type="hidden" name="flag" value="0">
<input type="hidden" name="entry" value="1">
<input type="submit" value="Submit">
<input type="reset" value="Reset"></form></td></tr></table>
</div>

<?php
} else {$FLAG=1;$Entry=0;
?>

<div id='s' style='position:absolute;top:53px;left:2px;border:1px solid black;background-color:#eee;'>
<?php

if(empty($table)){$table=$U."_psb";}
$meaning = str_replace("_psb", "_meaning", $table);

Above is the form that receives the user input for logging in. Note the hidden fields that are used to POST flags to the PHP POST function, requiring a page reload. It's very convenient that forms can send data to their own pages like this, since JavaScript cannot send data to PHP without POST, GET, or cookies. PHP, on the other hand, can send anything to JavaScript on the same page with JSON, or if it's simple numbers, without need of JSON. Note that the PHP else statement after the form uses the entire rest of the page as its "else." In creating the table name for the logged in user, the empty() function looks to see if the table name is already known, and it is known if the name has content. If it is empty, it gets created with the concatenation of the entered user name and the string "_psb". Let's call the administrator Joe and his user name got entered as "Joes_bunch", when he used the Registration script, got his general data entered into the "members" table, and 2 tables were created for his group, "Joes_bunch_psb" and "Joes_bunch_meaning". The former contains the list of first names (which he entered when he registered his group) and their current statuses and comments. The latter contains all the current meanings of the 100 status codes, which the administrator can change if it is desired by the group.

Below, the "Joes_bunch_psb" table (or whatever) is loaded as a MySQL Resource and PHP's while statement is used to pull the arrays from this result and the echo statment is used to print them into a table on the screen. Then arrays are defined and the table's Firstname and Status and ID fields are dumped into these arrays using a while statement and the array_push function. Since the database is still open, we also dump into an array the meaning field from the group's $meaning table (i.e., "Joes_bunch_meaning"). Finally we close the connection, jump into JavaScript, and use JSON to dump these PHP arrays into JavaScript ones, since we'll be using DHTML to dynamically manipulate this data, as well as using the update_psb.php file to update the MySQL table (i.e., "Joes_bunch_psb") when statuses and/or comments are changed.

// Make a MySQL Connection
mysql_connect("localhost", "yourusername", "yourpassword") or die(mysql_error());
mysql_select_db("yourdatabase") or die(mysql_error());

// Retrieve all the data from their table as a MySQL Resource
$result = mysql_query("SELECT * FROM $table") or die(mysql_error());

echo "<table border='1' width='578'>";
echo "<tr><th width='116'>Name</th><th width='25'>ID</th><th width='25'>Status</th><th width='412'>Comment</th></tr>";
// keeps getting the next row until there are no more to get
while($row = mysql_fetch_array($result)) { // Print out the contents of each row into a table
echo "<tr><td>";
echo $row['Firstname'];
echo "</td><td>";
echo $row['ID'];
echo "</td><td>";
echo $row['Status'];
echo "</td><td>";
echo $row['Comment'];
echo "</td></tr>";

}

echo "</table>";

$number=mysql_num_rows($result);

$myArray=array();

$res = mysql_query("SELECT Firstname FROM $table") or die(mysql_error());
while ($row = mysql_fetch_row($res)) {
array_push ($myArray, $row[0]);
}

$myArray1=array();

$res = mysql_query("SELECT ID FROM $table") or die(mysql_error());
while ($row = mysql_fetch_row($res)) {
array_push ($myArray1, $row[0]);
}

$myArray2=array();

$res = mysql_query("SELECT Status FROM $table") or die(mysql_error());
while ($row = mysql_fetch_row($res)) {
array_push ($myArray2, $row[0]);
}

$myArray3=array();

$res = mysql_query("SELECT meaning FROM $meaning") or die(mysql_error());
while ($row = mysql_fetch_row($res)) {
array_push ($myArray3, $row[0]);
}

mysql_close();

?>
</div>

<script language="javascript">

var fname = <?php echo json_encode($myArray); ?>;

number_records_in_table = <?php echo $number; ?>;

var ids = <?php echo json_encode($myArray1); ?>;

var memstatus = <?php echo json_encode($myArray2); ?>;

var psb = <?php echo json_encode($myArray3); ?>;

var tbl = <?php echo json_encode($table); ?>;

var Us = <?php echo json_encode($U); ?>;

a='82px';b='25px';h='25px';n=622;if(is_ie_mac){a='82px';b='23px';h='23px';n=772;}
if(Netscape&&!mactest){a='83px';b='26px';h='25px';};
if(Netscape&&mactest){a='78px';b='22px';h='22px';n=722;};
if(msafari){a='77px';b='21px';h='21px';n=676;};
if(wsafari&&!is_chrome){n=659;};
if(is_chrome){n=633;};
if(is_opera){n=615;};

Above, after the JSON action, we set variables according to browser, since the display differences were real—these browsers are in general agreement about how to display content, but they disagree on the details. Below, note that document.write() functions do all the heavy lifting. It turned out that regular HTML statements inside the PHP "else" brackets didn't work right for the page to work, but JavaScript statements worked nicely. First, we printed the page title, then an HTML table that displayed the meaning of the current statuses of each PSB™ member, using the psb() array it got from the JSON encoding of the PHP array gotten from the $meaning table, above. Next, a bunch of z-filled variables are set up with values that compensate for the number of group members—the more there are, the farther down the page it's necessary to put the rest of the page content.

Next we needed to get people to stop typing whenever their comment inputs filled the input box, so we warned them about it. Capital "W" takes up a lot more room than small "i" does, for example, so even though the field will hold 55 characters, if they're wide ones, users need to type fewer of them or wreck the display once the update happens. It won't hurt anything but it will look bad. We could have solved the problem by using Courier for the font, but it's too hard to read and unaesthetic. At first blush one might think we merely needed to limit the characters to 55, but wide ones, as we said, would wreck things. At second blush, one would think we'd stop the entry once it reached the end of the box by some JavaScript trick of reading the characters' screen positions. There IS no such JavaScript trick possible—it's easy to read the mouse position but it takes the C language to figure out the screen position of a character. If we are in error about this, we would LOVE to hear from readers who know a magical technique!

Anyway, notice that the form created on the page (using document.write) for receiving statuses and comments also has hidden fields for posting the user name's ID and the table name (along with the status and comments) to the update_psb.php file during updates. It also uses an onSubmit to run the function validate() to validate the comment and status code inputs, as discussed earlier. The next script prints out the status code meanings in a table of 100 items, complete with subtitles. Finally, we print out a clickable button for each group member which users utilize to indicate the member whose data they wish to change—usually their own, but older people might be helping out younger people who aren't ready to enter data to change their statuses. For example, a person caretaking a toddler may need to go somewhere so she changes the toddler's status from "I am being nurtured" code to "Want nurturing" and changes her own status from "I am a scheduled caregiver" to "Want Ride north - P.M." or whatever. Note that in the creation of the column of buttons, we add an onClick event to each button in which the person's group ID is stuck in the "member" variable, so the PSB™ knows which member the button refers to. Note that ID numbers are whatever for group members, but the ids[] array knows the IDs, so when the newstatus() function gets called, this array gets used to get a value to dump into the form so the correct ID gets POSTed. In addition to calling that function, the code also includes a command to focus the cursor in the status code input box on the form. Finally, notice that we use a different (shorter) button if the user is on a Mac, since they often use shorter table rows than Windows machines. Note the </div> at the end of the script—this is the far end of the container div that holds the entire page. Also note the "Refesh often" message that gets printed at the top right corner of the screen. This reminds users that other users might be updating statuses but such changes will not happen on their page unless they refresh the screen to pull the very latest data from the MySQL table.

document.write("<div id='user'>"+Us+"</div>");

document.write("<div style='absolute;top:0px;left:200px'><h1>Personal Status Board (PSB™)</h1></div>");

document.write("<div id='q' style='border:1px solid black;background-color:#eee;position:absolute;top:53px;left:582px'><table width=\"418\" border=\"1\" cellpadding=\"1\">");

document.write("<tr><th width='50' height='+h+'>Change</th><th width='373'>Meanings</th></tr>");

for (i=0;i<number_records_in_table;i++){document.write( "<tr><td>" + " " + "</td><td>" + psb[parseInt(memstatus[i],10)] + "</td></tr>");}

document.write ("</table></div>");

z=410;zz=360;zzz=340;zzzz=391;zzzzz=145;if (number_records_in_table>10){z=410+((number_records_in_table - 10)*30);zz=z-50;zzz=z-73;};if(Netscape||is_opera){zzzz=402;zzzzz=123;}

document.write ("<div style='position:absolute;top:"+zzz+"px;left:"+n+"px'><i>Please cease typing when you get here</i><span class='arrow'><b>↓</b></span></div>");

document.write ("<form style='position:absolute;top:"+zz+"px;left:10px;width:989px;' id='status' name='PSBform' method='post' action='update_psb.php' onsubmit='return validate()'><b id='newstatus'>Member </b><label for='status'><b>Status: </b><input type='text' name='status' size='2' maxlength='2' value=''></label><label for='comment' style='position:absolute;top:0px;left:370px;width:629px;'><b>Comment (optional): </b><input type='text' name='comment' size='55' maxlength='55'></label><input type='hidden' name='ID' value=' '><input type='hidden' name='table' value=' '><input type='submit' value='Update PSB' class='f'><input type='reset' value='Reset' class='g'></form>");

document.write("<div id='r' style='background-color:#eee;position:absolute;top:"+z+"px;left:"+zzzz+"px'><table border=\"1\" cellpadding=\"1\">");

document.write("<tr><th>Status Code</th><th>Meaning</th></tr>");

f=0;u=" ";

for (i=0;i<100;i++){

u=i.toString();if (u.length<2){u="0"+u}

if(u.charAt(1)=="0"){document.write( "<tr><th colspan=2>" + sub_title[f] + "</th></tr>");f=f+1}

document.write( "<tr><td>" + u + "</td><td>" + psb[i] + "</td></tr>")}

document.write ("</table><br><br><br></div><br><br><br>");

document.write("<div id='g' style='position:absolute;top:"+a+";left:587px'><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">");

if(!mactest){for (i=0;i<number_records_in_table;i++){document.write( "<tr><td style='height:"+h+";'><a HREF='#' onclick='member="+i+",newstatus(),document.PSBform.status.focus()'><div style='height:"+b+";'><IMG SRC='change.png' WIDTH=40 HEIGHT=22 BORDER=0></a></div></td></tr>");}
}else{
for (i=0;i<number_records_in_table;i++){document.write( "<tr><td style='height:"+h+";'><a HREF='#' onclick='member="+i+",newstatus(),document.PSBform.status.focus()'><div style='height:"+b+";'><IMG SRC='change-.png' WIDTH=40 HEIGHT=18 BORDER=0></a></div></td></tr>");}}

document.write ("</table></div>");

document.write ("<div style='color:white;font-size:18px;position:absolute;left:80%;top:10px'><b>Refresh often [F5]</b></div>");
</script>

<?php
}
?>

</div>

</body></html>