How to create multiple dynamic image slider ? [using PHP, MySQL & vanilla JS only ! ]

Coding Noob picture Coding Noob · Aug 13, 2018 · Viewed 19.9k times · Source


I'm new to PHP and JS programming and need help with my website project.
In a other question, I had a problem with an image posting system, which is solved:
SOS! How to display image albums in posts? [using PHP and MYSQL only].

Now I want to modify this posting system with dynamic image sliders. (next Level ^^)
At the end, it must be possible to scroll down trough the posts and in each post with more then 1 image, it must be possible to slide left & right through the images of this album.

Image Slider
I inspired me by a full screen image slider: https://codepen.io/bradtraversy/pen/boydaE
and a carousel slider: https://www.youtube.com/watch?v=KcdBOoK3Pfw
which are both vanilla but static (without database).


Below you can see my php file, where everything comes together.

display.php


<!DOCTYPE html>
<html>
<body>
<?php
$db = mysqli_connect("localhost", "root", "", "post_images");    

$result = mysqli_query($db, "SELECT * FROM posts");
while ($row = mysqli_fetch_array($result)) {
   echo "<div class=\"post_container\">";
     echo $row['post_title'];
     echo "<div class=\"image_container\">";
     SELECT img_file, img_title FROM images WHERE post_id = " .$rowx['id_post']);

     if(mysqli_num_rows($resultx) > 0) {
        if(mysqli_num_rows($resultx) == 1) {
           echo "<div class=\"post_image_displayer\">";
             while ($rowx = mysqli_fetch_array($resultx)) {
               echo "<img src='../folder_image_uploads/".$rowx['img_file']."' >";
               echo $rowx['img_title'];
             }
           echo "</div>";
        }
        elseif(mysqli_num_rows($resultx) > 1) {
           echo "<div class=\"post_image_slider\">";
             include_once 'incl_image_slider.php';
           echo "</div>";
        }
     }
     echo "</div>";
   echo "</div>";
}
?>
</body>
</html>


This code works perfectly, if there would be only 1 slider on this page. You see, I used include_once 'incl_image_slider.php'; . If I would use only include 'incl_image_slider.php'; , the page go crazy ... (only by the image slider). Even if everything has a class and no unique id.

incl_image_slider.php


<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="includes/incl_carousel_slider_style.css">
</head>

<div class="carousel-container">
    <div class="carousel-slide">
        <?php
        $db = mysqli_connect("localhost", "root", "", "post_images");
        $result = mysqli_query($db, "SELECT * FROM posts");
        $row = mysqli_fetch_array($result);
        $resultx = mysqli_query($db, "SELECT img_file, img_title FROM images WHERE post_id =".$row['id_post']);

        $rowz = mysqli_fetch_all($resultx, MYSQLI_ASSOC);
            echo "<img src='folder_img_uploads/".$rowz[0]['img_file']."' >";
            echo "<img src='folder_img_uploads/".$rowz[1]['img_file']."' >";
            echo "<img src='folder_img_uploads/".$rowz[2]['img_file']."' >";
            echo "<img src='folder_img_uploads/".$rowz[3]['img_file']."' >";
            echo "<img src='folder_img_uploads/".$rowz[4]['img_file']."' >";
        ?>
    </div>
</div>
<button class="prevBtn">Prev</button>
<button class="nextBtn">Next</button>

<script src="incl_image_slider_app.js"></script>


The problem with this is, I have to know for each post, how many images inside. So this can't be used dynamically with a database, someone have an idea what to change?

incl_image_slider_app.js

Partly this is from: https://codepen.io/bradtraversy/pen/boydaE

let sliderImages = document.querySelectorAll(".carousel-slide"),
arrowLeft = document.querySelector(".prevBtn"),
arrowRight = document.querySelector(".nextBtn"),
current = 0;

// Clear all images
function reset()
{
  for (let i = 0; i < sliderImages.length; i++)
  {
    sliderImages[i].style.display = "none";
  }
 }
 // Init slider
 function startSlide()
 {
   reset();
   sliderImages[0].style.display = "block";
 }
 // Show prev
 function slideLeft()
 {
   reset();
   sliderImages[current - 1].style.display = "block";
   current--;
}
// Show next
function slideRight()
{
  reset();
  sliderImages[current + 1].style.display = "block";
  current++;
}
// Left arrow click
arrowLeft.addEventListener("click", function()
{
  if (current === 0)
  {
    current = sliderImages.length;
  }
slideLeft();
});

// Right arrow click
arrowRight.addEventListener("click", function()
{
  if (current === sliderImages.length - 1)
  {
    current = -1;
  }
slideRight();
});

startSlide();


Actually this image slider don't slide, no idea why? But it shows the first image of a post. And it is not possible to bring this multiple times for each post, in my display.php

