Skip to content

Commit 8248c0d

Browse files
committed
-#2 - baseline for episode 19
1 parent 3df8f20 commit 8248c0d

File tree

9 files changed

+479
-0
lines changed

9 files changed

+479
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
npm-debug.log
22
**/node_modules/*
33
build/*
4+
.idea

ep19-call-api-jquery/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#### Setting up the application
2+
3+
```
4+
npm install
5+
npm start
6+
```
7+
8+
Visit http://localhost:8080 in browser.
9+
10+
#### Notes
11+
12+
* `npm install random-key --save`
13+
* [Source code](...)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import React from 'react';
2+
import DisplayList from './DisplayList';
3+
4+
var rand = require('random-key');
5+
6+
export default class App extends React.Component {
7+
8+
constructor () {
9+
super();
10+
this.state = { title: '', todos: [
11+
{ title: 'eggs', done: false, id: 1 },
12+
{ title: 'banana', done: false, id: 2 },
13+
{ title: 'bread', done: false, id: 3 }
14+
] };
15+
}
16+
17+
handleDone (idToBeMarkedAsDone) {
18+
var _todos = this.state.todos;
19+
var todo = _todos.filter((todo) => {
20+
return todo.id === idToBeMarkedAsDone;
21+
})[0];
22+
23+
todo.done = !todo.done;
24+
25+
this.setState({ todos: _todos });
26+
}
27+
28+
handleDelete (idToBeDeleted) {
29+
var newTodos = this.state.todos.filter( (todo) => {
30+
return todo.id != idToBeDeleted
31+
} )
32+
33+
this.setState({ todos: newTodos});
34+
}
35+
36+
handleSubmit (event) {
37+
event.preventDefault();
38+
39+
var title = this.state.title;
40+
var newTodos = this.state.todos.concat({ title: title,
41+
id: rand.generate(),
42+
done: false });
43+
44+
this.setState({ title: '', todos: newTodos });
45+
}
46+
47+
handleChange (event) {
48+
var title = event.target.value;
49+
this.setState({ title: title });
50+
}
51+
52+
handleClearCompleted (event) {
53+
var newTodos = this.state.todos.filter((todo) => { return !todo.done});
54+
this.setState({ todos: newTodos });
55+
}
56+
57+
render () {
58+
return <div>
59+
<h1> TODO </h1>
60+
<form onSubmit={this.handleSubmit.bind(this)}>
61+
<input type="text"
62+
onChange={this.handleChange.bind(this)}
63+
value={this.state.title} />
64+
</form>
65+
66+
<DisplayList
67+
handleDone={this.handleDone.bind(this)}
68+
handleDelete={this.handleDelete.bind(this)}
69+
todos={this.state.todos} />
70+
71+
<footer>
72+
All: ({ this.state.todos.length }) |
73+
Completed: ({ this.state.todos.filter((todo) => { return todo.done }).length }) |
74+
Pending: ({ this.state.todos.filter((todo) => { return !todo.done }).length }) |
75+
<a href='#' onClick={this.handleClearCompleted.bind(this)}>Clear Completed</a>
76+
</footer>
77+
</div>;
78+
}
79+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import React from 'react';
2+
3+
export default class DisplayItem extends React.Component {
4+
5+
constructor () {
6+
super();
7+
this.state = { editing: false }
8+
}
9+
10+
componentDidMount () {
11+
this.setState({ changedText: this.props.todo.title });
12+
}
13+
14+
handleEditing (event) {
15+
this.setState({ editing: true, changedText: this.props.todo.title });
16+
}
17+
18+
handleEditingDone (event) {
19+
if (event.keyCode === 13 ) { // submit
20+
this.setState({ editing: false });
21+
}
22+
}
23+
24+
handleEditingChange (event) {
25+
var _changedText = event.target.value;
26+
this.setState({ changedText: _changedText });
27+
}
28+
29+
render () {
30+
var todo = this.props.todo;
31+
32+
var viewStyle = {};
33+
var editStyle = {};
34+
35+
if (this.state.editing) {
36+
viewStyle.display = 'none';
37+
} else {
38+
editStyle.display = 'none';
39+
}
40+
41+
return <li className={ todo.done ? 'done' : '' }>
42+
<div style={viewStyle} onDoubleClick={this.handleEditing.bind(this)}>
43+
<input
44+
checked={todo.done}
45+
onChange={this.props.handleDone.bind(null, todo.id)}
46+
type="checkbox"
47+
style={{ fontSize: 'x-large' }} />
48+
49+
<label>
50+
{ this.state.changedText }
51+
</label>
52+
53+
<a href='#'
54+
className="destroy"
55+
onClick={ this.props.handleDelete.bind(null, todo.id) }>
56+
[x]
57+
</a>
58+
</div>
59+
60+
<input type="text"
61+
onKeyDown={this.handleEditingDone.bind(this)}
62+
onChange={this.handleEditingChange.bind(this)}
63+
style={editStyle}
64+
value={this.state.changedText} />
65+
</li>
66+
}
67+
68+
}
69+
70+
DisplayItem.propTypes = {
71+
todo: React.PropTypes.object.isRequired,
72+
handleDone: React.PropTypes.func.isRequired,
73+
handleDelete: React.PropTypes.func.isRequired
74+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import DisplayItem from './DisplayItem';
3+
4+
export default class DisplayList extends React.Component {
5+
6+
render () {
7+
return <ul id="todo-list">
8+
{ this.props.todos.map((todo, i) => {
9+
return <section id="main" key={todo.id}>
10+
<DisplayItem
11+
todo={todo}
12+
handleDone={this.props.handleDone}
13+
handleDelete={this.props.handleDelete} />
14+
</section>
15+
}) }
16+
</ul>
17+
}
18+
19+
}
20+
21+
DisplayList.propTypes = {
22+
todos: React.PropTypes.array.isRequired,
23+
handleDone: React.PropTypes.func.isRequired,
24+
handleDelete: React.PropTypes.func.isRequired
25+
}

ep19-call-api-jquery/app/main.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import './stylesheets/main.css';
2+
3+
import React from 'react';
4+
import App from './components/App';
5+
6+
main();
7+
8+
function main() {
9+
var div = document.createElement('div');
10+
div.setAttribute("id", "todoapp");
11+
document.body.appendChild(div);
12+
13+
React.render(<App />, div);
14+
}

0 commit comments

Comments
 (0)