Coding A Calendar App In Plain JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Here's another way of getting just the localized Day of the Week as a string:

new Date().toLocaleString(window.navigator.language || "us-EN", { weekday: "long", });

πŸ‘οΈŽ︎ 8 πŸ‘€οΈŽ︎ u/drumstix42 πŸ“…οΈŽ︎ Jan 27 2021 πŸ—«︎ replies

Just a thought, you could have done event delegation for the days instead of having each day have it’s own event handler. Otherwise really enjoyed the video.

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/sajvaz πŸ“…οΈŽ︎ Jan 28 2021 πŸ—«︎ replies

So are we saving locally (with a cookie) or online (with a database). NOTE: if you know what you are doing, making simple apps that store data online is super easy.

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/Simanalix πŸ“…οΈŽ︎ Jan 27 2021 πŸ—«︎ replies
Captions
hey everyone in this tutorial we're going to be creating a simple calendar app that allows you to add events and we're going to do it in plain vanilla javascript it's been quite a while since i've done a vanilla javascript tutorial so i'm pretty excited to get into this one but i just want to say that in an upcoming video we're going to be converting this exact same application over to react and i think that will help a lot of people see the benefits of using a framework or a library such as react for a project like this now before we dive in please don't forget to smash the like button for me subscribe if you haven't already so you don't miss any future videos and let's go ahead and begin okay so to get started let's just go ahead and create a couple of files now make sure that you have your code editor open in whichever folder you'd like to have your project in now i'm inside of a calendar folder that i just created and there's no files inside of here so i'm simply going to start by creating a couple of files and the first file i want to create is an index.html file which is going to be the entry point for the entire application then i'm going to create a style.css file which is going to hold all of the styles for this application now i'm just going to say that this is going to be focused solely on the html and the javascript side of things i'm going to give a rundown on how the css is working but i'm going to be pasting in the vast majority of the css and don't worry the code is on github and i'm going to put a link to it in the description so that you can go there and copy the css file and you don't have to worry about how the style is working rather how the functionality of the application is working but again i am going to give a basic rundown of how the css is making the calendar look the way it does on the screen but there's just so much css it would make the video almost twice as long if i went through every single line of css so i'm going to go ahead and paste in the css right now and as you can see there's 125 lines of css and don't worry we will go over how the calendar is being displayed and all of that but go ahead and copy that css into your file save it and then close it for now the only other file i need to create is a script.js file which is going to be where we house all of the javascript for our project now i'm going to go ahead and create the html skeleton for my project which i can generate using vs code snippets but it's going to look just like this you're going to have your basic html skeleton i'm going to replace the title here with calendar app vanilla js and i need to import my styles so i'm adding a link here to the head that's importing my style.css and at the very bottom of the body but in still inside of the body tags i'm going to create a script tag which is going to have a source reference to the script file so that it can load our javascript now we could put this in the head load it asynchronously and then inside of our javascript we could wait for the dom to load and then run the javascript but for this tutorial i think it's simpler just to add the script here at the end of the body but you have to make sure that you write all of your html above this script tag or else it will not work properly now before we even start talking about how we're going to display the calendar i just want to get a couple of elements inside of my body for containers just to get a couple of small tasks out of the way for now so i'm going to create a div here and i'm going to be using mostly ids throughout this app instead of classes because i'm going to be selecting a lot of these with javascript and i just think it's easier to use ids for that rather than classes although we will use a few classes throughout this tutorial where it's appropriate so for this particular id i'm going to call it container this is going to be the container for pretty much the entire application so everything is going to end up inside of here except for the modals and the modals are what are going to be displayed once you click on a day and that way you can enter in some information to add an event to a day but those are going to be pop-ups those will be outside of the container so we'll add those in just a moment but inside of the container we're going to have two main divs here the first one will have an id of header and then i'm going to copy this and paste it below the second one is going to be the calendar itself so we have header and calendar both inside of our container div but there's actually one more thing we want to add inside of here so we're actually going to add a third div and the id for this is going to be weekdays now this is where we're going to host our monday tuesday wednesday well it starts with sunday so we're going to be using the american calendar for this tutorial so keep that in mind but it's going to be sunday monday tuesday wednesday thursday friday saturday inside of here so we need to go ahead and add seven divs within here one for each weekday so one two three four five six seven and then starting with sunday i'm going to add each weekday so now i have seven divs with each weekday inside of it and then these seven divs are inside of a weekdays div so just make sure that you have this exact same thing here and this is going to be hard coded because the weekdays are never going to change but this is going to be dynamic and some of the information inside of the header is also going to be dynamic so we're not going to populate the calendar itself in the html file instead we're going to populate it using javascript because we need to get date information using javascript in order to populate this so we need to know what is the first day of the month start on for whichever month we're viewing for example if i go to my calendar here i actually i'm going to need to move my video over really quick so that you can see the calendar hopefully it's big enough for you to see if not it's fine you'll at least hear what i'm saying right here i have a calendar this is january 2021 and the first day of the month is on a friday now there are five squares before this square here on the first day of the month there's five squares from the previous month and that's because the sunday monday tuesday wednesday and thursday dates still have to be here but we we what we're gonna do is we're gonna make them empty we're gonna have empty squares here for these five days instead of showing days from the previous month so the first day of the month is going to start on friday for january and this is all going to be through javascript we're going to get this information these five days here we are going to call padding days we're going to call these padding days or padding squares in our javascript so keep that in mind keep that in the back of your head so that when we move forward through the javascript you'll understand what the concept of a padding day is the padding days are just going to be literally empty squares that are considered to be padding for the first row here on the calendar because each month might be different for example february the first day of the month lands on monday so there's one padding day on march there's also one padding day and then for april there's four padding days etc you you get the idea so now that we have this kind of basic skeleton set up we're going to add a little bit more in a second but first i just want to get this running so i'm going to save it i'm going to go over here and open this in my file explorer so now that i can see my actual index.html file here i can double click on it and now it opens up inside of my web browser i'll go ahead and zoom in a little bit so that it's easier to see for you all and since the css is already linked again i'm assuming you've already went to the github you've copied the css file you've pasted it into your own now you should see sunday through saturday and it should look similar to this almost like they're headers to a table and you can kind of think of it like that but as i go in here and dynamically create the squares i want to make sure that each square for a day falls on the correct weekday so for january we were just talking about how there's one two three four five padding days keep that in mind for a moment now i could have used flexbox i could have used grid there were several ways to create the layout for a calendar but i chose to do it this way because i think it's easier i think it's easier to explain and i think it's just easier overall the idea is this we're rendering out all of the squares on a single line except what we're doing is we're taking the container and we're giving a maximum width or the calendar container the whole entire div a maximum width and that maximum width is exactly the maximum width or is exactly the width of seven squares so if we were to try to put an eight square on the first row here so one two three four five six seven if we tried to put an eighth square on on this row it's going to wrap to the next line so when we see all of the squares displayed on the calendar and it looks like a grid what's actually happening is it's just wrapping each to the next line automatically because of this max width that we've set so if i go into my css i just want to show you this it's not actually a max width we're actually setting the property with itself on the container you can see that the container has a width of 770 pixels but if we look at each individual day days have 100 pixels so 7 days is equal to 700 pixels well where are those extra 70 pixels coming from because each day is 100 pixels that adds up to 700 pixels where why are we adding the additional 70 and the reason why is because we have a margin set for five pixels on each square so that there is space between each day on the grid and if we add a margin that's going to add a margin on the left and the right of 5 pixels each for a total of 10. so for seven days that 10 pixels margin is going to add up to 70 and that's why the width is set to 770 pixels and if we tried to add an eighth day it would then wrap to the next line and look like a grid so that's how we're going to be doing the layout so just keep that in mind again as we go into the javascript and begin displaying our days awesome so let's go ahead and start this whole thing off by getting the calendar displayed properly so we're going to have to access the date api that javascript gives us that's built into the web browsers we're going to access that we're going to build some date objects and then we're going to display the calendar on the screen and that is going to be the first step of this tutorial so let's go ahead and go to our script.js file and begin writing some code here now what i want to do is start off by creating a couple of pieces of state and then a couple of constants that won't change throughout the application's life cycle now the state will obviously change and the constant will not but basically as you'll see that once we convert this over to react you'll see how much more easy it is to manage state and rationalize the concept of application state with a framework or library such as react versus this vanilla javascript here now maybe if i was using a more object-oriented approach for this tutorial that might be different but i'm taking a more functional approach i'm taking that approach because functional programming is a little bit more of my preference in design patterns for web applications especially as applications start to grow i think functional programming has some benefits there but i don't want to go on and on about this let's just go ahead and start by creating some state now the way that i'm thinking about state is this is going to be global variables that we're going to set using let that can change in the future so one one thing that we're going to need is a nav variable and basically this is just going to be how we're keeping track of which month we're on now for example when we first load it we're going to display the calendar for the given month that it currently is so for example this is january when i load up the calendar i would expect to see january but if i click the back button to see the previous month we would see december of the previous year so i would set nav to negative one now if i go forward i would increment nav to one and then the month would be whatever the current month is plus the nav which would be february if if it was one march if it was two december if it was negative one november if it was negative two etc so nav is just a way to keep track of whichever month we're looking at we're going to set another piece of state called clicked and we'll initialize this to null and clicked is going to be whichever day we've clicked on so if i as a user click on say january 22nd because i want to add an event or view an event that already exists we will then set january 22nd equal to clicked and then finally we're going to have an events piece of state which is going to be an array of event objects and we're going to pull this from local storage however we want to make sure that this exists in local storage before we before we try to parse it out because you know you can only store strings in local storage you can't actually store objects so we have to call json.parse on that and if it's undefined and we try to call json.parson undefined it's going to give us an error message so we have to make sure that this thing actually exists inside of local storage before we try to call json.parse on it so i'm going to use a ternary operator to do that and i'm going to try and get events and if if we are able to pull events out of local storage then we know it exists and i can call json.parse with this value however if this doesn't exist what i really want to return is an empty array so events is either going to be an empty array or it's going to be the array of event objects and that's what it's initialized as and we're going to update it throughout the lifecycle of the application and then when the user adds an event or deletes an event we're going to manipulate this array and then restore it into local storage now for a couple of constants these are going to be things in the application that we're going to be referencing throughout the app but they're not they're never going to change like the state will change the state is available globally but those items are going to change what we're going to put underneath this are some constant values that are available globally but will not be changing so the first one is going to be weekdays these will never change this is just going to be an array of weekdays now go ahead and create an array and set it equal to each ever and every day of the week order does matter here so start with sunday and it should end with a saturday and we're going to use this essentially to figure out how many of those padding days we need to add so for example if the first day of january which it is the first day of january is friday if we look here we can look at friday in this array and say zero one two three four five it's the fifth day of the week and we know that because we have an array here in data so this gives us a way to determine which day of the week or how many padding days need to be there well if we count each item prior to that we can see that there's one two three four five total here which equates to how many padding days we need because on january 2021 there's one two three four five padding days total and this is how we're going to determine it so weekdays is going to be an array that we're going to use to determine the number of padding days required so another another piece of constant another constant we are going to need is the calendar reference so i'm just calling document.getelementbyid calendar and setting it equal to a variable called calendar that way throughout the application i can access the calendar without constantly having to write this line right here i could just instantly use the calendar reference makes it way easier going forward now we're going to add some some constants later that are going to be associated with the modals that we're going to add for the events but don't worry about that right now we'll get to those shortly so to display everything that we want to see on the screen right now we're going to have to create a load function that runs whenever the document loads that will then display the calendar so i'm actually going to create a literal function called load we could call this anything we want but i think load makes sense here and then below it i'm just going to call load here so i'm going to create the function above it and then i'm going to go ahead and fire it off so when this file is loaded into the browser right here in the script we're going to call this function one time and it's going to run this function however throughout the application as the user clicks on stuff we're also going to call load again that's why we're actually making a function called load because this is reusable logic so it makes sense to create a function instead of writing this like 30 lines of code over and over again throughout the application we can just create a function called load and i want to create a date object i want to create a date object so that i can get the information about the calendar that i need in order to display it so i'm going to do that i'm going to create a const called dt and i'm going to set it equal to a new date object so now by using the date constructor i've created a date object and i've assigned it to a variable called dt i want console.log this just to see what it looks like and since we're already pulling this script file in it should go ahead and run it since i'm calling load here we should see it logged and i'm going to open up my console and let's go inside of here i will need to refresh in order to see the changes and you can see that the date when i log it this is what it looks like now when you call console.log on this date object that is what you see however it really is actually an object an object with methods and an object with properties so we're going to use this in order to get the information that we need and we want to start by getting the day month and year from it so let's go ahead and get the day first the day is going to be equal to dt.getdate the month is going to be equal to dt.getmonth and i bet you can guess what the year is const year equals dt.get and it's actually get full year right here okay so let's see what these three things look like right here we can just simply log day month and year so remembering that it's in this order day month and year i'm going to save it and refresh and we can see that the day is the 25th which today i'm recording this it is the 25th the month is zero and we'll talk about that in a second and the year is 2021. now since the month is zero let's think about it january is the first month of the year so when you think of it in your head you think one but for months using the date object it's actually an index value so kind of like an array so zero is the first month and then february would be one march would be two and so on so we need to remember that and we need to whenever we try to print out the month we have to remember to always add 1 to it because it's an index value so instead of saying just month we need to say month plus 1. now we're coming to an interesting point here because we actually need to know how many days there are in the month we need to know how many days there are in the month because we need to know how many squares we need to render in this load function some months have 31 days some months have 30 days and february can have either 28 or 29 days and this year it has 28 days so we need to know how many days are in the month so we know how many squares to render on the screen so how can we figure out how many days exist in this month it's actually pretty easy with the date api although it does require a little bit of explanation as to how it's working so i'm going to create a variable called days in month and this is going to be a number that represents how many days are in the given month that we have currently so i'm going to create a new date object and i'm going to pass some information into this constructor that's gonna give us the number we want so i'm gonna pass in the year and i'm gonna pass in the month plus one remember that and then instead of giving one here i'm gonna add zero so the third one is the day and the first day of the month is one it's not like month where we have to increment it or use it as an indexed value it's really it's asking what is the first day so the value for the first day of a month is one so when we give it zero it's actually the last day of the previous month if we give it negative one it's the second to last day of the previous month and so on so by giving it zero what we're really saying is this month the first day minus one so in other words the last day of the previous month and what we are going to do is call get date on this so by adding plus one to this by adding one to month here we're actually going to the next month so let's think about this if it's january 2021 this is 2021 this is now february and by giving it zero now we're on the last day of january and now we're calling get date on this and this will give us whatever the date is for the last day in january which should be 31 because there's 31 days in january so let's console.log days in month and see what we have refresh 31. so there are 31 days in january so this gives us 31. now we actually know how many squares we have to render on the screen now we're actually also going to need the first day of the month because we're going to use the first day of the month to create a date object that we're going to use in order to create our padding days so let's just do it we'll create a variable called const first day of month and we're going to set it equal to pretty much the exact same thing we have here new date but it's going to be a little bit different year now instead of month plus one we're just going to say month because we actually do want this current month and instead of passing in 0 which would take us to december we're going to pass in 1 because that's the first day of january so this date object right here is going to be the first day of january if you're doing this in january if you're doing this tutorial some you know on a different month which is very likely it's um it's going to be whichever month you're currently on but it's going to be the first day but we're not calling getdate on it we're just going to leave the object by calling getdate that converts it to a string or it gets you the information the specific information that you want here it gets a number and it gets the day of the month we don't want that we want the actual date object because below this we are going to create a date string so let's create a date string here and this is going to be set equal to first day of the month dot to locale date string now the first argument here is going to be en hyphen us it's going to be the basically the locale because again this is going to be the united states of america calendar um so if you're if you use a different calendar wherever you're at maybe slightly different and the second argument is going to be some options for this date string so before i even pass in those options let me just show you what it gives us by default so i'm going to console.log date string and let's see what it gives us by default so i refresh it it gives us 1-1 2021 and that is that is definitely accurate today for me is january 25th 2021 so the first day of the month i'm currently in is indeed 1-1 2021. however this isn't enough information you see i need to know the day of the week i need to know the day of the week so that i can go through this array and figure out how many padding days we need so that i can render the proper padding days before the first day on the calendar so that our calendar looks proper whenever we render it on the screen so in order to do that i need to pass in some options here and there's four options specifically i'm going to pass in the option weekday and we want the long version of that we want to pass in a couple of other options because since now we're passing in the options it's no longer going to give us that full default string we have to explicitly pass in the information that we want so year is going to be numeric in other words we just want the number for the year the year is pretty much always a number right for the month we want the number as well so numeric so instead of the the literal word january it's going to give us one and then for the day we're gonna pass in numeric as well and i'll save this and let's again log it and see what we get this time versus the last time go back to my browser refresh and now i get the exact same thing except this time before that string is the word friday with a comma and a space so remember this comma and this space because that's what we're going to use to split this string in half and get our weekday out of this string so the first day of january is apparently a friday i just want to verify that so i'm opening up my calendar and i see that indeed the first day of january does fall on a friday and i know you probably can't see it very well but as i open my calendar i can see again that there's one two three four five padding days total but i have to calculate that in javascript so let's go ahead and calculate that right now so i need to create a variable called padding days and let's set it equal to a number how are we going to get this number well we have this weekdays array up here at the top so i'm going to say weekdays dot index of now i know just off the top of my head because i console.logged it that the value for date strings the first part of that is going to be friday but we actually have to pull the friday part of that string out because we need to pass in specifically just friday because we only have the weekdays in this array and we need to make sure that we're only passing in obviously the weekday and not the date itself so in order to do that i'm going to take the date string and i'm going to split it and i'm going to split it using that comma and that space i was showing you a moment ago now it's an array of two items where the first item is friday and then the second item is that 1-1 2021 part of the string so we want the first part of that array so i'm passing in this indexed value here and let me go ahead and just make sure that padding days is equal to what i think it is which should be five right because there's five padding days and this is logging five on my screen so i know that that is correct okay awesome so so far so good i know how many padding days are there and i know how many days of the month there are so now i actually have the ability to do a for loop and i can loop through all of the padding days and all of the days in the month and then render the padding days along with the day squares on the calendar in a long row that folds and wraps down t to a grid okay so how are we going to do this let's do a classic for loop and i need to set my i equal to one i'm going to set my i equal to one so let i equal one and then i'm gonna set i or i'm gonna keep looping until i is less than or equal to padding days plus days in month and the reason why i'm doing that is because i actually have to render empty squares on the screen for the padding days so we need to keep the padding days in mind and all of the days in the month and then afterwards we can just let the other squares be empty and then finally we want to increment the i during each iteration okay so the first thing we need to do inside of this for loop is create a day squared div so day square is equal to document.createelement and the element that we want to create is a div so for every single iteration we're going to create a div and we're going to assign that div to a value called day square but i also want to quickly add a class to daysquare so i'm saying classlist.ad and i can pass a string into here and i want to give this daysquare a day class okay so now i have a daysquare and i've given it a class called day now i have to check for some logic here to determine whether or not i should be rendering a padding day or if i should be rendering an actual day square itself so i'm going to create an if block here an if and an else so the logic that i want to check for here in my conditional statement is whether or not i is greater than padding days because if the current iteration that we're on since we're starting at 1 is greater than padding days then we know that we've iterated more times than there are padding days and if we have iterated more times than there are padding days then we know we should be rendering an actual day square instead of a padding day however if it's less than or equal to padding days then we know we should be rendering a padding day instead of an actual day square so in this else block what i want to do is add a class name to the day square and the class i want to add here is simply padding and we're going to use this to make sure that in our css which we've already pasted into our file this is going to make sure that it doesn't have the same styles as a day square so the day squares are going to have like a box shadow and it's going to be a little bit easier to see it an actual padding day is pretty much going to be invisible so that's why we're adding this to padding days now if we are in fact on an actual day and not a padding day we want to go ahead and run some logic the first thing i need to do is set the day number value inside of this div so for example if we're on day 11 as we're looping through if we're on iteration 11 plus whatever padding days we want to make sure that we render the number 11 inside of that square because a calendar obviously has the number for the day inside of the square so day square dot inner text is equal to i minus padding days and that's going to give us the number that we need for the current square we're on but we also want to make sure we add a event listener so add event listener for whenever the user clicks on it so i'm adding a click event listener here and i want to run a function i want to run a function every single time the user clicks on it but for now i'm just going to log click that way later on we can come back to this and add the actual function that we're going to run whenever the user clicks on a square for now i just want to uh log the word click so i'm going to save this and below below my if statement but still inside of my for loop i need to actually take the day square that we're on that we just created and i need to put it inside of the calendar container and if you remember on line five here we created a constant called calendar which is a reference to the calendar in the dom i can actually say right here calendar dot append child and i can pass in that day square right here now i'm going to refresh and let's see what we have so now i officially have a calendar rendered on the screen it doesn't do anything yet but it does display the weeks and the days and it displays just like a normal calendar the only problem is we can't go to we can't move back and forth through the months we're pretty much stuck on january and that doesn't help us very much so the next thing i want to do is add a couple of buttons at the top that allows us to go back and forth between the months and also on the left here i want to add a header that tells us which which month and year we're on so obviously in order to do that we're going to have to add buttons and a header we have the header div here but we need to add some stuff inside of here so that the user can see the date and also the ability to click on some buttons so we need to add some buttons and stuff inside of here so go back to your index.html file open up your header tags and let's add a couple of things the first thing is going to be an empty div that we're going to populate using javascript so give this an id using and let's call it month display below that we'll add a div and this is going to contain two buttons so go ahead and create a button you might as well copy and paste another button below it the first button is going to say back and then the second button is going to say next and we just need to give each of these an id that corresponds with it so the first button the back button is going to have an id of back button and then the second button will have an id of next button so now we have these buttons we need to go into our javascript file and set click event listeners on these buttons so that when the user clicks on them we can run a function that will run some logic that will give us the next date or the previous date and we also need to make sure that we populate the month display here as well so i'm saving and i'm going to refresh i just want to make sure that the buttons appear and as you can see the back and the next button have appeared right here so the first thing i want to do is just simply display the month in the header so go over to your script.js file and let's go inside of our load function so our load function is right here where is it right here somewhere inside of here i want to make sure that i populate this div right here with the month name that we're on so for example today for me is january 25th i want to see the word january inside of here so to do that i need to find the best spot to put it which i believe is going to be right here under padding days and i'm going to just document.getelementbyid the id i gave that div was month display i want to set the inner text for this the inner text i'm going to use these back tips backticks so that i can use some javascript string interpolation to take the date object that i created up here this dt variable i'm going to use this to create a string for the month that we're on the best way to do that is use string interpolation so the first one is going to be the month i'm going to put a space and the second one is going to be the year and the year is really simple because i can just pass in year we already have year right here on line 13 i'm already assigning year to a variable called year so i can just use that here that's done but i need to get the month and i need to say january specifically or february the full month instead of the abbreviation or the number so to do that i'm going to do dt.2 locale date string and again it's en us but this time we're going to pass in a different option than we are for this one instead of passing in these options for month we used numeric we want to pass in month long now i saved it i'm going to put this on a separate line so that we can see it all so now it's on two lines i'll save it refresh and now i see january 2021 right here but i still need to add my event listeners for these buttons and there's going to be more buttons later once we add the modals there's going to be cancel buttons delete buttons save buttons so i'm going to create a function here that is called init buttons and i'm going to create it below my load function so outside of my load function i'm going to create a new function called init buttons i'm going to call this function above my load call right here just like that so inside of init buttons i need to very simply create event listeners on my next button and my back button that's going to increment or decrement this nav and then call load again so let's go ahead and do that let's do this we'll start with the next button document dot get element by id next button add event listener i've typed click and the function that i want to run is going to be nav plus plus so i'm incrementing nav which is our global variable that's initialized as zero so the first time i click it it'll become one the second time i click it'll be two etc and then i want to call load so we're incrementing nav and then we're calling load again now inside of load i don't think we're taking nav into account whatsoever so we're going to have to go back into that and make sure we take nav into account but for now i just want to add my other one my other event listener for the button so i copied and pasted this right here and i pasted it below i need to change next to back and then instead of doing plus plus i need to do minus minus because that's going to decrement the value then call load so what do i need to do inside of the load function to take nav into account so that we're rendering the proper value on the calendar whenever i click next or back let's see here let's have a look so the first thing i'm realizing is that i probably need to reset the calendar each each time i call load because if i don't then what's going to happen is inside of this for loop we're going to end up creating another calendar below it because we're not clearing out the day squares so all of those day square divs that we're rendering on the screen we need to wipe those out before we render new ones in this load function so the best and easiest way to do that is to use the calendar reference that we have and set the inner html to an empty string so that is effectively wiping out all of the day squares and padding squares and everything inside of that calendar div it's wiping it all out and then we're going to run that for loop again and re-render everything okay so one thing that is for sure is we have this date object that is going to always be equal to whatever the date is currently but we can go through the months so the months can change we can go to the next month the previous month etc so below this we need to check for nav and we need to say if nav does not equal zero so if we've gone either backwards or forwards if nav does not equal zero then i just want to call dt.setmonth i'm gonna pass in a date object here dot getmonth and then i'm gonna increment it by whatever nav is so let's have a look at this line i'm calling set month equal to the current month so essentially this would just always be one if i'm in january but we're going to add nav to that so if i press forward and nav is equal to one then it's going if i'm in january then it's gonna become february if it's negative one it's going to subtract one and then it's going to become december so hopefully that makes good sense for you okay so that should be all we need to do in order to be able to go through the months so i refreshed in here and i saved all my files i'm on january 2021 and i'm going to click the next button now i'm in february it changed here and the days changed as well but i want to verify that this is accurate so i'm seeing that the first day of february 2021 seems to fall on a monday and there's 28 days in total and the last days on sunday let me just make sure on my calendar that that's accurate so i'm going to february and on my calendar actually monday is the first day and the 28th is the last day and i want to go back a couple as well to december 2020 and just verify that as well to make sure that this is good and i can be more confident in my code the first day of december 2020 was on a tuesday and the last day was on a thursday and it was the 31st so i'm going back to december and the information matches perfectly so i'm rendering the calendar and now i have the ability to go back and forth between months so i guess the next thing we should do is set up the ability to add events and luckily we already have the piece of state here at the top that is either an empty array or an array of event objects now obviously it's going to be an empty array at first because we haven't added any events yet and we also have this clicked variable which is going to be set equal to the date for the day that the user clicks on so remembering that we have this state here we can go ahead and go down here and set a couple of on click functions for the buttons that are going to be inside of our modals along with replacing this click console.log here with an actual show modal function or open modal function but we actually have to write the modal stuff inside of our html file so we need to actually create a couple of modals so below everything including the container this is going to break out of the container because these are going to be absolute positioned elements that are going to lay on top of the container we'll start by creating a div here with an id of modal back drop and b and d are both capitalized so make sure you write it like this modal backdrop back and drop are both capitalized this is an empty div there's not going to be anything inside of it we're just going to use this as a black overlay that kind of sits on top of the app itself to bring more focus to the modal i've already written all the css for all this stuff in the in our css file so you don't have to worry about that we're going to just make sure that we hide and show it in our javascript so the first modal that we're going to worry about is the new event modal so i'm just going to start with that and then we can come back to the other modal later this needs an id of new event modal and i'll give it an h2 with new event and i need an input inside of here the input needs an id of event title input and i guess i'll give it a placeholder of event title then below this i need two buttons i need a save button and a cancel button so copy and paste the first button will say save and the second button will say cancel and i need to give them ids that correspond so for the first one the id is save button and for the second one the id is cancel button and now i have everything i need for my modal i just need to show this modal whenever the user clicks on a day so instead of doing this console.log click i'm actually going to call a function called openmodal however we need to create this function first so i'm just going to create it up here above load function open modal and this function is going to take an argument specifically it's going to accept the date because we need to know which date the user clicked on before we show the modal because when they create the event and we save the event we need to know which date the event is for so it's going to accept date as an argument here and we need to set clicked equal to that date because remember clicked is our state that's going to help us determine which day the user clicked on we can set our global state here and the reason why we need that global state is because there's going to be other functions throughout the app that use this such as save event for example but for now let's go ahead and create an event for day variable and we want to loop through our events array and see if there's already an event for this day because if there is instead of showing a new event modal we want to show the event and give the user the ability to delete that event so i'm going to go in and say events.find remembering that events is an array i can use the find function for the array and for every event i want to find an event where e.date because e is the event object events is an array of event objects so for each event we want to find e.date is equal to clicked so we're going to try to find an event in that already exists for this day now this could either exist or it could not exist so we're going to create a conditional statement if event for day and then below we'll have else so if event for day we're going to show the delete modal otherwise we're going to show the new event modal so here i'm just going to console.log something that says event already exists and we'll come back to that so for now we'll focus on the case where the event already does not exist so it does not exist yet in which case we need to um we need to take that modal and set the display to block because by default in our css i've set that to hidden or display none so as you can tell here when i refresh even though we created that modal in the html document it's not showing up here because i have the display set to none in css so we need to show it now so inside of here i need to show it however it would be great if i had another const here for the new event modal so up here outside of all the functions below the calendar i'm going to create a new event modal variable and set it equal to document.getelementbyid new event modal and now inside of my else statement i can simply reference that new event modal and set the style dot display equal to block but i also regardless of which modal i show i need to show the backdrop so i actually need to create another constant up here for the backdrop so i'm going to do that backdrop and the id is modal back drop capital b capital d so below here i'm just going to say back drop dot style dot display is equal to block now let's see what happens when i click on a modal i i guess first i actually have to make sure i'm calling the function so down here on my line 58 could be different for years depending on how you're writing the code instead of calling console.log click i want to call open modal but make sure you remember that for our function here for openmodel it accepts date as an argument so down here we need to make sure that we're passing in the date and what it expects specifically is going to be the month the day and the year kind of like oh one or just one slash 25 slash 2021 so i'm gonna use interpolation for this the first one will be month forward slash second one will be the day forward slash and the third one is going to be the year and the year we already have it's very simple just pass in year for the month if you remember months are index valued so for january it's zero and for february it's one so i need to add one to it because i actually want the actual date string with the month month that makes sense to humans instead of computers so i'm gonna say month plus one and sorry that was supposed to be the first one so i'm going to copy that out and paste it into the first one the second one is day and day is going to be calculated by saying i minus padding days because we're inside of this for loop so we need to remember that we're looping through the padding days as well so we're just going to subtract padding days from that which will give us the proper day i will save it and see what happens when i click on 13 oh i need to refresh okay let's click on 13. when i clicked on 13 i now see this event modal and there's an input and a save and cancel button now none of this does anything yet so we need to set the click listeners for these two buttons to do something whenever we click on save or cancel and we also need to be able to grab the value from the input and when i click save it's going to add it to the events array and store it in local storage so heading back over to my javascript file inside of my init buttons function i'm going to add two event listeners document.getelementbyid the first one was save button and the second one which i'll just copy this and paste it below make it easy on myself the second one was cancel button i think cancel button will be the easiest for now so i'll do that one first cancel button needs to run a function and let's just give it a function called close modal because we're going to use this in multiple places so i need to actually create this closed modal function and i'll do it above the init buttons function here so i'm creating a function called close modal it does not need to take any arguments because it's just simply going to close the modal but there's multiple modals or at least there's going to be so i need to make sure that we close all the modals but we only have one in our html for now so we're gonna have to revisit this function and add the other modal to it later so new event modal dot style dot display is equal to none but we also need to do the same thing for the backdrop so backdrop dot style dot display is also equal to none we also want to make sure that we clear the input out because if i type something into our new event modal input here like this and then i click save or cancel and i close the modal if i open it again that text is still going to be there so we need to clear that input out and the easiest way to do that is to create a global variable here at the top i'll just call it event title input set equal to document dot get element by id event title input now that i have that reference i can just say event title input dot value is equal to an empty string effectively clearing it out and then finally i can set clicked to null because when we close the modal we no longer want to keep clicked equal to the day we want to just clear it out and then finally we can call load again so this should be good let me go back to my browser refresh i'll click on the 13th and when i click cancel it doesn't seem to be doing what i expected so let's see now the reason why is silly and it's my fault is because i was putting this close modal stuff i was i was doing this a little bit wrong i got a little bit ahead of myself so i'm gonna comment this out just for now i grabbed the element by id but i need to add an event listener to it that's the problem so the event listener is where i want to say close modal so grab it add an event listener of type click and then call close modal on click so save now let's give it a test refresh click the 13th click cancel click the ninth let's type some stuff in click cancel open it back up the input has been cleared so the cancel button is working perfectly fine let's go ahead and add the ability to create an event so obviously i'll need to uncomment that out and add an event listener here of type click but instead of calling close modal i need to call a different function that we haven't created yet and i'm probably going to want to call this function save event so i'll just go ahead and put this in here and create the function underneath close modal so function save event all right how is this function gonna work well let's think about it we need to get the value out of the input that should be the first thing we do so let's create a title input variable it does not need to be available globally because it's only going to really be accessed here so we already have a reference to the input here at the top it's available globally so i'm going to just simply check that value so if new event i'm sorry if event title input.value if we have a value in other words if the user has typed inside of the input then we can go ahead and save the event otherwise we don't want to save the event we want to add an error so let's let's set the event title input let's go to the class list and let's add a class called error now obviously if there is no error we want to make sure that we remove the error so inside of the if portion i'm going to call remove for that class but instead of title input it's supposed to be event title input so if the title exists i'm going to remove the error class and if it does not exist i'm going to add an error class but i'm also going to copy this line because i want to make sure that i call this inside of close modal as well because if we close the modal while there's an error we want to make sure we clear the error as well so we need to push the event to our array of events and we have the array of events up here so let's go ahead and push it to that array remembering that we only want to do that if there's a value in that input so events is an array so we can call push on that and we want to push an object into it with date equal to clicked because we're keeping track of clicked we can set date equal to clicked and then we just set the title equal to event title input.value since we know that the value exists here since we're checking for it here then finally after we push this event to our events array we want to restore this in local storage so let's go to localstorage.setitem the item key or the name of the piece of state that we want to store in local storage is going to be called events and remember we cannot store the actual object in local storage we have to json.stringify it first and we're going to json.stringify and save our events array to local storage so very simply we just remove the error class push the new event to our events array in state and then save it to local storage so let's test this out and see if this is working good so we're calling it here so it should call the function let's see save refresh i'm going to open up my console go to my application tab go to my local storage tab and i'm going to clear what i had from earlier and let's see what happens when i do this so i'm actually going to put it on the side so i can see things a little bit more clearly and i'm just going to click on one date here in january let's just say the 10th and i'm going to add an event here called do a tutorial i'm going to click save and let's see now we have an item in local storage with a date of 110 2021 so i know that it shows the proper date and the title is do a tutorial awesome couldn't ask for more really except when i click save it's really supposed to close the modal it didn't seem to close the modal so that's because we didn't call close modal so once we're done saving it i'm going to call close modal so save and refresh i'm going to add another event here so let's just say wednesday the 27th of january i'm going to release this tutorial which is actually true i'm going to click save now it removed the modal from the screen but let's make sure that it actually added it to my list of events here in local storage and it did so on the 27th of january i'm going to release this tutorial okay this is looking really good but i need to display the events you see it's cool that we have them stored but it's not very helpful if we're not displaying the events right so how can we do that well we already have a for loop where we are adding in items to our calendar we're adding days and padding days to our calendar so inside of this for loop we want to go ahead and simply check whether or not there's an event for the day that we're on when we're in our for loop and if there is an event for the day that we're on let's create a div add the text for the event and put it inside of our day square we actually already have some logic for event for day if i go to line 14 for myself you can see that the logic is i'm using a find function on the array to check for the to look inside of the array to see if we can find an event for the day that we're looking for so we're going to use very similar logic but here we're using clicked for this and we're not wanting to use clicked to determine whether or not there's an event for the day instead we're going to use the information that we have inside of the loop so i copied it but i'm actually going to change a little bit of it so inside of the padding days if statement part let's paste in that and let's get rid of clicked so what do we want to use to check for the date well very simply if you remember for each of these for each of these in local storage if i quickly show my application tab if we look the date is the month day and year in this format so 1 10 20 21 for example so we need to check if that is equal to the date that we're currently on and we actually already are rendering that right here we're calling that right here so what i should do is take this out of this open modal function and create a variable with that so const day string i guess we can call it and i'll set that equal here and instead of calling openmodal with that long string i'm going to call it with day string and i can also use that here as well so now i'm checking whether or not there's an event for the day that we're currently on now if there is an event for the day we're currently on then i want to create that event div and then put it inside of my day square so i'll create a new div const event div is equal to document dot create element div i want to add a class to it so event div dot class list dot add and i'll give it the event class let's add some inner text so event div dot inner text and the enter text here needs to be the day or the inner text here needs to be the event text so that ended up being event dot title and we have event for day right here so we can use event for day dot title then finally we need to make sure that we take the day square and we append child we pass this event div into that day square because we know later on we're taking this day square and putting it inside of the calendar so if there is an event for the given day that we're on while we're looping through we create a div add a class set the text and then put it inside of the day square now let's see what happens when i refresh okay so instantly it appears to be broken it says event event div dot inner text is not a function and that's my fault because i i treated it like a function i was not supposed to so my apologies on that get rid of the parentheses here and set it equal to so we're trying to set the event for day.title equal here we're setting the inner text equal to the event for day.title this was not a function that's my apologies so i save let's refresh and now i actually see the two events that i added on the days that i added them for so day 10 do a tutorial and then day e 27 release this tutorial so i'm going to click on this day right here and you can see that something has broken well it didn't really break it did what we already defined here which is log event already exists and if we go into our code you can see that we're logging event already exists inside of the open modal function and we're logging this if an event for the day already exists which it does so we're really getting the behavior that we want so if i refresh go to an at any day that doesn't have an event it opens the modal like we'd expect but if i click on a date where there is an event we need to show a different modal now we need to show the modal that allows us to delete this event in case we need to cancel our plans or something so head on over to your index.html file let's add this other modal so we have the new event modal below this i'm going to add a new div with a new id and instead of new event model we're going to call this delete modal or actually let's be a little bit more specific and call it delete event modal and inside of here we'll give it an h2 instead of saying new event we'll just say event below this i'm going to give it a paragraph tag where we're going to display the event itself so i need to give it an id of event text so that we can populate it dynamically within our javascript then we'll need a div container with two buttons inside of it my apologies we don't need a div then here we're gonna need two buttons so i will copy paste the first one will be delete and the second one will be cancel will be close so this will have an id of close button and this will have an id of delete button and that should be everything we need for the html file i'm pretty sure at this point we can just close this file and we shouldn't have to return to it don't hold me on that though i'm pretty sure we don't need it anymore so back to our script.js file we need to add the button event listeners that we just created because we created two new buttons i'm just going to copy these two lines and paste below instead of save button we have a delete button and instead of cancel button we have a close button and the close button is actually just going to close the modal so i don't have to change anything for the close button but for the delete button we should have a new function that we're going to create in just a moment called delete event so now we have four event listeners here at the bottom and above this function i'll create a new function called delete event and delete event is going to be somewhat simple we'll talk about it as i go through we need to reset events equal to all of the events except for the one that we're deleting so again we need to take the events and filter out the single event that we're deleting so we're going to set events equal to events dot filter and for every event we want to allow in the events that are not equal to clicked so if e dot date is equal to clicked i'm sorry if e dot date is not equal to clicked then we will let it into events it's going to filter out the one where it is equal to clicked so that's essentially like deleting it from the array we've deleted it from the array but we need to make sure that we reset it in local storage so we can quickly do that here the key is events and we just went to json.stringify events so we're filtering out the events array we're resetting it in local storage and then finally we'll just call close modal and if you remember close modal actually has the has the load function at the end so we don't have to call that twice so i can just save and should be able to delete events now let me just see if i refresh if i go to do a tutorial and i click it oh we still have to show the modal inside of our open modal function so back to the javascript if i go up to the top inside of the open modal function instead of console.logging event already exists i should probably just go ahead and show the modal but i should also set the text for the modal inside of it or set the text for the event inside of the modal so those are two things we need to do here the first thing is set the event text so i'm going to go ahead and just document.getelementbyid instead of creating a global variable for this since this will not be referenced anywhere else in the entire app i'm just going to do it here event text is the id we want and i'm just going to set the inner text equal to event for day dot title then below this since we will probably have to also reference the delete modal outside of this function for example inside of the close modal function we might as well go ahead and create a global variable for it so i'm copying the new event modal line here and below it i'm pasting it and removing new and putting delete here and here as well so now we have a reference to the delete event modal on my line 19 i'm just going to say delete event modal dot display dot style is equal to block and as you might suspect we need to go to the close modal function and pretty much right here where we're calling neweventmodal.style.display is equal to none we need to paste a line underneath it and remove new and add delete so now we're removing the new event modal and the delete event modal from the screen whenever we call close modal so refresh inside of here and let's see if i can delete the event here on the 10th okay so i'm clicking it and nothing's happening so i might have done something wrong i'm getting an error that says cannot set property style of undefined on line 19 of the javascript file uh it's because i did it backwards i did display dot style it's supposed to be style dot display that's my bad you guys might have already caught that so i'm going to refresh and try this again it should work so i'll click on the 10th and again it doesn't oh do i need did i i forgot to refresh so i refreshed it i clicked on the 10th and now i see a modal with the event the event name and then a delete and close button so click close just to make sure that works i'll click on the other one release this tutorial shows up that's as expected so now i want to see if i can delete this event right here i click delete and it did in fact disappear so if i click on it now it shows the new event modal and i can say do something else click save and now that event is displayed there so i'm going to click next and see if i can just add an event for a different month just to make sure this is working this is a different month click save that's there i want to refresh the app and then see if it's still there okay this is looking good the only thing left that i can think of right now is to set the current day i want to highlight the square for the current day because if i'm using a calendar i want to just easily be able to see what the current day is easiest way to do that is to simply add a class for the current day something maybe like current day could be the name of the class so let's go back into our javascript and add a new class for the current day so that will it will be highlighted at all times so running over to my javascript file i want to go to my load function because that's where we're going to call this thing we specifically need to go into our for loop and even more specifically we need to be inside of this if statement because we don't need to set this class we'll never need to set this class for a padding day so we'll be inside of this if statement right here this if block and we want to add another if block that's going to check to make sure that it is in fact the current day because if it is the current day if we're on the current day we want to add a class name to the day square that we're on right now so if i minus padding days is equal to day and if i highlight day you can see that day is this value right here which is the current day so since today's the 25th for me this value right here is and i'm checking if i minus padding days is equal to 25 for example however we should also really only check this if nav is equal to 0 because i don't want to highlight february 25th and march 25th and all the other 25ths i only want to highlight it for the current month so if the nav is zero then i know i'm on the current month so i'm only highlighting it if we're on the current month and the way that we're going to highlight it is we're going to add an id so instead of a class name let's add an id because there's only ever one current day for a given display so daysquare.id is equal to a string and we'll set current day i'm using javascript casing here click save click refresh and now the 25th is highlighted for me if i go to the next you can see the 25th is not highlighted as expected so it looks like we have a fully working calendar app in vanilla javascript i cannot wait to convert this over to react so you can see the benefits that react gives us but for now patch yourself on the back because you did a great job following through on this tutorial alright everyone i hope you enjoyed this tutorial and i hope you learned something now don't forget that we are going to be converting this app over to react in an upcoming video so subscribe so you don't miss that and i will see you all in the next video [Music] you
Info
Channel: PortEXE
Views: 19,137
Rating: undefined out of 5
Keywords: javascript tutorial, plain javascript tutorial, vanilla javascript, vanilla javascript tutorial, plain javascript, no framework, javascript without frameworks, javascript calendar, calendar app in javascript, code a calendar, calendar tutorial
Id: m9OSBJaQTlM
Channel Id: undefined
Length: 63min 46sec (3826 seconds)
Published: Wed Jan 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.