I hope there is someone who can help me.
Best Regards :)

Answer

Marleen picture Marleen · Aug 13, 2018

I think you want something like this. I've used Flickity Slider (pure JavaScript) instead of your JavaScript because I couldn't get that working (but then again, I can barely code a foreach loop in JavaScript :( ), hopefully this will give you something to start with. :)

https://flickity.metafizzy.co/

<!DOCTYPE html>
<html>
<head>
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.min.css">
<!-- JavaScript -->
<script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script>
</head>
<body>

<?php
$db = mysqli_connect("localhost", "root", "", "post_images");      
$result = mysqli_query($db, "SELECT * FROM posts");
?>

<?php while ($row = mysqli_fetch_array($result)) : ?>

    <div class="post_container">$row['post_title'];

        <?php $resultx = mysqli_query($db, "SELECT img_file, img_title FROM images WHERE post_id = " .$row['id_post']); ?>

        <?php if (mysqli_num_rows($resultx) == 1) : ?>

        <div class="image_container">

            <div class="post_image_displayer">

                <?php while ($rowx = mysqli_fetch_array($resultx)) : ?>
                <img src='../folder_image_uploads/<?php echo $rowx['img_file']; ?>'><?php echo $rowx['img_title']; ?>
                <?php endwhile; ?>

            </div>

        </div>

        <?php elseif(mysqli_num_rows($resultx) > 1) : ?>

            <div class="main-carousel" data-flickity='{ "cellAlign": "left", "contain": true }'>

                <?php while ($rowx = mysqli_fetch_array($resultx)) : ?>
                <div class="carousel-cell"><img src='../folder_image_uploads/<?php echo $rowx['img_file']; ?>' ></div>
                <?php endwhile; ?>

            </div>

        <?php endif; ?>

    </div>

<?php endwhile; ?>

</body>
</html>

The CSS and JavaScript files in the header include the slider plugin.

Then, the first SQL query gets all of the posts, the while loops over each one.

For each post, the second SQL query gets the images for the current post.

If there's only one image, it is printed inside a <div class="image_container">.

If there's more than one image, they're printed inside a <div class="main-carousel"> which tells the JavaScript plugin together with the data-flickity='{ "cellAlign": "left", "contain": true }' that it needs to show these in a slider.

The individual images in the slider are each printed inside a <div class="carousel-cell"> which is also required by the plugin.

This is repeated for all images of all posts, you don't need to use an include file.

Update with the slider by sinisake from this post

<!DOCTYPE html>
<html>
<head>
<!-- CSS -->
<link rel="stylesheet" href="">
<!-- JavaScript -->
<script src=""></script>
</head>
<body>

<?php
$db = mysqli_connect("localhost", "root", "", "post_images");      
$result = mysqli_query($db, "SELECT * FROM posts");
?>

<?php while ($row = mysqli_fetch_array($result)) : ?>

    <div class="post_container">$row['post_title'];

        <?php $resultx = mysqli_query($db, "SELECT img_file, img_title FROM images WHERE post_id = " .$row['id_post']); ?>

        <?php if (mysqli_num_rows($resultx) == 1) : ?>

        <div class="image_container">

            <div class="post_image_displayer">

                <?php while ($rowx = mysqli_fetch_array($resultx)) : ?>
                <img src='../folder_image_uploads/<?php echo $rowx['img_file']; ?>'><?php echo $rowx['img_title']; ?>
                <?php endwhile; ?>

            </div>

        </div>

        <?php elseif(mysqli_num_rows($resultx) > 1) : ?>

            <div class="slideshow-container">

                <?php $rowsx = mysqli_fetch_all($resultx, MYSQLI_ASSOC); ?>

                <?php foreach ($rowsx as $key => $rowx) : ?>

                  <div class="mySlides fade">
                    <div class="numbertext"><?php echo $key + 1; ?> / <?php echo count($rowsx); ?></div>
                    <img src='../folder_image_uploads/<?php echo $rowx['img_file']; ?>' style="width:100%">
                    <div class="text">Caption Text</div>
                  </div>

                <?php endforeach; ?>

                  <a class="prev" >&#10094;</a>
                  <a class="next">&#10095;</a>
                <div style="text-align:center">

                <?php foreach ($rowsx as $rowx) : ?>
                  <span class="dot"></span>
                <?php endforeach; ?>

                </div>  

            </div>

        <?php endif; ?>

    </div>

<?php endwhile; ?>

</body>
</html>

What I've changed here, I've stored the entire result of the second SQL query in an array ($rowsx), because then I can loop over it twice (with foreach instead of while).

The first time I loop over it is to print the individual images, and when all images have been printed I loop over the array a second time to print the "dots" for the navigation, because there need to be the same number of dots as there are images in the slider.