https://github.com/a-x-/table-builder
Isomorphic (universal) Powerful HTML table builder based on the JSON.
https://github.com/a-x-/table-builder
html-table table table-builder
Last synced: 3 months ago
JSON representation
Isomorphic (universal) Powerful HTML table builder based on the JSON.
- Host: GitHub
- URL: https://github.com/a-x-/table-builder
- Owner: a-x-
- Created: 2016-04-02T20:45:34.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2017-07-02T10:13:19.000Z (over 7 years ago)
- Last Synced: 2024-09-16T09:48:52.819Z (5 months ago)
- Topics: html-table, table, table-builder
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/table-builder
- Size: 273 KB
- Stars: 18
- Watchers: 2
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
table-builder [](https://travis-ci.org/a-x-/table-builder)
============Create HTML tables from a JSON in a both Node.js (0.10+) and browsers enviroments.
#### Installation
```sh
yarn add --production table-builder
```or
```sh
npm i --production table-builder
````--production` flag skips devDependencies of the table-builder (testing framework).
#### Usage
##### node.js and webpack
```js
import TableBuilder from 'table-builder'
```##### browser (without build tool)
1. Copy built UMD module:
`cp node_modules/table-builder/tablebuilder.js dist/tablebuilder.js`2. Insert tag:
``#### Simple Example
Each object represents one row in the data array.
```json
[
{ "name":"Larry Wall", "age":57, "link": "www.wall.org/~larry/" },
{ "name":"Bill Gates", "age":56, "link": "www.microsoft.com" },
{ "name":"Daffy Duck", "age":75, "link": "" }
]
``````javascript
var data = [/* see data section above */];// You can put key-value pairs if you strongly want keep headers order:
// [['name', 'User name'], ['age', 'User age'], ['link', 'Homepage']]
var headers = { "name" : "User name", "age": "User age", "link": "Homepage" };var Table = require('table-builder');
console.log(
(new Table({'class': 'some-table'}))
.setHeaders(headers) // see above json headers section
.setData(data) // see above json data section
.render()
);
```Rendered to:
```htmlUser name User age Homepage
Larry Wall
57
www.wall.org/~larry/
Bill Gates
56
www.microsoft.com
Daffy Duck
75
```
#### Example of simple scrapper with tablebuilder result representation
```js
const process = require('process')
const TableBuilder = require('table-builder')
const table = new TableBuilder({class: 'avito'})
const headers = {price: 'Price', title: 'Title'}
const thrw = require('throw')
const fetch = require('isomorphic-fetch')
const getHttp = (uri) => fetch(uri).then(r => r.status >= 400 ? thrw (r.status) : r.text())
const parseHtml = html => require('jsdom').jsdom(html)const uri = process.argv[2] || 'https://www.avito.ru/moskva/telefony/iphone?q=iphone+se'
const retreiveData = (document) => Array.from(document.querySelectorAll('.js-catalog_after-ads .item')).map(i=>({title:i.querySelector('.title'), price:i.querySelector('.about')})).map(({title,price})=>({title:title.textContent.trim(),price:price.textContent.trim()}))
const main = () =>
getHttp(uri)
.then(html => parseHtml(html))
.then(document => retreiveData(document))
.then(data => table.setHeaders(headers).setData(data).render())const style = `body { text-align: center; } .avito {width: 100%;} thead { text-align: left; } .price-td { text-align: right; }`
main().then(r=>console.log(style, r))
```
## API
#### Prisms
Prism are callbacks-preprocessors for specified fields.```javascript
var data = [ // Look the previous case differences: link format changed and name splitted into firstname and surname
{ "firstname":"Larry", "surname":"Wall", "age":57, "link": "www.wall.org/~larry/" },
{ "firstname":"Bill", "surname":"Gates", "age":56, "link": "www.microsoft.com" },
{ "firstname":"Daffy", "surname":"Duck", "age":75, "link": "" }
];(new Table({'class': 'some-table'}))
.setPrism('link', function (cellData) {
return cellData && ''+cellData+'' || 'N/A';
})
.setPrism('name', function (cellData, row) {
return row.surname + ' ' + row.firstname;
})
.setHeaders({ "name": "User name", "age": "User age", "link": "Homepage" })
.setData(data)
.render()
```Render output is equal the previous case.
Also, prism callback may return `{presentation: '...', raw: '...'}` object
for splitting html wrapped cell values and raw values.
For example, raw values uses in [totals](#totals).#### Totals
See following code:```js
table.setTotal('age', function (columnCellsCollection, rowsCollection) {
// Calc average age
return Math.round(
columnCellsCollection
.reduce(function (prev, val) { return +prev + val; })
/ columnCellsCollection.length
);
});
```It adds `tfoot` in the table with average age:
```html
62
```#### Grouping
Grouping fields util (`setGroup`).
```js
// ...
table
.setGroup('product_category', function (value, recordsCount, totals) {
// ...
})
// ...
.render();
```Group removes the field (`product_category`) from the table
and adds row-separators with the field's values (group names). and referenced items.Body of the setGroup callback may contains processor of group name.
Additionaly processor may use the group's `recordsCount` and `totals` collection for group
if `setTotal` for whole table have installed.If callback is not defined then tableBuilder uses group name without processing, as is.
## Empty data collection
```js
// Show table replacer block if data set is empty
// ...
table
// ...
.render()
|| 'Data collection is empty!';
```## Client side sorting, filtering
You can use [list.js](https://github.com/javve/list.js) with table builder.
## TODO
* [x] Unit tests, CI
* [x] Decompose methods
* [ ] More unit tests
* [ ] Run building and another activity only in the render() method, push intermediate methods into preordered list
* [ ] Framefork agnostic: possibility to use with React and another frameworks
* `tagBuilder` as a dependency injection (for compatibility with either: `innerHTML`, `createElement`, `React.Component`)
* [ ] Internal type constructors with asserts
* [ ] Data model, changing/accessing data api
* [ ] Client-side filters, multisort
* [ ] Plural versions of methods: `setPrisms`, `setTotals`
* [ ] Plugins system (call hooks for different cells)
* [ ] N/A maps
* [ ] Escaping
* [ ] Complex 2-level headers feature
* [ ] Sticky headers feature
* [ ] Vertical header feature
* [ ] Simplify prisms api: callback must returns presentation data only instead of `{raw, presentation}`## See also another solutions
**React based**:
* [react-data-grid](https://github.com/adazzle/react-data-grid) - I did not use it still
* [react-table](https://github.com/tannerlinsley/react-table) - I revealed problems with custom styles and stability
* _suggestions are welcome_**Framework agnostic**:
* _suggestions are welcome_