Skip to content

Instantly share code, notes, and snippets.

@ryardley
Last active February 26, 2017 11:58
Show Gist options
  • Save ryardley/9104b0c578f0495b1dc3a875869c00f9 to your computer and use it in GitHub Desktop.
Save ryardley/9104b0c578f0495b1dc3a875869c00f9 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import './App.css';
const SORT_UP = 'up';
const SORT_DOWN = 'down';
function alphanumeric(a,b){
if(a === b){ return 0; }
return a > b ? 1 : 0;
}
function alphanumericreverse(a,b){
if(a === b){ return 0; }
return a < b ? 1 : 0;
}
const compareFunctionMap = {
up: alphanumericreverse,
down: alphanumeric
}
function sortBy(tag, list, compare){
return list.sort((a, b) => {
return compare(a[tag], b[tag])
});
}
class App extends Component {
constructor(){
super();
this.state = {
list: [
{color: 'red', size: 1},
{color: 'yellow', size: 8},
{color: 'blue', size: 3},
{color: 'pink', size: 4},
]
}
}
toggleSort = event => {
// get data from state and element
const tag = event.currentTarget.getAttribute('data-id');
const { list: currentList, direction: currentDir } = this.state;
// toggle the direction
const direction = currentDir === SORT_UP ? SORT_DOWN : SORT_UP;
// Get the correct compare function
const compare = compareFunctionMap[direction];
// work out new list direction and tag
const list = sortBy(tag, currentList, compare);
// set the new state
this.setState({ list, direction, tag });
}
renderIcon = (thisTag, direction, lastTag) => {
// if this button is not the last sorted button or the direction has not been set yet
if(thisTag !== lastTag || !direction) {
return <span>*</span>;
}
return direction === SORT_UP ? <span>&uarr;</span> : <span>&darr;</span>;
}
render = () => {
const {list, direction, tag} = this.state;
return (
<div className="App">
<table className="table">
<thead>
<tr>
<th>Colour&nbsp;
<button
data-id="color"
onClick={this.toggleSort}>
{this.renderIcon('color', direction, tag)}
</button>
</th>
<th>Size&nbsp;
<button
data-id="size"
onClick={this.toggleSort}>
{this.renderIcon('size', direction, tag)}
</button>
</th>
</tr>
</thead>
<tbody>
{ list.map((item) => (
<tr key={item.color}>
<td>{item.color}</td>
<td>{item.size}</td>
</tr>
)) }
</tbody>
</table>
</div>
);
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment