From b4a238f54f6f4dbdab7027e2e0f5b60f3113b8c2 Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sat, 6 Jan 2018 21:04:11 -0500 Subject: [PATCH 1/9] REFACTOR STEP 1: Add React, ReactDOM, babel-standalone UMD scripts for prototyping with React --- index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/index.html b/index.html index c94c32c..55e4d3f 100644 --- a/index.html +++ b/index.html @@ -20,6 +20,9 @@ <h1>To Do List</h1> </button> </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/babel-standalone@6.15.0/babel.min.js"></script> <script src="jquery/todo.js" type="text/javascript"></script> </body> </html> From 5b19952674f393003bd5bdb4e8d525bdcbb8d4d2 Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sat, 6 Jan 2018 21:43:17 -0500 Subject: [PATCH 2/9] REFACTOR STEP 2: Create our new Add Todo Form component with JSX similar to original mark up --- components/AddTodoInput.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 components/AddTodoInput.js diff --git a/components/AddTodoInput.js b/components/AddTodoInput.js new file mode 100644 index 0000000..6afbcb8 --- /dev/null +++ b/components/AddTodoInput.js @@ -0,0 +1,10 @@ +class AddTodoInput extends React.Component { + render() { + return ( + <form className="form-inline d-inline" id="addForm"> + <input id="todoInput" className="form-control" type="text"/> + <button id="addTodo" type="submit" className="btn btn-primary mx-1">Add</button> + </form> + ); + } +} From 7baa831108e3558e881b79de95ba0471db5ae7ac Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sat, 6 Jan 2018 21:52:06 -0500 Subject: [PATCH 3/9] REFACTOR STEP 3: Render new component into the DOM --- components/AddTodoInput.js | 2 ++ index.html | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/AddTodoInput.js b/components/AddTodoInput.js index 6afbcb8..ac07205 100644 --- a/components/AddTodoInput.js +++ b/components/AddTodoInput.js @@ -8,3 +8,5 @@ class AddTodoInput extends React.Component { ); } } + +ReactDOM.render(<AddTodoInput/>, document.querySelector('[data-react-component="AddTodoInput"]')); diff --git a/index.html b/index.html index 55e4d3f..3b97db2 100644 --- a/index.html +++ b/index.html @@ -11,10 +11,7 @@ <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> + <span data-react-component="AddTodoInput"></span> <button id="clearCompleted" class="btn btn-outline-secondary mx-1" style="display: none"> Remove Completed </button> @@ -23,6 +20,7 @@ <h1>To Do List</h1> <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/babel-standalone@6.15.0/babel.min.js"></script> +<script src="components/AddTodoInput.js" type="text/babel"></script> <script src="jquery/todo.js" type="text/javascript"></script> </body> </html> From 7d2ab6ef23546d23f59bb9bf2dc2bac5483ecf9c Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sat, 6 Jan 2018 22:27:47 -0500 Subject: [PATCH 4/9] REFACTOR STEP 4.1: Add state to component --- components/AddTodoInput.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/components/AddTodoInput.js b/components/AddTodoInput.js index ac07205..9d3c83b 100644 --- a/components/AddTodoInput.js +++ b/components/AddTodoInput.js @@ -1,8 +1,17 @@ class AddTodoInput extends React.Component { + constructor(props) { + super(props); + this.state = { + text: '' + }; + } + render() { return ( <form className="form-inline d-inline" id="addForm"> - <input id="todoInput" className="form-control" type="text"/> + <input id="todoInput" type="text" + value={this.state.text} + className="form-control"/> <button id="addTodo" type="submit" className="btn btn-primary mx-1">Add</button> </form> ); From 4d0845cb7110998eadbf85aee76e55a65deaccb1 Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sat, 6 Jan 2018 22:31:04 -0500 Subject: [PATCH 5/9] REFACTOR STEP 4.2: update state on user input to the text field --- components/AddTodoInput.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/AddTodoInput.js b/components/AddTodoInput.js index 9d3c83b..865e451 100644 --- a/components/AddTodoInput.js +++ b/components/AddTodoInput.js @@ -6,11 +6,16 @@ class AddTodoInput extends React.Component { }; } + handleInput(e) { + this.setState({ text: e.target.value }); + } + render() { return ( <form className="form-inline d-inline" id="addForm"> <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> From 0334cf52004a0abf798af1d731d21ec12b368bf5 Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sat, 6 Jan 2018 22:35:23 -0500 Subject: [PATCH 6/9] REFACTOR STEP 4.3: handle the input submit --- components/AddTodoInput.js | 8 +++++++- index.html | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/components/AddTodoInput.js b/components/AddTodoInput.js index 865e451..83357a0 100644 --- a/components/AddTodoInput.js +++ b/components/AddTodoInput.js @@ -10,9 +10,15 @@ class AddTodoInput extends React.Component { 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"> + <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)} diff --git a/index.html b/index.html index 3b97db2..d0e51c2 100644 --- a/index.html +++ b/index.html @@ -20,7 +20,7 @@ <h1>To Do List</h1> <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/babel-standalone@6.15.0/babel.min.js"></script> -<script src="components/AddTodoInput.js" type="text/babel"></script> <script src="jquery/todo.js" type="text/javascript"></script> +<script src="components/AddTodoInput.js" type="text/babel"></script> </body> </html> From 008038d441bd2d06ba650e98b95313db80f7b77e Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sat, 6 Jan 2018 22:38:19 -0500 Subject: [PATCH 7/9] REFACTOR STEP 4.4: Remove the jQuery event listener --- jquery/todo.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/jquery/todo.js b/jquery/todo.js index d5a0322..14e1ebe 100644 --- a/jquery/todo.js +++ b/jquery/todo.js @@ -50,14 +50,6 @@ function maybeHideDeleteAll() { // 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); From 5e07826e270494aa0575d32cb5aad9717c699268 Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sun, 7 Jan 2018 15:55:40 -0500 Subject: [PATCH 8/9] REFACTOR STEP 5: Add new Remove Completed Button component --- components/RemoveCompletedButton.js | 25 +++++++++++++++++++++++++ index.html | 5 ++--- 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 components/RemoveCompletedButton.js diff --git a/components/RemoveCompletedButton.js b/components/RemoveCompletedButton.js new file mode 100644 index 0000000..136f305 --- /dev/null +++ b/components/RemoveCompletedButton.js @@ -0,0 +1,25 @@ +class RemoveCompletedButton 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; + } +} + +RemoveCompletedButton.defaultProps = { + show: false +}; + +ReactDOM.render( + <RemoveCompletedButton />, + document.querySelector('[data-react-component="RemoveCompletedButton"]') +); diff --git a/index.html b/index.html index d0e51c2..920c01d 100644 --- a/index.html +++ b/index.html @@ -12,9 +12,7 @@ <h1>To Do List</h1> <ul id="todos" class="list-group my-2"> </ul> <span data-react-component="AddTodoInput"></span> - <button id="clearCompleted" class="btn btn-outline-secondary mx-1" style="display: none"> - Remove Completed - </button> + <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> @@ -22,5 +20,6 @@ <h1>To Do List</h1> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></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> From 12c1fbb69d878c375f16fbb9e494f179ae743718 Mon Sep 17 00:00:00 2001 From: Ali Orlando <aorlando@onshift.com> Date: Sun, 7 Jan 2018 15:56:54 -0500 Subject: [PATCH 9/9] REFACTOR STEP 5.1: Update the jQuery to rerender RemoveCompletedButton on dependent interactions --- jquery/todo.js | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/jquery/todo.js b/jquery/todo.js index 14e1ebe..abb1fa2 100644 --- a/jquery/todo.js +++ b/jquery/todo.js @@ -39,22 +39,17 @@ 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(); - } + ReactDOM.render( + React.createElement(RemoveCompletedButton, { show: completedItems > 0 }), + document.querySelector('[data-react-component="RemoveCompletedButton"]') + ); } -// Attach the DOM events once the page has loaded -$(document).ready(function() { - // 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(); - }); -}); -