diff --git a/examples/todomvc/actions/FilterActions.js b/examples/todomvc/actions/FilterActions.js
new file mode 100644
index 0000000000..41ea3d40cb
--- /dev/null
+++ b/examples/todomvc/actions/FilterActions.js
@@ -0,0 +1,13 @@
+import * as types from '../constants/TodoFilters'
+
+export function showAll() {
+ return {type:types.SHOW_ALL}
+}
+
+export function showActive() {
+ return {type:types.SHOW_ACTIVE}
+}
+
+export function showCompleted() {
+ return {type:types.SHOW_COMPLETED}
+}
\ No newline at end of file
diff --git a/examples/todomvc/actions/index.js b/examples/todomvc/actions/TodoActions.js
similarity index 100%
rename from examples/todomvc/actions/index.js
rename to examples/todomvc/actions/TodoActions.js
diff --git a/examples/todomvc/components/Footer.js b/examples/todomvc/components/Footer.js
index 8ae9c59983..0a2bed5107 100644
--- a/examples/todomvc/components/Footer.js
+++ b/examples/todomvc/components/Footer.js
@@ -9,65 +9,79 @@ const FILTER_TITLES = {
}
class Footer extends Component {
+
renderTodoCount() {
- const { activeCount } = this.props
+ const { todos } = this.props;
+ const completedCount = todos.reduce((count, todo) =>
+ todo.completed ? count + 1 : count,
+ 0
+ )
+ const activeCount = todos.length - completedCount
+
const itemWord = activeCount === 1 ? 'item' : 'items'
- return (
-
- {activeCount || 'No'} {itemWord} left
-
+ return ( < span className = "todo-count" >
+ < strong > { activeCount || 'No' } < /strong> {itemWord} left < /span>
)
}
+ onShow(filter) {
+ switch (filter) {
+ case SHOW_COMPLETED:
+ this.props.filterActions.showCompleted();
+ break;
+ case SHOW_ACTIVE:
+ this.props.filterActions.showActive();
+ break;
+ default:
+ this.props.filterActions.showAll();
+ }
+ }
+
renderFilterLink(filter) {
const title = FILTER_TITLES[filter]
const { filter: selectedFilter, onShow } = this.props
-
- return (
- onShow(filter)}>
- {title}
-
+ return ( < a className = { classnames({ selected: filter === selectedFilter }) }
+ style = {
+ { cursor: 'pointer' } }
+ onClick = {
+ () => this.onShow(filter) } > { title } < /a>
)
}
+ onClearCompleted() {
+ this.props.todoActions.clearCompleted()
+ }
+
renderClearButton() {
- const { completedCount, onClearCompleted } = this.props
+ const { todos } = this.props;
+ const completedCount = todos.reduce((count, todo) =>
+ todo.completed ? count + 1 : count,
+ 0
+ )
+ const activeCount = todos.length - completedCount
if (completedCount > 0) {
- return (
-
+ return ( < button className = "clear-completed"
+ onClick = { this.onClearCompleted.bind(this) } >
+ Clear completed < /button>
)
}
}
render() {
- return (
-
- )
+ return ( < footer className = "footer" > { this.renderTodoCount() } < ul className = "filters" > {
+ [SHOW_ALL, SHOW_ACTIVE, SHOW_COMPLETED].map(filter =>
+ < li key = { filter } > { this.renderFilterLink(filter) } < /li>
+ )
+ } < /ul> { this.renderClearButton() } < /footer>)
}
}
Footer.propTypes = {
- completedCount: PropTypes.number.isRequired,
- activeCount: PropTypes.number.isRequired,
- filter: PropTypes.string.isRequired,
- onClearCompleted: PropTypes.func.isRequired,
- onShow: PropTypes.func.isRequired
+ todos: PropTypes.array.isRequired,
+ todoActions: PropTypes.object.isRequired,
+ filterActions: PropTypes.object.isRequired
}
export default Footer
+
diff --git a/examples/todomvc/components/TodoItem.js b/examples/todomvc/components/TodoItem.js
index a892951842..fa75646384 100644
--- a/examples/todomvc/components/TodoItem.js
+++ b/examples/todomvc/components/TodoItem.js
@@ -14,6 +14,16 @@ class TodoItem extends Component {
this.setState({ editing: true })
}
+ handleClick(evt) {
+ evt.preventDefault();
+ // because of linkState call in render, field will get value from this.state.editValue
+ setTimeout(function () {
+ if(!this.state.editing){
+ this.refs.toggleCompleted.getDOMNode().click();
+ }
+ }.bind(this), 200);
+ }
+
handleSave(id, text) {
if (text.length === 0) {
this.props.deleteTodo(id)
@@ -36,11 +46,11 @@ class TodoItem extends Component {
} else {
element = (
-
completeTodo(todo.id)} />
-