Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b4a238f
REFACTOR STEP 1: Add React, ReactDOM, babel-standalone UMD scripts fo…
Jan 7, 2018
5b19952
REFACTOR STEP 2: Create our new Add Todo Form component with JSX simi…
Jan 7, 2018
7baa831
REFACTOR STEP 3: Render new component into the DOM
Jan 7, 2018
7d2ab6e
REFACTOR STEP 4.1: Add state to component
Jan 7, 2018
4d0845c
REFACTOR STEP 4.2: update state on user input to the text field
Jan 7, 2018
0334cf5
REFACTOR STEP 4.3: handle the input submit
Jan 7, 2018
008038d
REFACTOR STEP 4.4: Remove the jQuery event listener
Jan 7, 2018
5e07826
REFACTOR STEP 5: Add new Remove Completed Button component
Jan 7, 2018
12c1fbb
REFACTOR STEP 5.1: Update the jQuery to rerender RemoveCompletedButto…
Jan 7, 2018
8a6b208
Add UMD scripts for Redux and ReactRedux
Jan 7, 2018
3262146
Define the initialState for the redux store
Jan 7, 2018
4ce6dd8
Define the action that describes what happened, wrap it in an action …
Jan 7, 2018
1b8a4c0
Define the pure reducer function for updating the state
Jan 7, 2018
97b4de7
Use the Redux library to create the store with the reducer
Jan 7, 2018
3c565f3
Use the ReactRedux library to connect the RemoveCompletedButton compo…
Jan 7, 2018
34eb227
fix action creator
Jan 7, 2018
2145597
Include the redux store script
Jan 7, 2018
a0f6079
Pass the store to the RemoveCompletedButton component for connect
Jan 7, 2018
528d660
Change the jQuery to dispatch the setHasCompletedItems action instead…
Jan 7, 2018
9adab12
Update README
aporlando Jan 10, 2018
8b39395
Merge branch 'master' of github.com:aporlando/jquery-to-react into re…
Jan 10, 2018
5170fb3
Merge branch 'master' of github.com:aporlando/jquery-to-react into re…
Jan 10, 2018
575b192
Merge branch 'refactor' of github.com:aporlando/jquery-to-react into …
Jan 10, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions components/AddTodoInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class AddTodoInput extends React.Component {
constructor(props) {
super(props);
this.state = {
text: ''
};
}

handleInput(e) {
this.setState({ text: e.target.value });
}

handleSubmit(e) {
e.preventDefault();
addTodo(this.state.text);
this.setState({ text: '' });
}

render() {
return (
<form className="form-inline d-inline" id="addForm" onSubmit={this.handleSubmit.bind(this)}>
<input id="todoInput" type="text"
value={this.state.text}
onChange={this.handleInput.bind(this)}
className="form-control"/>
<button id="addTodo" type="submit" className="btn btn-primary mx-1">Add</button>
</form>
);
}
}

ReactDOM.render(<AddTodoInput/>, document.querySelector('[data-react-component="AddTodoInput"]'));
28 changes: 28 additions & 0 deletions components/RemoveCompletedButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class UnconnectedRemoveCompletedButton extends React.Component {
handleClick() {
removeCheckedItems();
}

render() {
if(this.props.show) {
return (
<button onClick={this.handleClick} className="btn btn-outline-secondary mx-1">
Remove Completed
</button>
);
}
return null;
}
}

function mapStateToProps(state) {
return {
show: state.hasCompletedItems
};
}
var RemoveCompletedButton = ReactRedux.connect(mapStateToProps)(UnconnectedRemoveCompletedButton);

ReactDOM.render(
<RemoveCompletedButton store={store} />,
document.querySelector('[data-react-component="RemoveCompletedButton"]')
);
17 changes: 10 additions & 7 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@
<h1>To Do List</h1>
<ul id="todos" class="list-group my-2">
</ul>
<form class="form-inline d-inline" id="addForm">
<input id="todoInput" class="form-control" type="text"/>
<button id="addTodo" type="submit" class="btn btn-primary mx-1">Add</button>
</form>
<button id="clearCompleted" class="btn btn-outline-secondary mx-1" style="display: none">
Remove Completed
</button>
<span data-react-component="AddTodoInput"></span>
<span data-react-component="RemoveCompletedButton"></span>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/redux@3.7.2/dist/redux.js"></script>
<script src="https://unpkg.com/react-redux@5.0.6/dist/react-redux.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<script src="store/index.js" type="text/babel"></script>
<script src="jquery/todo.js" type="text/javascript"></script>
<script src="components/AddTodoInput.js" type="text/babel"></script>
<script src="components/RemoveCompletedButton.js" type="text/babel"></script>
</body>
</html>
30 changes: 7 additions & 23 deletions jquery/todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,14 @@ function toggleComplete(todo) {
}
}

function removeCheckedItems() {
$('#todos input:checked').closest('li').remove();
maybeHideDeleteAll();

}

function maybeHideDeleteAll() {
var completedItems = $('#todos input:checked').length;
if(completedItems > 0) {
$('#clearCompleted').show();
} else {
$('#clearCompleted').hide();
}
store.dispatch(setHasCompletedItems(completedItems > 0));
}

// Attach the DOM events once the page has loaded
$(document).ready(function() {
// When the form input is submitted, add the todo item
$("#addForm").on('submit', function(e) {
e.preventDefault();
var input = $("input#todoInput");
addTodo(input.val());
input.val("");
});

// When the form input is submitted, add the todo item
$("#clearCompleted").on('click', function(e) {
e.preventDefault(e);
$('#todos input:checked').closest('li').remove();
$(this).hide();
});
});

20 changes: 20 additions & 0 deletions store/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// The initial state of our store
const initialState = {
hasCompletedItems: false
};

function setHasCompletedItems(hasCompletedItems = false) {
return {
type: 'SET_HAS_COMPLETED_ITEMS',
hasCompletedItems: hasCompletedItems
};
}

function reducer(state = initialState, action) {
if (action.type = 'SET_HAS_COMPLETED_ITEMS') {
return { hasCompletedItems: action.hasCompletedItems };
}
return state;
}

var store = Redux.createStore(reducer);