Initialising DataTables with Twitter Bootstrap and Spring MVC Ajax

In the previous post I introduced handling Ajax requests from DataTables using Spring MVC.
Spring MVC with restful DataTables

This is only one side of the story though as I left out how I was doing the initialisation on the client side. I’m using DataTables with twitter bootstrap so my initialisation is doing two things, one setting up communication with the back end and two adding twitter bootstrap styling.

Continuing with the customer grid example this is my grid.

<table class="table table-striped table-bordered" id="customers">
  <thead>
    <tr> <th>ID</th> <th>Name</th> </tr>
  </thead>
  <tbody></tbody>
</table>
<script type="text/javascript">
	$(document).ready(function() {
	    $('#customers').dataTable( {
	    	"sAjaxSource": "/Root/customers/get",
	    	"bProcessing": true,
	    	"bServerSide": true,
	    	"sPaginationType": "bootstrap",
	    	"oLanguage": {"sLengthMenu": "_MENU_ records per page",
	    				  "sInfo": "Displaying _START_ to _END_ of _TOTAL_ records"},
	        "aoColumns":[
				{"mDataProp":"id"},
				{"mDataProp":"name"}
				]
	    } );
	} );	
</script>

The first three properties set up the Ajax processing, pagination type gives us bootstrap style paging buttons and oLanguage allows us to change the standard labels. When it came to mapping the columns I had to use the aoColumns property and setting the mDataProp value. In most of the examples online you’ll see a PHP script returning the JSON as an array but since we’re using Jackson we’re returning an object. The difference is this.

Array

{
  "aaData": [
    [
      "1",
      "Ben Thurley"
    ],
    [
      "2",
      "Another Person"
    ]
  ]
}

Object

{
  "aaData": [
    {
      "id" : "1",
      "name" : "Ben Thurley"
    },
    {
      "id" : "2",
      "name" : "Another Person"
    }
  ]
}

If you’re returning an array then you give DataTables the index of the property that matches the column, as we’re returning objects we have to give the name of the property that matches the column. We do this by setting the mDataProp property.

As an added bonus DataTables sends back these mDataProp values on the Ajax request which allows us to convert the sort column index into a meaningful column name.

The rest of the twitter bootstrap styling steps can be found on the DataTables site.
http://datatables.net/blog/Twitter_Bootstrap_2

It’s somewhat work in progress but I have also worked this into a JSP tag file so I don’t need to keep writing the same stuff in my JSP’s. It should in theory make it easy to change the tale plugin if required at a later date. I just added the following two tag files into WebRoot/WEB-INF/tags/table.

table.tag

<%@ tag language="java" %>
<%@ attribute name="id" required="true" %>
<%@ attribute name="datasource" required="true" rtexprvalue="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<c:set var="org_languagetool_tags_table_outputmode" value="TABLE" scope="request" />
	<table class="table table-striped table-bordered" id="${id}">
	  <thead>
	    <tr><jsp:doBody /></tr>
	  </thead>
	  <tbody></tbody>
	</table>
<c:set var="org_languagetool_tags_table_outputmode" value="SCRIPT" scope="request" />
<c:set var="org_languagetool_tags_table_firstcolumn" value="TRUE" scope="request" />
	<script type="text/javascript">
		$(document).ready(function() {
		    $('#${id}').dataTable( {
		    	"sAjaxSource": "<c:url value="${datasource}" />",
		    	"bProcessing": true,
		    	"bServerSide": true,
		    	"sPaginationType": "bootstrap",
		    	"oLanguage": {"sLengthMenu": "<spring:message code="table.records.count" />",
		    				  "sInfo": "<spring:message code="table.showing.records" />"},
		        "aoColumns":[
		                   	<jsp:doBody />
		                   	]
		    } );
		} );	
	</script>	

column.tag

<%@ tag language="java" %>
<%@ attribute name="field" required="true" %>
<%@ attribute name="label" required="true" rtexprvalue="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<c:choose>
  <c:when test="${org_languagetool_tags_table_outputmode == 'TABLE'}">
    <th><spring:message code="${label}" /></th>
  </c:when>
  <c:when test="${org_languagetool_tags_table_outputmode == 'SCRIPT'}">
    <c:choose>
      <c:when test="${org_languagetool_tags_table_firstcolumn == 'TRUE' }">
        <c:set var="org_languagetool_tags_table_firstcolumn" value="FALSE" scope="request" />
      </c:when>
      <c:otherwise>,</c:otherwise>
    </c:choose>
    {"mDataProp":"${field}"}
  </c:when>
</c:choose>

It’s not required unless you’re putting these in a jar but I also wrote out a tag library descriptor.

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
  <tlib-version>1.0</tlib-version>
  <short-name>Table</short-name>
  <uri>http://bthurley.org/tags/table</uri>
  
  <tag-file>
    <name>table</name>
    <path>/WEB-INF/tags/table/table.tag</path>
  </tag-file>  
  
  <tag-file>
    <name>column</name>
    <path>/WEB-INF/tags/table/column.tag</path>
  </tag-file>
 
</taglib>

By using a tld I’ve been able to specify a uri for importing and using the tag. Otherwise you can give the path to import the tag.

<%@ taglib prefix="tab" uri="http://bthurley.org/tags/table" %>
<tab:table id="customers" datasource="/customers/get" >
  <tab:column field="id" label="customers.field.id" />
  <tab:column field="name" label="customers.field.name" />
</tab:table>

I guess I’ll be adding to these tags as time goes on and I think of new things.