Skip to content

Instantly share code, notes, and snippets.

@simonelp
Forked from gianmarcotoso/Filter.jsx
Created March 8, 2016 11:30
Show Gist options
  • Save simonelp/45f73739fa71fd6dfc0d to your computer and use it in GitHub Desktop.
Save simonelp/45f73739fa71fd6dfc0d to your computer and use it in GitHub Desktop.
React Filter HoC
import React from 'react';
import { Component } from 'react';
let Filter = Filterable => class extends Component {
constructor(props) {
super(props);
this.state = {
items: props.items
};
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.filter !== this.props.filter || prevProps.items !== this.props.items) {
this.updateFilter();
}
}
componentDidMount() {
this.updateFilter();
}
updateFilter() {
let items = [];
let filter = {};
// Transform the filter values
Object.keys(this.props.filter).forEach( key => {
let transform = this.props.filterTransform[key];
let filterValue = transform ? transform(this.props.filter[key]) : this.props.filter[key];
if (filterValue === null || typeof filterValue === "undefined") {
return;
}
filter[key] = filterValue;
});
// Apply the transformed filter to each item
this.props.items.forEach( item => {
let itemSatisifesFilters = true;
for (let key in filter) {
let value = item[key];
let filterValue = filter[key];
// Numeric Value
if (filterValue.constructor === Number) {
if (filterValue !== value) {
itemSatisifesFilters = false;
}
}
// String Value
if (filterValue.constructor === String) {
if (value.trim().indexOf(filterValue) === -1) {
itemSatisifesFilters = false;
}
}
// Boolean Value
if (filterValue.constructor === Boolean) {
if (filterValue !== !!value) {
itemSatisifesFilters = false;
}
}
// Range Value
if (Array.isArray(filterValue)) {
if (value < filterValue[0] || value > filterValue[1]) {
itemSatisifesFilters = false;
}
}
}
if (itemSatisifesFilters) {
items.push(item);
}
} );
this.setState({items});
}
render() {
return (
<Filterable {...this.props} items={this.state.items}/>
);
}
}
Filter.propTypes = {
items: React.PropTypes.array.isRequired,
filter: React.PropTypes.object.isRequired,
filterTransform: React.PropTypes.object
}
Filter.defaultProps = {
filterTransform: {}
}
Filter.negate = value => !!!value;
Filter.notZero = value => parseInt(value) !== 0 ? value : null;
Filter.range = range => value => value ? [parseFloat(value) * (1 - parseFloat(range)), parseFloat(value) * (1 + parseFloat(range))] : null;
Filter.integer = value => parseInt(value) || null;
Filter.chain = (...filters) => value => { filters.forEach(f => { value = f(value) }); return value; }
Filter.ignore = value => null;
export default Filter;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment