I'm trying to modify a Bootstrap carousel so that it displays images 5 at a time; the images are stored in a directory on my website, but to find out which ones should be shown at all times I have to make a call to my database (in addition to the images themselves, I also intend to show other related information when I get the carousel work well).
This is the code:
<?php
$id_usuario = $_SESSION['id_usuario'];
include("conexion.php");
$sql = "SELECT titulo_cancion, titulo_disco, nombre_autor, ano
FROM listas NATURAL JOIN canciones NATURAL JOIN votan NATURAL JOIN discos NATURAL JOIN publican NATURAL JOIN autores
WHERE id_usuario = $id_usuario AND nota = 5
ORDER BY fecha_voto DESC";
$resultados = mysqli_query($conexion, $sql);
$filas = array();
while($filas[] = mysqli_fetch_assoc($resultados));
array_pop($filas);
$maximo = sizeof($filas);
?>
<div id="carrusel" class="carousel slide" data-ride="carousel" data-interval="false">
<div class="carousel-inner">
<?php
foreach($filas as $clave => $valor)
{
$clave = $contador * 5;
echo '<div class="carousel-item'; echo ($contador == 0) ? ' active">' : '">';
if($clave >= $maximo)
{
$contador = 0;
$clave = 0;
}
for($i = $clave; $i <= $clave + 4; $i++)
{
#$titulo_cancion = utf8_encode($filas[$i]['titulo_cancion']);
$titulo_disco = utf8_encode($filas[$i]['titulo_disco']);
#$nombre_autor = utf8_encode($filas[$i]['nombre_autor']);
$ano = $filas[$i]['ano'];
if(strpos($nombre_autor, ", The")) $nombre_autor = "The ".substr($nombre_autor, 0, strpos($nombre_autor, ", The"));
$decada = substr($ano, 0, 3)."0s";
if(strpos($titulo_disco, "/")) $nombre_foto = substr($titulo_disco, 0, strpos($titulo_disco, "/"));
elseif(strpos($titulo_disco, ":")) $nombre_foto = substr($titulo_disco, 0, strpos($titulo_disco, ":"));
else $nombre_foto = $titulo_disco;
#$recopilatorio = $ano;
echo '<img class="img-fluid mr-2" src="imagenes/'.$decada.'/'.$ano.'/'.$nombre_foto.'.jpg" width="214.01225" height="214.01225">';
if($i == $maximo - 1) break;
}
$contador++;
echo '</div>';
}
?>
</div>
<a class="carousel-control-prev" href="#carrusel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carrusel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
The code "works" but there is the obvious problem that when the foreach
carousel is finished it starts again from 0 even though the last photo shown was not exactly the last one in the collection; for instance:
For 7 photos, 7 routes are made foreach
, from $clave
0 to $clave
6, but given the internal logic of for
the photos are shown in two batches, from 0 to 4 and from 5 to 6; therefore, when foreach
he finally reaches $clave
6 he for
is showing (for the 4th time) the series of photos 0-4, but then series 5-6 does not appear, instead 0-4 appears again since it is $clave
again 0.
This problem does not occur when the last batch of photos to show coincides with the last $clave
, which happens when there are 5 photos (and all their multiples) or less and for some other numbers like 6, 8, 12 and 16 (I think they are the only ones for whom there are no problems).
The solution would be to tell foreach
it every time it restarts to take into account which batch of photos was the last one displayed. I have tried to find some mathematical relationship between the number of photos and 5 by calculating remainders and quotients but at the moment I don't see anything.
Another behavior that strikes me is that if there is only one photo to display, the carousel does not work, there is no scrolling. I don't know if this is something typical of Bootstrap, but in any case my batches are five photos and not one, so the logical thing would be that there would be no scrolling only if there are not at least six photos.
Anyway, let's see if someone comes up with something. Thank you very much in advance.
In the end I have chosen to limit the carousel so that it does not slide forever:
1) I have added the option
data-wrap="false"
inside<div id="carrusel"...>
2) I have modified the PHP code so that the
foreach
breaks if thefor
:In addition, this way I prevent the carousel from sliding if there are less than 6 photos, which kills two birds with one stone.