Skip to content

Commit

Permalink
Refactor components and state handling
Browse files Browse the repository at this point in the history
Add EditItem component
Rename components intuitively
  • Loading branch information
tribou committed Jul 3, 2015
1 parent 1e64d9e commit e4b415c
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 132 deletions.
5 changes: 2 additions & 3 deletions js/actions/TodoActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ module.exports = {
});
},

saveItem: function(text, index) {
saveItem: function(text) {
AppDispatcher.handleViewAction({
actionType: TodoConstants.SAVE_ITEM,
text: text,
index: index
text: text
});
},

Expand Down
146 changes: 81 additions & 65 deletions js/bundle.js

Large diffs are not rendered by default.

122 changes: 74 additions & 48 deletions js/components/Index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,74 +3,97 @@ var React = require('react');
var TodoStore = require('../stores/TodoStore.js');
var TodoActions = require('../actions/TodoActions.js');

var ItemRow = React.createClass({
var TodoItem = React.createClass({

render: function() {

return(
<tr>
<td>{this.props.item}</td>
<td>
<button type="button" onClick={this._delete} className="btn btn-link pull-right">
<span className="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</td>
</tr>
)
},

_delete: function() {
console.log('Deleting item key: ' + this.props.index);
TodoActions.removeItem(this.props.index);
}
});


var EditTodo = React.createClass({

getInitialState: function() {

return {
text: ''
};
}
},

render: function() {


if (this.props.item.editing) {

return(
<tr>
<td><input type="text" id="txtItem" onKeyDown={this._catchEnter} placeholder="Add new todo..." /></td>
<td>
<button type="button" id="remove" index={this.props.key}
onClick={this._save(document.getElementById('txtItem'), this.props.key)} className="btn btn-link pull-right">
<span className="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</td>
</tr>
)
} else {

return(
<tr>
<td>{this.props.item.text}</td>
<td>
<button type="button" onClick={this._delete} className="btn btn-link pull-right">
<span className="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</td>
</tr>
)
}
return(
<tr>
<td><input
type="text"
value={this.state.text}
onChange={this._onChange}
onKeyDown={this._catchEnter}
placeholder="Add new todo..."
className="form-control"
autoFocus={true}
/></td>
<td>
<button type="button"
onClick={this._save}
className="btn btn-link pull-right">
<span className="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</td>
</tr>
)
},

_save: function(value, index) {
TodoActions.saveItem(value, index);
_onChange: function(e) {
this.setState({
text: e.target.value
});
},

_delete: function() {
TodoActions.removeItem(this.props.key);
_save: function() {
TodoActions.saveItem(this.state.text);
},

_catchEnter: function(e) {
if(e.keyCode === 13) {
this._save(e.target.value, this.props.key);
this._save();
}
}


});


var ItemTable = React.createClass({
var TodoList = React.createClass({

render: function() {

var rows = [];
if(this.props.list) {
this.props.list.map(function(item, index) {
rows.push(<ItemRow key={index} item={item} />);
rows.push(<TodoItem key={index} index={index} item={item} />);
});
}

if(this.props.editing) {
rows.push(<EditTodo key={-1} />);
}

return(
<div className="table-responsive">
<table className="table">
Expand All @@ -84,11 +107,11 @@ var ItemTable = React.createClass({
});


var AddItem = React.createClass({
var AddTodo = React.createClass({

render: function() {
return(
<button type="button" onClick={this._add} className="btn btn-default btn-block btn-lg">
<button type="button" onClick={this._add} className="btn btn-link btn-block btn-lg">
<span className="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
)
Expand All @@ -99,12 +122,11 @@ var AddItem = React.createClass({
}
});

var TodoTable = React.createClass({

var TodoApp = React.createClass({

getInitialState: function() {
return {
list: TodoStore.getList()
}
return TodoStore.getList();
},

componentDidMount: function() {
Expand All @@ -116,18 +138,22 @@ var TodoTable = React.createClass({
},

_onChange: function() {
this.setState({
list: TodoStore.getList()
});
this.setState(TodoStore.getList());
},

render: function() {
return(
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-6 col-sm-offset-3">
<AddItem />
<ItemTable list={this.state.list} />
<div className="panel panel-default">
<div className="panel-heading">
<AddTodo />
</div>
<div className="panel-body">
<TodoList list={this.state.list} editing={this.state.editing} />
</div>
</div>
</div>
</div>
</div>
Expand All @@ -136,7 +162,7 @@ var TodoTable = React.createClass({
});

React.render(
<TodoTable />
<TodoApp />
, document.getElementById('app')
);

23 changes: 7 additions & 16 deletions js/stores/TodoStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ var CHANGE_EVENT = 'change';

// Define the store as an empty array
var _store = {
list: []
list: [],
editing: false
};

// Define the public event listeners and getters that
Expand All @@ -28,7 +29,7 @@ var TodoStore = ObjectAssign( {}, EventEmitter.prototype, {
},

getList: function() {
return _store.list;
return _store;
}

});
Expand All @@ -46,32 +47,22 @@ AppDispatcher.register(function(payload) {

// Add the data defined in the TodoActions
// which the View will pass as a payload
_store.list.push({
text: '',
editing: true
});
_store.editing = true;
TodoStore.emit(CHANGE_EVENT);
break;

case AppConstants.SAVE_ITEM:

// Add the data defined in the TodoActions
// which the View will pass as a payload

if(_store.list) {
_store.list.map(function(item, index) {
if(index === action.index) {
item[editing] = false;
item[text] = action.text;
}
});
}
_store.list.push(action.text);
_store.editing = false;
TodoStore.emit(CHANGE_EVENT);
break;

case AppConstants.REMOVE_ITEM:

// View should pass the item's index that
// View should pass the text's index that
// needs to be removed from the store
_store.list.splice(action.index, 1);
TodoStore.emit(CHANGE_EVENT);
Expand Down

0 comments on commit e4b415c

Please sign in to comment.