Tabulator: Angular Setup Guide

Created on 16 Oct 2018  路  23Comments  路  Source: olifolkerd/tabulator

Would anyone out there be willing to put together a short guide of how to use Tabulator with the Angular framework to go on the framewoks page of the Tabulator Website

Cheers

Oli :)

Help Needed Please Read

Most helpful comment

Here you go, a basic implementation for Angular. I trust and hope that this is enough to get people started.

Start by npm installing tabulator in your Angular project.

npm install tabulator-tables --save

The create a component as per the below code.

tabulator-table.component.ts

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import Tabulator from 'tabulator-tables';

/**
 * This is a wrapper class for the tabulator JS library.
 * For more info see http://tabulator.info
 */
@Component({
  selector: 'app-tabulator-table',
  templateUrl: './tabulator-table.component.html',
  styleUrls: ['./tabulator-table.component.scss']
})
export class TabulatorTableComponent implements OnChanges {
  @Input() tableData: any[] = [];
  @Input() columnNames: any[] = [];
  @Input() height: string = '311px';
  // list properties you want to set per implementation here...

  tab = document.createElement('div');

  constructor() {
  }

  ngOnChanges(changes: SimpleChanges): void {
    this.drawTable();
  }

  private drawTable(): void {
    new Tabulator(this.tab, {
      data: this.tableData,
      columns: this.columnNames,
      layout: 'fitData',
      height: this.height
    });
    document.getElementById('my-tabular-table').appendChild(this.tab);
  }

}

tabulator-table.component.html

<div id="my-tabular-table"></div>

Due to the way Angular pre-compiles component scss and the fact that tabulator is run after the fact I had to include my styles in the styles.scss (or any other global styles file). Just ensure that your custom css for tabulator is in a file that is loaded before the tabulator css(note that you have to include the tabulator css file in your angular.json). Below is my customised css for tabulator to better align with the style of Angular Material.

```
//Tabular styles override

.tabulator {
font-size: 12px;
border: none;
}

.tabulator .tabulator-header {
font-weight: normal;
border-bottom: 1px solid;
border-bottom-color: rgba(0, 0, 0, 0.12);
color: rgba(0, 0, 0, 0.54);
}

.tabulator .tabulator-header .tabulator-col {
height: 48px;
background-color: #ffffff;
border: none;
padding: 0 7px;
}

.tabulator-row {
border-bottom: 1px solid;
border-bottom-color: rgba(0, 0, 0, 0.12);
min-height: 48px;
vertical-align: middle;
}

.tabulator-row .tabulator-cell {
padding: 16px 7px;
border-right: none;
vertical-align: middle;
}

.tabulator-row .tabulator-cell:first-of-type,
.tabulator .tabulator-header .tabulator-col:first-of-type {
padding-left: 24px;
}

.tabulator-row.tabulator-row-even {
background-color: #ffffff;
}
```

This is my basic implementation of tabulator please modify and share your improvements.

All 23 comments

Here you go, a basic implementation for Angular. I trust and hope that this is enough to get people started.

Start by npm installing tabulator in your Angular project.

npm install tabulator-tables --save

The create a component as per the below code.

tabulator-table.component.ts

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import Tabulator from 'tabulator-tables';

/**
 * This is a wrapper class for the tabulator JS library.
 * For more info see http://tabulator.info
 */
@Component({
  selector: 'app-tabulator-table',
  templateUrl: './tabulator-table.component.html',
  styleUrls: ['./tabulator-table.component.scss']
})
export class TabulatorTableComponent implements OnChanges {
  @Input() tableData: any[] = [];
  @Input() columnNames: any[] = [];
  @Input() height: string = '311px';
  // list properties you want to set per implementation here...

  tab = document.createElement('div');

  constructor() {
  }

  ngOnChanges(changes: SimpleChanges): void {
    this.drawTable();
  }

  private drawTable(): void {
    new Tabulator(this.tab, {
      data: this.tableData,
      columns: this.columnNames,
      layout: 'fitData',
      height: this.height
    });
    document.getElementById('my-tabular-table').appendChild(this.tab);
  }

}

tabulator-table.component.html

<div id="my-tabular-table"></div>

Due to the way Angular pre-compiles component scss and the fact that tabulator is run after the fact I had to include my styles in the styles.scss (or any other global styles file). Just ensure that your custom css for tabulator is in a file that is loaded before the tabulator css(note that you have to include the tabulator css file in your angular.json). Below is my customised css for tabulator to better align with the style of Angular Material.

