Sort Table Data in JSON on browser Grails

Posted By : Akash Sharma | 21-Feb-2014

Most of the times we have to sort table data on browser.

For Sorting data on browser we generally do following steps:

1. Send the column name to the action on which you have sort data

2. Sort data on server in controller

3. Receive sorted data on view and fill in table

 

But if you have hundreds and thousands of entries in your table, then it causes many calls to the server for sorting and even for many users.

 

While I was facing this as a real problem, I just thought that if we could store that data on browser and sort it on browser itself. That could save many server calls.

Now a question arises that where to store data on browser.

The answer is JSON.

 

Through this functionality, I get all the data of Table in first hit and store it in JSON on browser.

For sorting this data further, I sort the data with my custom JS code.

 

Below is the demo code which I want to share with you.

In the controller, I have passed full table data with list of column names to show in view.

Currently the table data is without pagination.

 

Domain Code:

package com.myapp.data

class Employee
{
  String name
  String age
  int salary
  String designation
  Date dob
  static constraints = {}
}

 

Controller Code:

class EmployeeController 
{
  def sortTableData(){
    ArrayList fullTableData=Employee.list()
    List columnNameList=getColumnNameList("com.myapp.data.Employee")
    [fullTableData:fullTableData, columnNameList:columnNameList]
  }
  
  // Get list of column names of a domain class except id and version
  List getColumnNameList(String domainName)
  {
    def grailsDomainClazz=new DefaultGrailsDomainClass( grailsApplication.getClassForName(domainName) )
    def grailsDomainClazzProperties = grailsDomainClazz.getProperties()
    List columnNameList=new ArrayList()
    grailsDomainClazzProperties.each() {
      columnNameList.add( it.name)
    }
    columnNameList.remove('version')
    columnNameList.remove('id')
    return columnNameList
  }
}
  

 

In GSP , I created dynamic div ids and fill table data in it.

GSP file (sortTableData.gsp)

<%! import grails.converters.JSON %>

<html>
<head>
<meta name="layout" content="main" />
</head>
<body>
<g:javascript library="jquery"></g:javascript>
<g:set var="numOfColumn" value="${columnNameList.size() }"></g:set>
<g:set var="numOfRows" value="${fullTableData.size() }"></g:set>

Sort By:
<select id="columnSelectList">
  <g:each in="${columnNameList}" var="columnName">
    <option value="${columnName }">${columnName }</option>
  </g:each>
</select>

<table>
  <thead>
    <tr>
      <g:each in="${columnNameList}" status="i" var="columnName">
        <th>${columnName}</th>
      </g:each>
    </tr>
  </thead>	
  <tbody>
    <g:each in="${fullTableData}" status="j" var="emp">
      <tr>
        <g:each in="${columnNameList}" status="i" var="columnName">
          <td id="${columnNameList[i]+j}"></td>
        </g:each>
      </tr>
    </g:each>
  </tbody>
</table>

<script type="text/javascript" src="${resource(dir: 'js', file: 'customTableSorting.js')}"></script>

<script type="text/javascript">
		
$(document).ready(function(){
  employeeList=[];
  columnNames=[];
  numOfColumn=${numOfColumn};
  numOfRows=${numOfRows};
  // Save table data in JSON variable employeeList
  saveTableData('${columnNameList as JSON}', '${fullTableData as JSON}');
  // On page load, table data is sorted on the basis of first column name by default
  sortResults('${columnNameList.get(0)}',true);
  // Fill sorted data in table
  fillDataInTable();
  bindSelectTag();
});
</script>

</body>
</html>

 

customTableSorting.js

// Parse model coming from action-controller to JSON variable
function parseModelToJS(jsonString)
{
  jsonString=jsonString.replace(/\"/g,'"');
  var jsonObject=jQuery.parseJSON(jsonString);
  return jsonObject
}

// Save table data in employeeList (array of objects) JSON variable
function saveTableData(columnNameList, fullTableData)
{
  columnNames=parseModelToJS(columnNameList);
  var employeeModelList=parseModelToJS(fullTableData);
  for(var counter=0; counter<numOfRows; counter++)
  {
    var employee=employeeModelList[counter];
    var empObject={};
    for(var columnCounter=0; columnCounter < numOfColumn; columnCounter++)
    {
      var columnName=columnNames[columnCounter];
      empObject[columnName]=employee[""+columnName+""];
    }
    employeeList.push(empObject);
  }
}

// Sort array of JSON objects on the basis of prop element
function sortResults(prop, asc)
{
  employeeList = employeeList.sort(function(a, b){
    if (asc) return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
    else return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
  });
}

// Fill employeeList (array of objects) JSON data in Table
function fillDataInTable()
{
  for(var counter=0; counter<numOfRows; counter++)
  {
    var empObject=employeeList[counter];
    for(var columnCounter=0; columnCounter < numOfColumn; columnCounter++)
    {
      var columnName=columnNames[columnCounter];
      $("#"+columnName+counter).html(employeeList[counter][""+columnName+""]);
    }
  }
}

//bind select tag change event
function bindSelectTag()
{
  $(document).on("change", "#columnSelectList", function(){
    sortResults(''+$("#columnSelectList option:selected").val()+'',true);
    fillDataInTable();
  });
}
 

Here is the demo view for above code

 

Thanks

Akash Sharma

 

About Author

Author Image
Akash Sharma

Akash is a bright Groovy and Grails developer and have worked on development of various SaaS applications using Grails technologies. Akash loves playing Cricket and Tennis

Request for Proposal

Name is required

Comment is required

Sending message..