JavaScript is pretty amazing you can Create All sorts of Handy components like Um tabs accordions or sliders but you Don't have to stop there you can create Much more complex things like for Example a to-do app and this is one of Those things that pretty much everyone Uses nowadays either it's you know on on Our phones or on the web or on the Desktop and if you ever wanted to create Something like this yourself but you Didn't know how Well you're in the right place because That's exactly what you learn in this Course more specifically we'll be Creating this it's a very simple app That allows us to add tasks to edit them To mark them as complete and finally to Delete them and all of this happens with The help of some CSS some vanilla JavaScript and the browser's local Storage because everything we do is Saved locally so it's available to us Anytime but hey if we're just meeting my Name is Adi and I'm a professional web Designer and developer now we're gonna Split this course in three parts first We'll write the HTML for the app then We'll make everything look good by Writing the CSS and finally for the most Important part we'll use JavaScript and The browser's local storage to power up Everything I think this is is a great
Exercise if you want to learn front-end Development because you'll be learning Some CSS and JavaScript techniques that Are going to be really helpful to you in The long run with that said this is not Exactly a course for beginners because You do need to be at least familiar with CSS and with JavaScript to Um to make this work basically to Understand everything we're doing also Another note This tutorial is not exactly focused on Accessibility because we're on short on Time we're going to be focusing more on The JavaScript aspect of it and we'll Kind of a forego some of the Accessibility issues that that should be Addressed when building something like This now before we get started I would Like to thank the sponsor of today's Video which is envato elements here you Can find tons of useful resources like Fonts icons UI kits WordPress themes Music stock photos and much more for Creatives like me this is an awesome Resource because all the assets have Simple commercial licensing and you're Not bound to any contract therefore you Can cancel whenever you want so if You're interested check out the link in The video description alright let's get The ball rolling and start building our App by first writing the markup Before we get started I would just like
To mention that this video is based on a Tutorial written by Mr George martsoukos And you'll find a link to the written Tutorial down in the video description Along with links to any other resource That I used and if you want to follow Along I also included a starter kit that Will give you the exact code that I'll Be working on in this video oh and don't Forget to subscribe to another test Plus For more free courses and tutorials just Like this one alright let's write some Code now in the downloadables for this Course you'll also find a figma file and That will be um using to create and Style our to-do app and this looks or The app looks something like this very Very simple on the top we have a header Which also contains our form that we're Going to use to type in the name of the Task and then here we have the some Statistics like the number of remaining Tasks so how many are unchecked the Number of completed tasks and also the Total number of tasks the task itself Has A check mark to indicate whether or not It's completed Task name and then a close button or a Delete button that we can use to delete The task and this is what it looks like On mobile and on desktop Very similar except the stats are now Placed on the site like so in vertical
Orientation alright so with this in mind Let's get to coding so I have The starter kit right here we have an Index HTML We have an app.js and an app CSS which Just contains some starting CSS uh to Get things moving and if we open the Index.html you'll see that we have a Blank page basically but I am loading a Reset file modern normalize I am loading A fig tree as a Google font and I'm also Loading the app CSS and app.js so let's Go ahead and open a live server so we Can see what we're doing in a real time And let's start by defining the header So we'll say header with an ID of main Header and inside we'll use a div class Container because I want to be able to Center this content on the page and also Give it a proper width and we'll do an H1 that says today and then we have the Form And we'll give this an ID of to do form Now inside Will have an input type text and we'll Give it a name Of Task name And also set a placeholder that says Something like this buy groceries and Then finally we'll set autofocus So that when we refresh the page the Focus is already on the actual input and As you can see this is already styled
And I did that on purpose I didn't want To spend too much time writing the CSS For certain elements on the page like This form basically but instead when We're going to write the CSS I'm going To show you how to style the actual Tasks because we have a little bit more Work to make these custom so that's the Uh the input now let's also add a button And the button will be of type submit And it's just going to say add task like So okay now We're done with the header Let's create the main content so I'm Going to create a section I'm going to Create a div class container and I'm Going to give it an ID of main content And then we'll create these statistics Okay so each statistic will be a list Item so let's create a list with a class Of stats And then each list item will have two Spans inside one span says Remaining and the other span which will Actually give an ID of remaining tasks I Will initialize these with zero so now Let's paste these two more times and This will be for completed and this will Be for Total like so then after the stats list We're going to have the to-do list so Again you will with a class of to do's And then we're going to say list item And then let's see exactly what we have
Inside Uh one of these tasks right so let me Just hide uh hide the UI here so we have What it looks like to be a radio button But we'll actually use check boxes we Have the name of the task and we have This close button so in here inside each List item we'll start with a div and Inside will have an input type check box And don't worry if the end result looks Like a radio button will actually style This and we'll give it a name of tasks And we'll give it an ID of let's say one And then we'll use a span for the text Content okay and inside uh we're just Gonna say for example task one then We're going to use a button and we're Going to give it a title of remove task We're also going to give it a class of Remove task And inside based on the design here we Need to place this X this icon right now we could export This as an image and just load the image In here but I'm not using Any kind of Um image in this code so we're gonna Keep things nice and simple and because This is an SVG I can just copy the SVG Code and I can paste it in my code Editor and that looks something like This okay so now if we take a look you Can see that we have the checkbox we Have the task name and we also have the
Close button of course we need to uh to Style these a little bit more so let's Actually Uh duplicate this One more time and I'll set an ID of two And the span will say task two now this Will not be hard coded these uh list Elements we will be generating them from JavaScript later on but for now we need Them hard coded in the uh HTML file so We can style them properly and once That's done let's uh go ahead and finish Up the markup by creating the footer and I'm going to use a container class and Just create a paragraph and a small Element for the footer text so that's All the markup that we need very simple It's just a demo app and I don't want to Spend too much time on this because You're probably more interested in the In the JavaScript code so with the app Markup complete now it's time to focus a Little bit on the CSS side to make those Tasks look just like our initial design So let's go ahead and do that next So let's get straight into this let's Open up the app CSS and here under the To-do list section Let's start with the parent element And we'll say margin bottom for Rems and This is just to create a bit of distance Between the two do's and the footer Now let's have a look at how these are Supposed to look like based on our
Design so a box with rounded Corners White as as the background everything is Aligned to the center and then when we Have a completed task we change the Color of the text we change the icon Here And also the color of the background and Of course we also have a bit of distance Between these uh these tasks So let's start by targeting Each list item and we'll say this uh Background color Uh White like so let me actually make This A lot bigger so you can see what we're Doing uh let's do the Border radius I'm Using a global variable there or a CSS Custom property let's create the spacing Between them so margin bottom we'll do One REM Uh let's also add a bit of padding 1.5 Ram top and bottom one ram To the side like so now to properly Display uh the contents one next to the Other and also align them to the middle We're going to be using flexbox so I'm Going to say display Flex And let's say justify content space Between And this will basically push the first Group to the left and the button to the Right And let's do a line items to the center So everything is Center aligned okay now
If you remember the structure for uh Each uh to do item is a div which Contains the input and the text and then The button now the div We need to use flexbox on that as well To align uh the contents inside to the Center So we're going to say To Do's list item div display Flex And align items Center and also let's Set a gap of 0.75 Rams to create a bit Of spacing between the check mark and And the text and let's also create a Style for the completed task so when it Says list item let's add a class of Complete So that we can style it So I'm going to say to use a list item With the class of complete Here we're going to change the Background color to color disabled I Have a variable defined at the top of The page like so Let's set the text decoration to line Through So that's the text is crossed off and Let's also change the color of the text To Uh color text disabled Like so perfect now let's see about this Checkbox because our design Shows Um an empty circle As a default and then a circle with a
Check mark inside it for uh when it's Checked So how exactly do we do that well If you remember we are using check boxes Right not radio buttons but the thing is You can style a checkbox to look like a Radio button or to look like anything You want basically and it's actually Pretty easy to do so what I'm going to Do is uh Target the input type checkbox And Inside I'm going to start with this Appearance none and that's going to Remove all the default styling from that Element Uh let's continue by setting background Color to transparent And by setting the margin to zero so now It's a complete reset Now let's build it The way we want so I'm going to start by Setting width and height to 1.5 ramps Like so let's give it a border we're Going to say two pixels solid and we're Going to use a color called color text And actually this needs to be inside a VAR Color text like so okay so now we have a Nice border let's make it round I'm going to set the Border radius To a hundred percent So now we have a circle awesome now when It's checked I want to display This check mark inside it right in the
Middle okay so to do that I'm actually Going to Define some additional Styles Here I'm going to say display to grid And I'm gonna Set Place content in the center you can Do this with flexbox but using grid is Easier because we can use this property Called Place content and it's going to Center it both horizontally and Vertically now how exactly do we add That checkbox well it's really easy to Do with a before pseudo element so I'm going to say input type checkbox B4 And I'm going to set the content for now Let's say x okay and as you can see that X is placed right in the middle it Doesn't look like it's in the middle Because currently it's um it's a piece Of text it has a different line height So it's not actually uh it doesn't Appear to be in the center but instead Of this x we need to put this check mark And we can do that by copying it as an SVG and I'm not sure why figma won't let Me do that right now Usually in figma you do have an option To copy as As SVG so you copy that SVG code and Then you use a tool called URL encoder For SVG so what you do is you basically Insert the SVG here and that's gonna Give you a ready to use format for CSS And that format looks something like This so you'll say content
URL And then that SVG which you can paste Right here will be transformed into Something like this so you paste that in You save And now we have the check mark being Displayed right there in the middle of My circle it's pretty hard to see right Now because we need to make some Additional uh changes to the CSS and let Me actually see why uh figma won't let Me copy an element as an SVG I'm actually very very curious so Let's say I want to go here And copy this as an SVG yeah so weird Uh what if I open up my icon app right So let's say I want to copy this I'm going to copy the SVG code from here Okay just to to show you how this Thing's how this thing works right so When you insert the SVG code in it it Gives you the encoded format basically Or ready for CSS and you just copy that From here And you put it right here where it says Content in the studio element so this is A very handy tool you can find a link to It in in the video description all right So now that we have the uh before pseudo Element all set up uh let's actually Hide it by default and for that we're Going to be using transforms And I'm going to use scale and I'm going To set that to zero so we're gonna
Shrink it all the way to zero And we're going to add a transition I'm Going to be using the global transition That I defined right here on the top Which is transition all properties 0.2 Seconds ease in and out So now back here let's target the Checked state of the checkbox so I'm Going to say input type checkbox checked And here we gotta do two things first of All change the background color to color Text disabled and also change the Border Color to the same value color text Disabled okay so now when I click on This checkbox As you can see it changes state And now we just have to display the Check mark Inside so let's actually uh Copy this and here it checked and we'll Target the before pseudo element and We'll just set a transform scale to one And would you look at that Now we're actually missing the Transition here to make everything Smooth I almost wrote smooth there so I'm gonna Load in my Global transition so now Checking or unchecking this checkbox Which looks like something else happens With a nice transition Very cool what else let's see about this Button okay so I'm gonna say to Do's List item button first of all let's get
Rid of the border so border zero uh Let's set a padding of 0.25 Rams and Let's place the X icon right in the Middle for that we'll be using display Grid again and place content Center Like that and let's set the background Color To transparent because I just want to Display the SVG now currently we cannot See the SVG because we need to give it a Width and a height so I'm going to say To Do's list item a button SVG set the Width to 1.25 Rams set the height to the Same Value And just like that we now have a visible X Icon now let's make this a bit more Interactive and add some hover and Active States so for that let's take a Look at the structure of the SVG first So we have SVG and then each of the Lines in the x is represented by a path Which has a stroke color So in CSS We can say to Do's a list item button Let's target the hover state of the Button and then we'll Target the SVG Path and we'll change its stroke color To color text so let's see if that works Great let's uh add a nice transition so Let me just copy this And I'm gonna Target
Just the path And I'm going to set a transition to the Global transition That's better and when the button is Clicked so We're targeting active Uh we can simply do a transform scale Let's say we shrink it by 80 percent And let's actually Shrink the entire SVG Like so And we don't need to add a transition to This because I think the way it looks uh Now is just a right now we're almost Done we just have one more element to Take care of and here's the thing this To-do app allows us to edit the tasks The tests that are not completed by Simply clicking On the task name And to achieve that the elements that Displays the test name needs to have a Special attribute called content Editable So if we go to task 1 In the span I can type content editable And I can Make it equal to true or I can just Leave it like so it has the exact same Effect and you'll see that now when I Click inside here I can Change this to whatever I want Right but I also want to style uh the
Way it looks when it's edited and we Have that style Right here in Figma and it's this one right here we Have just a tiny bit of padding Around the element Rounded corners and a different Background color so the way to do that In CSS Is the following way We're going to Target This span And we're going to add a padding of two Pixels by default we're going to add a Border radius of well we'll just use the Global border radius which is 6 pixels And let's also add a transition because We're going to need it okay now by Default you won't see much of a Difference Because we also need to change the focus State So we're going to say to Do's list item Span Focus we're going to change the Background color to the color of the Body which is this light blue And let's also get rid of that outline Okay so now when we focus it You can see that we changed the Background And then uh it would be nice to create a Separate style for when we hover on the Element uh to let us know that hey you Can actually edit uh this bit
So we can say to Do's list item span With the attribute of content editable Yeah on Hover we're going to change the Background color to Color body So now you'll see that when we hover With our Mouse Uh that background changes but of course It doesn't change here because this is Not editable right I can click inside But if it doesn't have that attribute Then I cannot edit The element but this one has so I can click inside And I can edit its contents and I was Supposed to have a transition here so uh Span TR I meant to say transition here Not transform Okay so that looks much much better Okay so that's the CSS that we have to Write basically pretty simple I wanted to focus more on this section Right here because I think uh we used Some some interesting techniques for Creating custom uh looking check boxes But now that everything is done on the CSS part we need to make this functional Right so we have a good looking app but Nothing works on it it just sits there Doing nothing so let's address that by Writing some JavaScript code As I mentioned earlier in this course We're going to be using vanilla
JavaScript and also the browser's local Storage uh to save our tasks basically So when we refresh the page uh the tasks Will still be there but how exactly do We create a task and add it to the Browser's local storage well To figure that out let's open up the App.js file and we're going to start by Getting some Dom elements because these Are elements that we're going to be Referring to a lot so we're gonna place Them or reference them in constants So first we'll get the to-do form I'm Going to use document query selector to Do form and this is referring to this Element right here that we defined in Our markup then we need to get the to-do List same deal document query selector Uh and this has the class of to Do's Then we have a constant for a total Tasks and this will of course Reference total tasks which is this Element sorry this element right here if You can remember in HTML we defined a Span with an ID of total tasks let's do The same for The remaining and completed so this is For completed and this is for remaining Perfect Uh what else Let's also get the main input and that's Going to be uh to do form Input we just have one so we don't need To uh to give it an ID or anything like
That and finally let's create A variable Called tasks That equals to Json dot parse local Storage Get item tasks And don't worry I'll explain what this Is doing in just a little bit or An empty array So here's how the local storage works And if we go to the browser this is uh Firefox but This basically Works in any browser in Firefox if we go to the if we open up The developer tools and we go to storage And we look at local storage for our Website we can say that we don't have Anything set up just yet we can do that Manually right we can give it a key For example test and we can give it a Value For example hello right so the data for This item in local storage is test and Hello and this will remain even if I Reload on the page that I'm currently in It's just a way to save custom Information in the browser now the way To get and set information in the local Storage from JavaScript is by using The local storage object and we have Some methods here get item and set item Okay so let me just delete this for uh For now and we actually have a an error Here
I did a little typo there okay so what We're doing With this variable is we're saying hey Use the Json object and then parse it And as an argument we're saying Go into the local storage and search for Something called tasks Okay so if we find them then take those Turn them into an array and place them In tasks otherwise tasks will be equal To an empty array pretty simple right Now How do we create A task and place it in local storage Well for that we type something in And we click add task so in JavaScript We need to start by listening to the Submit event in the form So I'll say to do form add event Listener submit And here we'll pass in this function Which takes e or you know you can call This whatever you want and this is the Event and we're going to say e dot Prevent default and this allows me to Skip or cancel the default submission of The form next step is to get the input Value the one that I type here so I'm Going to define a constant called input Value and that's going to be equal to Main input dot value like so next we'll Do a simple check we say if Input value Is blank then we just return We exit the
Function now What moves Beyond this point or what Follows Beyond this point will happen Only if we have an input value so we Start by creating an object for the task So we say constant let's call it task And let's create a new object and let's Set some Properties for that object we'll give it An ID and for the ID you know we can Create whatever kind of ID we want but An easy way is to say new date dot get Time and I'll show you how that looks in Just a little bit Will also give it a property a name and That's going to be The value that we got from the input And another one a Boolean called is Completed and by default this is set to False Okay so now Let's actually do a console log For the task and you'll see that when I Type something in Hello This creates an object With an idea of one six six seven three Eight and blah blah blah blah name is Equal to hello which is the text that I Just entered and is completed is set to False by default now what is up with This ID well It's generated Using the date object so every time
We're creating a new task we're getting The current date in what's called Unix Time it's also known as Epoch time But basically This uh this string of numbers that you See here uh represents the number of Seconds That have elapsed since 12 o'clock Midnight UTC January 1st 1970. don't ask me why exactly this date In particular but it's just how it is so If I'm gonna create another task now You'll see that the ID is different Because we now have this exact amount of Seconds that have elapsed since January 1st 1970. So this is a great way of of creating a Unique ID now what do we have here well We have two tasks basically but these Are not saved anywhere right if I do a Refresh of the page We don't see anything else in the Console so let's actually save these Tasks these objects that we're creating Uh in the local storage first of all we Need to add the task object to the task Array this one here for that we'll say Tasks dot push and we'll pass in each Task that that we create And finally we'll say local storage set Item we'll give it a name of tasks and Then we'll pass in the tasks array but Here's the thing local storage only Supports strings so to convert that
Array into a string we're going to use Json Dot stringify and we'll pass in the Tasks array Okay so let's see How this works If I'm going to create A new task let's say task one And I go to local storage Now we can see that the script saved This task that I just created in local Storage and I can now refresh the page And it's still there Right so we have the object we have the ID we have the task name and is Completed false if I'm going to add Another one let's say task 2 hit enter Now in local storage I have two objects Saved that's pretty cool isn't it so now That these are saved in local storage We need to actually create them in the Page so for that let me just go back to The HTML And let's remove these Hard-coded tasks okay because we need to Create them from scratch using JavaScript And how do you do that well we call a Function called create task we pass in The task object that we created right Here and let's go ahead and create that Function and then uh finally I'll do a To the form reset and also main input Focus all right so now every time I add The task
Let's say task one The function create task gets called And then the form and the input are Reset and focus respectively so now Let's work on this function the create Task function what we need to do here is Create a list element I'll give it the Proper attributes like ID and if the Task is completed give it a class of Complete I'll create the correct markup and then Add it to the HTML or add it to the page So let's start by creating a constant For the task element and that's going to Be documents create Element list item let's set the ID so We're going to say task element Dot set attribute ID and we're going to Set it to task.id So task is the object received by the Function And if you remember the object contains ID As its property next we're going to do a Check if task dot is completed so if This is true then the task element will Also receive a class so class list add The class of complete next let's create The element markup so Define a constant Task element markup equals to we're Going to use back ticks for some string Interpolation here and the markup will Look something like this it's exactly Like the HTML we wrote except we're
Replacing some hard-coded values with These Expressions so instead of the ID Being hard coded we're actually using The task ID I'm all adding something Here If the task is completed then I add the Attribute of checked and then in the Span If the task is not completed I add the Attribute of content Editable and then inside the span I just Add the task name and then for the Button I'm changing the title to remove the Task name and then task And the rest is exactly the same I'm Using the same SVG code that I was using In the HTML now if you're not familiar With This way with the template literals Basically just go ahead and do a Google Search for that so JavaScript template Literals this basically allows us to use JavaScript inside of a string by using These back texts so once the markup is Complete uh we gotta do task elements so Our new elements in our HTML is going to Be equal to task element markup And then all we have to do is add this New element to our page for that we're Going to Target its parent which is To-do list We're going to use the append child Method and we're going to pass in task l
So let's save and now let's see if this Works let's go test one and now that's Added Test two Three four five and so on and so forth And if we take a look in local storage We can see that we have all the objects We have Task 1 task two we have task one Again because uh these are some of the Previous tasks that that I created so It's all in local storage but if I'm Gonna do a refresh now they are not Displayed they are still In local storage but we never told our Page to render them if they are in local Storage so let's go ahead and do that Right now now if you remember the very First thing we did here was to do a Json Powers and if there are items in local Storage place them in the tasks array But we never did anything with this So let's do that right now we're gonna Say if local storage dot get item tasks So if we have items in local storage Then We'll do the following tasks Dot we can use the map here to go Through each task so I'll say task and We'll pass in a function and that says Create task and then task so now if we Do a save we can see The script will render every single task That we have saved in local storage Because of these lines right here so
We're doing a check if we have items in Local storage then we go through each One saved in the tasks array using a map And for each task we call the function Create task and we pass that in pretty Cool right now one thing that we're Missing is The test counts because these are still At zero so let's write a function that Will actually count Everything we have Okay and that function we can call it Count tasks and it looks something like This first of all we need to determine How many tasks are completed so we'll Create a constant called Completed Tasks Array and this will be equal to tasks so This is the array where all of the Existing tasks are stored And we'll use the filter functionality To only display or to only get the tasks That have the is completed property set To true so We'll say tasks or task and the function Should basically say task Dot is Completed Equals true so what does filter do well It's very simple We apply filter to an array and we set Up a function now filter will go through Every single item in this array and for Each item it's gonna run this function
If the function returns true then that Particular item in the array will be Placed in the new array it's actually Pretty cool stuff so now all we can do Is update The stats that we have here So we can say total tasks Dot text content is equal to tasks Dot Length and since we have a small problem Here now we have a little bit of an Error all right so let's see total tasks Um Okay we're not actually calling this uh Anywhere so let's actually call this Task right after we create A task Like so so we'll say count Tasks so now We can see that we have eight tasks in Total one two three four five six seven Eight great So that's the total Number of tasks The completed tasks will be equal to Completed task array dot length Same thing right now we have zero Completed tasks so the number says zero And finally remaining tasks Will be equal to Tasks dot length minus completed tasks Or sorry completed task array.length Okay so remaining is basically total Minus completed great now let's see About removing a task
And we remove a task by clicking on the X button so then let's go right here And we're going to add an event listener On this entire task element and then We're gonna differentiate depending on The target of the click Okay so we'll do to-do list Dot Add event add event listener On click and we're gonna do the Following we have the event The Click Event that's being passed to this Function right So here we can say if e Dot Target dot Class list That contains remove task so in other Words If the element that I clicked on has the Class of remove task then we proceed and In our case the only element that has That class Is The button right Class remove task So in other words If I click on This button Then I move on with uh with the remove Function so let's go ahead and write That function but first we need to get The task ID so I'm going to create a Constant called Task ID and that's going to be equal to E Target dot closest list item
Dot ID because If we take a look In the inspector we can see that the ID Of the task is added to the list item Okay but we're actually clicking on the Button to remove and the button doesn't Have any kind of ID attribute so what we Do is we Get the button and then we get the Closest list item which of course is It's parent element and then we get the ID attribute So with this task ID we call the Function remove task and of course we Pass it To the function So let's go ahead and create That function let's pass in task ID of Course you can call this whatever you Want and then uh the way we're gonna Remove a task is the following first We're gonna take it out of the tasks Array then we're gonna update the local Storage and then we're gonna remove Add that task from the actual page so How do we do that First Let's remove it from the tasks array We'll say tasks equal to tasks dot Filter remember tasks.filter returns an Array So we're going to filter task And the function we'll say the following Task.id is not equal to percent
Task ID we use percent to sanitize this A little bit just in case uh you know The the ID is uh is corrupted in some Way So what this basically does is if the ID Of the current task in the array doesn't Match Whatever I sent it then we return true And the current task that's being Verified is placed back in the tasks Array otherwise It's skipped so this allows us to Basically recreate the tasks array Without the one that we want to delete Now with this done let's update the new Tasks in local storage so we're going to Say localstorage dot set item tasks and Then again Json Stringify Tasks now let's remove the task from the Page so we're going to say document Get element by ID remember we have the Task ID being provided to this function And we can just say Remove And finally let's do a recount So count tasks All right So now let's also check out the local Storage and you can see that we have Quite a few tasks here So let's delete task one as you can see This is the very first object so when I Click this
Uh it appears that we have deleted Everything hmm hold on so what happens What just happened here okay so this was A a weird error that I encountered or a Weird Behavior Uh apparently if I was You know placing these in Curly braces for the function here Basically It was wiping out the entire array I Don't know why but using this notation So basically without the curly braces uh Seems to do the trick so let's Do another test here so let's say uh Demo one demo two okay so let's delete Demo two Now if we look in local storage yeah we Still have demo one in there Yeah really weird so you know this works Uh works just as well and let me Actually update this as well just so we Don't run into any more uh issues later On so accounting should still work just Fine all right moving on so uh this uh This is the function for removing the Task and it does basically two things it Updates the local storage it takes out All the tasks that we want to delete From the local storage and it also takes It out of the actual page by using the Remove here And then after we remove a task we of Course do a recount to see how many are Left but I also noticed one other Problem if I click directly on the on
The X here it doesn't work it doesn't Delete it now why is that well let's Take a look at how we're actually Triggering this remove Um function Or checking if the class list of the Item were clicking on contains remove Task and this works just fine when we Click on the Button but when we click inside the Button The script actually considers that we Clicked on the SVG or the paths inside The SVG and in which case those do not Contain the class of remove task so what We can do here to get around this Problem is to say or and I'm going to Copy this so or Etarget dot Parentelements.class list contains Remove task So this would work if we click on the SVG element yeah the parent of the SVG Element is the button and the button Does contain remove task but what if we Click inside the path inside the SVG Well in that case we got to do another Or here And we would say etarget dot parent Class dot parent class again so we're Going up two levels and with that in Place you'll see that this works no Matter where We click so I can click here I can click
Here I can click here I can click inside The actual SVG I can click here as well oh I actually Made a mistake here not parent class I Meant parent element that's why the last One was a bit Twitchy Okay so Let's try and do that again Yeah okay so now everywhere you click Um like inside or around that X will be Properly captured And the remove task will be executed all Right so what do we have so far we are Properly creating a task we are deleting A task but we still need to do two Things we need to be able to Update The task by changing the name and also To mark this as complete when we click On the checkbox So let's go ahead and do that right now For updating we'll do this To-do list Advent listener and I'm gonna listen for Input events And again we have the events that we can Pass in and then just like the remove Task we can grab the ID and we can call The update function so update task I'm Gonna pass in the task ID but also Uh the Target and you'll see why this is Important in just a little bit so the Update function looks something like This we are getting the task ID and We'll just call it El that's the event
Target first we need to find the task That is being edited right so we'll say Constant Task will be equal to tasks dot find and Again we'll pass in the task so we're Basically iterating through every single Element in the tasks array And in here We're going to say task ID is equal to Parse and task ID Basically this gives us The exact item from the tasks array that Matches the task ID that we passed to The update function so there are Basically two ways that we're updating The task either we clicked On the check box Or we edited the span element okay so we Do a simple check here if the task name Is editable Yeah we're getting the new content Otherwise It means the checkbox was clicked So we'll say if Element has Attribute uh content editable then we Say task.name will be equal to the new Content so element dot text content else It means we clicked on the checkbox so When that happens what do we do well First we need to define a couple of Constants we'll get the span element and We'll say element next Element sibling because if you remember
From the HTML Yeah the span Is right next to the input type checkbox So it's a sibling so we're getting the Span And we're also getting the parent so Constant parent equals to El closest Li So we're getting the closest list item Which is their parent element now what Do we do with these well we'll do the Following first of all if we click the Check box And it was unchecked we basically Checked it If it was checked and we clicked it we Unchecked it So what do we do is we say task is Completed equals to not task Is completed we basically switch The checked or unchecked state so then We say if task is completed then we make The text not editable so we say span dot Remove attribute content editable And we also add the class of complete to The parent element so we say parent dot Uh classlist dot add complete now in the Opposite scenario where an element is Checked but we uncheck it we do the Reverse we set the attribute content Editable to For example true And we remove The complete class from the parent So now with the task successfully edited
We gotta save it to local storage so we Say local storage Set item Tasks just like we've been doing so far Json dot stringify tasks and then let's Do another account because if we checked Or we completed a task these need to be Updated as well so now if we click this It's marked as completed it's no longer Editable and the status or these stats Have been updated and then if we uncheck It This is now considered under remaining Or is being counted on the remaining and It's now back to being editable So now you'll see that when I click in Here and I edit and I click outside it's Automatically Been saved to local storage let's go Ahead and delete this let's check out The local storage Yeah we have nothing in here Let's add a couple of tasks like so Let's do a couple of refreshes to make Sure everything is saved correctly in Local storage let's update task number Two Let's do a refresh Correct as being saved let's delete Task 3 and let's complete Now task three so Refresh everything is saved correctly Now in local storage and of course I can Also delete
A completed task And I can complete or uncomplete Any of the ones remaining now one thing If we Edit one of these tasks And we hit enter It goes on the next line I don't want That I want to do something so that when I hit enter after editing one of these Tasks It just removes the focus from that Element and I exit edit mode and it Doesn't go on the next line so the way To do that is to add another Event listener on the to-do list so We're gonna say to-do list dot add event Listener this time I'm going to be Listening for key down and just like With the others I'm going to pass in the Event to this function And we're going to do a quick check if The event dot keycode is equal to 13 Which is the code for the enter Then I'm going to say e Prevent default so this Will now allow me to hit the enter key But I will not go on or I will not Create a new line But I also want to exit edit mode so the Way to do that is to Simply say E dot Target Dot blur and the blur function Simply removes the focus okay so let's Say I'm gonna edit this hit enter
And I'm exiting edit mode And that's it that is our finished to-do List That we built using uh vanilla JavaScript and also By using the browser's local storage all Right and that's about it for this Course thank you very much for watching I hope it was useful and if you have any Questions please leave a comment down Below also if you want to grab a copy of The code that we wrote check out the Links in the video description as always Don't forget to also check out the Envato test plus YouTube channel for More content like this but also to learn About web design and web development and Much more it's all free so make sure to Also hit that subscribe button and give This video a thumbs up if you liked it I'm ADI and until next time take care Foreign [Music]