Question

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();
?>
Was it helpful?

Solution

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.

OTHER TIPS

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();
    ?>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top