```
//Tabular styles override

.tabulator {
font-size: 12px;
border: none;
}

.tabulator .tabulator-header {
font-weight: normal;
border-bottom: 1px solid;
border-bottom-color: rgba(0, 0, 0, 0.12);
color: rgba(0, 0, 0, 0.54);
}

.tabulator .tabulator-header .tabulator-col {
height: 48px;
background-color: #ffffff;
border: none;
padding: 0 7px;
}

.tabulator-row {
border-bottom: 1px solid;
border-bottom-color: rgba(0, 0, 0, 0.12);
min-height: 48px;
vertical-align: middle;
}

.tabulator-row .tabulator-cell {
padding: 16px 7px;
border-right: none;
vertical-align: middle;
}

.tabulator-row .tabulator-cell:first-of-type,
.tabulator .tabulator-header .tabulator-col:first-of-type {
padding-left: 24px;
}

.tabulator-row.tabulator-row-even {
background-color: #ffffff;
}
```

This is my basic implementation of tabulator please modify and share your improvements.

Hey @Lourensk99

Thanks for the guide! i will look at getting that live on the website shortly.

Cheers

Oli :)

Hey @Lourensk99 ! This is AMAZING and helped me setup Tabulator with Angular. I do have one question. My data doesn't appear unless I click on one of the headers to sort. I am pulling it the same way you are. Any clue as to why that would happen?

Figured it out. You need to trigger a redraw! I stored the Tabulator init into a variable and then triggered a redraw after appending it to the container.

Hey @cbloss

Thanks for the feedback, does the above example need updating? could you provide a snipped of code so i could update it to help other users.

Cheers

Oli :)

Hey @cbloss

Thanks for the feedback, does the above example need updating? could you provide a snipped of code so i could update it to help other users.

Cheers

Oli :)

Might not be a bad idea. Or at least mentioned that the table may need to be re-drawn. I followed @Lourensk99 example pretty closely but for two things: I added the ID of the element as an Input so I can dynamically add it. That element with that id also had a element with a class panel-content. It's kind of like the xpanel in bootstrap.

private drawTable(): void {
    const container = document.getElementById(this.id).getElementsByClassName('panel-content')[0];

    const table = new Tabulator(this.tab, {
      data: this.tableData,
      columns: this.columnNames,
      columnVertAlign: "bottom",
      layout:"fitColumns",
    });

    container.appendChild(this.tab);

    table.redraw(true);
  }

It's also worth mentioning my table had stacked columns so there were a couple more settings. I hope this helps someone else out. :)

Great stuff, thanks for the info.

Would you be happy for me to put some of your tweaks on the Tabulator website?

Cheers

Oli :)

You're welcome and I'd be very happy! :+1: Thanks!

This looks really awesome and I appreciate the example. But I'm an old c++ guy and am new to all of the browser UI technologies so please forgive my ignorance. I created a new .Net Core Web application and chose type angular. I have done the following to my project. I have added a tabTable component and copied the code you have posted here including the table.redraw(true) in the drawTable function. I added the css to styles.css. I updated the "styles" section of 'angular.json' to include styles.css and tabulator.min.css.
After all that, I can see the table but no headers or data. It has the correct number of columns and rows but there is no data. It would be great if you could just point me in the right direction or let me know what step I've left off.

Below you can see this very simple app.
Added file 'person.ts', contents below
export interface IPerson {
id: number;
firstName: string;
lastName: string;
state: string;
}

In 'app.component.ts' I added these lines. Only change from VS template
import { IPerson } from './people/person';

export class AppComponent implements OnInit {
  title = 'ClientApp';
  people: IPerson[] = [];
  columnNames: string[] = ["id", "firstName", "lastName", "state"];

  ngOnInit() {
    this.people = [
      {
        id: 1,
        firstName: "John",
        lastName: "Smith",
        state: "Iowa"
      },
      {
        id: 2,
        firstName: "Jane",
        lastName: "Doe",
        state: "Arizona"
      }
    ];
  }

In 'app.component.html' I added the following (the name of my component is tabTable)

Sorry for asking a dumb question. It was totally due to my being very new to all of this stuff. I was able to get it working and thought I would add the steps I followed here in case any other newbies were struggling. For people just getting started with javascript, angular and typescript, follow these steps to get a basic tabulator table. You have to have node.js and angular cli (I used version 7.3.1) installed before proceeding.
1) Use Angular CLI to create project.

ng new DemoTabulator
cd DemoTabulator

2) Use npm to install bootstrap and tabulator

npm install jquery popper bootstrap --save
npm install tabulator-tables --save

