Image Gallery Demo 2: Ken's Image Gallery


Image Galleries

One of the nice things about the web is the ability to display images, and display them in a variety of ways. One of the frustrating things about the web is the same. It can be difficult.

If you read the page on Lightbox 2, you will see that I had tinkered with that code for my own CMS, but ultimately wasn't satisfied with what could be done. So, I went and created my own, using a Bootstrap Modal form. This gave me the ability to have a panel displaying the description of the image -- some images need descriptions and this worked for me.

Ken's Image Gallery

This uses a combination of the thumbnail images, and a call to a modal form, so you need a combination of Bootstrap, a modal form defined the way you want it to look, the Javascript needed to open the the modal form, the Javascript needed to clear out the description when the modal form closes, and so on. There are also some CSS items that are needed to help modify the appearance of the modal form, as well as the thumbnail images.

For my CMS (which is what I built this for) I keep the modal form in its own file, and use a PHP call to insert it into the web page when I want it, and I keep the Javascript in a separate file. For this demo, it will all be contained in the same file (this one).

The Styles

In your cascading style sheet for your own web app (for my CMS these are all in the GSPCMS.css file), or in the page you need the following styles:

               /* for the thumbnails */
               .gallery_image
               {
                  float: left;
                  width: 220px;
                  height: 305px;
                  border: solid 1px #ccc;
                  margin: 5px;
                  border-radius: 5px;
                  text-align: center;
                  overflow-y: auto;
               }
               
               .gallery_thumbnail
               {
                  border: solid 1px #ccc;
                  border-radius: 2px;
                  background: white;
                  margin-top: 5px;
                  max-width: 200px;
                  max-height: 220px;
               }
               
               /* DIV for the caption/credit text */
               .gallery_title
               {
                  text-align: center;
                  font-size: 16px;
                  margin-top: 15px;
                  margin-bottom: 20px;
               }
               
               .gallery_caption
               {
                  font-weight: bold;
                  font-size: 18px;
                  line-height: 1em;
               }
               
               .gallery_credit
               {
                  font-style: italic;
                  font-size: 14px;
                  line-height: 1em;
               }
               
               /* for the modal form */
               /* center modal vertical */
               #imageModal.modal:before
               {
                 content: '';
                 display: inline-block;
                 height: 100%;
                 vertical-align: middle;
                 margin-right: -4px; /* Adjusts for spacing */
               }
               
               /* center modal horizontal */
               #imageModal.modal
               {
                 text-align: center;
                 padding: 0!important;
               }
               
               #imageModal .modal-dialog
               {
                  overflow-y: initial !important;
                  display: inline-block;
                  text-align: left;
                  vertical-align: middle;
                  width: 1000px !important;
               }
               
               #imageModal .modal-body
               {
                  max-height: 750px;
                  max-width: 1200px;
               }
               /* I imagine for most photos the description text
                  won't be big enough to be a problem, but for
                  at least one site I intend to use this with
                  the overflow option is vital ... */
               #imageModal .modal-body .modal-text
               {
                  padding-bottom: 10px;
                  max-height: 700px;
                  overflow-y: auto;
               }
               
               #imageModal .modal-footer
               {
                  text-align: left !important;
               }
               
               #imageModal .modal-footer .modal-credit
               {
                  font-size: 20px;
                  font-weight: bold;
                  text-align: left !important;
               }
               
               #imageModal .modal-body .modal_img
               {
                  max-height: 700px;
                  max-width: 100%;
               }
            

That's quite a bit more CSS than in the version used for Lightbox 2, but a lot of this is for the modal form.

The Modal Form

Modal forms have three parts: a header, the body, and a footer. For this particular situation I chose to use all three parts.

               <!-- modal form for gallery image WITH description -- opened by clicking on
                  a thumbnail image, using JS script code that is inserted at bottom of page -->
                <div id="imageModal" class="modal fade" tabindex="-1" role="dialog">
                   <div class="modal-dialog modal-lg" role="document">
                      <div class="modal-content">
                         <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                               <span aria-hidden="true">×</span>
                            </button>
                            <h3 class="modal-title" id="descModalLabel"></h3>
                         </div> <!-- / modal-header -->
                         <div class="modal-body">
                            <div class="row">
                               <div class="col-md-7 modal-image">
                                  <!-- an image will be passed here -->
                               </div>
                               <div class="col-md-5 modal-text">
                                  <!-- and text will be shown here -->
                               </div>
                            </div> <!-- / row -->
                         </div> <!-- / modal-body -->
                         <div class="modal-footer">
                            <span class="modal-credit">
                               <!-- text for credit will be here -->
                            </span>
                            <button type="button" class="btn btn-default pull-right" data-dismiss="modal">Close</button>
                         </div> <!-- / modal-footer -->
                      </div> <!-- / modal-content -->
                   </div> <!-- /modal-dialog -->
                </div> <!--/ modal -->
                <!-- end of modal form -->
            

The items that are bold are ones you should pay some attention to. I am using classes that are defined in the styles noted above. In addition I am using the Bootstrap grid to break the body of the modal into two columns. This requires the row, as well as the "col-md-x" classes. The Bootstrap grid uses 12 columns, so I am dividing the body of the modal form into two areas, one that is 7 columns wide for the image, and one that is 5 columns wide for the description text.

The Javascript (below) will reference some of the classes in order to place the image or text into the appropriate places of the form before it opens.

HTML for Images

