Tuesday 16 June 2015

Change content using select menu in a Bootstrap page with the help of jQuery

I recently delivered the solution to a stackoverflow question. The question was around using a select menu to display different content contained in divs using jQuery.
Below is the solution, but the only difference is that I've contained it in a Bootstrap page. The important bit are 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 select content</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
    <style>
    body
    {
      padding-top:2em;
    }
    </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-12">
          <select name="type" id="type" class="form-control">
            <option>Select some content</option>
            <option value="bar">Bar</option>
            <option value="restaurant">Restaurant</option>
            <option value="hotel">Hotel</option>
          </select>
          <hr />
          <div id="bar" class="type well">Bar</div>
          <div id="restaurant" class="type well">Restaurant</div>
          <div id="hotel" class="type well">Hotel</div>
        </div>
      </div>
    </div>
    <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.4/js/bootstrap.min.js"></script>
    <script>
    (function()
    {
      $('div.type').hide();
      $('#type').change(function()
      {
          $('div.type').hide();
          $('#'+$(this).val()).toggle();
      });
    })();
    </script>
  </body>
</html>

Wednesday 10 June 2015

Bootstrap formhandler calling class methods with JSON returned and processed

This entry offers a number of techniques through 4 files.

  • index.php contains a message alert which will only be displayed when there is a message to put in it. The forms use an action which contains the name of a class and method which will be used to process the results. There is also a call to custom.js
  • custom.js handles the form submissions and delivers the data returned to the page. It passes the form action and field content to formhandler.php. It receives JSON which then is either passed to a message alert or a data table.
  • formhandler.php receives the call from custom.js. This contains the form action and field content. It takes the form action and uses them to create calls to classes and methods named in the form action. For example and action of myclass/mymethod would be used to create calls similar to those below. The inclusion of the $_POST array allows the form field content to be passed to the class. The data returned is then passed back to custom.js for processing.
$myclass = new myclass($_POST);
$myclass->mymethod;

  • myclassname.class.php contains the example class and methods. The class receives the $_POST array and processes its content. There are 3 methods which demonstrate how to return a string, an array and an object.

This approach is a quick way of utilising many classes. It does not require a .htaccess file to simplify form actions and is flexible in its handling of returned data through JSON.
Have fun.

index.php

<!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>Form handler for many PHP classes using jQuery</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.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]-->
    <style>
    body
    {
      margin-top:2em;
    }
    #message, #data-table
    {
      display:none;
    }
    </style>
  </head>
  <body>
    <div class="row">
      <div class="container">
        <div class="col-md-12">
          <div id="message" class="alert alert-success" role="alert"></div>
          <!-- <form action="myclassname/myclassmethod_string" method="POST"> -->
          <!-- <form action="myclassname/myclassmethod_array" method="POST"> -->
          <form action="myclassname/myclassmethod_object" method="POST">
            <div class="form-group">
              <label for="name"></label>
              <input type="text" name="name" class="form-control" />
            </div>
            <button type="submit" class="btn btn-default">Submit</button>
          </form>
          <table id="data-table" class="table table-striped">
            <thead>
              <tr>
                <th>Name</th>
                <th>Age</th>
              </tr>
            </thead>
            <tbody>
            </tbody>
          </table>
        </div>
      </div>
    </div>
    <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.4/js/bootstrap.min.js"></script>
    <script src="custom.js"></script>
  </body>
</html>

custom.js

(function()
{
  $('form').on('submit', function(event)
  {
    $.post('formhandler.php?action='+$(this).attr('action'), $(this).serialize(), function(data)
    {
      var json_obj = JSON.parse(data);
      if(json_obj.hasOwnProperty('message'))
      {
        $('#message').text(json_obj.message);
        $('#message').show();
        $('#message').fadeOut(3000);
      }
      else
      {
        $.each(json_obj, function(name,age)
        {
          $('#data-table > tbody').appendRow(name,age);            
        });
        $('#data-table').show();
      }
    });
    event.preventDefault();
  });
})();

$.fn.appendRow = function()
{
  var s = '<tr>';
  for (var i = 0; i < arguments.length; i++)
  {
    s += '<td>'+arguments[i]+'</td>';
  }
  s += '</tr>';
  return $(this).append(s);
}

formhandler.php

<?php
if(isset($_GET['action']))
{
$arr = split('/', $_GET['action']);
$class = $arr[0];
$method = $arr[1];
require_once $class.'.class.php';
if(class_exists($class))
{
$evalStr = '$'.$class.' = new '.$class.'($_POST);';
eval($evalStr);
if(method_exists($class, $method))
{
$evalStr = '$returnValue = $'.$class.'->'.$method.'();';
eval($evalStr);
}
else
{
$returnValue = 'Method does not exist';
}
}
else
{
$returnValue = 'Class does not exist';
}
}
else
{
$returnValue = 'No action given';
}

if(is_object($returnValue) || is_array($returnValue))
{
echo json_encode($returnValue);
}
else
{
$returnArr = array('message'=>$returnValue);
echo json_encode($returnArr);
}
?>

myclassname.class.php

