Bootstrap Popovers


Bootstrap Popovers -- What Are They?

Popovers are something I discovered completely by accident while trying to figure out how to do something else. They are similar to a modal, except that they are designed to display when a mouse hovers over a link or an object. They are a window that opens, closes when focus is off the link or window, and so on. They are, however, not easy to use, and I had to rely heavily on assitance from developers over on StackOverflow to come up with a way to get them to work. I actually was able to combine them with modal forms as well, which was no small feat. [Bootstrap Popovers].

The simple form I found was when working on my CMS, I wanted the ability when the administrator was viewing images uploaded to a gallery, to see a larger version of the image. I spent a huge amount of time digging into various sample code across the web to try to find something, and was doing ... well, okay. However, while looking for other information on the Bootstrap site, I found Popovers and started experimenting.

A Simple Popover

The example here is a simpler version of what I'm talking about -- it will take an image and then when you hover the mouse over the image open a window displaying a larger Popover window.


The HTML

The first thing you need is the HTML necessary to display the image and to provide the necessary code for the popover:

               <div class="manage_gallery_image">
                  <span class="popover-markup" data-toggle="popover" >
                     <a href="#" class="trigger2" data-popover-content="#content1">
                        <img class="manage_gallery_thumbnail" src="miscimages/Death_to_stock_Marzocco_Coffee_9.jpg" alt="">
                     </a>
                     
                     <div class='hide' id='content1'>
                        <div class='popover-body'>
                           <img class='manage_gallery_big thumbnail' src='miscimages/Death_to_stock_Marzocco_Coffee_9.jpg' />
                        </div>
                     </div>
                  </span>
               </div>
            

The JavaScript

The problem is that this is very incomplete -- there is a bit of JavaScript that needs to be executed as well to be able to open the popup window.

               <script>
                  $('.popover-markup > .trigger2 ').popover(
                  {
                     html : true,
                     content: function()
                     {
                        return $(this).parent().find('.popover-body').html();
                     },
                     placement : 'left',
                     container: 'body',
                     trigger : 'hover'
                  });
               </script>
            

If you examine the code, you can see that placement is set to the left. With Bootstrap you can set the placement on top, bottom, left, or right. The Javascript code shown will look through a page and find all instances of the "popover-markup" item, and set this so that moving the mouse over each instance will open the popover using these settings.

The CSS

You also need to style the whole thing, here's the style sheet information being used:

               /* override Bootstrap settings */
               .popover
               {
                  max-width: 75% !important;
                  font-size: 19px !important;
               }

               .manage_gallery_image /* This is the outer div ... */
               {
                  float: right;
                  width: 170px;
                  border: solid 1px #ccc;
                  margin: 5px;
                  border-radius: 5px;
                  text-align: center;
                  overflow-y: auto;
               }
               
               .manage_gallery_thumbnail
               {
                  border: solid 1px #ccc;
                  border-radius: 2px;
                  background: white;
                  margin-top: 5px;
                  margin-bottom: 5px;
                  max-width: 150px;
                  max-height: 220px;
               }
               
               .manage_gallery_big
               {
                  max-width: 600px;
                  max-height: 800px;
                  position: relative;
                  margin-bottom: 5px;
               }
            

The first class definition above is overriding the Bootstrap popover size, and setting the maximum width to 75% of the width of the browser window. This is important. The font-size will be useful later.

Overview / Summary of Simple Version

The simple version shown here is rather nice, it provides a nice tool for the administrator. In my CMS, many images can be displayed this way on the same page, all of them are right-aligned (floated) within the forms that I am generating (via PHP), and if the admin is not sure what the image content really is (some are pretty detailed), then they can get the larger view, determine if they wish to allow the image to be displayed on the site, etc.

One drawback is that I am actually streaming the images out using PHP, and inserting the image id in to the content (if you look at the HTML above, where you see "content1", I am streaming out a primary key value for each image and attaching it to the word "content"), so that each image has its own popover defined. I am also streaming out the name of the image and the path to where it is stored so it can be displayed properly.

One of the things I discovered while working with some of the other options I found on the web to do something similar is that they relied heavily on having the thumbnail image and the larger image both stored on the server, which sort of defeats the purpose. Web browsers these days can handle resizing images and not losing resolution rather handily, so there does not seem to be a need to have multiple file sizes anymore.

A More Complex Version

User Profile with a popover and a modal form. For this to work, we use the same modal as we did in the modals page of this site, to show the user profile. We also are using a popover set to display minimal information about the user. If you hover the mouse over the username, you get the popover, and if you click the username you get the full modal with more detail.

What tripped me up creating this was the fact that the Bootstrap data-toggle attribute can only be used for one thing on any control. Unlike buttons, for example, where you can stack classes (class="btn btn-lg btn-success", for example), the data-toggle only works with the first item given it.

The solution, as it turns out, is to use a span tag to surround the whole thing that has its own data-toggle for the popup, and then we can make it all work. This was pointed out to me by someone on StackOverflow. The span tag doesn't do anything else, and there we are. The "stripped down" code for this is here ("stripped down" meaning that not all the data is included, but the important tags and such are):

               <div class="row">
               <center>
                  <span class="content_author">Author (username):
                     <span class="popover-markup" data-toggle="popover" >
                        <a href="" class="trigger userprof" data-title="User: ken"
                           data-body="<img src='profileimages/ken_profile_1477083603.jpg'
                           class='modal_profile_image' alt='Profile Image' />
                           <div class='modal_profile_name'>
                              Ken Mayer
                           </div>
                           Anything else we want to display in the modal
                           </div>"
                           data-toggle="modal" data-target="#userModal"
                           data-popover-content="#content1">ken
                        </a>
                        <div class='hide' id='content1'>
                           <div class='popover-heading'>
                              <h4>User: ken</h4>
                           </div>
                           <div class='popover-body'>
                              Whatever we want to display in the popover body
                           </div>
                        </div>
                     </span>
                  </span>
               </center>
               </div> <!-- / row -->
            

Probably the trickiest part of this is getting the quotes in the right places. As noted in the modals page of this site, they have to be "just right" or they interfere with each other. One trick to keep in mind is that if you are using, for example, single quotes, and need another single quote, is that you can either "escape" the single quote by using a backslash character (\), something like 'Fred O\'Malley', or you can convert the single quote to the HTML entity: &#039; -- start with the ampersand and end with the semicolon.

As always, the popover must have a unique name. When generating it from PHP, the code uses the primary key for the users table for the username, and that gives us what we're seeing above. There are some more CSS tags for the popover so that we get the data to appear correctly, but not a lot. This will appear as it does below. It has been placed in a Bootstrap well to make it stand out from the rest of the document.

Summary

If you download and examine all the (large amounts) of code for the GSPCMS application, you will find in "user_name.inc" (in the 'root\forms\content_elements_view' folder) the code to do all of what I am talking about. However it is PHP code, loading data out of a table. It works great in the CMS.

Credit Where Credit Is Due

For the example shown here, I am using an image from "Death to Stock Photos", a rather nice place to get free photos that are a little different from the standard "stock" photo websites. You have to sign up for them, and once a month they send a .zip file with anywhere from 10 to 15 photos on a theme, which you are free to use. You can visit them here: [Death to Stock Photos].

In addition, I got some help on combining the Bootstrap popover and modal forms into a single set of code via the community of developers at StackOverflow.