I have page where I display thumbnails of different image albums/categories and I try to make it when user click on the thumb to open modal with all images loaded from this category. The problem is that is seems I can't understand it very well how exactly will happen this. Now I have all the albums on the page but the modal is opened only when I click on last thumb. This is what I have so far:

 <?php
     require_once 'misc/database.php';

echo '<section id="portfolio" class="grid">';
          foreach($pdo->query("SELECT * FROM albums ORDER BY album_id") as $row) 
          {
                echo '
<figure class="effect-portfolio wow fadeIn"> <!-- Portfolio 3 -->
        <img src="'.$row['album_image'].'" alt="03_img"/> <!-- Your image here -->
        <figcaption> <!-- Caption -->
          <h2>'.$row['album_name'].'</h2>
          <a href="#portfolioModal2-'.$row['album_id'].'" class="portfolio-link" data-toggle="modal"></a>
        </figcaption> <!-- End caption -->   
</figure> <!-- End portfolio 3 -->  ';
          }
      echo '</section>
      <div class="portfolio-modal modal fade" id="portfolioModal2-'.$row['album_id'].'" tabindex="-1" role="dialog" aria-hidden="true">
      <div class="modal-content">
            <div class="close-modal" data-dismiss="modal">
                <div class="lr">
                    <div class="rl">
                    </div>
                </div>
            </div><div class="container">
                    <div class="row">';

        if(isset($row['album_id'])){
                $album_id = $row['album_id'];           
        $query2 = $pdo->query("SELECT * FROM images WHERE image_album = $album_id ORDER BY image_id DESC ");
                foreach ($query2 as $row2) {                                 
                    echo '<div class="col-lg-8 col-lg-offset-2">
                            <div class="modal-body">
                                <div class="item active">
                                  <img src="img/'.$row2['image_path'].'" alt="">
                                </div>
                            </div>
                        </div>';
                }      
        }
    echo '</div>
        </div></div></div> ';
    Database::disconnect();       
?>

Recommended Answers

All 10 Replies

Member Avatar for diafol

It looks as though you are loading many modal forms and downloading all the images (although hidden). Phew! That's a lot. In this case, you may wish to implement some ajax goodness.

You have a few choices as far as I can see:

Leave your album links as they are.

When an album link is clicked, run an ajax request to retrieve images and data from the DB. As you're re-using the same modal, there's no need to create loads and have many different ids.

Typically capture the link click event and run the Ajax:

<a href="#portfolioModal" class="portfolio-link" data-id="<?=$row['id'] ?>" data-toggle="modal"></a>

I'm assuming that you're using jQuery with bootstrap?

<script>
$('.portfolio-link').click(function(e)
{
    //you may need to e.preventDefault()
    //unsure if this would affect the modal showing
    //so need to experiment

    var id = $(this).data('id');
    getImages(id);


});

function getImages(id)
{
    $.get('get_images.php',{id: id})
        .done(function(data)
        {
            //use data to populate modal;
        });
}
</script>

Off top of my head and it's a bit rough, but may point the way.

I think the same that ajax is the best and may be only possible solution here but I'm not into ajax at all and have no idea how to implement it.
Do I need to place whole modal source code part into get_images.php or no?

p.s.
And yes I'm using jquery with bootstrap.

Member Avatar for diafol

Ok, many ways to implement this.
Probably the easiest is to place the innards of the modal into the php file, that way you can build up the content dynamically as you loop through the dataset rather than to get javascript update the modal using some sort of template.

BTW - try to get rid of all that php-string html - use plain html wherever posssible.

So keep the html in the page as is and empty the content of:

<div class="row"></div>

inside the modal. Perhaps give it an extra class or id to serve as a convenient hook, but you could use dom selectors just the same.

<div id="dynamic-content" class="row"></div>

So... from my post above...

function getImages(id)
{
    $.get('get_images.php',{id: id})
        .done(function(data)
        {
            $('#dynamic-content').html(data);
        });
}

And that should be it on the front-end. The PHP file will just build up some HTML, something like this:

$output =''; 
if(isset($_GET['id']))
{
    $db = new PDO(...); //or have an include file for this
    $stmt = $db->prepare('SELECT ... WHERE album_id = ? ORDER BY ...');
    $stmt->execute(array($_GET['id']));
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    foreach($result as $row)
    {
        //BUILD HTML by concatenating $output string, e.g.
        $output .= "<div>{$row['image_label']}</div>";
        $output .= "<div class='img-holder'><img src='/images/{$row['path']}' /></div>";
    }
}
echo $output;

The real problem is that I can't understand it in my head how will work. So on the page I have:

<div class="row">
    <?php
     // code to select all albums/categories from database
    ?>
    <div class="modal>
     // here to retrieve images of selected album
    </div>
</div>

What I understand from your answer is that I can keep the PHP part in row div (where I will load albums) and whole modal window will be moved into get_images.php and will be loaded viad ajax/js when album is selected?

Is that right?

Member Avatar for diafol

OK, been a while. Here's a working example of how you could do it. As this took a little time, I've used my own classes and ids - you'll need to change them to suit yourself.

HTML (with PHP) PAGE

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Gallery</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta name="description" content="">
  <meta name="author" content="">
  <link rel="stylesheet" href="">

    <link href="assets/css/bootstrap.css" rel="stylesheet">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>
<body>
<!-- JUST ME CREATING QUICK N DIRTY LINKS -->
<?php for($i=1;$i<6;$i++){?> <a href="#myModal" class="portfolio-link" data-id="<?=$i?>">Image <?=$i?></a> <?php }?>
<!-- END LINKS -->

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
            </div>
            <div class="modal-body">
                <div class="row" id="dynamic-content">
                    <img width="100%" src="" />
                    <p></p>
                </div>
            </div>
        </div>
    </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

<script type="text/javascript" src="assets/js/bootstrap.min.js"></script>
  <script>
      $('.portfolio-link').click(function()
      {
          var id = $(this).data('id');
          getImages(id);
      });

      function getImages(id)
      {
          $.getJSON('get_images.php',{id: id},function(data)
              {
                  $('#myModalLabel').html(data.title);
                  $('#dynamic-content img').attr('src', '/assets/img/' + data.img);
                  $('#dynamic-content p').html(data.desc);
                  $('#myModal').modal('show');
              });
      }
  </script>
</body>
</html>

The PHP that retrieves info from DB, file or wherever else (get_images.php):

<?php
//DEFAULT DATA
$img = 'default.png';
$title = "This is the default image";
$description = "This is the default description";


//GET DATA
if(isset($_GET['id']))
{
    //DO DB CONNECTION AND RETRIEVE VIA PREPARED STATEMENT USING $_GET['id']
    //HERE's SOME DUMMY DATA (don't bother understanding this - it's just my junk output

    $imgs = [1=>'snowdonia.jpg','dan-yr-ogof.jpg','bedd-gelert.jpg','craig-y-nos.jpg','carreg-cennen.png'];
    $img = isset($imgs[$_GET['id']]) ? $imgs[$_GET['id']] : 'error.png';
    $title = "This image #" . $_GET['id'];
    $description = "This is a description from image #" . $_GET['id'];
}

//OUTPUT DATA
echo json_encode(array('img'=>$img,'title'=>$title,'desc'=>$description ));

Thank's for your answer again!
Let me try to implement this and I will let you know what is happening.

Thank's again!

p.s.
I assume that I can't put my query to DB in the part where you put QUICK N DIRTY LINKS..

p.s2.
Also in the <script></script> part which id should I pass album_id which I use in WHERE clause to retrieve images or image_id? I guess is album_id...

Member Avatar for diafol

RE p.s Yes of course you can
RE p.s2 Pass whatever id you need to retrieve the data from your DB for the content - so if you want to retrieve all the thumb images from album #2, then pass the album_id. If you just want to show one image, then pass the image_id.

The 'id' that you pass in the ajax goes to get_images.php. It's up to you what data that file returns to javascript as the 'data' json object.

My example was intended as a "simple" example for you to customize to your own needs. If you get stuck with a specific case, come back.

All right for now. Going to try it now. Thank's!

Ok, here is what I've done so far. So I've successfully loaded images from the album on the page. When I click on some album it is showing the modal but empty. The question is how to fill it now?
Here is the front-end

