Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 58 additions & 13 deletions 25-multiplecomponents-lab_v16/src/01-redspotter.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,58 @@
/**
* Lab 01:
*
* Write a game that shows 10 squares: 9 gray and 1 red.
* When a user clicks on the red she gets 5 points and red changes its place.
* When a user clicks on any other square nothing happens.
*
*/

import React from 'react';

export default class RedSpotter extends React.Component {
}
import React from 'react';

export default class RedSpotter extends React.Component {

constructor(props) {
super(props);
this.state = {
score: 0,
boxes: [
{ id: 10, color: "#ff0000" },
{ id: 20, color: "#c0c0c0" },
{ id: 30, color: "#c0c0c0" },
{ id: 40, color: "#c0c0c0" },
{ id: 50, color: "#c0c0c0" },
{ id: 60, color: "#c0c0c0" },
{ id: 70, color: "#c0c0c0" },
{ id: 80, color: "#c0c0c0" },
{ id: 90, color: "#c0c0c0" },
{ id: 100, color: "#c0c0c0" }
]
};
}

shuffle = (id) => {
var _ = require('lodash');

if (id === "new") {
this.setState({ boxes: _.shuffle(this.state.boxes) });
this.setState({ score: 0 });
} else {
(id === 10 ?
this.setState({ score: parseInt([this.state.score]) + 10 }):
this.setState({ score: parseInt([this.state.score]) - 5 })
);

this.setState({ boxes: _.shuffle(this.state.boxes) });
}
}

render() {
return (
<div>
<input type="button" value="New Game" onClick={() => this.shuffle("new")} ref={btn => { this.btn = btn }} /> Score : <label>{this.state.score}</label>
<p />
<div>
{this.state.boxes.map((element, index) => {
return <div key={index} id={element.id} style={{
backgroundColor: element.color,
width: '50px', height: '50px', float: 'left', margin: '5px'}}
onClick={() => this.shuffle(element.id)} ref={(box) => { this.box = box }}></div>
})}
</div>
</div>
);

}
}

153 changes: 146 additions & 7 deletions 25-multiplecomponents-lab_v16/src/03-shoppinglist-filters.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,146 @@
/**
* Lab 03: Shopping List Filters
*
* Add two filters to the shopping list built in previous lab:
* - Ability to show only products matching a given name
* - Ability to show only products that were fully bought
*/
import React from 'react';

export default class ShoppingListWithFilters extends React.Component {
constructor(props) {
super(props);
this.state = {
filterText:"",
items: []
};
}

modifyQuantity(e, itemId){
let updatedItemIndex = this.state.items.findIndex( el => el.id === itemId);
let updatedItem = this.state.items[updatedItemIndex];
let noOfUnits = e.target.closest("td").querySelector("input").value;

if(updatedItem.unit > 0){
updatedItem.unit = updatedItem.unit- noOfUnits;
}

let updatedList = this.state.items
updatedList[updatedItemIndex] = updatedItem;

return updatedList;
}

buy = (e,itemId) => {

this.setState({
items: this.modifyQuantity(e,itemId)
});

}

delete = (index) => {
const itemsArr = this.state.items;
this.setState({
items: [...itemsArr.slice(0,index), ...itemsArr.slice(index+1)]
});
}



add = () => {
let itemName = this.name.value;
let itemImageUrl = this.url.value;
let itemUnit = this.unit.value;

this.setState({ total:parseInt([this.state.total])+1,items: [...this.state.items, { id:Math.random()*100 ,name: itemName , url: itemImageUrl ,unit: itemUnit}] })
}

filterByName = () => {
let filter = this.nameFilter.value
this.setState({
filterText: filter
});
}

render() {

const style = {
fontFamily: 'Arial',
padding: 10,
color: "#444",
border: "3px solid black",
position: "relative",
width: "700px",
height: "25px",
letterSpacing: 0,
overflow: "hidden",
fontSize: 14,
}

let itemsList = this.state.items
let filterTxt = this.state.filterText



if(filterTxt.length>0){
itemsList = itemsList.filter(element => element.name === filterTxt);
}

return (
<div>
<table>
<tbody>
<tr>
<td>Name:</td>
<td><input type="text" ref={name => { this.name = name }} /></td>
</tr>
<tr>
<td>Image:</td>
<td> <input type="text" ref={url => { this.url = url }}/> Use full path</td>
</tr>
<tr>
<td>Unit:</td>
<td><input type="text" ref={unit => { this.unit = unit }} /></td>
</tr>
<tr>
<td></td>
<td><input type="button" value="Add Item" onClick={this.add} /><p /></td>
</tr>



</tbody>
</table>

<table style={style}>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Item Name <input type="text" onChange={() => this.filterByName(itemsList)} ref={nameFilter => { this.nameFilter = nameFilter }} /></td>
<td>Item Image</td>
<td>Item Unit </td>
<td></td>
<td></td>
</tr>
{itemsList.map((element, index) => {
return <tr key={index}>
<td>{element.name}</td>
<td><img src={element.url} height="42" width="42"/></td>
<td>{element.unit}</td>
<td>
<input type="text" ref={unitsNo => { this.unitsNo = unitsNo }} />
<input type="button" value="Bye!" onClick={(e) => this.buy(e,element.id)} />
</td>
<td><input type="button" value="Delete" onClick={() => this.delete(index)} /></td>
</tr>
})}

</tbody>
</table>

</div>
);

}
}