3) Add style sheets to project
Open 'angular.json' and find the "styles" array under "projects"->"DemoTabulator"->"architect"->"build". In my file it was located at line 25.
Change that entry from

    "styles": [
        "src/styles.css"
    ],

to

    "styles": [
        "src/styles.scss",
        "./node_modules/bootstrap/dist/css/bootstrap.min.css",
        "./node_modules/tabulator-tables/dist/css/tabulator.min.css"
    ],

4) Add custom css for tabulator
Add the css posted by @olifolkerd into the 'styles.css' file.

5) Add a div tag to your html file
add the following div in your 'app.component.html' file where you want the table to be displayed
<div id="tabulator-div"></div>

6) Create the table in your typescript file 'app.component.ts'.

import { Component, OnInit } from '@angular/core';
import Tabulator from 'tabulator-tables';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'DemoTabulator';
  people: IPerson[] = [];
  columnNames: any[] = [];
  myTable: Tabulator;

  ngOnInit() {
    this.people = [
      { id: 1, firstName: "John", lastName: "Smith", state: "Ohio" },
      { id: 2, firstName: "Jane", lastName: "Doe", state: "Iowa" },
      { id: 3, firstName: "Bill", lastName: "Great", state: "Hawaii" },
      { id: 4, firstName: "Ted", lastName: "Adventure", state: "Arizona" }
    ];

    this.columnNames = [
      { title: "Id", field: "id" },
      { title: "First Name", field: "firstName" },
      { title: "Last Name", field: "lastName" },
      { title: "Location", field: "state" }
    ];

    // reference id of div where table is to be displayed (prepend #)
    this.myTable = new Tabulator("#tabulator-div"); 
    this.myTable.setColumns(this.columnNames);
    this.myTable.setData(this.people);
  }
}

interface IPerson {
  id: number,
  firstName: string,
  lastName: string,
  state: string
}

Sorry I didn't respond faster. The columnNames structure was probably the main reason why you weren't seeing at least the header. Sometimes (for me anyway), it's best to copy and paste in examples on the site (for the column structure) and the modify it as see fit. I usually pass in blank data until I get the columns set.

Glad you were able to figure it out though! :)

ajaxUrl:"ajaxdata.php" how can I use the infinite scroll the serverside rendering and the virtual dom using an angular pattern? can I redirect it to an angular service? using HTTP module? do you have examples for it? @olifolkerd @cbloss @TCantele

Something that people may run into if following the container/presenter pattern when passing the data in via @Inputs is that the data appears to come in as immutable, and tabulator doesn't like this, so you'll need to pass a copy of the input data to tabulator,

How to add bootstrap table classes to tabulator table using above approach? I followed the docs to Angular Setup, but unable to add bootstrap classes directly. Please assist

The import statement - import Tabulator from 'tabulator-tables'; doesn't work. Please, can someone advise why this is happening?

I have installed tabulator-tables but it doesn't recognise this line when instantiating the instance - new Tabulator(this.tab, {

@Dota2Pro that鈥檚 great. Works nicely. Appreciate the effort. I found mine to work even though it threw an error in finding the package before.

Hi, can any one add a filter example please. I am trying to add a simple filter which can filter through the entire table and not specific column. Is it possible using Tabulator, if so then how can we implement in angular? Thanks.

Found it myself. You can find it here: https://stackblitz.com/edit/angular-91wefh.

This line shows as an error - just like when I tried it in an application. Why is this so difficult to make work? import Tabulator from 'tabulator-tables'; <--- red squiggly line and "unknown module" error

@whaduu try import 'tabulator-tables'

Creating a component as described in the setup guide is not working for me, when using this component on more than one route.

Consider for example following routes:
const routes: Routes = [ { path: 'page/a', component: pageAComponent }, { path: 'page/b', component: pageBComponent }, ];

When including the component (i.e. app-tabulator-table) in pageAComponent and navigating to page/a, the table renders fine.

Now consider the case where the component is included in both pageAComponent and pageBComponent. When opening /page/a, the table is again rendered fine. When navigating to /page/b from /page/a, the table is not shown.

For me this issue was solved by replacing
document.getElementById('my-tabular-table').appendChild(this.tab); as indicated in the Tabulator's Angular Setup Guide, with
this.mytabulatortable.nativeElement.appendChild(this.tab);
and adding
@ViewChild('mytabulatortable') mytabulatortable

And in the .html replace
<div id="my-tabular-table"></div>
with
<div #mytabulatortable></div>

