Table content overflowing enclosing div

A block level element like this div is sized to fit the width of its parent, not the width of its content.
At the top level of a document the parent is typically the viewport (a viewport is the visible portion of the canvas).

If you have a table with content that can’t be broken up because it doesn’t have spaces or there are lots of columns then the width may be greater than the viewport – especially if you are using a laptop or mobile browser.

In this instance the content will break out of the enclosing div.

stuff@longstring stuff@longstring stuff@longstring stuff@longstring stuff@longstring breakout

To resolve this,
use style display:table
Works with IE 8 onwards and tells the div to display as a table.

stuff@longstring stuff@longstring stuff@longstring stuff@longstring stuff@longstring enclosed

use style float:left
Works with IE6 onwards
When an element is floated it uses the value of defined width or auto in which case it shrinks to fit its content.
There’s a definition of shrink-to-fit by the W3C

stuff@longstring stuff@longstring stuff@longstring stuff@longstring stuff@longstring enclosed
Posted in CSS | Leave a comment

Blog Tutorial with Fat-Free Framework v3

This article is adapted from my first one originally written 30/09/2011 for v2
This version was updated 18/02/13 for v3.05

Version 3 is better with even less typing required to access the power of this simple framework.

A while ago now I read an excellent tutorial on ‘Rapid Application Prototyping in PHP Using a Micro Framework‘, this used the Slim micro framework but one thing that bothered me was it required 5 packages before development could start.
These were: Slim (the micro framework), Slim Extras (additional resources for Slim), Twig (template engine), Idiorm (object-relational mapper) and Paris (Active Record implementation).
It struck me that if you need an extra 4 packages alongside Slim for a basic blog then maybe it is a little too skinny and I set out to find a micro framework that could do the same thing without these dependencies.

I found the Fat-Free Framework. It is condensed into a single 50KB file and has a host of features, you can find out about these on the web site so I won’t repeat it here. Instead I’ve reproduced the Slim tutorial to create a simple blog site, but using Fat-Free Framework instead.
You will need PHP 5.3 on your server, I used Ubuntu 12.04 for the tutorial as that version of PHP is easily installed.

Step 1: Setup

Download Fat-Free Framework (F3) from the website.
F3 works just as happily in the site root as from a subdirectory – I’ll assume you’re using an empty website site to do this tutorial.
Unzip the contents of the F3 download and copy the contents into your website root.
The folder contents should look like this:
folder contents

Notice how much simpler the starting site is compared with Slim + extra packages.

Move up one level in the directory heirarchy and set the permissions:

sudo chgrp -R www-data blog
sudo chmod -R 775 blog
cd blog
sudo chmod -R 777 tmp

If using Apache, mod_rewrite will need to be running.

You can browse this site right away and get the F3 start page.
Fat-Free Framework start page

(Once the site has been visited, F3 will create additional folders cache and temp – you don’t need to worry about these).

Step 2: Bootstrapping

As everything we need is already part of F3 you don’t need to do anything here!

You can however tidy up the site to remove the current home page and add a database connection.
Edit index.php and remove the two route functions – these are just used to display the welcome page and the documentation. It should look like this once they have been removed:


To setup a database connection add the following between the set and run commands:

  new DB\SQL(

All the User Interface files will go in the ui directory, you can delete welcome.htm however the contents of the css folder may be useful as they provide some basic styling to make your pages look a little nicer.

Step 3: Routing

Similar to Slim you need to tell F3 the route request method (GET, POST, PUT etc), the URI to respond to and how to respond.
Example home page route:

$f3->route('GET /',
  function ($f3) {
  //do something

And if you want to use a route with parameters you would use something like this:

$f3->route('GET /view/@id',
  function ($f3) {
    $id = $f3->get('');

This tells F3 to expect a URI parameter and assigns it to a PHP variable in the anonymous function.

Now for our blog we need basic administration routes like this (the code will come later):

// Admin Home
$f3->route('GET /admin',
  function ($f3) {
//Admin Add
$f3->route('GET /admin/add',
  function($f3) {
//Admin Edit 
$f3->route('GET /admin/edit/@id',
  function($f3) {
//Admin Add and Edit both deal with Form Posts
//don't use a lambda function here
$f3->route('POST /admin/edit/@id','edit');
$f3->route('POST /admin/add','edit');
function edit($f3) {
//Admin Delete
$f3->route('GET /admin/delete/@id',
  function($f3) {

Notice that we’re using the same function to process Add and Edit form posts so it isn’t anonymous but the function name is passed as a parameter to the route command.

Step 4: Models

The ORMs in Fat-Free Framework do all the hard work for you – no directories, files or code required here.
Are you beginning to see how much simpler this is compared with Slim?

Here’s the SQL that will set you up with the 2 tables necessary for this tutorial:

USE `blog`;
  `timestamp` datetime NOT NULL,
  `title` VARCHAR(128) NOT NULL,
  `summary` VARCHAR(128) NOT NULL,
  `content` text NOT NULL,
  `author` VARCHAR(128) NOT NULL,
  PRIMARY KEY (`id`)
INSERT INTO `article` (`id`, `timestamp`, `title`, `summary`, `content`, `author`) VALUES
(1, '2011-07-28 02:03:14', 'Hello World!', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut ', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', 'Mr White'),
(2, '2011-07-28 02:03:14', 'More Hello World!', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut ', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', 'Mr Green');
  `name` VARCHAR(255) NOT NULL,
  `password` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`)
INSERT INTO `user` (`id`, `name`, `password`) VALUES
  ('1', 'admin', 'password');

Step 5: Application Front End

Like the Slim tutorial we’re going to keep this simple.
F3 has a set of object-relational mappers (ORMs) to make it easy and fast to work with data.
Instantiate a data mapper object that interacts with the users table, call the find method to return a simple array of results, finally the set command is used which will pass the variable between MVC components. F3 calls this a framework variable.

$article=new DB\SQL\Mapper($f3->get('DB'),'article');

You could condense the final two lines together like $f3->set('articles',$article->find()); but I’m keeping this verbose to aid readability and help you figure out how it is all working.

To use templating you need a base layout file in the ui folder called layout.html, feel free to link in the contents of /ui/css if you want it to look nicer

<!DOCTYPE html>
    <title>{{ @html_title }}</title>
      <meta charset='utf8' />
    <include href="{{ @content }}" />

The F3 template engine uses {{ @name }} to write out the value of a framework variable.
The include tag will embed the contents of a file at the position where the directive is stated – in the example above we’re using a framework variable as the URL so that the content is dynamic.

Now lets create the first of those content files with the view for the homepage, called blog_home.html

<h1>Blog Titles</h1>
<repeat group="{{ @articles }}" value="{{ @item }}">
  <p><a href="view/{{ @item['id'] }}">{{ trim(@item['title']) }}</a> by {{ @item['author'] }}</p>
  <p>{{ @item['summary'] }}</p>

The repeat tag will loop through an array, setting item to the current array element. Within the loop item contains the array of data retrived from the database table and this is accessed using the column name as the array key.

Now that the view is in place we can complete the code in index.php to display it. Set the framework variable to tell the template which view to include, then tell F3 to serve the template.

  echo Template::instance()->render('layout.html');

Serving the template also converts it to PHP code the first time it’s used and this optimised version is used thereafter which is great for performance.
The full code for the home page function is:

//home page
$f3->route('GET /',
  function ($f3) {
    $f3->set('html_title','Home Page');
    $article=new DB\SQL\Mapper($f3->get('DB'),'article');
    echo Template::instance()->render('layout.htm');

Now for the detail view, in index.php we need to get an Mapper object, search for the id then send the data to the view/template. In this case we could have assigned each value individually e.g. $f3->set('title',$article->title); but it is quicker to put all the values in the POST framework variable with the copyTo command.

$f3->route('GET /view/@id',
    function ($f3) {
    $id = $f3->get('');
    //create Mapper object and search for id
    $article=new DB\SQL\Mapper($f3->get('DB'),'article');
    $article->load(array('id=?', $id));
    //set framework variables
    //serve up the view
    echo Template::instance()->render('layout.html');

And the view file itself called blog_detail.html accesses the individual data items from the POST framework variable:

<h1>{{ @POST.title }}</h1>
Published: {{ @POST.timestamp }} by {{ }}
<a href="/">Back to Homepage</a>

Step 6: Application Back End

The admin home page just needs to list the blog articles and provide links, the code is similar to that for the homepage.

$f3->route('GET /admin',
  function ($f3) {
    $f3->set('html_title','My Blog Administration');
    $article=new DB\SQL\Mapper($f3->get('DB'),'article');
    echo template::instance()->render('layout.html'); 

The view called admin_home.html and contains a table of the results. It looks like this:

<h1>My Blog Administration</h1>
<p><a href='admin/add'>Add Article</a></p>
      <th colspan='2'>Actions</th>
  <repeat group="{{ @list }}" value="{{ @item }}">
      <td>{{ @item.title }}</td>
      <td>{{ @item.timestamp }}</td>
      <td>{{ }}</td>
      <td><a href="admin/edit/{{ }}">Edit</a></td>
      <td><a href="admin/delete/{{ }}">Delete</a></td>

The output of this look like:
Admin Home Page
Now a form to add and edit articles, called admin_edit.html

<form name="blog" method="post" action="{{ @BASE }}{{ @PARAMS.0 }}" >
  <label for='title'>Title: </label><br /><input type="text" name="title" id="title" value="{{ isset(@POST.title)?htmlspecialchars(@POST.title):'' }}" size="60"/><br />
  <label for='author'>Author: </label><br /><input type="text" name="author" id="author" value="{{ isset('' }}" size="60"/><br />
  <label for='summary'>Summary: </label><br /><textarea name="summary" id="summary" cols="60" rows="10">{{ isset(@POST.summary)?htmlspecialchars(@POST.summary):'' }}</textarea><br />
  <label for='content'>Content: </label><br /><textarea name="content" id="content" cols="60" rows="10">{{ isset(@POST.content)?htmlspecialchars(@POST.content):'' }}</textarea><br />
  <input type="submit" value="Submit"/>

I’ve kept this basic, apologies for the lack of styling but that’s not what this tutorial is about.

The lines containing isset are using the ternary operator to check that the template variable exists before trying to access it.

Now for the logic with the routes, add & edit both use the same view remember.

$f3->route('GET /admin/add',
  function($f3) {
    $f3->set('html_title','My Blog Create');
    echo template::instance()->render('layout.html');
$f3->route('GET /admin/edit/@id',
  function($f3) {
    $f3->set('html_title','My Blog Edit');
    $id = $f3->get('');
    $article=new DB\SQL\Mapper($f3->get('DB'),'article');
    echo template::instance()->render('layout.html');

Now we assigned a function for the POST routes and here’s the content:

$f3->route('POST /admin/edit/@id','edit');
$f3->route('POST /admin/add','edit');
function edit($f3) {
  $id = $f3->get('');
  //create an article object
  $article=new DB\SQL\Mapper($f3->get('DB'),'article');
  //if we don't load it first Mapper will do an insert instead of update when we use save command
  if ($id) $article->load(array('id=?',$id));
  //overwrite with values just submitted
  //create a timestamp in MySQL format
  $article->timestamp=date("Y-m-d H:i:s");
  // Return to admin home page, new blog entry should now be there

And to delete a record

//Admin Delete
$f3->route('GET /admin/delete/@id',
  function($f3) {
    $id = $f3->get('');
    $article=new DB\SQL\Mapper($f3->get('DB'),'article');

There’s a lot less coding required here than with Slim + extras.

Step 7: Using Middleware

This isn’t relevant to using the Fat-Free Framework.
Basic authentication using a database is built in.
The following lines are added to the admin homepage route, they will cause a username/password prompt to appear. If the details are in the user table of the database a session variable is set which allows access to the other admin screens. If unsuccessful they get an error page.

//assign a mapper to the user table
$user=new DB\SQL\Mapper($f3->get('DB'),'user');
//tell Auth what database fields to use
$auth=new \Auth($user,
//the following will display an HTTP 401 Unauthorized error page if unsuccessful

In the other admin routes, add this line at the start of the function to deny access if they haven’t authenticated

if (!$f3->get('SESSION.user')) $f3->error(401);

That’s it (if you didn’t spot it in the SQL, my example uses name: admin and password: password for the login credentials).

You could instead choose to redirect back to the homepage with:

if (!$f3->get('SESSION.user')) $f3->reroute('/');

Step 8: Summary

So here is another example of how to quickly get a prototype running using a PHP micro framework.
Is it any faster than with Slim? I’d like to think that it is, there’s less code, less complexity and you aren’t dependent on other packages which may end up changing in some way or not being maintained.
I’ve used F3 to create a times tables application for my son and found it was fun to build and made me more productive – I’ve now put it online at for anyone to use.

Slim is released under the MIT Public License and you are free to use, modify and even sell it.

F3 is released on the GNU Public License (GPL v3). You are allowed to use it your business or for commercial gain – but if you make any money you should consider making a donation to the project.

You can download the files used from here
And access the files online via my Bitbucket repository.

I’ve done another tutorial on creating a near identical blog application to this but using CakePHP: Blog Tutorial with CakePHP Framework which may be interesting to compare with differences with using a micro-framework.

Posted in MySQL, PHP | 11 Comments

jQuery Autocomplete widget for CakePHP 2.2

A JavaScript autocomplete element that links through to your database isn’t built into CakePHP any more – here is a simple solution to add to your application using a jQuery plugin.
Why a plugin? jQuery doesn’t include this functionality, it is provided by jQuery UI but including that library may be a heavyweight solution for your application.

It should end up looking like the image below – as you type, relevant options from your database will appear in the list beneath.

CakePHP autocomplete widget

You can download the jQuery autocomplete plugin from
Extract the files from the archive and move the .css and .js files from the src folder into the css and js folders of the CakePHP webroot directory.

Link to the CSS and JavaScript in your default layout:

echo $this->Html->css('jquery.autocomplete');
echo $this->Html->script('jquery.autocomplete.min.js');

Add a small form to your View, in this example there is a model called company and we want to use autocomplete on the name field.

echo $this->Form->create('Company', array('type' => 'post', 'action' => 'find'));
echo $this->Form->input('name');
echo $this->Form->submit();
echo $this->Form->end();

Add this script block to the bottom of the document which activates the plugin and tells it where to submit AJAX requests to:

    $("#CompanyName").autocomplete("/Companies/find.json", {
    minChars: 3

Modify jQuery.autocomplete.css to look nice with CakePHP default CSS:

.acResults ul li {
	margin: 0px;
	padding: 2px 5px;
	cursor: pointer;
	display: block;
	font: menu;
	overflow: hidden;
	color: #333;

Now back to some CakePHP – Your Controller needs a new action which the AJAX requests will be sending data to:

public function find() {
  $this->Company->recursive = -1;
  if ($this->request->is('ajax')) {
    $this->autoRender = false;
    $results = $this->Company->find('all', array(
      'fields' => array(''),
      //remove the leading '%' if you want to restrict the matches more
      'conditions' => array(' LIKE ' => '%' . $this->request->query['q'] . '%')
    foreach($results as $result) {
      echo $result['Company']['name'] . "\n";
  } else {
  	//if the form wasn't submitted with JavaScript
    //set a session variable with the search term in and redirect to index page
    $this->redirect(array('action' => 'index'));

And finally add some code to the index action in the index action, which handles what happens if the form was submitted via a button press rather than AJAX.

//if there's a session with some data in, add a filter to the search conditions
if ($this->Session->check('companyName')) {
  $name = $this->Session->read('companyName');
  if ($name) {
    $this->paginate['conditions'][] = array(' LIKE' => '%' . $name . '%');
    $this->request->data['Company']['name'] = $name;

That’s it.

To to make submit buttons appear alongside form elements
here is a simple bit of jQuery to improve the appearance

  $('div.input, div.submit').css({
    'float' : 'left',
    width : '200px',
    clear : 'none'
  $('div.submit').css('margin-top', '14px');
  $('div.input.text').css('margin-top', '-4px');

Thanks to the answer on this question from StackOverflow for some inspiration

Posted in JavaScript, PHP | 12 Comments

How to turn CakePHP datetime select element into date and time pickers

This uses CakePHP 2.2.4

The CakePHP FormHelper datetime element is functional but also fairly tedious to use, here is a picture of how it looks.


With a small amount of effort you can change your view to use date and time pickers that present a much richer experience to your users.

Rich Date Picker:

CakePHP Date Picker

Rich Time Picker:

CakePHP Time Picker

In this example I’m using a model called ‘tasks‘ that contains a field named ‘due‘ of type datetime.
The model, controller and view are all using the default code generated by the ‘bake’ console command.

Third party components – I’ve found two easy to use libraries:

1. Zebra_Datepicker 1.6.2

2. jQuery timePicker 0.2

Download both of these and extract the files.
Locate the JavaScript files from the downloads and put the following into your CakePHP app/webroot/js:

Locate the CSS files and put the following into CakePHP app/webroot/css:

If you want to move calendar.png into an images folder then make sure you update the URL links in the zebra_datepicker.css file

Link to these in your default layout app/View/Layouts/default.ctp:

echo $this->Html->css('zebra_datepicker');
echo $this->Html->css('timePicker');
echo $this->Html->script('jquery.timePicker.min');
echo $this->Html->script('zebra_datepicker');

Note that you must already have a jQuery script linked to your template, if not the following above the previous 2 lines:

echo $this->Html->script('');

In the view file, convert the existing datetime input to text:

echo $this->Form->input('due', array('type' => 'text'));

Now for the JavaScript. I don’t want to disturb what CakePHP is trying to do so firstly I hide the TaskDue element, then add separate text inputs for date and time. Then I activate widgets for each of these elements. Finally I add a submit event to put the values in those widgets back into the CakePHP input element in the format it is expecting.

Here is the code which should be added to the bottom of the document:

<script type="text/javascript">
    //hide TaskDue and add two inputs in its place for date + time
    //when submitted, put their values into TaskDue
    $('#TaskDue').hide().after('<input type="text" name="DueDate" id="DueDate" value="" style="width:200px" />&nbsp;<input type="text" name="DueTime" id="DueTime" value="" style="width:200px" />');
    //enable datepicker
      format: 'd/m/Y'
    //enable timepicker
      startTime: "09:00",
      endTime: "17:00",
      show24Hours: true,
      separator: ':',
      step: 20
    //put values back into CakePHP input element
    $("#TaskAddForm").submit(function() {
      var DueDate = $("#DueDate").val();
      var DueTime = $("#DueTime").val();
      DueDate = DueDate.split('/');
      $("#TaskDue").val(DueDate[2] + '-' + DueDate[1] + '-' + DueDate[0] + ' ' + DueTime + ':00');

You may need to change the timePicker CSS a little to work with the default CakePHP CSS:

div.time-picker {
  position: absolute;
  height: 191px;
  overflow: auto;
  background: #fff;
  border: 1px solid #aaa;
  z-index: 99;
  margin: 0;
div.time-picker-12hours {
div.time-picker ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
div.time-picker li {
  cursor: pointer;
  height: 12px;
  padding: 4px 3px;
  color: #000;
div.time-picker li.selected {
  background: #0063CE;
  color: #fff;
Posted in JavaScript, PHP | 1 Comment

Creating a dynamic listview with jQuery Mobile

This example was written for jQuery Mobile v1.2

A dynamic listview is a widget whose content depends on a previous user interaction with the page. I struggled to find some simple instructions on how to dynamically alter the contents of a listview, the jQuery Mobile documentation for listviews only covers adding items.

The trick I do is to empty and rebuild the list each time the content needs to change.
I could do this completely with JavaScript but instead I store a hidden DOM element because it is easier to get the markup right, then use this like a template to create the list from.

Lets start with some example HTML:

<ul id="template" style="display:none">
  <li><a href="#" data-val="acura">Acura</a></li>
  <li><a href="#" data-val="audi">Audi</a></li>
  <li><a href="#" data-val="bmw">BMW</a></li>
  <li><a href="#" data-val="lexus">Lexus</a></li>
  <li><a href="#" data-val="nissan">Nissan</a></li>
  <li><a href="#" data-val="toyota">Toyota</a></li>
  <li><a href="#" data-val="volkswagen">Volkswagen</a></li>
<ul data-role="listview" id="carslist">

I’ve removed the href destination and added a data attribute to each of the list elements – this would be used if you wanted to do further scripting when one of these was clicked as it’s an easy way of getting the value.

Now for the JavaScript/jQuery. The buildList function does the work, receiving an array with names of the template elements that I want to appear in the list. Remember with jQuery Mobile you don’t use the standard jQuery document ready event – instead bind to the pageinit event. All I’m doing in the pageinit code block is attaching events to the buttons on the page which change the contents of the list, and adding an event when a list item is clicked to show that it is working.

//this function empties the list and rebuilds it
function buildList(cars) {
  jQuery.each(cars, function(k, v) {
    $('#template a[data-val="' + v + '"]').parent().clone(true).appendTo('#carslist');
   //by cloning the elements with 'true' parameter you keep any events associated with them
$(document).bind('pageinit', function() {
  $('#template a').click(function() {
    //do something when a listview element is selected
  $('#european').click(function() {
  $('#japanese').click(function() {
 //build the initial list with all the options available

It looks like this:
jQuery Mobile dynamic listviewYou can find a working dynamic listview example in jsFiddle.

Posted in JavaScript | 4 Comments