Part 3: Deleting all 'To-dos'.
Now, let's say we want to clear our to-do list and start afresh. We could add a Delete all button. So let's do that. Here we've added a new button, and again styled it with some bootstrap classes. We've given it the MT5 class to give it a large top margin to keep it away from the Add button. We don't want our users to accidentally hit the Delete all button instead of the Add button.
The button has an on-click event hooked up to a Delete all todo's function, which we'll implement next. Let's now add this Delete all function. We only need two lines of code. One to clear the local storage JSON data item, one to empty the to-do list DOM element on our page. Let's refresh the page and see if it works. Good, our list is cleared and the JSON data local storage item has also been cleared.
We can add the items again, and then delete all just to test for sure that everything is working as expected. Good. But this seems a bit risky to have a button that obliterates our full to do list. Maybe we should add a confirmation prompt to Delete button in case the user accidentally presses it. Let's do this now. We use the JavaScript confirm function which returns a Boolean. True, if the user clicks OK, false, if they cancel. If the user clicks OK, we'll delete all our todos. Otherwise we won't. Let's check it's working.
Try it on a mobile device, chrome dev tools. This gives us a way of simulating different screen sizes, which is useful for testing a user interface for mobile or tablet devices. Switch to Mobile M. 375 pixels width. Then change zoom to 100%. You can see the elements on the screen look very small compared to the size of the screen. On mobile, we would expect the buttons to be at least half the width of the screen, for example. Much bigger than now.
So what's going on here? Well, the page isn't scaling well. It's still behaving like a page being viewed in a large screen. The content is scaling to fit without adjusting in layout at all. And we therefore get the effect of a zoomed out page on mobile. Let us fix this. Fortunately, this is really easy to fix. Let's add a viewport meta tag which ensures the page is scaled correctly, regardless of the screen size. Let us test this in the browser. Refresh page. That looks much better. The buttons are now accessible for a mobile device user.
We can make some improvements here though. With such a small screen, the Todo list of the left and the Add form on the right are fighting for space. So let's adjust our two column bootstrap layout, so the content flows better on smaller screens. To do this, let's change the bootstrap layout classes on our column divs. Here, we're changing the classes so that we will have a two column layout only on medium-sized screens and larger. For smaller screens and mobile devices for example, the columns will fall back to full width. Let us test this. Great, so things are looking pretty good.
Let's add a couple of todos to see how things stack up. Great, now let us check things still look okay in a larger screen. And our two columns are back. So far, we've built out an app using Vanilla JavaScript. And there is value in understanding how to use vanilla JavaScript to code from scratch. But there are other benefits to be gained, by using JavaScript libraries such as jQuery. jQuery is a JavaScript library that lets us implement things easier, often in fewer lines code. It also has the benefit of ensuring cross-browser compatibility, so we don't need to check on the browser specific implementations of JavaScript.
So let us update our app and replace some of our code with jQuery to demonstrate the differences and benefits. We'll also add some animations to enhance the user experience. With jQuery, animating elements is very easy. In order to be able to use jQuery, we need to include it on our page, we'll do this by referencing the jQuery files already hosted on a CDN. This is the same approach that we took with bootstrap. We'll include this code within the head section of our HTML document. Let's also tidy up some leftover commented code while we are looking through things.
Now, let us demonstrate how jQuery can be used to write more concise code. We'll make all the changes and then we'll walk through them, leaving the old comments in place but commented out, so we can compare the old with the new. First, let us look at our register event listeners function. We can definitely see some savings here. With jQuery, we can select all elements with the Delete class and bind the click event with them in one line. The code is less verbose or uses less words, and is therefore easier to understand. This is a great benefit. Our Delete todo function has changed slightly. We can identify the list item element and delete or remove it in a single line now, which is good. We are using jQuery's flexible selector features, to select the list item element with the data ID attribute value or the todo ID we've passed in line 57. jQuery simple remove function is also a little cleaner than the native JavaScript remove child DOM function.
Next, looking at our new todo function, we have managed to condense this function right down into a small number of lines. We've done this partially through the benefits of jQuery syntax, but also building the list item HTML in plain text instead of using native JavaScript DOM operations. This makes it a lot easier to see visually the HTML we are actually building. And as the benefit of shrinking many DOM operations into a single line of HTML preparation.
There is a small change in our Delete all todos function also. We are using the jQuery empty function to empty the todo list of all child elements. And lastly, we can now remove the variable mylist declaration near the top of our code, because we are now using jQuery element selectors, rather than native JavaScript.
Let us clean up our commented code now since we don't need it. Now, let's use jQuery to improve our user experience. We are going to add some subtle animations, which make it easier for the user to see when new todos are added and deleted. Instead of instantaneously appearing or disappearing, we are going to fade them in or out. Let us make one simple change first. Instead of using the jQuery remove function, let us use the jQuery fade-out function when we are deleting todo items. Let's save and refresh our browser, and try deleting our todo to see it in action. Great. It was as simple as using the jQuery fade out function. This function has other options so you can control the speed of the fading-out for example.
If you are interested in seeing what else you can control, have a look for examples and documentation online. Let us try making todos fade-in when we add them. Here, we need to approach things a little differently. We need to add the new list items to the list hidden initially, and then fade them in. To do this, we can use an endless tail on the new list items to set the display property to none. Then we use jQuery to fade it in. Let's save it and refresh and test it out. Great, works nicely.
To demonstrate another automation we could use, let us try slide-up instead of fade-out. Let us test that and try it out. So now we can see a nice effect of removing an item and the rest of the list items smoothly slide up to fill the space instead of jumping. One improvement we can make to the user experience and reliability of the app, is to add some basic validation to the Add form. Currently, if we hit add when the form is empty, it will add an empty todo. This isn't great. So let's fix this.
One way of addressing this, is to add a pair of if statements at the appropriate places where we add new todos. If a todo title is blank, we won't add a new todo. Let's test and verify it works. Great. We click Add when the input field is blank and nothing happens, as it should.
So let's summarize what we've accomplished in this tutorial. We have created a basic todo app using JavaScript that runs locally in our browser. We've used bootstrap to implement some basic UI styling. We have persisted our data locally by using the browser local storage. We've added jQuery to enhance our coding and enable us to add some simple animations. We've seen how to use the JavaScript console in Chrome Developer Tools, as well as viewing the contents of local storage. We've also seen how it's often necessary to refactor and simplify our code, as well as keeping it clean, and documenting it with comments when appropriate.
In terms of extending this app further, what if we wanted to use our todo list across different devices? That's where we need to introduce remote storage rather than just relying on our browser's local storage. A common way to do this would be to set up a remotely hosted server site component for this app, which consists of a RESTful API. Allowing us to read and write data to a database.
Building an API is not covered in this tutorial series but we will look at how to connect our app to an existing API later in this series. That's it for now. JavaScript is an awesome tool, and the more you use it, the more you'll be able to do with it. So keep practicing