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>