Filter

by evgkch

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>
<div id="app"></div>

CSS

body {
  background-color: whitesmoke;
  color: #1F1F1F;
}
.filter-item {
  margin: 5px 0;
  user-select: none;
}
input[type="checkbox"] {
  display: none;
}
.checkbox-custom {
    position: relative;
    width: 20px;
    height: 20px;
    border: 2px solid #d0d5d8;
    border-radius: 2px;
}

.checkbox-custom,
.label {
    display: inline-block;
    vertical-align: middle;
}

.label {
  margin-left: 5px;
}
input[type="checkbox"]:checked + .checkbox-custom::before {
    content: '';
    display: block;
    position: absolute;
    top: 2px;
    right: 2px;
    bottom: 2px;
    left: 2px;
    background: #00AAE7;
    border-radius: 2px;
}

Babel + JSX

class Store {
	constructor(storeID, data) {
  	this.storeID = storeID;
    this.data = data || {};
  }
	update(state) {
  	let bufferStore = Object.assign({}, this.data, state);
  	this.data = bufferStore;
    updateApp();
    this.view();
  }
  view() {
  	console.log(this)
  }
}
const data = Array.from({ length: 4 }, (v, k) => ({ name: `Name ${k + 1}`, children: Array.from({ length: 4 }, (n, l) => ({ displayName: `Option ${k + 1}.${l + 1}`, id: `${k + 1}.${l + 1}` }) )}) );

const changeFilter = (array) => (filterId) => {
	let buffer = array,
			index = buffer.indexOf(filterId);
	index === -1
  	? buffer.push(filterId)
    : buffer.splice(index, 1);
  return buffer;
}

const store = new Store(
    'STORE',
    {
    data: data,
    filter: {}
    }
)
store.view()

const createCtrl = (store) => class ctrl {
	static addFilter(name, selectedItemId) {
  	this.refreshFiters(name);
  	let filter = store.data.filter,
  			newFilter = changeFilter(filter[name])(selectedItemId);
  	store.update({
    	filter: Object.assign({}, filter, { [name]: newFilter })
    });
  }
  static refreshFiters(name) {
  	if (!store.data.filter[name]) {
    	store.update({
      	filter: Object.assign({}, store.data.filter, { [name]: [] })
      })
    }
  }
}

const controller = createCtrl(store);

const updateApp = () => React.render(
	<App store={store.data} />,
    document.getElementById('app')
);

class App extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        const { store } = this.props;
        return(
        	<div>
            {
            	store.data.map((item, i) =>
              	<div key={i} className="filter-category">
              	  <div><strong>{item.name}</strong>
                    <div>{item.children.map(el =>
                    	<div key={el.id} className="filter-item">
                        <label>
                          <input type="checkbox" onChange={(e) => controller.addFilter(item.name, el.id)}...