Adding Todos - Build a Full CRUD Todo App with Tailwind CSS, JavaScript and Local Storage

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello there everybody, welcome back to another video and in today's video, let's continue our todo app series that we left off. So in the first two videos, we set up our project and we built the homepage respectively. Now let's work on how we can create a todo or add a todo. So I'm going to go ahead and open up the terminal and I'm just going to run npm run dev to start our development server. Remember, this is the command that we are going to use because we are using wheat and we're not using the normal HTML, CSS and JavaScript. All right. So if I click open this, this is how it looks like. We launched it and this is how we designed the homepage. Now what I want is when I enter something inside of here and I click add it, it should get added in the local storage. So we're not going to display that to do right over here in this video, we are going to have a separate video for that where we're going to create a full element with the delete and edit buttons. But right now what I want is just when I enter something and I click on add or I hit enter, that should appear in the local storage. So if I open up the developer tools and if I go to the application tab in here, we have local storage, which is empty right now. So I want this to have a todos key. So a key that will be todos and a value that will be the array of todos. All right, enough talk. Let's start working on it. So right over here inside of the HTML, we have the basic HTML code inside of the JavaScript file. We'd have nothing but the CSS import. So we'll start off by getting these elements from the DOM. So if you look closely, we have a form, we have an input and we have a button. So we, we want all three of these elements inside of our JavaScript and we can easily get those. So let's go ahead and do that. I'll say const todo form is what I'm going to call it equals to document dot get element by ID. If I go back in the HTML, we give this form an ID of todo form. So we go back, get element by ID and then parse in todo form as the ID. So we got the todo form. Now let's get the input and the button. So there's a trick. Instead of giving the ID to the input and the button, we gave it a name in the second video where we were building the homepage and I gave it the name for a purpose so that we can easily access them from the todo form. Let me show what I mean. So if I just go ahead and say const, uh, if I just say to do input, that will be equal to todo form index of todo input. So what this means is basically inside of the todo form, we already have the todo input available. So we can access it like, like so, or we can also access it with the dot notation like this. So it will be the same thing. And this is basically how JavaScript works. You can simply get the element like, so if you want to, if you can select the form successfully, you can also get the inner children with the name attribute. So that's the first step. We get the todo input. I'm actually going to use this notation bracket notation because it kind of looks different than the dot notation so that it doesn't look like a normal object. So we have the todo input. Now let's also get the button right over here. In this video, we are not going to use the button, but I'll just show by selecting it how it works. So it's the same thing. If I just copy and paste this line below, I can just rename this to submit a BTN and then go there and then submit BTN. That's the basic DOM manipulation. We're not manipulating the DOM, but at least we are getting it. All right. So that's the first step. Now the next step is how we can handle the form event. So basically when the user submits the form, which means when I enter something and if I hit add, the page refreshes. If I just show it again, you can slow it down. So the page refreshes and we don't want this behavior. Instead what we want is that whenever I submit the form, a new todo should get added to an array that I'm going to create just now and it should also go ahead and get added to the local storage. So coming back, what I can easily do is I could say todo form dot add event listener as simple as that. And I can add the submit event. Now you'll be confused a little bit that why did not add the click event on the submit button. So this button, why don't we add the click event? Well, because if I just go back to the app and if I enter anything, if I hit enter, the page refreshes, which means the form gets submitted on the button click as well as the enter key. But if I only add the event listener to the button, then the enter key won't work, which is bad for accessibility. I hope you get the point. Now, coming back, we have this submit event. What I can do is I can pass in a callback function right over here and I get the event back in here. So what is this arrow function? Well, this is when the form gets submitted. This function that I highlighted, this function gets called and we get back an event parameter in here. Now, what I can easily do is I could just say, well, event dot prevent default. What this is going to do is it's going to prevent the default behavior of the form, which is the page refresh. So if we come back and if I just enter anything random and I hit enter, you see nothing really happens. The form gets submitted, but the page does not refresh. And even if I click on the add button, still nothing happens. If I were to just go ahead and add, let's say console dot log, hello, I'd say form submitted instead of printing out hello. We come back. I'm going to open up the console right over here. And if you look closely, if I just enter anything, if I click on add, you see form submitted, which means the form gets submitted, but the page does not refresh. That's what we want. Now let's work on the actual part of how we can add a to do. This was just the setup of adding the to do. Now what I'm going to do is I'm going to create a class for the to do. What it basically means is I'm going to give it a structure of how the to do should look like. Now, if you're not familiar with the classes in JavaScript, I would highly suggest to learn that first. And I'll also recommend a video up top. But if you easily understand what's happening in this video, then you are totally fine because going on, I will also explain how the class works. So let's forget about all this because we wrote it for later on. Now what I can do is I could just go right over here and I could create a class. I'll just have some space so that we can write the class properly. So I'm going to use the class keyword class and then I could say to do and just open the curly brace. So all this is is just a blueprint of an object. So if you look to an object, this is how an object looks like with sort. Let's say an ID of something. And then we have a title, which is also something. So this is how an object looks like. And you can create an object simply by, let's say, assigning it to a variable. So now we have an object variable. But what we want is we don't want some random data inside of the object. We can create a structure to that object so that our object remains constant. What I mean by that is, let's say we are creating a to do, so I'm just going to go ahead and say to do. And then this to do object is going to contain the ID, the title, and the last property is going to contain is going to be completed. So let's do that. Completed is going to be either true or false, which means if the to do is completed or not, if it's checked or unchecked. So this is going to be our object. But what I'm doing is I'm creating a class so that our code stays consistent with the to do class so that our code stays organized with the class. Also if you don't want to use the class, you can totally skip it. It's all up to you. I personally prefer using class. And by using class, you will also learn some new concepts, which is a lot better than learning nothing. Coming back to the point, let's go ahead and work on the class. So inside of this class to do, what we are going to do is we're going to create a constructor. So I'm just going to go ahead and say constructor as simple as that. So this is a basically a function that is called whenever we create a new object using this class. So basically what it means is when I go ahead and do something like this, const to do or const to do equals to new and then use the to do class something like this. Whenever I use the new keyword, it calls the constructor. Now what we can do is we could just go ahead and say inside of the constructor, I want the title to be passed in because whenever a new to do is created, we want the new title. And what I can easily do is I could say this dot title is equal to title. Now this confuses a lot of people. Let me explain it easily. If you already know it, you can skip it. So this refers to this class right over here. And basically what I'm doing in this line is that this dot title, meaning whatever the new object is created, I want that title property on that object. So which means to do dot title. I want this property to be assigned to whatever the title pass the title we get from the parameters. So if I just say random title right over here, I just simply assign it to this to do dot title. So basically the new object that we create, it has the title property, which is equal to this random title. That's the first step. The next step is we could say this dot completed is going to be equal to false. Now why this? Because whenever we create a new to do, we do not want it to be checked. We want it to be unchecked. So we set this to false and finally we can set the ID. So if I go up top, I could say this dot ID is equal to, and then we want a random ID, a random UUID and a UUID is just a random string with all the randomness baked in. And we can simply generate a UUID by an inbuilt function that is called crypto dot random UUID as simple as that. So what this is going to do is it's going to assign the ID inside of our object to a random UUID. Whenever a new to do is created, the title will be the title that we pass in and the completed will be false. So now if I were to go ahead and say, Hey, to give me the to do dot and you see, we get intelligence. We get the completed, which is of type Boolean. We get the ID, which is of type this string. It consists of random strings. Then we have the title, which is Annie. Well, this is one because we are not using TypeScript, but it really does not matter right now. At least we get this intelligence. So this means that our to do object is now ready, but we don't want to create just one to do object. We want to go ahead and create an array of these to dos. So right now, what I'm going to do is I'm just going to say const to dos is going to be equal to an empty array. That's it. Inside of this array, we are going to store all these to do objects. Now comes the fun fart 😜. Now comes the fun part, adding this to do inside of our array. What we can do is you could go ahead and create a function. So let's do that function add to do. Let's just go ahead and do that. So inside of this function is where we are going to write the logic to add a to do in this array. And there's one little side tip I want to give is that if you just go ahead and do this type of thing, which is called a JS doc comment. So if I add this and then you say add type and then give it the type of open these curly braces and then give you the type of to do array. So if I do something like this, now this to dos, this array, this variable will be assigned the type of to do array. So basically this means it's an array of to dos. So this is going to help us a lot when we are coding. So we get a lot of intelligence and all that stuff. Coming back to add to do now, this is a function that we want to call in the funk in the to do form event listener. So I'm just going to hit save so that everything gets formatted nice and quick. Now this function add to do should be called right over here. So what we can do is we could just say add to do. What this basically means is when the form is submitted, I want to prevent the default behavior for step and then I want to add the to do. That's it. Coming back to the function, let's create a new to do. So I'm just going to say const new to do. You can call this variable whatever you want. I'm just calling it new to do and that will be equals to new to do. So basically we are using this constructor now and we have to pass in the title, which in our case should be this to do input. So if I just going to say to do input dot value. So whatever the user enters into the to do input, we are going to place it inside of the constructor, which means we get the new to do. And if I were to let's say console dot log the new to do, let's hit save. Coming back to the app, I'm just going to open up the console because we console log it and then I'm just going to say just random stuff, hit add and you see we get back a new to do. Now what this has inside of itself is the completed property set to false, the ID to a random string and the title, which is what we enter in right over here. Let's go back to where we were. So this is basically the object that we have created using that class. Now time to add it to the array. So coming back to the code, this is the array and we just want to push it inside of the array. So if I just hit to do is dot push and I'm just going to push the new to do. That's it. Let's get rid of the console log and I'm going to console dot log the to do's array now. Not the new to do, but the array so that we can visualize it. Coming back. If I were to just say, well, hey, to do one and hit enter. So you see, we had an array of inside there. We have one to do. And then if I expand this, you see we had the index zero, which has the title of to do one. Then if I were to say, uh, to do last, whatever, then we get the array with the two items, which is to do one and to do last. Now this works totally fine. But what if I were to just go ahead and enter in nothing in this input? And if I hit add, you see, it says, please fill out this field. But what if I just enter some spaces? And if I click on add, you see still it gets added. And this time we get these spaces. We don't want that to happen. So inside of our code, I could simply go ahead and here I could make an if checks. If the to do input that we have to do input dot value, dot value, dot trim is equal to an empty string. Now, what this means is that it's going to take the value of the input. It's going to trim it. And basically the trim method trims out the white spaces at the start and end. So you've got a clean empty string if they enter only spaces. So if using trim, we get an empty string, all we're going to do is just return nothing else. So what this means is if, well, the user enters an empty string or the user enters only spaces, we are going to return out of this function and none of this code will get executed then. All right. Coming back. Now if I were to go ahead and add some spaces, click on add, nothing happens. Click on it again. Nothing happens. If I add some content, click on add, it gets added. Congratulations. We get these spaces, which is kind of annoying as a user experience. So what I'm going to do is come back and just save it as the trim. So whenever I create a new to-do, I'm going to take the value and I'm going to trim it as easy as that. Let's come back. If I go ahead and add some spaces, click on add, nothing happens. If I add some content now, click on add and expand this. You see the content gets added successfully without these random spaces. Let's go ahead and add the start. And even if I add something at the end and let's change it a little bit, hit add. You see new to-do, the to-do index one has no spaces. Now that's it for the array. But what if I want it in the local storage? Right now, if I look back and the application tab, the local store is empty. So what we can do is to add it inside of local storage. Let me get rid of this. And then inside of our class, we are going to add methods to do that or functions in simple words. So inside of the class to-do, I'm going to go down there and I'm going to create a method. I'm going to call it save to-do. And inside of this function, now you don't need to use the function keyword if you are in the class. So if you do so. So coming back, just call, just give it a name, save to-dos. And then inside of here, all I'm going to do is just say local storage dot set item. And give it a name, which will be to-dos in our case. And then the value should be the to-dos array. So this array, we can access it easily right over here. There is no worry about that. So this array, we save it right over here. Now if we look back, this is of type to-do array. But if I go inside of set item, you'll see that we have to save it as a string. So what we can do is we could just use the json.stringify method and wrap this to-dos inside of there. So what this will do is it will convert this to-do array to a string. So it will be just a random string. So what this will do is if I go ahead in the console, I'm just going to say json.stringify. And then I'm just going to pass in an array of, well, 1, 3, 55.5, doesn't really matter. And that will convert this to a string. That's what we want. Coming back, this is the method save to-dos. And all we want to do is we want to call this method whenever we add a new to-do. But we cannot call it directly. Because if I decide to do that, to-do dot save to-dos, you see I don't get any intellisense. This is just the VS Code thing. So I don't get any intellisense to call this method. What I can do in that case, I can make this method static. So what this means is I can call this method directly from the to-do class. If the method was not static, then I have to go ahead and use something like new to-do dot save to-dos. I have to do something like this, which does not make any sense. So let's remove this. And now let's make this a static method. So if I go back, I could just go ahead and say to-do dot save to-dos. And you see we get the proper intellisense now. And simply call this function. Hit save. Now coming back, we aren't going to see nothing right over here. But if I just open the application tab, local storage inside the application tab, I'm just going to say A, B, C, D. Hit enter. You see we instantly get this update inside of local storage, which is our to-dos array. So this is an array with an object inside of it. And we successfully get it. So that's the first step. Now let's see how we can get this data from local storage. So coming back to the app, we already have set up this static method. Let's create one more static method that will be used to get the to-dos. So I could just go down. I could use a static keyword. I could say get to-dos. This is simply a function. And inside of here, I could say local storage dot get item. And we want to get the to-dos. Now this is going to return us a string or null. What we can do is we can again use the JSON object. So I could just go ahead and say JSON dot parse. And then we could just pass in this thing right over here. The JSON parse is going to take the string, and then it's going to convert that to an object or an array or whatever that is. So to demonstrate that, we are back again. I'm just going to go up top. This is the JSON stringify that we used. Now if I just take this string, and if I just call JSON dot parse, and inside of the parse method, if I just enter the string, you're going to see this returns back the original array. That's what we want. Back in our app, we have JSON parse is going to take this string, and it's going to convert this to an array. Now you see this can also return null. If the user is totally new to the website, which means they don't have anything inside of local storage, this is going to return to us null. What we can do in that case, if we could just go ahead and say, I'm just going to create a variable called todos, or I could, let's just call this lctodos, because we are getting this from the local storage. So it's called lstodos. Let's do that. So this can be either null, or this can be the array that we want. What we can do is if it returns null, we could just use the logical or operator, and we could just go ahead and say an empty array. So if this part is null, we are going to fall back onto the empty array, because that's what we want if it's totally null. Now after that, inside of the gettodos, all we are going to do is we're just going to return the lstodos. So all this is doing is just going to, whenever we call gettodos, we are going to get back the todos as an array. And we can use the same trick in here. So whenever we refresh the page, I'm just going to go ahead and console.log todos object right over here, this array that we created. And if you go ahead and look at it, it's an empty array. But if I go ahead and look inside of the local storage in the application tab, you see local storage is filled up with this data. Let's also add some more data. So you see now inside of local storage, we have a bunch of todos, but we don't have those inside of the array. So if I refresh, you see it's an empty array. So when the page reloads, what we can do is instead of setting this to an empty array, I could just say todo.gettodos. So basically I can call this method gettodos, that's going to return me back the local storage todos. Hit save. As you can see, we finally get an array with four objects, which is the thing that we have in local storage. Now if I were to go ahead and add a data, let's say hello, hit enter, this will get added to the local storage. But if I refresh, you see we get this array with five items. Now that is basically it to create a todo. Now there is one more thing that I would like to point out is if I just go ahead and enter some data and if I hit enter or if I click on add, you'll see it stays right there. We want it to be erased. What we can do is in that case, we just take the todo input and let's just go ahead and go down. We could just go inside this event function, this submit function, and then you could say todo input.value that will be equal to an empty string. What this will do is it will reset the value of the todo input. Coming back, if I were to add some data, click on add, you see it gets cleared. That's all we want to do. Now I hope this video helped you out. Please like it, share it with others and comment down below if you have any doubt, if you have got any suggestions for me. And finally, subscribe to the channel, hit the bell icon. See you guys in the next one.
Info
Channel: Max Programming
Views: 603
Rating: undefined out of 5
Keywords: javascript, typescript, react, js, web development, node js, nodejs, javascript for beginners, learn javascript, javascript tutorial, javascript todo list, javascript todo app, javascript todo list tutorial, tailwind css, tailwind css tutorial, tailwind css react, vitejs, todo app javascript, crud todo list react, crud todo app, crud todo list, vanilla js vs react, crud application, todo crud app, localstorage javascript, localstorage in react js, local storage
Id: yKOFt1OJqRQ
Channel Id: undefined
Length: 23min 13sec (1393 seconds)
Published: Sat Apr 08 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.