Wednesday, 11 March 2015

Twitter Bootstrap carousel gallery with thumbnails and modals using jQuery

The challenge is to create a Twitter Bootstrap carousel with the following attributes:

  • Thumbnails of each image as the indicators.
  • Hovering over images highlights the fact that you can click on them.
  • Clicking on an image will display them in a modal window.

The solution lies below with areas of interest highlighted in red.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap thumbnail gallery</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <style>
    img
    {
      width:6em;
    }
    img:hover
    {
      opacity: 0.4;
      filter: alpha(opacity=40);
    }
    #exampleModal > div.modal-dialog > div > div.modal-body > img, #carousel-example-generic > div.carousel-inner > div.item > img
    {
      width:100%;
    }
    #carousel-example-generic > ol.carousel-indicators > img, #carousel-example-generic > ol.carousel-indicators > img.active
    {
      width:2em;
    }
    #carousel-example-generic > ol.carousel-indicators > img.active
    {
      height:3em;
    }
    </style>
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="row">
      <div class="container">
        <div class="col-md-4">
          <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">

            <!-- Start of Indicators -->
            <ol class="carousel-indicators">
              <img src="derek.jpg" data-target="#carousel-example-generic" data-slide-to="0" class="active">
              <img src="jimmy.jpg" data-target="#carousel-example-generic" data-slide-to="1">
              <img src="peter.jpg" data-target="#carousel-example-generic" data-slide-to="2">
              <img src="johnnie.jpg" data-target="#carousel-example-generic" data-slide-to="3">
              <img src="steve.jpg" data-target="#carousel-example-generic" data-slide-to="4">
              <img src="mick.jpg" data-target="#carousel-example-generic" data-slide-to="5">
            </ol>
            <!-- End of Indicators -->

            <!-- Start of Wrapper for slides -->
            <div class="carousel-inner" role="listbox">
              <div class="item active">
                <img src="derek.jpg" alt="Derek" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="jimmy.jpg" alt="Jimmy" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="peter.jpg" alt="Peter" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="johnnie.jpg" alt="Johnnie" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="steve.jpg" alt="Steve" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="mick.jpg" alt="Mick" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->        
            </div><!-- .carousel-inner -->
            <!-- End of Wrapper for slides -->

            <!-- Start of Controls -->
            <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
            <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
            </a>
            <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
            <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
            </a>
            <!-- end of Controls -->
          </div><!-- #carousel-example-generic -->    
        </div>
        <aside class="col-md-8">
         
        </aside>
      </div>
    </div>

    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" 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"></h4>
          </div>
          <div class="modal-body"></div>
        <div class="modal-footer"></div>
        </div><!-- /.modal-content -->
      </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <script>
    (function()
    {
      $('#exampleModal').on('show.bs.modal', function (event)
      {
        var img = $(event.relatedTarget);
        var alt = img.attr('alt');
        var src = img.attr('src');
        var modal = $(this);
        modal.find('.modal-title').text(alt);
        modal.find('.modal-body').html('<img src="'+src+'" />');
      });
    })();
    </script>
  </body>
</html>

Launch images in modal windows within Twitter Bootstrap using jQuery

So the challenge has 4 parts:
Make the image appear in thumbnail size on the page before it appears in the modal.
Change the opacity of the image on hover, so that users know if they click on it something may happen.
When the image is clicked, take information from the image tag and pass it to the modal window.
Make the image take up the whole modal window when launched.
Below is how to do it. I've highlighted the code in red.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Image to modal</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <style>
    img
    {
      width:6em;
    }
    img:hover
    {
      opacity: 0.4;
      filter: alpha(opacity=40);
    }
    #exampleModal > div.modal-dialog > div > div.modal-body > img
    {
      width:100%;
    }
    </style>
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <img src="mick.png" alt="A picture of Mick" data-toggle="modal" data-target="#exampleModal"><br />
    <img src="rojin.jpg" alt="A picture of Rojin" data-toggle="modal" data-target="#exampleModal">

    <!-- Now the modal window -->
    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" 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"></h4>
          </div>
          <div class="modal-body"></div>
        <div class="modal-footer"></div>
        </div><!-- /.modal-content -->
      </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <script>
    (function()
    {
      $('#exampleModal').on('show.bs.modal', function (event)
      {
        var img = $(event.relatedTarget);
        var alt = img.attr('alt');
        var src = img.attr('src');
        var modal = $(this);
        modal.find('.modal-title').text(alt);
        modal.find('.modal-body').html('<img src="'+src+'" />');
      });
    })();
    </script>
  </body>