<?php
class myclassname
{
private $pa;
function __construct($postArray = array())
{
$this->pa = $postArray;
}

function myclassmethod_string()
{
return 'Your name is '.$this->pa['name'];
}

function myclassmethod_array()
{
$myArr = array('Peter'=>'35', 'Ben'=>'37', 'Joe'=>'43');
return $myArr;
}

function myclassmethod_object()
{
$myObj = (object) array('Peter'=>'35', 'Ben'=>'37', 'Joe'=>'43');
return $myObj;
}

function __destruct()
{

}
}
?>

Wednesday 22 April 2015

Display PHP code in the browser

There are 2 ways to do this I've recently discovered:
First, use the highlight_file command thus,
highlight_file('hello.php');

Second, allow .phps files. To do this (I'm using an Ubuntu Apache on local host here), go to the file /etc/apache2/mods-available/php5.conf
Change the line highlighted in red to the one highlighted in blue
<FilesMatch ".+\.phps$">
    SetHandler application/x-httpd-php-source
    # Deny access to raw php sources by default
    # To re-enable it's recommended to enable access to the files
    # only in specific virtual host or directory
    Order Deny,Allow
    Deny from all
    Allow from all
</FilesMatch>
Now, if you rename hello.php to hello.phps and display it in your browser, it will show as PHP code.
Hope this helps.

Monday 30 March 2015

Simple Twitter Bootstrap with Knockout

The code below demonstrates some simple features of Knockout (or knockout.js) within a Twitter Bootstrap page. The funny thing is, you need jQuery for Twitter Bootstrap, so you're forced to get the best of both worlds, at the cost of your page loading speed.

The page does 3 things:
As you put text into the input box, the text is synchronised with the H1 tag
When you're happy, you can click the "I'm happy" button
Clicking the button adds the text to the list group below

I've put the Knockout items 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 with Knockout</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.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>
    <div class="row">
      <div class="container">
        <div class="col-md-6">
          <!-- This is used for adding text from the input box to the title -->
          <h1 data-bind="text:title"></h1>
          <form class="form-inline">
            <input type="text" class="form-control" data-bind="value:title, valueUpdate:'afterkeydown'">
            <!-- This is used to kick off the 'addOlEntry' function when the button is clicked -->
            <button type="submit" class="btn btn-primary" data-bind="click:addOlEntry">I'm happy</button>
          </form>
          <hr />
          <!-- Loop through the olArray -->
          <ol class="list-group" data-bind="foreach:olArray">
            <!-- Add a list item for each entry in the olArray -->
            <li class="list-group-item" data-bind="text:$data"></li>
          </ol>
        </div>
      </div>
    </div>
    <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.4/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
    <script>
   /* Create a title variable and make it observable. This becomes synced to the input box within the      HTML.
Create an array and make that also observable.
Create a function which is called when the button is clicked and adds the title text to the array.#
Bind it all together. */
    var vm = 
    {
      title:ko.observable(),
      olArray:ko.observableArray(),
      addOlEntry:function()
      {
        this.olArray.push(this.title());
      }
    }    
    ko.applyBindings(vm);
    </script>
  </body>
</html>

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'];
?>

Thursday 5 February 2015

JS and CSS fall back using PHP

There are several solutions to JS and CSS out there on the web. I've tried quite a few, but I find that if I take my network connection out, they don't work. They don't fall back. Recently, maxcdn.bootstrapcdn.com went down causing websites, including my own, to suffer from a lack of bootstrap. Even though I'd put in some fall back code.
This prompted me to write the following code. Now I know I'll be criticised for using PHP as the solution, but if you've suffered as I have, you may consider this worth a try. Below is the PHP class followed by the HTML page which makes use of the class with the calls highlighted in red. In this case I'm calling Twitter Bootstrap.
callfallback.class.php
<?php
class callfallback
{
function __construct()
{

}

function getCSS($remote, $local)
{
if($this->testExists($remote) == TRUE)
{
echo '<link rel="stylesheet" href="'.$remote.'" />'.PHP_EOL;
}
else
{
echo '<link rel="stylesheet" href="'.$local.'" />'.PHP_EOL;
}
}

function getJS($remote, $local)
{
if($this->testExists($remote) == TRUE)
{
echo '<script src="'.$remote.'"></script>'.PHP_EOL;
}
else
{
echo '<script src="'.$local.'"></script>'.PHP_EOL;
}
}

function testExists($url)
{
$file_headers = @get_headers($url);
if($file_headers[0] == 'HTTP/1.1 200 OK')
{  
 return TRUE;
}
else
{
 return FALSE;
}
}

function __destruct()
{

}
}
?>
index.html
<!DOCTYPE html>
<?php
require_once 'callfallback.class.php';
$cfb = new callfallback;
?>
<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 Fallback Template</title>
  <?php
  $cfb->getCSS('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css','css/bootstrap.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>
 
  <?php
  $cfb->getJS('https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js','js/jquery-1.11.2.min.js');
  $cfb->getJS('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js','js/bootstrap.min.js');
  ?>
</body>
</html>