Com base na sua pergunta anterior, cada
ustartlocation
éúnico (daí porque você pode usá-lo como um índice em seu $devices
variedade). Usando este mesmo conceito, você pode preencher o $devices
array de "ustartlocation
para (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'];
}
}
Porque seu display-loop já itera em cada
U
e exibe o dispositivo atribuído, você não precisa modificar nenhuma outra parte. No entanto, a ressalva disso é que o nome do dispositivo repetirá para cada U
em vez de span isto. Para ampliar isso, precisaremos trabalhar um pouco mais. Para começar, podemos apenas armazenar o
usize
em $devices
array em vez de preencher cada posição individual. Além disso, para evitar muito trabalho/cálculos extras posteriormente, também armazenaremos um dispositivo "espaço reservado" para cada posição adicional. 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';
}
}
Em seguida, em seu loop de exibição, você verificará se a posição atual é um placeholder ou não (se for, basta exibir o
U
e não faça nada pelo dispositivo; se não estiver, exiba o dispositivo ou 'vazio'). Para obter o efeito "span" para cada dispositivo, definiremos o rowspan
da célula igual ao usize
do dispositivo . Se for 1
, será uma única célula; 2
, ele abrangerá 2 linhas, etc (é por isso que "não fazer nada" para o dispositivo nas linhas de espaço reservado funcionará):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>";
}
Então, como pode ser visto - o primeiro método acima que simplesmente repete o dispositivo para cada
U
abrange é muito mais simples. No entanto, o segundo método apresentará uma exibição mais amigável. É sua preferência para qual método você deseja usar e qual você acha que será mais sustentável no futuro. ATUALIZAÇÃO (code-fix &multi-direction spanning)
Eu não percebi que sua tabela estava sendo construída em ordem decrescente, então eu tinha o
ustartlocation
como a "localização superior" que causou um deslocamento errôneo de linha/célula. Corrigi o código acima para definir corretamente um "local superior" com base no ustartlocation
e usize
para cada dispositivo que irá corrigir esse problema. Como alternativa, como a direção pode ou não ser importante, personalizei o
$devices
-populando loop (abaixo) para dar suporte à criação de um intervalo de linha que vai ou para cima ou para baixo, dependendo completamente da bandeira que você especificar. O único código que você precisará alterar (se você já tiver o loop de exibição personalizado acima) seria o while
loop que preenche $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';
}
}
}
Este novo bloco de código irá, se o
usize
abrange mais de 1, determine a "célula superior" e a "célula inferior" para o dispositivo atual. Se você estiver abrangendo para cima , a célula superior é ustartlocation + usize - 1
; se você estiver abrangendo para baixo , é simplesmente ustartlocation
. A localização inferior também é determinada desta maneira.