</html>

Monday, 23 February 2015

Basic HTML5 web app template which works online and offline

Here I provide the code for 3 main files in the creation of a web app. This obviously remains working when there is no internet connection, but differently since back end databases etc. would no longer be available.
In order for this to work, you should also download jQuery.
First we will need an appcache file (in this case mobile.appcache) which tells the browser what to store locally. It should look like this:
CACHE MANIFEST
# 2015-02-23 v1.0.0
index.html
html5shiv/3.7.2/html5shiv.min.js
respond/1.4.2/respond.min.js
jquery/1.11.2/jquery.min.js
onlineoffline.plugin.js

NETWORK:
*
Every time you make a change, update the date and version numbers in order for receivers of the web app to get the updated version.
Next we'll need a jQuery plugin (onlineoffline.plugin.js) to handle differences in web app behaviour when online or offline:
(function($)
{
    $.fn.extend(
    {
        onlineoffline:function(options)
        {
            
        }
    });

    $.fn.handleOnline = function()
    {
        console.log('Handling online');
    };

    $.fn.handleOffline = function()
    {
        console.log('Handling offline');
    };
})(jQuery);
Finally, the HTML file (index.html). This makes a reference to the appcache and detects if the web app is online or offline. I've kept the CSS in this file too in order to reduce the number of files needed in this example.
<!DOCTYPE html>
<html lang="en" manifest="mobile.appcache">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">    
    <title>Simple online/offline</title>
    <style>
    body
    {
      font:0.9em/1.5em Sans-serif;
    }
    </style>
  </head>
  <body>
    <h1>Hello world!</h1>
    <script src="jquery/1.11.2/jquery.min.js"></script>    
    <script src="onlineoffline.plugin.js"></script>
    <script>
    setInterval(function()
    {
      if(navigator.onLine == true)
      {
        $(this).handleOnline();
      }
      else
      {
        $(this).handleOffline();
      }      
    }, 250);
    </script>
  </body>
</html>

Friday, 20 February 2015

Match the current URL with the responding navigation items of a Twitter Bootstrap site

