Skip to content

Instantly share code, notes, and snippets.

@luelher
Created May 24, 2018 01:46
Show Gist options
  • Save luelher/2ead54a9ff0ab2bfbd5f3ce5d225a392 to your computer and use it in GitHub Desktop.
Save luelher/2ead54a9ff0ab2bfbd5f3ce5d225a392 to your computer and use it in GitHub Desktop.
React Sortable Table Exercise
<div id="react-content"></div>
class Main extends React.Component {
/*
This exercise should take approximately 1 hour
Use best practices
The resulting app should:
- display the data in a simple table with dynamic column headings
- sort the table by any column ascending or descending order by clicking a column heading
- allow deletion of table rows
- allow adding new items via the form
*/
constructor(props) {
super(props);
this.id_count = 3
this.state = {};
this.state.data = [
{id: 1, name: 'Iron Man', budget: '120000000', rating: 8},
{id: 2, name: 'Captain America', budget: '130000000', rating: 6},
{id: 3, name: 'The Hulk', budget: '90000000', rating: 5},
];
this.state.sortKey = 'id';
this.state.sortAsc = true;
this.state.name = '';
this.state.budget = '';
this.state.rating = '';
this.addFilm = this.addFilm.bind(this);
this.handleInputsChange = this.handleInputsChange.bind(this);
this.deleteFilm = this.deleteFilm.bind(this);
this.deleteFilm = this.deleteFilm.bind(this);
this.sortBy = this.sortBy.bind(this);
}
sortBy(column) {
let { sortKey, sortAsc } = this.state;
sortAsc = !sortAsc;
let sort_result = this.sortByColumn(this.state.data.slice(0), column.target.id, sortAsc)
this.setState({ data: sort_result, sortAsc: sortAsc });
}
sortByColumn(data, sortKey, sortAsc) {
return data.sort(function (a, b) {
if (sortAsc) {
return a[sortKey] - b[sortKey];
} else {
return b[sortKey] - a[sortKey];
}
});
}
addFilm(event) {
const { name, budget, rating } = this.state;
this.id_count = this.id_count + 1;
this.setState({ data: this.state.data.concat({id: this.id_count, name: name, budget: budget, rating: rating}), name: '', budget: '', rating: '' });
event.preventDefault();
}
deleteFilm(film) {
// Delete a film from the table here
const data_deleted = this.state.data.filter( (item) => item.id != film.target.id);
this.setState({ data: data_deleted });
}
handleInputsChange(e) {
if (e.target.name === "name") {
this.setState({name: e.target.value})
} else if (e.target.name === "budget") {
this.setState({budget: e.target.value})
} else {
this.setState({rating: e.target.value})
}
}
render() {
const data = this.state.data;
const headers = Object.keys(data[0] || []);
return (
<div key={1}>
<table>
<Headers columns={headers} sortBy={this.sortBy} />
<tbody>
{data && data.map((item, index) => <Row film={item} deleteFilm={this.deleteFilm} />) }
</tbody>
</table>
<p />
<form onSubmit={this.addFilm}>
<input type="text" value={this.state.name} name="name" placeholder="name" onChange={this.handleInputsChange} />
<input type="text" value={this.state.budget} name="budget" placeholder="budget" onChange={this.handleInputsChange} />
<input type="text" value={this.state.rating} name="rating" placeholder="rating" onChange={this.handleInputsChange} />
<input type="submit" value="Add" />
</form>
</div>
);
}
}
const Headers = ({columns, sortBy}) => {
return (
<thead>
<tr>
{columns && columns.map( (col, index) => <td className="col-header" key={index} id={col} onClick={sortBy} >{col}</td> )}
</tr>
</thead>
);
};
const Row = ({film, deleteFilm}) => {
return (
<tr>
<td>{film.id}</td>
<td>{film.name}</td>
<td>{film.budget}</td>
<td>{film.rating}</td>
<td id={film.id} className="delete" onClick={deleteFilm}>x</td>
</tr>
);
};
ReactDOM.render(<Main />, document.getElementById('react-content'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
table {
border-collapse: collapse;
}
th, td {
border: 1px solid #888;
padding: 3px;
text-align: left;
}
input {
display: block;
margin: 2px 0;
}
.delete {
color: red;
cursor: pointer;
}
.col-header {
font-weight: bold;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment