Skip to content

Commit 9fcc27b

Browse files
author
Matt Calthrop
committed
Add tutorial17
Also add lodash, along with bower.json
1 parent 216491d commit 9fcc27b

File tree

5 files changed

+160
-1
lines changed

5 files changed

+160
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
*~
22
node_modules/
3+
bower_components/
34
.DS_Store
45
*.iml
56
.idea

bower.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "react-tutorial",
3+
"description": "Code from the React tutorial.",
4+
"main": "server.js",
5+
"authors": [
6+
"mcalthrop"
7+
],
8+
"license": "MIT",
9+
"keywords": [
10+
"react",
11+
"tutorial",
12+
"comment",
13+
"example"
14+
],
15+
"homepage": "https://github.com/mcalthrop/react-tutorial",
16+
"moduleType": [
17+
"es6"
18+
],
19+
"ignore": [
20+
"**/.*",
21+
"node_modules",
22+
"bower_components",
23+
"test",
24+
"tests"
25+
],
26+
"dependencies": {
27+
"lodash": "~3.10.1"
28+
}
29+
}

public/index.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<script src="/node_modules/react-dom/dist/react-dom.js"></script>
1010
<script src="lib/babel-core.5.6.15.browser.js"></script>
1111
<script src="/node_modules/jquery/dist/jquery.js"></script>
12+
<script src="/bower_components/lodash/lodash.js"></script>
1213
<script src="/node_modules/marked/marked.min.js"></script>
1314
</head>
1415
<body>
@@ -21,6 +22,7 @@
2122
<!--<script type="text/babel" src="scripts/tutorial8-10.js"></script>-->
2223
<!--<script type="text/babel" src="scripts/tutorial11-13.js"></script>-->
2324
<!--<script type="text/babel" src="scripts/tutorial14.js"></script>-->
24-
<script type="text/babel" src="scripts/tutorial15.js"></script>
25+
<!--<script type="text/babel" src="scripts/tutorial15-16.js"></script>-->
26+
<script type="text/babel" src="scripts/tutorial17.js"></script>
2527
</body>
2628
</html>

public/scripts/tutorial17.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/* global $, React, ReactDOM */
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+
// TODO: send request to the server
60+
this.setState(this.getInitialState());
61+
}
62+
},
63+
render: function () {
64+
return (
65+
<form
66+
className="commentForm"
67+
onSubmit={this.handleSubmit}>
68+
<input
69+
type="text"
70+
placeholder="Your name"
71+
value={this.state.author}
72+
onChange={this.handleAuthorChange}
73+
/>
74+
<input
75+
type="text"
76+
placeholder="Say something&hellip;"
77+
value={this.state.text}
78+
onChange={this.handleTextChange}
79+
/>
80+
<input
81+
type="submit"
82+
value="Post"
83+
/>
84+
</form>
85+
);
86+
}
87+
});
88+
89+
var CommentBox = React.createClass({
90+
loadCommentsFromServer: function () {
91+
$.ajax({
92+
url: this.props.url,
93+
dataType: 'json',
94+
cache: false,
95+
success: function (data) {
96+
this.setState({data: data});
97+
}.bind(this),
98+
error: function (xhr, status, err) {
99+
console.error(this.props.url, status, err.toString());
100+
}.bind(this)
101+
});
102+
},
103+
getInitialState: function () {
104+
return {
105+
data: []
106+
};
107+
},
108+
componentDidMount: function () {
109+
this.loadCommentsFromServer();
110+
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
111+
},
112+
render: function () {
113+
return (
114+
<div className="commentBox">
115+
<h1>Comments</h1>
116+
<CommentList data={this.state.data}/>
117+
<CommentForm />
118+
</div>
119+
);
120+
}
121+
});
122+
123+
ReactDOM.render(
124+
<CommentBox url="/api/comments" pollInterval={5000}/>,
125+
document.getElementById('content')
126+
);

server.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ app.set('port', (process.env.PORT || 3000));
2222

2323
app.use('/', express.static(path.join(__dirname, 'public')));
2424
app.use('/node_modules', express.static(path.join(__dirname, 'node_modules')));
25+
app.use('/bower_components', express.static(path.join(__dirname, 'bower_components')));
2526
app.use(bodyParser.json());
2627
app.use(bodyParser.urlencoded({extended: true}));
2728

0 commit comments

Comments
 (0)