<body>
    <?php
     require_once 'misc/database.inc.php';
     $pdo = Database::connect();
     echo '<section id="portfolio" class="grid">';
          foreach($pdo->query("SELECT * FROM albums ORDER BY album_id") as $row) 
          {
             echo'
                <figure class="effect-portfolio wow fadeIn">
                <img src="'.$row['album_image'].'" alt="03_img"/>
                    <figcaption>
                        <h2>'.$row['album_name'].'</h2>
                        <a href="#myModal-'.$row['album_id'].'" class="portfolio-link" data-toggle="modal"></a>
                    </figcaption> <!-- End caption -->   
                </figure>';
          }
     echo '</section>

    <div id="dynamic-content" class="row"></div>';
    Database::disconnect();       
    ?>

<!-- END LINKS -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
            </div>
            <div class="modal-body">
                <div class="row" id="dynamic-content">
                    <img width="100%" src="" />
                    <p></p>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
  <script>
      $('.portfolio-link').click(function()
      {
          var album_id = $(this).data('album_id');
          getImages(album_id);
      });
      function getImages(album_id)
      {
          $.getJSON('get_images.php',{album_id: album_id},function(data)
              {
                  $('#dynamic-content img').attr('src', 'img/' + data.img);
                  $('#myModal').modal('show');
              });
      }
  </script>
</body>

And this is get_images.php

<?php
require_once 'misc/database.inc.php';
$img = 'default.png';
$pdo = Database::connect();
//GET DATA
if(isset($_GET['album_id']))
{
    $query = $pdo->query("SELECT * FROM images WHERE image_album = $album_id ORDER BY image_id DESC ");
    foreach ($query as $row)
    {                                                    
        $img = '<img src="'.$row['image_path'].'" class="img-responsive" alt="">';
    }      
}
//OUTPUT DATA
Database::disconnect(); 
echo json_encode(array('img'=>$img));

Can you help me what is wrong here?

p.s. As you can see I've trying to give the album_id on the href in the loop here

a href="#myModal-'.$row['album_id'].'" class="portfolio-link" data-toggle="modal">

but may be this is mistake?

Member Avatar for diafol
foreach ($query as $row)
{                                                    
    $img = '<img src="'.$row['image_path'].'" class="img-responsive" alt="">';
}     

You are overwriting $img on every iteration of the loop, so you only get the last image. You are also wide open to SQL injection as you do not sanitize or vaidate the input (GET).

In addition, as you're using this:

$('#dynamic-content img').attr('src', 'img/' + data.img);

it expects just the url of the image, not the complete tag. ALso it ooks like you want to paste more than one image, so your hidden modal, should have a different structure ("template"):

Also, this is wrong:

<a href="#myModal-'.$row['album_id'].'" class="portfolio-link" data-toggle="modal"></a>

As we're just using the single hidden modal with the 'id' of myModal. We really don't need .$row['album_id'].' here. Why is there no text or image inside the tag?

e.g. <a href="#myModal" ....>Click here</a>

CLEAN UP

OK, so to tidy it up. Your links could look like this:

<a href="#myModal" class="portfolio-link" data-id="<?=$row['album_id']?>"><?=$row['album_name']?></a>

Your modal content could look like this:

<div class="modal-body">
    <div class="row" id="dynamic-content">
    </div>
</div>

Your ajax script:

  function getImages(album_id)
  {
      $.getJSON('get_images.php',{album_id: album_id},function(data)
          {
              $('#dynamic-content img').html(data.img);
              $('#myModal').modal('show');
          });
  }

Your PHP script (use prepared statement):

<?php
require_once 'misc/database.inc.php';
$img = 'default.png';
$pdo = Database::connect();
//GET DATA
if(isset($_GET['album_id']))
{
    $img = '';
    $id = $_GET['album_id'];
    $stmt = $pdo->prepare("SELECT * FROM images WHERE image_album = ? ORDER BY image_id DESC");
    $stmt->execute(array($id));
    $data = fetchAll(PDO::FETCH_ASSOC);
    foreach ($data as $row)
    {                                                    
        $img .= "<img src='{$row['image_path']}' class='img-responsive' alt=''/>";
    }      
}
//OUTPUT DATA
Database::disconnect(); 
echo json_encode(array('img'=>$img));

Once you get it to work, you can work on retrieving other data maybe.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.