问题
So, I asked this question earlier this week, and @newfurniturey helped me out, but now I have a new problem: I'd like to be able to put devices in that span more than one U (hence, the usize column in the devices db table) - some devices can span take up half a cabinet. Also, I'd like to be able to mark devices as being in the front or rear of the cabinet, but that should be simple enough for me to figure out.
Here's the working code (see old question for db setup) for just 1U devices:
<SCRIPT LANGUAGE="JavaScript" type="text/javascript">
<!--
function clickHandler(e)
{
var targetId, srcElement, targetElement;
if (window.event) e = window.event;
srcElement = e.srcElement? e.srcElement: e.target;
if (srcElement.className == "Outline")
{
targetId = srcElement.id + "d";
targetElement = document.getElementById(targetId);
if (targetElement.style.display == "none")
{
targetElement.style.display = "";
srcElement.src = "images/minus.gif";
}
else
{
targetElement.style.display = "none";
srcElement.src = "images/plus.gif";
}
}
}
document.onclick = clickHandler;
-->
</SCRIPT>
<noscript>You need Javascript enabled for this page to work correctly</noscript>
<?
function sql_conn()
{
$username="root";
$password="root";
$database="racks";
$server="localhost";
@mysql_connect($server,$username,$password) or die("<h2 align=\"center\" class=\"red\">[<img src=\"images/critical.gif\" border=\"0\">] Unable to connect to $server [<img src=\"images/critical.gif\" border=\"0\">]</h2>");
@mysql_select_db($database) or die("<h2 align=\"center\" class=\"red\">[<img src=\"images/critical.gif\" border=\"0\">] Unable to select $database as a database [<img src=\"images/critical.gif\" border=\"0\">]</h2>");
}
sql_conn();
$sql_datacenters="SELECT * FROM `datacenters`";
$result_datacenters=mysql_query($sql_datacenters);
$j=0;
echo "<table border='1' style='float:left;'>";
while ($datacenters_sqlrow=mysql_fetch_array($result_datacenters))
{
echo "<tr><td>";
echo "<h2 class='black' align='left'>";
echo "<IMG SRC='images/plus.gif' ID='Out" . $j . "' CLASS='Outline' STYLE='cursor:hand;cursor:pointer'>"; // fancy icon for expanding-collapsing section
echo " " . $datacenters_sqlrow['rack'] . ": " . $datacenters_sqlrow['cagenum'] . "</h2>"; // datacenter name and cage number
echo "<div id=\"Out" . $j . "d\" style=\"display:none\">"; // opening of div box for section that is to be expanded-collapsed
echo $datacenters_sqlrow['notes'] . "<br /><br />"; // datacenter notes
$sql_cabinets="SELECT * FROM `cabinets` WHERE `datacenter` = '$datacenters_sqlrow[0]' ORDER BY `cabinetnumber` ASC";
$result_cabinets=mysql_query($sql_cabinets);
while ($cabinets_sqlrow=mysql_fetch_array($result_cabinets))
{
$sql_devices="SELECT * FROM `devices` WHERE `datacenter` = '$datacenters_sqlrow[0]' AND `cabinet` = '$cabinets_sqlrow[1]' ORDER BY `ustartlocation` ASC";
$result_devices=mysql_query($sql_devices);
echo "<table border='1' style='float:left;'>"; // opening of table for all cabinets in datacenter
echo "<tr><td colspan='2' align='middle'>" . $cabinets_sqlrow[1] . "</td></tr>"; // cabinet number, spans U column and device name column
$devices = array();
while($row = mysql_fetch_array($result_devices)) {
$devices[$row['ustartlocation']] = $row['devicename'];
}
for ($i = 0; $i < $cabinets_sqlrow[2]; $i++) // iterates through number of U in cabinet
{
$u = $cabinets_sqlrow[2] - $i; // subtracts current $i value from number of U in cabinet since cabinets start their numbers from the bottom up
echo "<tr>";
echo "<td width='15px' align='right'>$u</td>"; // U number
echo (isset($devices[$u]) ? "<td width='150px' align='middle'>$devices[$u]</td>" : "<td width='150px' align='middle'>empty</td>");
echo "</tr>";
}
echo "</table>"; // closes table opened earlier
}
echo "</td></tr>";
echo "</div>"; // close for div box that needs expanding-collapsing by fancy java
$j++; // iteration for the fancy java expand-collapse
}
echo "</table>";
mysql_close();
?>
回答1:
Based on your previous question, each ustartlocation
is unique (hence why you can use it as an index in your $devices
array). Using this same concept, you could populate the $devices
array from "ustartlocation
to (ustartlocation + (usize - 1))
".
$devices = array();
while($row = mysql_fetch_array($result_devices)) {
$endLocation = ($row['ustartlocation'] + ($row['usize'] - 1));
for ($location = $row['ustartlocation']; $location <= $endLocation; $location++) {
$devices[$location] = $row['devicename'];
}
}
Because your display-loop already iterates through each U
and displays the device assigned, you shouldn't need to modify any other portion. However, the caveat to this is that the device-name will repeat for every U
instead of span it. To span it, we'll need to do a little more work.
To start, we could just store the usize
in the $devices
array instead of filling in each individual position. Also, to prevent a lot of extra work/calculations later, we'll also store a "placeholder" device for each additional position.
while($row = mysql_fetch_array($result_devices)) {
// get the "top" location for the current device
$topLocation = ($row['ustartlocation'] + $row['usize'] - 1);
// populate the real position
$devices[$topLocation] = $row;
// generate a list of "placeholder" positions
for ($location = ($topLocation - 1); $location >= $row['ustartlocation']; $location--) {
$devices[$location] = 'placeholder';
}
}
Next, in your display-loop, you will check if the current position is a placeholder or not (if so, just display the U
and do nothing for the device; if it isn't, display the device, or 'empty'). To achieve the "span" effect for each device, we'll set the cell's rowspan
equal to the device's usize
. If it's 1
, it will be a single cell; 2
, it will span 2 rows, etc (this is why "doing nothing" for the device on the placeholder-rows will work):
for ($i = 0; $i < $cabinets_sqlrow[2]; $i++) {
$u = $cabinets_sqlrow[2] - $i;
echo "<tr>";
echo '<td width="15px" align="right">' . $u . '</td>';
if (isset($devices[$u])) {
// we have a "device" here; if it's a "placeholder", do nothing!
if ($devices[$u] != 'placeholder') {
echo '<td width="150px" align="middle" rowspan="' . $devices[$u]['usize'] . '">' . $devices[$u]['devicename'] . '</td>';
}
} else {
echo '<td width="150px" align="middle">empty</td>';
}
echo "</tr>";
}
So, as it can be seen - the first method above that simply repeats the device for each U
it spans is much simpler. However, the second method will present a more user-friendly display. It's your preference to which method you want to use and which one you think will be more maintainable in the future.
UPDATE (code-fix & multi-direction spanning)
I didn't realize that your table was being built in descending-order so I had the ustartlocation
as the "top location" which caused an erroneous row/cell shift. I've fixed the code above to properly set a "top location" based on the ustartlocation
and usize
for each device that will fix that issue.
Alternatively, as direction may or may not be important, I've customized the $devices
-populating loop (below) to support creating a row-span that goes either upwards or downwards, completely depending on the flag you specify. The only code you'll need to change (if you already have the customized display-loop from above) would be the while
loop that populates $devices
:
$spanDevicesUpwards = true;
while($row = mysql_fetch_array($result_devices)) {
if ($row['usize'] == 1) {
$devices[$row['ustartlocation']] = $row;
} else {
$topLocation = ($spanDevicesUpwards ? ($row['ustartlocation'] + $row['usize'] - 1) : $row['ustartlocation']);
$bottomLocation = ($spanDevicesUpwards ? $row['ustartlocation'] : ($row['ustartlocation'] - $row['usize'] + 1));
$devices[$topLocation] = $row;
for ($location = ($topLocation - 1); $location >= $bottomLocation; $location--) {
$devices[$location] = 'placeholder';
}
}
}
This new block of code will, if the usize
spans more than 1, determine the "top cell" and "bottom cell" for the current device. If you're spanning upwards, the top-cell is ustartlocation + usize - 1
; if you're spanning downwards, it's simply ustartlocation
. The bottom-location is also determined in this manner.
回答2:
Hoping this will work for you..........for front/rear you can name you device as SERVER3/front or SERVER3/rear:
<SCRIPT LANGUAGE="JavaScript" type="text/javascript">
<!--
function clickHandler(e)
{
var targetId, srcElement, targetElement;
if (window.event) e = window.event;
srcElement = e.srcElement? e.srcElement: e.target;
if (srcElement.className == "Outline")
{
targetId = srcElement.id + "d";
targetElement = document.getElementById(targetId);
if (targetElement.style.display == "none")
{
targetElement.style.display = "";
srcElement.src = "images/minus.gif";
}
else
{
targetElement.style.display = "none";
srcElement.src = "images/plus.gif";
}
}
}
document.onclick = clickHandler;
-->
</SCRIPT>
<noscript>You need Javascript enabled for this page to work correctly</noscript>
<?
function sql_conn()
{
$username="root";
$password="root";
$database="racks";
$server="localhost";
@mysql_connect($server,$username,$password) or die("<h2 align=\"center\" class=\"red\">[<img src=\"images/critical.gif\" border=\"0\">] Unable to connect to $server [<img src=\"images/critical.gif\" border=\"0\">]</h2>");
@mysql_select_db($database) or die("<h2 align=\"center\" class=\"red\">[<img src=\"images/critical.gif\" border=\"0\">] Unable to select $database as a database [<img src=\"images/critical.gif\" border=\"0\">]</h2>");
}
sql_conn();
$sql_datacenters="SELECT * FROM `datacenters`";
$result_datacenters=mysql_query($sql_datacenters);
$j=0;
echo "<table border='1' style='float:left;'>";
while ($datacenters_sqlrow=mysql_fetch_array($result_datacenters))
{
echo "<tr><td>";
echo "<h2 class='black' align='left'>";
echo "<IMG SRC='images/plus.gif' ID='Out" . $j . "' CLASS='Outline' STYLE='cursor:hand;cursor:pointer'>"; // fancy icon for expanding-collapsing section
echo " " . $datacenters_sqlrow['rack'] . ": " . $datacenters_sqlrow['cagenum'] . "</h2>"; // datacenter name and cage number
echo "<div id=\"Out" . $j . "d\" style=\"display:none\">"; // opening of div box for section that is to be expanded-collapsed
echo $datacenters_sqlrow['notes'] . "<br /><br />"; // datacenter notes
$sql_cabinets="SELECT * FROM `cabinets` WHERE `datacenter` = '$datacenters_sqlrow[0]' ORDER BY `cabinetnumber` ASC";
$result_cabinets=mysql_query($sql_cabinets);
while ($cabinets_sqlrow=mysql_fetch_array($result_cabinets))
{
$sql_devices="SELECT * FROM `devices` WHERE `datacenter` = '$datacenters_sqlrow[0]' AND `cabinet` = '$cabinets_sqlrow[1]' ORDER BY `ustartlocation` ASC";
$result_devices=mysql_query($sql_devices);
echo "<table border='1' style='float:left;'>"; // opening of table for all cabinets in datacenter
echo "<tr><td colspan='2' align='middle'>" . $cabinets_sqlrow[1] . "</td></tr>"; // cabinet number, spans U column and device name column
$devices = array();
$devices_size=array();
while($row = mysql_fetch_array($result_devices)) {
$devices[$row['ustartlocation']] = $row['devicename'];
//$devices_size[$row['ustartlocation']+$row['usize']-1] = $row['usize'];
$devices_size[$row['ustartlocation']] = $row['usize'];
}
$start="";
$new="";
for ($i = 0; $i < $cabinets_sqlrow[2]; $i++) // iterates through number of U in cabinet
{
$u = $cabinets_sqlrow[2] - $i; // subtracts current $i value from number of U in cabinet since cabinets start their numbers from the bottom up
echo "<tr>";
echo "<td width='15px' align='right'>$u</td>"; // U number
$rowspan=$devices_size[$u];
//$rowspan1=$
if($rowspan>1)
{
$start=$u;
$new=$u-$rowspan+1;
echo (isset($devices[$u]) ? "<td width='150px' align='middle' rowspan='".$rowspan."'>$devices[$u]</td>" : "<td width='150px' align='middle' rowspan='".$rowspan."'>$devices[$new]</td>");
}
else{
if($u<=$start && $u>=$new)
{
}
else
{
echo (isset($devices[$u]) ? "<td width='150px' align='middle' >$devices[$u]</td>" : "<td width='150px' align='middle'>empty".$row."".$u."</td>");
}
}
echo "</tr>";
}
echo "</table>"; // closes table opened earlier
}
echo "</td></tr>";
echo "</div>"; // close for div box that needs expanding-collapsing by fancy java
$j++; // iteration for the fancy java expand-collapse
}
echo "</table>";
mysql_close();
?>
来源:https://stackoverflow.com/questions/13219921/how-can-i-populate-html-table-numbered-rows-based-on-whether-they-match-row-numb