Admittedly I only recently started using Angular, so the issue I'm experiencing may be due to a misunderstanding of Angular on my part. But as far as I understand, the preferred way to do DOM manipulations in Angular is by using e.g. @ViewChild instead of direct access using getElemenyById anyway. Someone who has more experience with Angular may be able to chime or on whether the setup guide should be updated accordingly, or not.

In any case, I don't think this is an issue with Tabulator itself, but maybe with the setup guide.

Creating a component as described in the setup guide is not working for me, when using this component on more than one route.

Consider for example following routes:
const routes: Routes = [ { path: 'page/a', component: pageAComponent }, { path: 'page/b', component: pageBComponent }, ];

When including the component (i.e. app-tabulator-table) in pageAComponent and navigating to page/a, the table renders fine.

Now consider the case where the component is included in both pageAComponent and pageBComponent. When opening /page/a, the table is again rendered fine. When navigating to /page/b from /page/a, the table is not shown.

For me this issue was solved by replacing
document.getElementById('my-tabular-table').appendChild(this.tab); as indicated in the Tabulator's Angular Setup Guide, with
this.mytabulatortable.nativeElement.appendChild(this.tab);
and adding
@ViewChild('mytabulatortable') mytabulatortable

And in the .html replace
<div id="my-tabular-table"></div>
with
<div #mytabulatortable></div>

Admittedly I only recently started using Angular, so the issue I'm experiencing may be due to a misunderstanding of Angular on my part. But as far as I understand, the preferred way to do DOM manipulations in Angular is by using e.g. @ViewChild instead of direct access using getElemenyById anyway. Someone who has more experience with Angular may be able to chime or on whether the setup guide should be updated accordingly, or not.

In any case, I don't think this is an issue with Tabulator itself, but _maybe_ with the setup guide.

Hi, I had the same issue as you had, but your solution didnt worked with me. Table component for some reason doesnt initialize table(when in pageAComponent).

Edit: When routing to different page and routing back to page with table, table renders correctly.

Sorry for asking a dumb question. It was totally due to my being very new to all of this stuff. I was able to get it working and thought I would add the steps I followed here in case any other newbies were struggling. For people just getting started with javascript, angular and typescript, follow these steps to get a basic tabulator table. You have to have node.js and angular cli (I used version 7.3.1) installed before proceeding.

  1. Use Angular CLI to create project.
ng new DemoTabulator
cd DemoTabulator
  1. Use npm to install bootstrap and tabulator
npm install jquery popper bootstrap --save
npm install tabulator-tables --save
  1. Add style sheets to project
    Open 'angular.json' and find the "styles" array under "projects"->"DemoTabulator"->"architect"->"build". In my file it was located at line 25.
    Change that entry from
    "styles": [
        "src/styles.css"
    ],

to

    "styles": [
        "src/styles.scss",
        "./node_modules/bootstrap/dist/css/bootstrap.min.css",
        "./node_modules/tabulator-tables/dist/css/tabulator.min.css"
    ],
  1. Add custom css for tabulator
    Add the css posted by @olifolkerd into the 'styles.css' file.
  2. Add a div tag to your html file
    add the following div in your 'app.component.html' file where you want the table to be displayed
    <div id="tabulator-div"></div>
  3. Create the table in your typescript file 'app.component.ts'.
import { Component, OnInit } from '@angular/core';
import Tabulator from 'tabulator-tables';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'DemoTabulator';
  people: IPerson[] = [];
  columnNames: any[] = [];
  myTable: Tabulator;

  ngOnInit() {
    this.people = [
      { id: 1, firstName: "John", lastName: "Smith", state: "Ohio" },
      { id: 2, firstName: "Jane", lastName: "Doe", state: "Iowa" },
      { id: 3, firstName: "Bill", lastName: "Great", state: "Hawaii" },
      { id: 4, firstName: "Ted", lastName: "Adventure", state: "Arizona" }
    ];

    this.columnNames = [
      { title: "Id", field: "id" },
      { title: "First Name", field: "firstName" },
      { title: "Last Name", field: "lastName" },
      { title: "Location", field: "state" }
    ];

    // reference id of div where table is to be displayed (prepend #)
    this.myTable = new Tabulator("#tabulator-div"); 
    this.myTable.setColumns(this.columnNames);
    this.myTable.setData(this.people);
  }
}

interface IPerson {
  id: number,
  firstName: string,
  lastName: string,
  state: string
}

Thanks a lot. Have been struggling for a long time but this article helped my way through. :) 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tomheaps picture tomheaps  路  3Comments

KES777 picture KES777  路  3Comments

KES777 picture KES777  路  3Comments

c3pos-brother picture c3pos-brother  路  3Comments

mconnelley picture mconnelley  路  3Comments