app.jsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. 'use strict';
  2. var Comment = React.createClass({
  3. rawMarkup: function() {
  4. var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
  5. return { __html: rawMarkup };
  6. },
  7. render: function() {
  8. return (
  9. <div className="comment">
  10. <h2 className="commentAuthor">
  11. {this.props.author}
  12. </h2>
  13. <span dangerouslySetInnerHTML={this.rawMarkup()} />
  14. </div>
  15. );
  16. }
  17. });
  18. var CommentForm = React.createClass({
  19. getInitialState: function() {
  20. return {author: '', text: ''};
  21. },
  22. handleAuthorChange: function(e) {
  23. this.setState({author: e.target.value});
  24. },
  25. handleTextChange: function(e) {
  26. this.setState({text: e.target.value});
  27. },
  28. handleSubmit: function(e) {
  29. e.preventDefault();
  30. var author = this.state.author.trim();
  31. var text = this.state.text.trim();
  32. if( !text || !author ) {
  33. return;
  34. }
  35. this.props.onCommentSubmit({author: author, text: text})
  36. this.setState({author: '', text: ''});
  37. },
  38. render: function() {
  39. return (
  40. <form className="commentForm" onSubmit={this.handleSubmit}>
  41. <input
  42. type="text"
  43. placeholder="Your name"
  44. value={this.state.author}
  45. onChange={this.handleAuthorChange}
  46. />
  47. <input
  48. type="text"
  49. placeholder="Say something..."
  50. value={this.state.text}
  51. onChange={this.handleTextChange}
  52. />
  53. <input type="submit" value="Post" />
  54. </form>
  55. );
  56. }
  57. });
  58. var CommentBox = React.createClass({
  59. getInitialState: function() {
  60. return {data: []};
  61. },
  62. loadCommentsFromServer: function() {
  63. $.ajax({
  64. url: this.props.url,
  65. dataType: 'json',
  66. cache: false,
  67. success: function(data) {
  68. this.setState({data: data});
  69. }.bind(this),
  70. error: function(xhr, status, err) {
  71. console.error(this.props.url, status, err.toString());
  72. }.bind(this)
  73. });
  74. },
  75. handleCommentSubmit: function(comment) {
  76. var comments = this.state.data;
  77. comment.id = Date.now();
  78. var newComments = comments.concat([comment]);
  79. this.setState({data: newComments});
  80. $.ajax({
  81. url: this.props.url,
  82. method: 'POST',
  83. dataType: 'json',
  84. data: comment,
  85. success: function(data) {
  86. this.setState({data: data});
  87. }.bind(this),
  88. error: function(xhr, status, err) {
  89. this.setState({data: comments});
  90. console.error(this.props.url, status, err.toString());
  91. }.bind(this)
  92. });
  93. },
  94. componentDidMount: function() {
  95. this.loadCommentsFromServer();
  96. setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  97. },
  98. render: function() {
  99. return (
  100. <div className="commentBox">
  101. <h1>Comments</h1>
  102. <CommentList data={this.state.data}/>
  103. <CommentForm onCommentSubmit={this.handleCommentSubmit}/>
  104. </div>
  105. );
  106. }
  107. });
  108. var CommentList = React.createClass({
  109. render: function() {
  110. var commentNodes = this.props.data.map( function(comment) {
  111. return (
  112. <Comment author={comment.author} key={comment.id}>{comment.text}</Comment>
  113. );
  114. });
  115. return (
  116. <div className="commentList">
  117. {commentNodes}
  118. </div>
  119. )
  120. }
  121. });