Tuesday, 8 October 2019

React JS - Dynamic Table Skeleton to load data from Json Files. Options to hide and display columns and control rows based on some column value.



Overview

I am just a month old to React JS. Having worked in PHP for more than a decade, and starting off with React JS is a totally new experience. 

I looked foremost to learn how to construct tables from any JSON non-nested structure and display it in simple HTML format.

So, let's start.

Data

Example 1:
Let's take a json file with cities information:

export var cities = [
    {city: "New York",   temperature: 40, show:true},
    {city: "New Delhi",  temperature: 45, show:false},
    {city: "New Jersey", temperature: 41, show:true},
    {city: "Bengaluru",  temperature: 32, show:false},

    {city: "Mumbai",     temperature: 46, show:true} 
   

Example 2:
Let's take another json file with employees information:

export var employees = [
    {"id": "001", "employeename": "Peter D", "age":"34", "designation":"Programmer", show:true},
    {"id": "002", "employeename": "Mary S",  "age":"30", "designation":"Executive", show:true},
    {"id": "003", "employeename": "Ram N",   "age":"40", "designation":"Architect", show:false},
    {"id": "004", "employeename": "Sneha K", "age":"22", "designation":"Intern", show:true},
    {"id": "005", "employeename": "Mehek S", "age":"28", "designation":"Programmer", show:false},
    {"id": "006", "employeename": "Rohan M", "age":"33", "designation":"Consultant", show:true}
]


Both above files have no related columns.

What we intend to do?

Using React JS, build a skeleton component which can take any such non-nested JSON structure and output well-formatted tables as shown below:









Step 1: index.js

Import following files:


import React from 'react';
import React from 'react';
import {render} from 'react-dom';
import './style.css';
import {cities, cities_params} from './cities.js';
import {employees, employees_params} from './employees.js';
import DynamicTableSkeleton from './DynamicTableSkeleton.js';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import './react-tabs.css';

export class App extends React.Component {

  render() {
        return (
            <DynamicTableSkeleton table={cities}/>
            <DynamicTableSkeleton table={employees}/>
          );
    } 
}
export default App;
render(<App />, document.getElementById('root'));



Note: cities.js and employees.js can be replaced with any other Json data of your choice. And you can import as many Json data files.

style.css


#DynamicTableSkeleton.css
table{  font-family: "Tahoma";   background-color: white;   width: 80%; }
th{ font-family: "Tahoma"; background-color: rgb(159, 178, 228); }
tr{ background-color: darkslateblue }
td:nth-child(even{background-color: #f2f2f2;}
td:nth-child(odd{background-color: silver;}
td{ font-family: "Tahoma"; }
.class_blue{ color: blue }
.class_red{ color: red }



DynamicTableSkeleton.js

Lets build it step by step in detail:


Step 1:


There are four methods:

  1. extractKeys() -  Will extract the keys from the Json data which can be used to build the Column title for the Table.
  2. getColumnTitles() - To get all the column titles for the Table.
  3. getRows() - To display all rows information in table format from the data in Json file.
  4. getEachRow() - To get information about each row in Json data to display as a single row in the Table.

class DynamicTableSkeleton extends Component {
   constructor(props){
   super(props);    
   this.extractKeys = this.extractKeys.bind(this);
   this.getColumnTitles = this.getColumnTitles.bind(this);
   this.getRows = this.getRows.bind(this);
   this.getEachRow = this.getEachRow(this);
   }

   extractKeys= function(){  }
   getColumnTitles = function(){ }
   getRows = function(){ }
   getEachRow = function(){ }

  render(){ return(); }
}

export default DynamicTableSkeleton



DynamicTableSkeleton => extractKeys()

Purpose: Extracting the keys of the first rows of the JSON Data:

export var employees = [

    {"id": "001", "employeename": "Peter D", "age":"34", "designation":"Programmer", show:true}
]



class DynamicTableSkeleton extends Component {   
constructor(props){
      super(props);    
      this.extractKeys = this.extractKeys.bind(this);
      this.getColumnTitles = this.getColumnTitles.bind(this);
      this.getRows = this.getRows.bind(this);
      this.getEachRow = this.getEachRow(this);
   }

  extractKeys= function(){
     return Object.keys(this.props.table[0]);
  }

  getColumnTitles = function(){ }
  getRows = function(){ }
  getEachRow = function(){ }

  render(){ return(); }

}

export default DynamicTableSkeleton


this.props.table[0] => table here refers to the property passed as follows in index.js file

            <DynamicTableSkeleton table={cities}/>


DynamicTableSkeleton => getColumnTitles()

Purpose: With the extracted keys, print the table column headers.

class DynamicTableSkeleton extends Component {   
constructor(props){
      super(props);    
      this.extractKeys = this.extractKeys.bind(this);
      this.getColumnTitles = this.getColumnTitles.bind(this);
      this.getRows = this.getRows.bind(this);
      this.getEachRow = this.getEachRow(this);
   }

  extractKeys= function(){
     return Object.keys(this.props.table[0]);
  }

 getColumnTitles = function(){    var columns = this.extractKeys(); return columns.map( (each_column, value)=>{ if(this.props.table_params !== undefined) {     if(this.props.table_params[0][each_column]) return <th>{each_column.toUpperCase()}</th> } else { return <th>{each_column.toUpperCase()}</th> } } ) }


  getRows = function(){ }
  getEachRow = function(){ }

  render(){ return(); }

}

export default DynamicTableSkeleton


DynamicTableSkeleton => getRows() & getEachRow()

Purpose: Print rows below the table column headers.

class DynamicTableSkeleton extends Component {   
constructor(props){
      super(props);    
      this.extractKeys = this.extractKeys.bind(this);
      this.getColumnTitles = this.getColumnTitles.bind(this);
      this.getRows = this.getRows.bind(this);
      this.getEachRow = this.getEachRow(this);
   }

  extractKeys= function(){
     return Object.keys(this.props.table[0]);
  }

 getColumnTitles = function(){    var columns = this.extractKeys(); return columns.map( (each_column, value)=>{ if(this.props.table_params !== undefined) {     if(this.props.table_params[0][each_column]) return <th>{each_column.toUpperCase()}</th> } else { return <th>{each_column.toUpperCase()}</th> } } ) }

 getRows = function(){ var rows = this.props.table; return rows.map((each_row, value)=>{ return <tr> {this.getEachRow(each_row)}  </tr> })       }
      
getEachRow = function(each_row){
   var table_headers = this.extractKeys();
   const class_blue = { color:'blue'};
   const class_red = { color:'red'};
   const class_name = each_row.show ? class_blue : class_red;
   return table_headers.map((key, value)=>{
   if(this.props.table_params !== undefined) {  
   if(this.props.table_params[0][key]) 
   return <td style={class_name}>{each_row[key]}</td>
   } else {
   return <td style={class_name}>{each_row[key]}</td>  
   }
  })
}


  render(){
  }

}

export default DynamicTableSkeleton


And finally we render it.



class DynamicTableSkeleton extends Component {   
constructor(props){
      super(props);    
      this.extractKeys = this.extractKeys.bind(this);
      this.getColumnTitles = this.getColumnTitles.bind(this);
      this.getRows = this.getRows.bind(this);
      this.getEachRow = this.getEachRow(this);
   }

  extractKeys= function(){
     return Object.keys(this.props.table[0]);
  }

  getColumnTitles = function(){
   var columns = this.extractKeys();
   return columns.map( 
    (each_column, value)=>{
    if(this.props.table_params !== undefined) {  
    if(this.props.table_params[0][each_column])
    return <th>{each_column.toUpperCase()}</th>
    } else {
     return <th>{each_column.toUpperCase()}</th>
    }
   }
   )
}

 getRows = function(){
   var rows = this.props.table;
   return rows.map((each_row, value)=>{
   return <tr>
   {this.getEachRow(each_row)} 
   </tr>
  })      
}
      
getEachRow = function(each_row){
   var table_headers = this.extractKeys();
   const class_blue = { color:'blue'};
   const class_red = { color:'red'};
   const class_name = each_row.show ? class_blue : class_red;
   return table_headers.map((key, value)=>{
   if(this.props.table_params !== undefined) {  
   if(this.props.table_params[0][key]) 
   return <td style={class_name}>{each_row[key]}</td>
   } else {
   return <td style={class_name}>{each_row[key]}</td>  
   }
  })
}


  render(){
   return(
      <div><table><thead>
      <tr>{this.getColumnTitles()}</tr>
      </thead>
      <tbody>
      {this.getRows()}
      </tbody></table>
      </div>
    );
  }

}

export default DynamicTableSkeleton




OUTPUT:
















Special thanks to: https://medium.com/@subalerts/create-dynamic-table-from-json-in-react-js-1a4a7b1146ef The article helped me to understand how to print data from Json into table with React Js and it helped me to create the planned Dynamic Table Skeleton.

In the next post, I will cover on how to add react-tabs to view different JSON data in tabbed format.

Thank you!

React JS - Dynamic Table Skeleton to load data from Json Files. Options to hide and display columns and control rows based on some column value.

Overview I am just a month old to React JS. Having worked in PHP for more than a decade, and starting off with React JS is a totally ...