Baserat på din tidigare fråga, varje ustartlocation
är unik (därav varför du kan använda det som ett index i dina $devices
array). Med samma koncept kan du fylla i $devices
array från "ustartlocation
till (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'];
}
}
Eftersom din display-loop redan itererar genom varje U
och visar den tilldelade enheten, du borde inte behöva ändra någon annan del. Men förbehållet till detta är att enhetsnamnet kommer att upprepas för varje U
istället för span Det. Till span det måste vi göra lite mer arbete.
Till att börja med kunde vi bara lagra usize
i $devices
array istället för att fylla i varje enskild position. För att förhindra mycket extra arbete/beräkningar senare kommer vi också att lagra en "platshållare"-enhet för varje ytterligare 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';
}
}
Därefter, i din display-loop, kommer du att kontrollera om den aktuella positionen är en platshållare eller inte (om så är fallet, visa bara U
och gör ingenting för enheten; om den inte är det, visa enheten eller "tom"). För att uppnå "span"-effekten för varje enhet ställer vi in cellens rowspan
lika med enhetens usize
. Om det är 1
, kommer det att vara en enda cell; 2
, det kommer att sträcka sig över 2 rader, etc (det är därför "att göra ingenting" för enheten på platshållarraderna kommer att fungera):
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>";
}
Så, som det kan ses - den första metoden ovan som helt enkelt upprepar enheten för varje U
det spänner är mycket enklare. Den andra metoden kommer dock att ge en mer användarvänlig skärm. Det är din preferens vilken metod du vill använda och vilken du tror kommer att vara mer underhållbar i framtiden.
UPPDATERA (kodfix &multi-direction span)
Jag insåg inte att din tabell byggdes i fallande ordning så jag hade ustartlocation
som den "översta platsen" som orsakade ett felaktigt rad-/cellskifte. Jag har fixat koden ovan för att korrekt ställa in en "toppplats" baserat på ustartlocation
och usize
för varje enhet som kommer att åtgärda problemet.
Alternativt, eftersom riktningen kan vara viktig eller inte, har jag anpassat $devices
-populating loop (nedan) för att stödja att skapa ett radspann som går antingen uppåt eller nedåt, helt beroende på vilken flagga du anger. Den enda koden du behöver ändra (om du redan har den anpassade display-loopen från ovan) är while
slinga som fyller $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';
}
}
}
Detta nya kodblock kommer, om usize
spänner över mer än 1, bestäm "översta cellen" och "bottencellen" för den aktuella enheten. Om du spänner uppåt , den översta cellen är ustartlocation + usize - 1
; om du spänner nedåt , det är helt enkelt ustartlocation
. Bottenläget bestäms också på detta sätt.