<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
body {
padding: 5px
}
/* Controllers Hierarchy
App
C SearchBar
f ProductTable
f CategoryRow
f ProductRow
*/
function ProductRow(props) {
let styles = {border: 'dotted red 1px', paddingLeft: '8px', color: 'blue'}
if(!props.stocked){
styles.color= 'red'
styles.fontStyle = 'italic'
styles.fontFamily = 'normal';
}
return <div style={styles}> {props.name} {props.price} </div>;
}
function CategoryRow(props){
return <div style={{background: 'yellow', paddingLeft: '4px'}} > {props.category} </div>;
}
function ProductTable(props) {
let rows = [];
let lastCategory = null;
const products = props.products
.filter( p => {
const key = props.searchBoxKey.toLowerCase();
const index = p.name.toLowerCase().indexOf(key);
return (index >= 0 )
});
products.forEach( (x, i) => {
if(x.category !== lastCategory){
rows.push( <CategoryRow category={x.category} key={'a' + i } />);
lastCategory = x.category;
}
rows.push( <ProductRow
name={x.name}
price={x.price}
stocked={x.stocked}
key={'b'+ i }
/> )
});
return <div style={{border: 'solid green'}} > {rows} </div>;
}
class SearchBar extends React.Component{
constructor(props){
super(props);
this.handleFilterTextChange = this.handleFilterTextChange.bind(this);
};
handleFilterTextChange(e){
this.props.handleSearchBox(e.target.value)
};
render(){
return (
<form>
<input
type="text"
placeholder="Search..."
onChange={this.handleFilterTextChange}
/>
<p>
<input type="checkbox" /> {' '} Only show products in stock
</p>
</form>);
};
}
class App extends React.Component {
constructor(props){
super(props);
this.state = {
searchBoxKey: '',
checkShowInStock: false
};
this.handleSearchBox = this.handleSearchBox.bind(this);
}
handleSearchBox(filterText){
this.setState({
searchBoxKey : filterText
});
}
render(){
return (
<div key='i1'>
<SearchBar
handleSearchBox={this.handleSearchBox}
/>
<ProductTable
products={this.props.products}
searchBoxKey={this.state.searchBoxKey}
key='i2'
/>
</div>);
};
};
const PRODUCTS = [
{ category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'},
{ category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'},
{ category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'},
{ category: 'Sporting Goods', price: '$79.99', stocked: true, name: 'Socer'},
{ category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'},
{ category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'},
{ category: 'Electronics', price: '$299.99', stocked: false, name: 'BacoPhone 7'},
{ category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'}
];
ReactDOM.render(
<App products={PRODUCTS} />
, document.getElementById('container')
);
View Compiled
This Pen doesn't use any external CSS resources.