Skip to content

Commit 2c4c883

Browse files
committed
Initial commit
0 parents  commit 2c4c883

13 files changed

+7240
-0
lines changed

.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# See http://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
# dependencies
4+
node_modules
5+
6+
# testing
7+
coverage
8+
9+
# production
10+
build
11+
12+
# misc
13+
.DS_Store
14+
.env
15+
npm-debug.log
16+
.idea

README.md

+1,244
Large diffs are not rendered by default.

package.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "react-datatables",
3+
"version": "0.1.0",
4+
"private": true,
5+
"devDependencies": {
6+
"datatables.net": "^1.10.13",
7+
"jquery": "^3.1.1",
8+
"react-scripts": "0.8.4"
9+
},
10+
"dependencies": {
11+
"react": "^15.4.1",
12+
"react-dom": "^15.4.1"
13+
},
14+
"scripts": {
15+
"start": "react-scripts start",
16+
"build": "react-scripts build",
17+
"test": "react-scripts test --env=jsdom",
18+
"eject": "react-scripts eject"
19+
}
20+
}

public/favicon.ico

24.3 KB
Binary file not shown.

public/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
7+
8+
<title>React App</title>
9+
</head>
10+
<body>
11+
<div id="root"></div>
12+
</body>
13+
</html>

src/App.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, {Component} from 'react';
2+
import Input from './Input';
3+
import Table from './Table';
4+
5+
class App extends Component {
6+
constructor() {
7+
super();
8+
this.state = {
9+
names: []
10+
}
11+
}
12+
13+
onAddClick(name, nickname) {
14+
let updated = false;
15+
const result = this.state.names.map((nameData) => {
16+
if (nameData.name === name) {
17+
updated = true;
18+
return {name, nickname}
19+
}
20+
return nameData;
21+
});
22+
if (!updated) {
23+
result.push({name, nickname});
24+
}
25+
26+
this.setState({
27+
names: result
28+
})
29+
}
30+
31+
render() {
32+
return (
33+
<div className="App">
34+
<Input onAddClick={(name, nickname) => {
35+
this.onAddClick(name, nickname);
36+
}} />
37+
<Table names={this.state.names} />
38+
</div>
39+
);
40+
}
41+
}
42+
43+
export default App;

src/Input.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React, {Component} from 'react';
2+
3+
4+
class Input extends Component {
5+
6+
constructor() {
7+
super();
8+
this.state = {
9+
name: '',
10+
nickname: ''
11+
}
12+
}
13+
14+
updateValue(fieldName, value) {
15+
this.setState({
16+
[fieldName]: value
17+
})
18+
}
19+
20+
onAddClick() {
21+
this.props.onAddClick(this.state.name, this.state.nickname);
22+
}
23+
24+
render() {
25+
return (
26+
<div className="app-input">
27+
<div>
28+
<span>Name:</span>
29+
<input type="text" onChange={(e) => {
30+
this.updateValue('name', e.target.value)
31+
}} />
32+
</div>
33+
<div>
34+
<span>Nickname:</span>
35+
<input type="text" onChange={(e) => {
36+
this.updateValue('nickname', e.target.value)
37+
}} />
38+
</div>
39+
<button onClick={() => {
40+
this.onAddClick()
41+
}}>Add
42+
</button>
43+
</div>
44+
);
45+
}
46+
}
47+
48+
Input.PropTypes = {
49+
onAddClick: React.PropTypes.func
50+
};
51+
52+
export default Input;
53+

src/Table.js

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import React, {Component} from 'react';
2+
3+
import './datatables.css';
4+
5+
const $ = require('jquery');
6+
$.DataTable = require('datatables.net');
7+
8+
const columns = [
9+
{
10+
title: 'Name',
11+
width: 120,
12+
data: 'name'
13+
},
14+
{
15+
title: 'Nickname',
16+
width: 180,
17+
data: 'nickname'
18+
},
19+
];
20+
21+
function reloadTableData(names) {
22+
const table = $('.data-table-wrapper').find('table').DataTable();
23+
table.clear();
24+
table.rows.add(names);
25+
table.draw();
26+
}
27+
28+
function updateTable(names) {
29+
const $element = $('.data-table-wrapper');
30+
const table = $element.find('table').first().DataTable();
31+
let dataChanged = false;
32+
table.rows().every(function () {
33+
const oldNameData = this.data();
34+
const newNameData = names.find((nameData) => {
35+
return nameData.name === oldNameData.name;
36+
});
37+
if (oldNameData.nickname !== newNameData.nickname) {
38+
dataChanged = true;
39+
this.data(newNameData);
40+
}
41+
return true;
42+
});
43+
44+
if (dataChanged) {
45+
table.draw();
46+
}
47+
}
48+
49+
50+
class Table extends Component {
51+
componentDidMount() {
52+
$(this.refs.main).DataTable({
53+
dom: '<"data-table-wrapper"t>',
54+
data: this.props.names,
55+
columns
56+
});
57+
}
58+
59+
shouldComponentUpdate(nextProps) {
60+
if (nextProps.names.length !== this.props.names.length) {
61+
reloadTableData(nextProps.names);
62+
} else {
63+
updateTable(nextProps.names);
64+
}
65+
return false;
66+
}
67+
68+
render() {
69+
return (
70+
<div>
71+
<table ref="main" />
72+
</div>);
73+
}
74+
}
75+
76+
Table.PropTypes = {
77+
names: React.PropTypes.array
78+
};
79+
80+
export default Table;

0 commit comments

Comments
 (0)