Each image needs to use the same set of tags, changing out just the items that need to be changed, the caption, the path to the image name, etc.:

               <div class="gallery_image">
                  <a href="" data-toggle="modal" data-target="#imageModal"
                             data-title="Marzocco Coffee 1  <a href='miscimages/Death_to_stock_Marzocco_Coffee_1.jpg' class='btn btn-default btn-xs'
                                       title='Open in New Window' target=_blank>
                                       <i class='fa fa-external-link' aria-hidden='true'></i></a>"
                              data-text="<span class='modal_txt'><strong>Description:</strong>
                                 <p>Text description goes here</p<</span>"
                              data-credit="Photo/Image Credit: Death to Stock"
                              data-image="<img class='modal_img img-responsive center-block' src='miscimages/Death_to_stock_Marzocco_Coffee_1.jpg' alt='Coffee'>">
                              <img src="miscimages/Death_to_stock_Marzocco_Coffee_1.jpg"
                                   class="gallery_thumbnail" alt="Coffee" />
                  </a>
                  <div class="gallery_title">
                     <p class="gallery_caption">Marzocco Coffee 1</p>
                     <p class="gallery_credit">Credit: Death to Stock</p>
                  </div>
               </div>
            

This is a lot more complex than the setup for Lightbox, because we are nesting some HTML tags inside of HTML attributes for the anchor tag. The following are the attributes:

After the anchor tag we then have the img tag which is the one used for the thumbnail. Now we could have different images (some image galleries have a thumbnail sized image, and the full sized image, or even a medium and full sized image), but web browsers can handle using the same image in difference sizes. In this case the image tag uses the "gallery_thumbnail" class, which definse the size of the image.

The last bits are part of the thumbnail display, so we output the caption and credit under the image in the thumbnail itself.

The image gallery displayed below has all of the above going on. Interestingly, my editor things I am missing a quote for one of the attributes, and that is because of the way the information is nested. Believe it or not, everything is correct in the code shown above. It works! However, to display this on the modal form, the Javascript will need to be set up -- see below.

The Javascript

The following Javascript would go after any script tags used to include Javascript code in your page:

               <!-- image gallery modal -->
               <script>
                  $('#imageModal').on('show.bs.modal', function (event)
                  {
                     var button = $(event.relatedTarget); // Control that triggered the modal
                     var title = button.data('title'); // Extract info from data-* attributes
                     var image = button.data('image'); // Extract info from data-* attributes
                     var text = button.data('text'); // Extract info from data-* attributes
                     var credit = button.data('credit');
                     var modal = $(this);
                     modal.find('.modal-title').append( title );
                     modal.find('.modal-body .modal-image').append( image );
                     modal.find('.modal-body .modal-text').append( text );
                     modal.find('.modal-footer .modal-credit').append( credit );
                  });
                  
                  // when modal closes, clear out the body:
                  $('#imageModal').on('hidden.bs.modal', function ()
                  {
                      $(this).find(".modal-title").text('');
                      $(this).find(".modal-image").text('');
                      $(this).find(".modal-text").text('');
                      $(this).find(".modal-credit").text('');
                  });
               </script>
            

This code is interesting. It is based loosely on code provided by the folk at Bootstrap, but I got some help from some developers over on Stack Overflow to get it just right.

The difficulty is in the way the modal dialog works. In order to display HTML in the form, you have to use the modal's append() method. However, if there is already text there, it will do what you would expect -- add the new text to whatever was there. So instead, what is happening is that when the modal closes, we clear out the text in the different parts of the form. Then, when we use the append() method, we are putting new text in there. That is where I needed some serious help from folk over on Stack Overflow, and they did come through for me. It took some digging and trying various options, but this one works like a charm.

Example Image Gallery

The following is a set of images from Death to Stock Photos, all set using the appropriate HTML tags so that we get a set of thumbnail images. Clicking on any of them should bring up the modal window and you can see how it works.


I put a break tag in after the last image, but I could also have included the whole set of images in a div tag, with the only purpose being that a div tag breaks up the page at that point. Leaving both of these out would cause, when resizing your screen, the images to wrap correctly, but the text under the last image might end up to the right of it instead.

A couple of the images have enough text that the overflow defined in the styles shows how useful it can be -- a vertical scrollbar is given for the text so you can scroll up/down.

When you open the modal form, note that in the title there is a small button to the right of the caption (using an image from Font-Awesome) that will open the photo in a new browser window. This is handy for images that contain art when someone might want to view the image in even greater detail (this comes up for one of the purposes I intend to use the gallery for at a later date).

The one thing that is missing is the ability to scroll through the larger images like you can with Lightbox. However, I didn't feel like trying to write the code that would do something like that -- it's pretty complex, and frankly, this was plenty of work on its own. (For what it's worth, the software being used on one my sites that I intend to replace this with does the same thing, and no one has complained ...)

Summary

This took more work than Lightbox, but it really gave me the ability to do what I wanted to do. It also let me prove to myself that yes indeed, I can work out a fairly complex problem and build something to my own liking, which at the time I worked on this was important. My ego was taking a hit from some other things I had worked on. Creating this image gallery code really helped me out in that area.

Credit Where Credit Is Due

The filler text used for the descriptions was taken from [Bacon Ipsum], another site that generates "ipsum lorem" type text that can be used to fill things out.

The photos used are from [Death to Stock Photos]. If you sign up, they will, once a month, email a set of photographs that you can use free for whatever purposes you wish. I have found that they are generally decent photos, and while the topics range all over the place, they can be useful for, if nothing else, examples ...

Finally, if you choose to use this code, I would greatly appreciate a call-out just to give me some credit for my own work.