Skip to content

Commit 000b4e2

Browse files
author
Matt Calthrop
committed
Add tutorial20
1 parent 4cd451b commit 000b4e2

File tree

2 files changed

+151
-1
lines changed

2 files changed

+151
-1
lines changed

public/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<!--<script type="text/babel" src="scripts/tutorial14.js"></script>-->
2525
<!--<script type="text/babel" src="scripts/tutorial15-16.js"></script>-->
2626
<!--<script type="text/babel" src="scripts/tutorial17.js"></script>-->
27-
<script type="text/babel" src="scripts/tutorial18-19.js"></script>
27+
<!--<script type="text/babel" src="scripts/tutorial18-19.js"></script>-->
28+
<script type="text/babel" src="scripts/tutorial20.js"></script>
2829
</body>
2930
</html>

public/scripts/tutorial20.js

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/* global $, _, React, ReactDOM, marked */
2+
3+
var Comment = React.createClass({
4+
rawMarkup: function () {
5+
var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
6+
7+
return {__html: rawMarkup};
8+
},
9+
render: function () {
10+
return (
11+
<div className="comment">
12+
<h2 className="commentAuthor">
13+
{this.props.author}
14+
</h2>
15+
<span dangerouslySetInnerHTML={this.rawMarkup()}/>
16+
</div>
17+
);
18+
}
19+
});
20+
21+
var CommentList = React.createClass({
22+
render: function () {
23+
var commentNodes = this.props.data.map(function (comment) {
24+
return (
25+
<Comment key={comment.id} author={comment.author}>
26+
{comment.text}
27+
</Comment>
28+
);
29+
});
30+
31+
return (
32+
<div className="commentList">
33+
{commentNodes}
34+
</div>
35+
);
36+
}
37+
});
38+
39+
var CommentForm = React.createClass({
40+
initialState: {
41+
author: '',
42+
text: ''
43+
},
44+
getInitialState: function () {
45+
return _.clone(this.initialState);
46+
},
47+
handleAuthorChange: function (e) {
48+
this.setState({author: e.target.value});
49+
},
50+
handleTextChange: function (e) {
51+
this.setState({text: e.target.value});
52+
},
53+
handleSubmit: function (e) {
54+
e.preventDefault();
55+
var author = this.state.author.trim();
56+
var text = this.state.text.trim();
57+
58+
if (text || author) {
59+
this.props.onCommentSubmit({
60+
author: author,
61+
text: text
62+
});
63+
this.setState(this.getInitialState());
64+
}
65+
},
66+
componentDidMount: function () {
67+
// check if required properties have been set
68+
if (!this.props.onCommentSubmit) {
69+
throw new Error('onCommentSubmit property not set');
70+
}
71+
},
72+
render: function () {
73+
return (
74+
<form
75+
className="commentForm"
76+
onSubmit={this.handleSubmit}>
77+
<input
78+
type="text"
79+
placeholder="Your name"
80+
value={this.state.author}
81+
onChange={this.handleAuthorChange}
82+
/>
83+
<input
84+
type="text"
85+
placeholder="Say something&hellip;"
86+
value={this.state.text}
87+
onChange={this.handleTextChange}
88+
/>
89+
<input
90+
type="submit"
91+
value="Post"
92+
/>
93+
</form>
94+
);
95+
}
96+
});
97+
98+
var CommentBox = React.createClass({
99+
loadCommentsFromServer: function () {
100+
$.ajax({
101+
url: this.props.url,
102+
dataType: 'json',
103+
cache: false,
104+
success: function (data) {
105+
this.setState({data: data});
106+
}.bind(this),
107+
error: function (xhr, status, err) {
108+
console.error(this.props.url, status, err.toString());
109+
}.bind(this)
110+
});
111+
},
112+
handleCommentSubmit: function (comment) {
113+
$.ajax({
114+
url: this.props.url,
115+
dataType: 'json',
116+
type: 'POST',
117+
data: comment,
118+
success: function (data) {
119+
this.setState({data: data});
120+
}.bind(this),
121+
error: function (xhr, status, err) {
122+
console.error(this.props.url, status, err.toString());
123+
}.bind(this)
124+
});
125+
},
126+
getInitialState: function () {
127+
return {
128+
data: []
129+
};
130+
},
131+
componentDidMount: function () {
132+
this.loadCommentsFromServer();
133+
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
134+
},
135+
render: function () {
136+
return (
137+
<div className="commentBox">
138+
<h1>Comments</h1>
139+
<CommentList data={this.state.data}/>
140+
<CommentForm onCommentSubmit={this.handleCommentSubmit}/>
141+
</div>
142+
);
143+
}
144+
});
145+
146+
ReactDOM.render(
147+
<CommentBox url="/api/comments" pollInterval={5000}/>,
148+
document.getElementById('content')
149+
);

0 commit comments

Comments
 (0)