So, you've got a Twitter Bootstrap website and you want the navigation items to become active when you're in the corresponding page. Below I wrote the jQuery plugin to do just that.
First the HTML
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">  
    <title>jQuery navigation plugin for bootstrap</title>
    <link href="bootstrap-3.3.2-dist/css/bootstrap.min.css" rel="stylesheet">      
  </head>
  <body>
    <nav class="navbar navbar-default">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-1">
            Menu          
          </button>
          <a class="navbar-brand" href="#"><span class="glyphicon glyphicon-education" aria-hidden="true"></span></a>
      </div><!-- .navbar-header -->
      <div class="collapse navbar-collapse" id="navbar-collapse-1">
        <ul class="nav navbar-nav">
          <li><a href="index.html">Home</a></li>
          <li><a href="irrigation.html">Irrigation</a></li>
          <li><a href="pump.html">Pump</a></li>
        </ul>
      </div><!-- #navbar-collapse-1 -->
    </div><!-- /.container -->
  </nav>
    <script src="jquery/1.11.2/jquery.min.js"></script>  
    <script src="bootstrap-3.3.2-dist/js/bootstrap.min.js"></script>  
    <script src="js/matchactive.plugin.js"></script>
    <script>
    (function()
    {
       $('ul.nav > li > a').matchactive();
    }();
    </script>
  </body>
</html>

And now the matchactive.plugin.js
(function($)
{
    $.fn.extend(
    {
        matchactive:function(getvar)
        {
            var pathArray = window.location.pathname.split( '/' );
            var sn = pathArray[pathArray.length - 1];
            var setOfAnchors = $(this);
            $(setOfAnchors).each(function()
            {
            if($(this).attr('href') == sn)
            {
            $(this).parent().addClass('active');
            }
            });
        }
    });
})(jQuery);

Thursday, 19 February 2015

jQuery plugin for content shared by multiple pages

Often content will appear in multiple pages in your website. For example, headers and footers will be the same on all pages. This is easily done using PHP, but it can also be done using jQuery, in fact better. Below is a Twitter Bootstrap page. As you can see I have a nav, a header and a footer. All of which have nothing in them, but I do have 3 things in my armoury:

  • A directory called 'includes/' which contains navbar.html, header.html and footer.html. They hold the content I need to fill these empty elements.
  • A plugin called 'include.plugin.js' (shown in red) which applies external file content to these empty elements.
  • A 'custom.js' (shown in red) which can be loaded on every new page I create.


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">  
    <title>jQuery includes</title>
    <link href="bootstrap-3.3.2-dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="css/custom.css" rel="stylesheet">
    <!--[if lt IE 9]>
    <script src="html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <nav class="navbar navbar-default"></nav>

    <div class="row">
      <div class="container">
        <header class="col-md-12"></header>
      </div><!-- .container -->
    </div><!-- .row -->  

    <div class="row">
      <div class="container">
        <div class="col-md-12">
          <p>Use the navigation.</p>
        </div>
      </div><!-- .container -->
    </div><!-- .row -->
   
    <div class="row">
      <div class="container">
        <footer class="col-md-12"></footer>
      </div><!-- .container -->
    </div><!-- .row -->

    <script src="jquery/1.11.2/jquery.min.js"></script>  
    <script src="bootstrap-3.3.2-dist/js/bootstrap.min.js"></script>
    <script src="js/receiveget.plugin.js"></script>
    <script src="js/include.plugin.js"></script>
    <script src="js/custom.js"></script>
  </body>
</html>

Now let's have a look at the include.plugin.js. It does a simple load, but while we're waiting for the content to come through a loader gif is put inside the calling element. This is overwritten when the content arrives.
(function($)
{
    $.fn.extend(
    {
        include:function(includefn)
        {
            $(this).append($('<img>',{src:'img/loading.gif'}));            
            $(this).load(includefn);
        }
    });
})(jQuery);

Finally, custom.js which contains the calls we need.
(function()
{
$('nav.navbar.navbar-default').include('includes/navbar.html');
$('header').include('includes/header.html');
$('footer').include('includes/footer.html');
})();

jQuery plugin to receive GET parameters and add them to an element

Below is my simple page. What I'd like to do, as you can see from the code in red is to call a jQuery plugin. The plugin find the message parameter sent to a page and apply its value to the #message div. So the call to the page would be something like this mypage.html?message=Hello+world
Then the words 'Hello world' would appear inside the div.

<!DOCTYPE html>
<html lang="en">
<head>  
<body>  
  <div class="id="message"></div>
  <script src="jquery/1.11.2/jquery.min.js"></script>
  <script src="js/receiveget.plugin.js"></script>
  <script>
  (function()
  {
    $('#message').receiveget('message');
  })();
  </script>
  </body>
</html>

So here is my receiveget.plugin.js
(function($)
{
    $.fn.extend(
    {
        receiveget:function(getvar)
        {
            var sPageURL = window.location.search.substring(1);
            var sURLVariables = sPageURL.split('&');
            for (var i = 0; i < sURLVariables.length; i++)
            {
                var sParameterName = sURLVariables[i].split('=');
                if (sParameterName[0] == getvar)
                {
                    $(this).text(decodeURIComponent(sParameterName[1].replace('+', ' ')));
                }
            }
        }
    });
})(jQuery);

Tuesday, 10 February 2015

Using Font Awesome icons and jQuery to show form loading in Twitter Bootstrap page

Font Awesome is a really useful tool for adding icons to your website. It also comes with animated icons which can be used to show when your form is waiting for a response. In the example below, I have created a basic Twitter Bootstrap page. The page has a form. When the form is submitted, there is a delay in its response. During the delay, I use jQuery to show a Font Awesome animated icon.
First the Twitter Bootstrap page with the differences in red:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Font Awesome Animated Icons</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">   
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
  <i class="fa fa-circle-o-notch fa-spin"></i>  
  <form action="response.php" method="POST">
    <input type="text" name="yourname" id="yourname" placeholder="Enter your name" />
    <button type="submit">Submit</button>
  </form>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
  <script>
  (function()
  {
    var thisForm = $('form');
    var i = $('i');
    i.hide();
    thisForm.submit(function()
    {
      i.show();
      thisForm.hide();
      $.post(thisForm.attr('action'),thisForm.serialize(), 
      function(data)
      {
        thisForm.empty().html(data);
        i.hide();
        thisForm.show();
      });  
      return false;
    });
  })();
  </script>
  </body>
</html>
Now my response.php
<?php
sleep(2);
echo 'Hello '.$_POST['yourname'];
?>