Skip to content

Instantly share code, notes, and snippets.

@gianmarcotoso
Last active March 10, 2016 16:30
Show Gist options
  • Save gianmarcotoso/5ff5cb393d9688ee5d69 to your computer and use it in GitHub Desktop.
Save gianmarcotoso/5ff5cb393d9688ee5d69 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
};
}
componentWillReceiveProps(nextProps) {
this.updateFilter(nextProps);
}
componentDidMount() {
this.updateFilter(this.props);
}
updateFilter({items, filter, filterTransform}) {
let _items = [];
let _filter = {};
let _filterTransform = filterTransform || {};
// Transform the filter values
Object.keys(filter).forEach( key => {
let transform = _filterTransform[key];
let filterValue = transform ? transform(filter[key]) : filter[key];
if (filterValue === null || typeof filterValue === "undefined") {
return;
}
_filter[key] = filterValue;
});
// Apply the transformed filter to each item
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 !== parseFloat(value)) {
itemSatisifesFilters = false;
}
}
// String Value
if (filterValue.constructor === String && value) {
if (value.toString().trim().indexOf(filterValue) === -1) {
itemSatisifesFilters = false;
}
}
// Boolean Value
if (filterValue.constructor === Boolean) {
if (filterValue !== !!value) {
itemSatisifesFilters = false;
}
}
// Range Value
if (Array.isArray(filterValue)) {
if (parseFloat(value) < filterValue[0] || parseFloat(value) > filterValue[1]) {
itemSatisifesFilters = false;
}
}
}
if (itemSatisifesFilters) {
_items.push(item);
}
} );
this.setState({items: _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