Datatables jquery plugin – sorting date with JSON data

Datatables is powerful but the documentation can be confusing in places. If you want a column to sort on a date one option (of many) is to have a formatted date to display to the user and an integer timestamp to use for the sorting.

Datatables column sorting with date

Here is some JSON that could be used to create this

var data = [
 {
 "name": "Airi Satou (33)",
 "position": "Accountant",
 "office": "Tokyo",
 "displayStartDate": "23\/01\/03",
 "startDate": "1043362800",
 "salary": "162700",
 },
 {
 "name": "Angelica Ramos (47)",
 "position": "Chief Executive Officer (CEO)",
 "office": "London",
 "displayStartDate": "17\/01\/03",
 "startDate": "1042761600",
 "salary": "1200000",
 }
];

The JavaScript used to get proper sorting of the date column involves adding an extra object to the date column which allows another data item to be used for the sort.

$('#example').DataTable( {
 data: data,
 columns: [
 { data: 'name' },
 { data: 'position' },
 { data: 'office' },
 { data: {
   _: 'displayStartDate',
   sort: 'startDate'
 }},
 { data: 'salary'}
 ]
 } );

One advantage of this approach is that date formatting is done up on the server which may be useful if you are sending tens of thousands of rows of data to the client.

Adding a custom hover event to a morris.js donut chart

Morris.js is a lightweight and relatively simple JavaScript charting solution compared when compared with some of the others in the sector which have lot of options.

morrisjs-charts

However with that simplicity comes a lack of documentation.

Adding a custom hover event to donut chart

Here’s some HTML which adds a visible label element (like you get with a line chart) next to the donut chart:

<div id="morrischart" style="height: 250px; width: 250px; float: left"></div>
 <div id="morrisdetails-item" class="morris-hover morris-default-style" style="position:static; float: left;">
 <div class="morris-hover-row-label">2010 Q4</div> <div class="morris-hover-point">this is a test</div>
</div>

I won’t cover how to create the donut chart in JavaScript as you can just lift that from the morris.js examples, but you must assign the chart to a variable:

var donut = new Morris.Donut({...});

Finally the code to add hover events should look like this:

for(i = 0; i &lt; donut.segments.length; i++) {
  donut.segments[i].handlers['hover'].push(function(i){
    $('#morrisdetails-item .morris-hover-row-label').text(donut.data[i].label);
    $('#morrisdetails-item .morris-hover-point').text(donut.data[i].value);
  });
}

Here is a working example on JSFiddle.

jQuery get list of form element ids as text

Here is a little JavaScript snippet to run in a browsers console – I created this to a form and lists the ids of all the form elements (so I could do things with them in PHP)

var temp;
$(':input').each(function () {temp += "'" + ($(this).attr('id')) + "',"});
temp;

It declares a global variable, finds all the elements and appends their id’s along with quotes into the variable and finally displays the contents in the browser console.

Brief review of responsive jQuery event calendar plugins – Sep 2014

It was hard to find a decent, active, jQuery event calendar plugin that was responsive so I’ve shared my research here.

FullCalendar seems to be the default choice for putting an event calendar on a website at the moment – but it isn’t responsive so no good for me. It’s late 2014, time for mobile first folks.

Calendario looks very nice (maybe overly styled), the last change on GitHub was six months ago and there are 7 open issues dating back by nearly a year, so I think it is safe to say it isn’t being actively developed at the moment.

Kalendar is free, but you are meant to link to the JavaScript file on the developers site instead of hosting it yourself. The documentation is basic – it doesn’t show how you can add an event to the calendar once it has been rendered, and the appearance – although flat and minimalistic – didn’t appeal to me.

kalendar jquery plugin

I finally settled on Responsive Calendar. I think it looks great, it scales down for mobile devices and you can add events once the calendar has been rendered. It also integrates with Twitter Bootstrap. It is free for non commercial use.

Responsive Calendar

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 https://github.com/dyve/jquery-autocomplete
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.

<?php
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:

<script>
  $(document).ready(function(){  
    $("#CompanyName").autocomplete("/Companies/find.json", {
    minChars: 3
    });
  });
</script>

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('Company.name'),
      //remove the leading '%' if you want to restrict the matches more
      'conditions' => array('Company.name 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->Session->write('companyName',$this->request->data['Company']['name']);
    $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('Company.name 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

$(document).ready(function(){
  $('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
http://stackoverflow.com/questions/6071828/autocomplete-search-form-cakephp