I’m relatively new to web programming. New to Javascript, PHP, Ajax, etc. I have been searching Google to a seemingly simple solution to this problem for a while now, but have given up. I believe there is a race condition happening, but everything related to race conditions and PHP and Javascript seem to have a case-by-case solution.
Here’s the setup:
I have a PHP page that outputs a table. In one of the rows in one of the tables, I fill a cell with an additional table. It has 5 cells, and I would like to change the colors of the cells to reflect the signal strength of wifi cards on a machine (there are currently only two cards). So after a table has been filled and the id’s of the cells have been set, I call a javascript function that posts another piece of PHP code to cat /proc/net/wireless, parse and return the signal strength of the card I have called.
The problem:
The javascript and PHP code that parses the wireless cards, gets the cell ID’s and set the colors works fine for one card. However, when I call the Javascript function from within a tag in PHP, only the last call does anything. The first seems to do nothing.
I’m completely stumped, and have exhausted all my Google search terms…
PHP code:
<?php include('assets/header.inc.php'); ?>
<script type="text/javascript" src="<?php echo _JS_?>/ajax_home_display.js"></script>
<div id="cm_body" onload="return false">
<?php
$ap_intf = rtrim(shell_exec("cat /tmp/config | grep AP_DEV | cut -d'=' -f2"));
$mesh_intf = rtrim(shell_exec("cat /tmp/config | grep MESH_DEV | cut -d'=' -f2"));
$uptime = rtrim(shell_exec("uptime | awk '{print $3}' | cut -d',' -f1"));
function display_status_intf($intf, $name)
{
global $uptime;
$packet_success = "100%";
echo "
<tr>
<td style=\"font-size:14px; font-weight:bold;\"><pre>$intf [$name]</pre></td>
<td id=\"sig_status_$intf\">
<table id=\"intf_status\" class = \"list\" cellpadding=10>
<td id=\"sig_st_1_$intf\"></td>
<td id=\"sig_st_2_$intf\"></td>
<td id=\"sig_st_3_$intf\"></td>
<td id=\"sig_st_4_$intf\"></td>
<td id=\"sig_st_5_$intf\"></td>
</table>
<td><pre>$uptime</pre></td></td>
<td style=\"text-align:center;\"><pre id=\"packet_success_$intf\">$packet_success</pre></td>
</tr>
<script>update_interface('$intf')</script>
";
}
// Make a table
echo "<table class=\"list\" cellpadding=1>";
echo "<tr><th>Interface</th><th>Signal Status</th><th>Uptime</th><th>Packet success</th></tr>";
// Make a row on the table for the first wifi card (wifi0)
if ($ap_intf)
display_status_intf($ap_intf, "AP");
// Add a blank row
echo "<tr><td colspan=\"7\" height=\"30px\"></td></tr>";
// Make a row on the table for the second wifi card (wifi1)
if ($mesh_intf)
display_status_intf($mesh_intf, "Mesh");
echo "</table>";
?>
</div>
<?php include('assets/footer.inc.php'); ?>
Javascript code:
THRESH1 = -60;
THRESH2 = -55;
THRESH3 = -50;
THRESH4 = -45;
function update_interface(intf)
{
xmlhttpPost("run_interface_status.php","intf="+intf,interface_stat_response);
}
function interface_stat_response(strQuery,strResponse)
{
var sig_st = [];
// Trim response
var test_return = strResponse;
var intface = strQuery.split("=");
var intf = intface[1];
// Get cell ID's, put in an array sig_st
for (i=1;i<=5;i++)
sig_st[i] = document.getElementById("sig_st_"+i+"_"+intf);
// Reset all colors to default
for (i=1;i<=2;i++)
sig_st[i].setAttribute("style", "background-color:transparent");
if (test_return != "err") {
// Set all colors based on the wifi strength
sig_st[1].setAttribute("style", "background-color:red");
if (test_return > THRESH1)
sig_st[2].setAttribute("style", "background-color:orange");
if (test_return > THRESH2)
sig_st[3].setAttribute("style", "background-color:yellow");
if (test_return > THRESH3)
sig_st[4].setAttribute("style", "background-color:green");
if (test_return > THRESH4)
sig_st[5].setAttribute("style", "background-color:green");
}
}
The Ajax heavy lifting (if it matters)
function xmlhttpPost(strURL,strQuery,responseFunc)
{
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', strURL, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
responseFunc(strQuery,self.xmlHttpReq.responseText);
}
}
self.xmlHttpReq.send(strQuery);
}
function trim(s)
{
s = s.replace(/(^\s*)|(\s*$)/gi,"");
s = s.replace(/[ ]{2,}/gi," ");
s = s.replace(/\n /,"\n");
return s;
}
Some additional information: I believe it to be a race condition since Firebug shows that two posts have been fired, each returning the correct values, but when I place a breakpoint in the beginning of the response function (interface_stat_response()), Firebug only falls in it once with the latter $intf and $strength variables (wifi1’s stuff).
Also any general pointers would be great. I know the code isn’t pretty, but I want to get better :3
After reviewing everything, the best I can offer is…
Try replacing your AJAX heavy lifting, with the jQuery post method http://api.jquery.com/jQuery.post/
It will require jQuery but it should be easy enough to try and it might fix it.
jQuery is a very helpful tool in dealing with AJAX/JS in general.
If the problem is in your AJAX heavy lifting, this should fix it.