This repository has been archived by the owner on Jan 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
todo_app.js
127 lines (126 loc) · 3.58 KB
/
todo_app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
var TodoApp = React.createClass({
getInitialState: function() {
return {data: {items: []}};
},
fetchTodos: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, error) {
console.log('An error ('+status+') occured:', error.toString());
}.bind(this)
});
},
componentDidMount: function() {
this.fetchTodos();
},
saveTodo: function(todo) {
// quick! append added todo to list of todos
var todos = this.state.data.items;
var newTodos = todos.concat([todo]);
this.setState({data: {items: newTodos}});
// save todo in db
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: todo,
success: function(data) {
// update list of todos from fresh db
this.setState({data: data});
}.bind(this),
error: function(xhr, status, error) {
console.log('An error ('+status+') occured:', error.toString());
}.bind(this)
});
},
setStatus: function(id, status) {
// update todo in db
$.ajax({
url: '/todos/'+id+'/status.json',
dataType: 'json',
type: 'POST',
data: {completed: status},
success: function(data) {
// update list of todos from fresh db
this.setState({data: data});
}.bind(this),
error: function(xhr, status, error) {
console.log('An error ('+status+') occured:', error.toString());
}.bind(this)
});
},
notDoneFilter: function(todo) {
return !todo.completed;
},
clearAll: function() {
// it was either making ugly ajax call (I hate how this code looks)
// or making one call for every todo entry
$.ajax({
url: '/todos/complete_all.json',
dataType: 'json',
type: 'POST',
success: function(data) {
// update list of todos from fresh db
this.setState({data: data});
}.bind(this),
error: function(xhr, status, error) {
console.log('An error ('+status+') occured:', error.toString());
}.bind(this)
});
},
sort: function(items, dragging) {
var data = this.state.data;
data.items = items;
data.dragging = dragging;
this.setState({data: data});
if (dragging == undefined) {
this.setOrder();
}
},
setOrder: function() {
// get order
var ordered = this.state.data.items.map(function(item, index) {
return {id: item.id, order: index};
});
// send request
$.ajax({
url: '/todos/set_order.json',
dataType: 'json',
type: 'POST',
data: {order: JSON.stringify(ordered)},
success: function(data) {
// update list of todos from fresh db
this.setState({data: data});
}.bind(this),
error: function(xhr, status, error) {
console.log('An error ('+status+') occured:', error.toString());
}.bind(this)
});
},
render: function() {
return (
<div>
<header className="todoheader">
<h1>Todos</h1>
</header>
<TodoForm onTodoSubmit={this.saveTodo} />
<TodoList
data={this.state.data}
onSetStatus={this.setStatus}
sort={this.sort} />
<footer className="todofooter">
<span className="todofooter__counter">
{this.state.data.items.filter(this.notDoneFilter).length} items left
</span>
<a href="#" onClick={this.clearAll} className="todofooter__completeall">
Mark all as complete
</a>
</footer>
</div>
);
}
});