How to Build a Kanban Board with JavaScript (No Frameworks)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey how's it going guys my name is dom and today i'm going to be showing you how to build this kanban board right here using html css and javascript now if you're subscribed to this channel you know that i like to keep things in vanilla or pure javascript so this is going to be no different this solution right here requires no external libraries or frameworks now let's have a look at what it can actually do so right here i can add a new column or sorry a new item and i can say something like hey guys how's it going right i can save it just like that i can move this item around by dragging and dropping into different positions if i want to that is also going to save and i can even edit the content for example something like a bottle and that is going to work now i can also just double click to delete that item so that is the functionality of the kanban board it is very simple and hopefully it's going to be a fun project for you guys to work on now also keep in mind that this here is going to require an intermediate knowledge of javascript so if you are just starting out to learn javascript some of the things in today's video might be a little bit confusing for you guys and i apologize in advance but if you've been using javascript for a little bit now you know this this hopefully should make sense okay so the source code is also going to be linked down below if you run into any issues all right so i do want to show you what the what the data looks like for the kanban board right here because we're going to be using local storage to persist the data in the kanban board but you can easily swap it out for your own api or back end if you wanted to okay so speaking of or going into the local storage part here if i go into the application tab of the browser right here we can see under the kanban data key i've got all of the content or the data for the kanban board which you guys just saw so right here this kanban data is just a json array and this array contains three objects one for each column not started in progress and completed okay so expanding these columns right here each column has its own id one two three and it's also got this items array so inside this array it contains every single item for that column in this case here the first one has the content of edit video and the um and the item id is 72714 so that is the what the data looks like for the local storage um you know for this kanban board okay so that's just um let's just keep this in mind when we get to the point where we are coding the local storage layer all right so that's that one now going inside this tab let's begin from scratch to create what i just showed you all right so going inside the text editor right here we're starting with this index.html okay so you guys should also have a similar file right here which is going to be linked up to a css file here that goes to main.css and is currently empty okay i've also got this javascript file right down here it goes to js then main.js which is also empty it's also got a type of module so this right here is important because we're going to be using es6 import export syntax for this solution today so make sure you have the css file and the javascript file linked up just like that okay so as usual i like to show you guys the html and the css first before moving on to the javascript okay so we're going to do that right now so dropping down inside the body we're going to be writing out some html now just keep in mind that eventually the javascript is going to be generating the html for us but just so we can see our progress with the css we're going to be putting some html inside here so let's make a new div with a class of kanban so this right here is going to be the main container for the kanban board inside here we can make a new div with a class of kanban underscore underscore column so this right here is going to represent a single column on the kanban board i'm also using the block element modifier css naming convention but you can name these classes whatever you like okay inside the column we're going to need three things the first thing is going to be the title uh then we need the list of every single item and lastly we need a button to add a new item okay so inside the kanban column let's make a div called kanban underscore underscore column dash title we can say something like not started inside here okay let's make a seconds div with our class of can ban underscore underscore items so of course inside here we're going to store every single item we can drop down once again and make a new button right here this button is going to have a class of kanban underscore underscore add dash item and also a type of button okay we can just say inside the button a plus then say add okay so that is the basic structure of a single column on the kanban board if i save this and go inside the browser we are going to get something like this ok cool so let's add a sample item going back inside here inside the items div we can create a new div so this div right here is going to have a class of kanban underscore underscore item dash input okay so this right here is going to be a div which the user can actually edit as if it's a text area okay so we can say something like you know do or let's say wash the dishes okay now to make this editable by the user we're going to make this or give an attribute of content editable just like that so now basically you've got this input field which is a div okay so that's just to put it simply right that is our input the next thing is going to be a new div with a class of kanban underscore underscore drop zone so what this drop zone is it's basically just that that area which is going to highlight when the user drags an item over it okay so going back to the example kanban board here the drop zone is simply just that dark that dark gray rectangle which is going to be above and underneath an item okay so just putting a sample a drop zone inside here so we can style it up so this is the html we're going to need to actually now work on the css so going in the browser we get something like this so let's go inside the css now to essentially make everything look nice so the first thing here is going to be to target the kanban class we're going to give this a display of flex also a padding of 30px a width of 750 px a background of let's just do zero zero nine five seven eight that is the decode green color and also a border radius here of five pixels so why use display flex we're going to be using flexia to create our our three column layout so i can save this go back in the browser and we have something like this okay so not looking too bad so far as we can see we've also got that that 750 pixel width on the actual kanban board next up we can just simply uh target every single item inside the kanban board and give this a font family of sans serif you can of course make this font whatever you like now when it comes to the kanban underscore underscore column class for this i'm going to give this a flex of one this will ensure that every single column has an equal width okay also for the kanban column we're going to say not then say last child so basically every single kanban column that is not the last one is going to have a margin right we can say margin right of 30px and basically that is going to give us space between every single item as we can see in my example cool so moving on to the kanban underscore underscore title class so when it comes to the column title should i say when it comes to the column title we can just give this a margin bottom of 20 pixels a font size here of 30 pixels a color of white and a user select of none this will prevent accidental highlights when selecting the content inside your items i can save this go back in the browser and we have something like this on the actual title moving on we can actually begin styling up the items themselves so when it comes to that we can just say kanban underscore underscore item dash input so when it comes to the input field or the or the div which the user is going to be editing we can give this some padding we can say padding then say 10px and then 15px so basically we have 10 on the top and bottom and 15 for the left and right we're going to also give this a box sizing of a border box to ensure that it doesn't go over its bounds i'm going to give this a background of white a border dash radius here of 5 pixels and a cursor of pointer this is to this is to suggest to the user that you can actually you know click and drag these items save this go back in the browser and we get something like this cool so going back inside the css we can begin styling up the drop zone so we can just say can ben underscore underscore then do drop zone so when it comes to the drop zone itself we're going to be giving this a height of 10 pixels okay also a transition of background at 0.15 seconds and heights at also 0.15 seconds so the reason for this transition we're going to find out right now so essentially when the user drags an item over a drop zone we need to change the height and the background color to tell them you can actually drop here so for that we're going to be saying kanban underscore underscore drop zone dash dash active so we're going to be using javascript to add this active modifier class to the drop zone element and the modifier is going to change the height to 20px and the background to rgba 000 and then 0.25 this right here is going to create a 25 opaque black and you know cause the background to seep through so let's demonstrate this right now going back in the browser we can see we've got some space for the actual drop zone right down here between the add button and the item so right there let's add the class here of dash dash active using the developer tools on the right side here i can press enter and we get that you know class being applied so that is what the active class is doing so like i said earlier we're going to be doing this using javascript so going back in the css let's finish this off by styling up the add item button so for this uh going underneath the drop zone we can say kanban underscore underscore then say add dash item so for these ones i'm going to say a width here of 100 percent padding of 10px top and bottom and 0 left and right a font size of 16px a color of also white a background here of rgba00 and then 0.1 for a 10 percent opaque black let's get rid of the default border let's give this a border radius of 5 pixels much like the others and also a cursor of pointer so saving this right here going back in the browser we get something like this i'll just refresh here and we get the add button all styled up so that uh that is the css for the kanban board we can now work on the javascript okay so when it comes to the javascript for the kanban board i just want to take you guys back to the local storage example from earlier so just try and remember what this structure looks like because we're going to be essentially coding this local storage layer right now okay so going back inside the text editor let's go inside the js directory right here and we're going to be creating a new folder called api inside this api folder or directory let's make a new file called kanban api.js so inside here it's going to contain all of the code for the local storage components so we're going to say export default class called kanban api so basically this export default allows us to then import this class into the other javascript files now this class right here is going to contain a bunch of static methods or functions to interact with the local storage but if we drop down here let's define some basic functions to actually interact with the local storage directly so the first one here is going to be a function called read so the reads function is going to essentially read from local storage directly so we can just say a new constant called json equal to gets localstorage.getitem we're going to be getting the item of kanban dash data okay so that is the key right there specified next up we guess we're just going to say if there is no json so basically if this is the first time the user is you know using the kanban board in their browser we can return the default data so the default data is going to look like this we're going to need our three columns the first one is going to have an id of one this is going to be the in progress column it's also going to contain an empty items array just like that so now we can simply copy and paste you know that object two more times id of two and then id of three so this is your default data right here like i said this is gonna run when the user is loading up the kanban board for the first time okay we can now just simply return json.parse and just pass the json string and of course this case is when the user is returning to their you know session or to their kanban board okay that is the read function right there next up we have the save function so function called save it's going to take in a new data right there so this right here this data is going to be essentially what this function returns so right here we can just say localstorage.setitem at kanban data then pass through json.stringify just like that then pass through the data that of course is now going to save your data so basically all the methods we're going to be defining inside here all of the create read update delete you know actions are going to make use of this read and save function from down here cool so let's define our first main function for you know dealing with the api that is going to be to get all of the items inside a particular column so we can say static get items here then pass through a column id so this right here is going to be very straightforward we're going to simply get a reference to the column which the user is trying to receive so we can say const column is equal to we're going to read from the local storage then we can say dot fine so remember the read function here is going to give you an array so we're calling the find method on the array we're going to grab each column i'm going to check is the column dot id equal to the column id being passed in if so it's going to find it and put it inside this constant okay so basically remember this constant of column refers to one of these inside here this object with an id and the items array so this whole object is this column right here next up we can say if there is no column then what are we going to do we're going to simply return an empty array so arguably you could throw an error here or you know just return out or something like that but in this case here going to keep it simple and just return an empty array if it's all good we found the column we can say return column.items to retrieve that items array so now if i save this and just to test this method works if i go inside the main.js let's import the kanban api class so import kanban api from dot forward slash api then kanban api dot js just like that so now let's just say console.log and we can call kanban api dot get items in column one let's save this and go back in the browser and then we can just simply open up the console here and we get an empty array now of course the reason for this empty array is because we haven't got you know any items inside that column but i just want to remove or want to comment out the html from earlier on so let's go back in the index html right here and just comment out everything inside the kanban class okay so back in the browser and we get something like this so like i mentioned earlier this right here is going to be empty so inside the application tab we do not currently have a key for the kanban board this right here was from earlier i apologize let's delete this right here so we are starting empty there is no key of kanban dash data right here so i do want to just quickly copy the data from my example and put it inside our you know our little dev area here so make a new key called kanban data and put the sample data from earlier inside there i can now refresh the page and now in column one we get the singular item here of edits video with the id also so that is the first function or method here for getting an item or sorry getting the items inside a column next up we're going to need to insert a new item so for this one we can say static called insert item so for here when you're inserting an item you need to know what the column id is so we can just pass through a column id right here as well as the contents for the new item we can then read the data so we can say const data is equal to reads from local storage we can then find the column which the user is trying to insert into we can simply copy the copy the code from right up here and just change this read into the data this right here is very important because we're going to be re-saving this data constant into the local storage so we're just saying column is equal to data dot find get me the column with the same id which we're passing into the method here we can then just drop down here and we can say const item is equal to a new object so this right here is going to be the new item to insert we can give this an id and we can simply generate this id randomly we can say math.floor then say math.random times 1 million okay so of course in a real world application you would be generating this id on the server side but in this case right here let's just do it using some client-side javascript we can also set the content property here to be whatever the user passes in so to shorthand this we can just remove this colon then content it's going to do the exact same thing okay cool so now we've prepared all of the constants we can now move on to actually inserting that item so first off let's check if the column exists we're going to say if there is no column then we can just say throw new error we can just say column column there we go does not exist something like that okay if everything goes well we can just say column.items.push and let's add that new item to the bottom of the list okay now we can save the data back to local storage remember because this column right here is a reference to an array inside this data constant right up here when i save this whatever we pushed to this one is going to be included inside there okay cool we can now just say return item to return the newly created item i can save this right here go back in the main.js and we can simply attempt to insert a new item so we're going to say console.log kanban api dot insert item into let's do the second column here and we can say something like i am new i can save this scope back in the browser and now we can see the insert item method returned an object right here with an id and some content perfect right now inside the application tab under the kanban data we can see that in column number was 2 what column was it column 2 in column 2 we have the newly created item right down here no we don't let's refresh and we still do not so actually my mistake guys i apologize it's the second column here id of two there we go so now we can see we get the i am new contents right there being inserted that's working perfectly fine so we can go back and i might just remove this line just to prevent it from you know inserting on each save so we can get rid of that go back in the api file so now we can move on to creating the updates method so right here we can say static update item now the way it's going to work is basically we're going to be passing through an item id so which item are we going to be updating a second property right here or second parameter should i say is going to be called new props so basically this new props object is going to contain the information to update for this item so this could include the content itself the column and also a new position for that particular item okay so right down here just like the insert we're going to begin by getting a reference to the data equal to read we can now basically using this item id we need to figure out first off let's actually get a reference to the item object which we're trying to update as well as its current column okay so of course you pass in the item id you don't know which column the item belongs to so inside here we can say const then say item and current column inside square brackets here so we're going to be using array destructuring to basically then run this function so we can type out a new function inside here inside these parentheses and then call that function straight away okay so now if we return an item or return an array from here for example 1 and 2 item is going to have a value of 1 and current column is going to be 2. so that is the array d structuring right there using this technique so let's figure out the item object and the current column based on the item id so inside here we can say for const column of data so for every single column object inside the data array remember the data array refers to this right here an array of objects for the columns okay so for each object inside here each each column we're going to attempt to retrieve the item so we can just say const item is equal to column.items.find so let's attempt to find the item with the same id as we pass in okay so inside here we can just say item then just do item dot id is equal to the item id which we pass in guys remember this item here is different to this item here okay so this is individual to this one right here it's just a loop and it's just checking if the item being looked at has the same id if it if it does it's going to return it into the item constant right here so if we find the item with the id which we're going to be passing through or which which we pass through we can return the array with the item and also the column which we also are looping through so basically now when you call the update item method we're going to have the item object and the current column is in i might just pause here and console.log the item and the current column constant okay so i'm going to save this go inside the main.js and just test this method so going back inside the local storage let's try to update our newly created item right down here with an id of four one six seven six so i'll copy this id go back in the main js then just say kanban api dot update item with the id of that right there if i save this and go back in the browser we get first off the actual item object itself based on the id and secondly we get the actual column object containing the id of the column obviously column two as well as the list of all of the current items inside the column including the one we're trying to update okay so that is our first step for the update item method next up we need to basically just check if there is an item so we can say if there is no item found then we can throw a new error and just say item not found just like this okay cool next up we can actually update the item content so we can say item.content is equal to if we are providing the content property inside the new props parameter or argument we can say is equal to undefined so my mistake if we don't provide some content to that property here we can just use the current value so we can say item dot content otherwise just say new props dot content just like that and the most complicated part now or the most complex part now is going to be to update the item column and position if you decide to pass it through so we're going to say right here update column and position so if you want to update you know drag and drop an item we can say if new props dot column id is not undefined and you're also providing a position so we can say new props dot position here does not equal undefined so of course position just refers to the position in the column itself so between 0 and the amount of items inside your column if you provide a new column and position we're going to get a reference to the column which you are trying to move the item into so we can say const target column is equal to data dot find then we can say column if the column dot id matches uh the new props dot column id then we've got the target column so i might just pause here once again and just console.log the target column and now i'm going to try to move the item right here into a new column we can say inside the new props here we can say something like a column id let's move it to the column one in the position of zero so the first item inside the first column is where we're going to be moving this item into remember this item right now is in column 2. if i save this and go back in the browser we can see that for the targets column console log here we are getting the first column with the id of 1 which contains the edit video item of course this one right here in the not started okay so that is uh that is that console log right there so moving on we can actually just check if the target column exists so we can say if there is no target column then we can throw an error throw new error then just say target column not found very straightforward next up we can simply make that move so if you pass in you know a new column id a new position let's update that data we're going to say in the current column let's delete the item from its current column so we can say current column dot items dot splice then pass through here current column item of then pass through the item so what's happening here basically we're just getting a reference or we're finding out which index the item is currently in uh passing it into the splice column which is going to delete it because i passed through one right here so basically it's removing one item from this particular index effectively deleting our item from its current column we're going to do a similar thing right down below to move it to a new column we can say move item into its new column and position so for this we can say target column dot items dot splice then say new props dot position whatever position the user is passing in we're going to move it there then we're going to say 0 for the delete count so up here we said one we're going to delete an item down here we're going to say don't delete anything but instead just insert a new item we can pass through here the item to insert into this position inside the target column array i apologize if that right there didn't make too much sense you can always just simply console log the progress as you move through it so the last step for this is going to be to right below here just simply say save and then save the updated data object to local storage i can save this now and go back in the browser as we can see we actually ran this code right here so let's check the local storage so going inside the application tab we can see that in the id of one we have the i am new item moved up here into the position of zero i forgot to mention that the position is going to be zero base which means index zero is going to be position zero or the first item now in its original column of one or two should i say we can see it is now gone so the move has worked we've updated that item now i did forget to test the actual you know content update so let's keep these the same and then just say something like content you know i've changed something like that save this back in the browser and now we can see we have the i've changed updated right there for the item that we passed in so that is the update item method complete the last one for this kanban api is going to be to delete an item it's going to be a lot simpler than the previous one so so down here we can say static delete item pass in the item id i'm going to do a very similar thing where we're going to be reading the data initially then we can just say 4 const column of data so looping through every single column here we're going to try to find the item so like i said this is going to work in a very similar fashion to what we saw right up here so i might just actually copy this code it's the exact same so let's just say item column find the item buy the id then just say if there is no item found or i should say if the item was not found inside this column with this id then we can simply continue so skip to the next column otherwise we can just say column dot items dot splice then just say column.items.index of then pass through item then say one now guys i think this right here is actually bad my mistake because you do not want to skip the entire column if one of them isn't the actual you know target item to delete so we'll say right down here potentially if you found the item then move this code up to delete it just like that my mistake i apologize then next up we can just say save then pass through here the data itself so i can save this then go back in the browser and we can actually test out this delete so let's go back in the main.js right here we can just say kanban api dot delete item then pass through our newly created item 41676 save this go back in the browser and we can see in the first column here that item is now gone so that is all of our basic creates or sorry you know create read update delete methods defined inside the api so next up we can begin working on the view for the kanban board okay so when it comes to coding up the view for the kanban board basically the user interface what the user interacts with we're going to be creating a new directory inside the javascript directory here called view now inside this view we're going to make a new file called kanban dot api sorry kanban.js by mistake so inside this kanban.js file it's going to be a class so this class here is going to define the entry point for the user interface code so inside here we're going to say export default class called kanban now inside here we're going to define a constructor and it's going to take through a root element okay so if you're not too sure how to use javascript classes i've got a whole video dedicated to that but basically this route here refers to this div with a class of kanban in the html so like i mentioned at the very start all of this code here is going to be generated using javascript so that is why we only pass through this route it just means we're going to be using this div to hold all of the you know kanban html and things like that so we're going to pass through that route right there and we're going to say this dot root is equal to root just to simply keep a reference to it now the next step down here is going to be to define a static method called columns and this right here is going to return an array of every single column and its name or title we can say return then pass through here an array of objects we can say an id of one has a title or name of not started okay and do the exact same thing for the next two all right now obviously guys it's probably better if you retrieve the title from your server side but in this case here to keep things simple i'm simply just defining the title of each column and its corresponding id as we stored it inside the local storage layer id of three refers to the completed title right there so now for every single column here so right up here we can say kanban dot columns call that static method right there then say dot for each so for every single column inside our list of columns we can simply do this so going to be essentially i'll just say to do just for now right so we're going to come back to this but we're going to say to do creates a column class okay or an instant so it creates a an instance of column class there we go so we're we're going to come back to this right here so what do i mean by this instance of column class so we need to now have a new javascript class to essentially define the user interface for an individual column that is displayed to the user okay so that is where it gets interesting so let's stop in this file right now and create a new class inside this view and call this one column.js so this one now is going to be saying export default class called column now here this constructor is going to take through an id and a name so remember this class represents a single column in the user interface got the id and the name or the title okay the title of that column so now let's define the html for a column we already saw that in the html from the very beginning with this you know class right here so now let's basically move this html into the javascript so going down here we'll say static creates roots so inside this create root the goal of this method is to return a plane or sorry it's to return an html element as an object containing the basic structure for a particular column so right here we'll say const range equal to document.createrange now this uh this whole range thing is purely just a technique for generating html using javascript so if you don't understand this part don't worry we're just using it to like i said create html so down here we'll say range.select node then pass through document.body and this then allows us to say return range dot create contextual fragment then using the javascript template strings the back ticks near the one on your keyboard we can drop down to a multi-line string and now we can just simply define the html for the kanban column so going back to the index.html let's copy this particular html which we wrote up earlier on and this looks like all of this stuff right here copy this back inside here and paste it right there so we don't need everything inside the html here so we can just remove here the items itself and just keep you know the div right there we can remove the not started title we're going to be adding that in dynamically we're going to be changing the class here to for the items to be kanban underscore underscore column dash items so i made a mistake there guys i apologize but just make sure you rename this to be column dash items instead of just items and down below for the button that can remain the same so this is our html structure for a single item okay sorry by mistake column now we can say dot children here and say at index 0. so this create contextual fragment is basically to put it in simple words it's just a virtual dom tree so basically you can just say dot children as you would normally to get the first one which just simply refers to this entire div as an html object so now we've got the root for a single column in html so now we can say right up here this dot elements is equal to a new empty object and basically we're going to be storing every single html element which we care about inside this object we can say this.elements.root is equal to dot creates root so now we have the root element we can add some more on we can get the title the items container and the add item button so we'll say this.elements dot title is equal to this dot elements dot root now i might just minimize the sidebar here dot root dot query selector and we'll just say kanban underscore underscore column dash title um as the class there i might just remove the uh the sidebar here just to make some more space there we go so we're basically just calling the query selector on the root itself so it's only for this local column not the whole document we've got the title we can now do the exact same thing for the items element and make this column dash items right there and the same for the add item button and just make this kanban underscore underscore add dash item so we have those elements right there so i might just stop right here and actually get something working to further demonstrate what's happening so going back inside the kanban.js down in this to do section we are going to create a new instance of that column so we'll say const column view is equal to a new instance of the column this has been automatically imported right up here but just make sure you change this to be column.js we can pass through the column.oops column.id and column.title into that constructor okay now let's append the root element from here onto the kanban board we'll say this dot root referring to the main container this one right here this dot root dot append child let's add that column view we'll say column view dot elements dot root i'll save this and go back in the browser and we get something like this we actually get nothing the reason being is because if i go back in the main.js there is nothing inside here so we're not actually calling this kanban class so let's do that right now we're going to say right inside here new kanban once again automatically imported just change this to be kanban.js so new kanban and pass in here document.query selector then pass through here the class of kanban just like that cool so passing in that kanban container if i save this all of this code here should now be running go back in the browser let me get this right here as we can see we've got each column appended to the html which we created earlier and of course our commented out code is still there that's working fine all of this stuff is being generated using javascript so next up let's add the title and a few more things so going back inside the text editor let's head into the column.js file so for this one we need to say this.elements.root.dataset.id is equal to id so this just helps us identify which column id it is and it's going to be useful later on when we get to dragging and dropping but for now let's include that right there we're also going to say this.elements.title so the title div dot text content is going to be equal to the title which we pass into the constructor that is going to display the name of of course the column save this back in the browser and we get this right here the name is now displaying and of course we get this data dash id on the actual column itself there we go all right next up if we go back inside here we need to now display every single item that appears under the column okay so for this let's drop down here now i do want to just add some code in so i don't forget about it so before we get to actually listing each item let's just say this dot elements dot add item dot add event listener so just adding an event listener and on click to the add item button so down here we can just say something like to do add items so we're going to get back to this later on like i said but let's keep it there so i don't forget about it then just drop down here and actually you know make every single item under the column appear so right here we need to call the api we're going to say kanban api once again it's got that automatic import let's make this dot js so kanban api dot get item so calling our get items method finally passing through here the column id will then say dot for each so for every single item being returned we're going to grab the item data and we'll just say for now console.log then pass in the item save this back in the browser and we get here in the console every single item that exists you know in the page or on the actual kanban board okay cool next up we need to of course display the actual item in the column itself so we need to once again create a class to represent a item but first let's go down here and just make a new method called render item so we're going to be passing that responsibility onto this method right here so it's going to take in the data just like that all right then we can now call you know this dot render item then pass through here the item just like that so right inside here let's make a comment once again say to do creates the item instance just like we did for the column so let's stop right here and go inside the directory structure and make a new file called item.js to of course represent an item so we're going to do a very similar thing as we did for the column so inside here we'll say export default class of item so for this item class okay this item class we're going to be having a constructor the constructor is going to take through the item id and the contents for that item okay now once again let's make a static method here called creates root it's going to take through here nothing actually so there we go so we have this creates root method now i might just copy and paste the code from the column make it a bit easier for ourselves so i'll copy this and paste it inside here and just change the html so what i want to do here is i want to make a i want to make a container element for each item so let's go down here we'll just say div with a class of kanban underscore underscore item so we haven't actually we haven't seen this class before basically this class is going to simply contain the content editable you know input okay so inside here we'll say div with a class of kanban underscore underscore item dash inputs then say content editable just like we did in the html and we can leave this empty now you do also want to add a draggable attribute here of true on the kanban item class this is going to help us with the drag and drop functionality which we're going to be getting onto later on in the video so that is our creates root for a particular item or an individual item all right so right up here we can say this.elements is equal to a new object just like we did for the previous example with a column we can say this.elements.root is equal to item.createroot just like that we can now say items sorry elements.item sorry sorry guys input okay a lot of words here so this.elements.input is going to be equal to this dot elements dot root dot query selector here and just passing in the class of the kanban item input to get a reference to that particular html element now similar to the column let's drop down here this.elements.root.dataset dot id equal to the id being passed in okay then we'll just say elements dot inputs dot text content is going to be equal to the contents which we passed in to inject that content right there now when it comes to the item itself in order to detect changes when the user wants to update the content we need to store a reference to the current content value so we'll say right down here this this.content is equal to the content being passed in okay so that right there we're going to get to this later on and what it actually does but for now let's keep that right there and now we can just stop here and go back to the column.js so when it comes to the column.js inside the render item method we are going to be creating a new instance of that item class so we'll say a const item equal to a new instance of item passing through data dot id and then data dot content right there okay we can then just say this dot elements dot items dot append child let's add the item dot elements dot root to the items div okay and we'll stop right there so i can save this right here and go back in the browser and we get something like this as we can see we get every single item being rendered inside the html all right so um we are mostly done with with the column.js the next step is going to be to add the code in for this add item button so when you click on the add item button we need to of course add a new item so let's comment this out or remove the code for it and we'll say const new item is going to be equal to once again calling the api we'll say kanban api dot insert item okay we're going to be inserting this item into this particular column id pass it in right there with the default data of an empty string that is your starting item content empty right then we'll just say this dot render item and pass through the new item okay very straightforward just like that save this go back in the browser now if i press add we get that new item right there if i refresh because we called the api it's going to save it's going to persist and it's there forever so that is the majority of the code for the column we're going to be coming back to this later on when we get to adding in the drag and drop but for now it is complete we can continue on with the item class so the item class here is going to be the main one okay so let's drop down here and we're going to be of course you know continuing on with this class so we're going to need quite a few event listeners the first thing i want to do with the item here is give the user the ability to update the content of a single item so let's define a new function here called on blur it's going to be equal to a new function like i just said and inside this on blue this is what's going to happen when the user clicks on the content to edit it and then clicks away okay so when they click away they're most likely going to be finished with editing the content so we can say const new content is equal to this dot elements dot inputs dot text content and we'll just trim off the edges off their you know text which they entered okay so we've got the new content i'm going to stop here in just console.log the new content value and also log out this dot content which we defined right up here this is the original content okay then down here we can say this dot elements dot inputs dot add event listener okay when the user you know blows or clicks away from the input field we can run the on blur function so i'm going to stop right here save it go back in the browser and if i was to go inside the new item right here and i say red for example and get out of it we get this in the console we get an empty string for the original content and red for the new content okay let's try the edits video one let's make this edits two videos for example get out of it we get edit video then edit two videos so we have to check if this value changed okay if it changed we need to of course do something update it right so we'll say if the new content is equal to the old content then we're going to do nothing return out straight away otherwise we need to update this dot content we'll say the new content is going to be the new content okay then let's call the api we'll say kanban sorry kanban api dot updates item pass through here the item id which comes from the constructor right up here then the object we're going to pass in the contents property and make this this dot content the new content value once again just update your kanban api import to be dot js so now if i save this right here and go back in the browser let's make this edits two videos blur out it is now saved if i refresh we can see it persists and it stays there so that is our on update or so on blur and the actual item updating complete all right the next step is going to be to get the deletes working when i want to delete an item so for this if i drop right down here under the blur we'll say this dot elements dot root dot ad event listener when the user double clicks on a item we're going to run this function so this function here is going to first prompt the user and make sure they actually want to delete an item so we'll say const check is equal to confirm then say are you sure you want to uh to delete this item okay well and we'll say if the check was successful they do want to actually you know delete the item there we'll say kanban api oops kanban api dot delete item pass in the id to delete then drop down here and do a bit of cleaning up so once the item gets deleted from the local storage we need to then remove sorry remove the item from the html so we'll say this.elements.input dot remove event listener remove the blur events and we can just say on blur because that is how you identify an event listener to remove it you just pass in the type and then the function which gets called of course this matches up with the ad event listener right up here so that's going to work perfectly fine so next step we'll just say these dot elements dot root dot parent element dot remove child then pass in these stock elements dot root so basically right here we're going to the parents which is going to refer to the column itself then we're saying let's remove the child element of this item effectively getting rid of it from the html i'll just comment out this line here to see a comparison so going in the browser if i double click on the new item and press ok it's gone from local storage okay but it's still right here if i refresh it goes away so having this line in here to remove the sorry remove from the parent is gonna of course make it go away visually i'll add it back hey okay i'll double click press ok and now it's gone from the visuals as well so that is the delete complete and that is the code which is all done aside from the drag and drop so that is where a lot of some new code is going to be added into so let's get into that right now okay so when it comes to getting the drag and drop working for the kanban board the first step is going to be to go right down here in the item class and we're going to be adding a new event listener so we'll just say here this dot elements dot root dot add event listener we're going to listen for the drag start event so this drag start event is going to allow um the actual item to be dragged by the user so we're going to grab onto the event object right here so this little e and we can simply set some information on the data transfer component of the event object so this is basically how we're able to communicate between two html elements as they get dragged and dropped so just bear with me if you're not too sure how this works if you want i've also got a video dedicated to the drag and drop api if you want to check it out but for now we'll just say e dot data transfer dot set data for text okay then we're going to pass in here the id okay now this can probably or this probably should be text forward slash plane if you want to be specific so we're setting the text to be the id so this refers to of course the item id all right so we've got this drag start i'm just going to save this right here and then go back in the browser then attempt to drag one of these items so i'll just grab onto the edit video here and we can see i'm able to drag it across so this is the first step in getting the drag and drop working or you know the actual you know kanban repositioning working so if i drop on this text this input field or this you know div we get the item right there we get the item id so this is where this is where that set data came from so whatever we set inside here the id if i make this decode for example and drag and drop okay so whatever we set inside that particular method that is going to be attached to that particular event that drag and drop event it gets attached to it so of course in that case right there when i showed you this we don't want that we don't want this drag to do that okay so to prevent this from happening so to prevent sorry i can't talk sorry um it's been a long day to prevent that from happening we need to go back inside here and we need to say this dot elements dot input dot add event listener listen for the drop event so when the input field gets dropped on um we need to basically just stop that from happening so we'll grab the e event object and we'll say e dot prevents defaults okay so this here has nothing to do with the standard kanban drag and drop this is just to prevent the text from appearing inside the input fields by accident so now if i drag and drop this it no longer works so we're basically just preventing the default behavior of that you know copy and paste or whatever you want to call it but it's important to know that with that demonstration you're attaching the id the item id to that event so now we can move on to actually getting the kanban drop or drag and drop working so for this let's make a new class inside the view called drop zone dot js this drop zone class is going to represent a singular drop zone like i showed you at the very beginning in the html so this drop zone is going to contain the majority of the code for the kanban drag and drop so here sorry i had a bit of a mouth sound there so we'll say export default class drop zone all right so in this drop zone class i'm going to have a single method called static creates drop zone so this is going to once again just like the column and the item it's going to create the html so i'll just copy from the creates root here okay just like this so const range etc now here instead of returning we're gonna say const drop zone is equal to then range dot create contextual fragment inside here just pass through a simple div okay with a class of kanban underscore underscore drop zone okay then at the very end we're going to return the drop zone so just like the other one but of course this time we're gonna do things inside here before we return it so this is where the magic happens with the drag and drop so the very first thing to do is once we have a drop zone okay we need to add that css class of active to give the user the impression that you can actually drop here so we're going to say dropzone.addeventlistener and listen for the drag over events okay we're going to grab on to the event object once again and then say e dot prevent default this is important to ensure that drag and drop actually works in different scenarios we can then say drop zone dot class list okay we can say add and we can add that kanban underscore underscore drop zone dash dash active modifier class so now okay this you know drop zone class has been created we now need to add the drop zone or add a drop zone um underneath every single item okay so going inside the item class let's create a new constant in the constructor called bottom drop zone okay the bottom of the item we can say drop zone dots creates drop zone just like this now of course this is wrong so we have to import drop zone with a capital z okay just be careful here it's going to come from dot fold slash dropzone.js so now we have the bottom drop zone let's add the drop zone to the container for the kanban item okay so right up here in the constructor once again we're just going to say under this we'll say this dot elements dot root okay dot append child let's append that bottom drop zone so now if i save this in the browser we can see we have some space between each item this is the space for the dropdown this is that is literally the drop zone right there so if i click and hold over a drop zone it gets that active class it doesn't go away we need to of course add that in but it is being added there so that is our code working of course if i drop nothing happens so we of course need to actually fix that but now let's go back inside the code and continue on with the drop zone class so after we've added this you know event listener for the drag over um let's add the event listener for the drag leave so we can say dropzone.addeventlistener when the user drag leaves okay we can simply just we can remove the active class so we'll say classlist.remove this time around save this code back in the browser we can drag over go away and it goes away right there so that's working perfectly fine and we can now continue on with more code for the drop zone so this is where the majority of the things happen so drop zone dot add event listener and we can listen for the drop event so when the user decides to drop onto a drop zone we're going to grab onto the event object and we'll say as usual prevents default on there we'll then also remove the drop zone active class because that's a different way for the user to of course you know lose focus on the drop zone so we can remove that class right there then we're going to define a bunch of constants okay first off we're going to find out which column is the user trying to drop onto we'll say const column element is equal to drop zone dot closest okay can ben underscore underscore columns so basically this right here is going to give you the html element for the column which this drop zone is inside of okay then we'll say const column id what is the id of that column we can use the number sorry equals we can use the number function right here and we can say column elements dot data set dot oops dataset dot id so grabbing that data set id which we set in this line here in the column class we're grabbing it from here we have the column and the column id i can now just do console.log let's log out the column elements and the column id just to track our progress save this back in the browser drag over a column sorry a drop zone let go we got the kanban column and the id of two right there so basically we're defining these constants to eventually pass them into um you know the api to update the item okay next up we need to figure out okay you've dropped you know you've dropped this into this column here now which position are you trying to drop into all right so for that i might actually go back in the column code and we're actually going to have a drop zone inside the column because as you can tell if i go back in the website or the browser i can't drag on top of a item right there so the first position you know in a in a column so let's add a drop zone to the column itself at the very beginning so i'm back inside here in the column let's make a new constant called top drop zone in the column class equal to drop zone dot creates drop zone right there then of course going right down here we'll say this.elements dot items dot append child okay and we're going to be appending the top drop zone so this append child is going to happen before we render out the items which means that the drop zone is going to appear on top i save this go back in the browser and we have some space now between the title and the item so now i can drag this above onto the drop zone right there so let's get back to the drop zone code and we're going to be figuring out what position did the user drop onto of course in this case here if i drop onto this middle section between planning and coding those items this is position number one remember the position is going to be zero based so position one is going to be the second in the list zero is going to be the first one so we want one to come out of our drop there so back inside here we'll say const okay and we'll say drop zones in column equal to array dot from then say column elements dot query selector all select every single can ban drop zone so this is halfway there to figuring out our position i'll just console log this drop zone is in column basically it's going to be an array of drop zones save this back in the browser i'll drag onto the middle section here and we get three drop zones inside this particular column right there so now it's going to be as easy as just figuring out okay which one is this zero one or two back in the code we can say const dropped index is equal to drop zones in column dot index of then pass through the drop zones in oops my mistake this needs to be the drop zone so this drop zone is of course our main drop zone right there so just basically find the index of our one in the list of all of them okay so now the dropped index is going to be equal to this case here it'll be the 1. do it again on top it gets 0 and then of course 2 down there if i drag and drop onto the same one we still get 0. bottom here we get 1. so that is our you know that constant defined so we're almost there in terms of all of our constants next up we need to deal with or figure out um you know things relating to the actual item so um basically which item did we attempt to you know uh drop or drag and drop so for this we can just say const item id is equal to number then say e dot data transfer dots gets data then text forward slash plane so this right here is basically getting the events where is it on the item this set data here for the id is being then picked up by this code here so basically now if i console.log the item id we're going to get the id of the item which we're dragging across boom 2304 all right so we have the item id next up we're going to get the actual item element which we are dragging and dropping we're going to do this using the item id so we'll say const drops item element is equal to document.query selector then we're going to pass through here because remember remember we used the we used the data set on the div right here so this data id so i'm going to simply use a query selector i'm going to be selecting the element with the attribute of a data dash id equal to then inside these are double quotes here we can use the string interpolation here i believe it's called i've got about memory right now apologize but passing inside here this uh dollar signs and these curly braces we can pass through the item id so now the dropped item element is going to be equal to of course the one in which we're dropping and we get that one right there there we go it is working fine so now we have a lot of our constants the very last thing to do here is going to be to figure out okay i've dropped on a particular you know drop zone where do i then insert that item in the html what does it what does the user see visually straight away so we'll say const insert after is equal to you know what guys let's let's just uh let's just stop there for now i want to get to that later on i apologize um let's just now use the api to actually drop and update some elements all right so we'll get back to this later on if i go down to the console here i'll remove this line i'm going to call the kanban api so we'll say kanban api dot update item we're going to update the item we're going to pass through the item id which we of course discovered also the new column id into that new props object okay then we'll say position is equal to the dropped index all right so we're going to make the api call also remember guys to add that dot js right up here there we go um we're making the api call of course to update the item if i save this go back in the browser and i drop in the middle here that is now saved in the api or in the local storage if i refresh it's now appearing right there so our save is complete but of course we do not get that instant you know drop right there okay so to to fix that we go back to this insert after code so where are you inserting which which drop zone are you inserting after all right for this we'll say drop zone dot parent elements dot class list dot contains kanban item so this is checking if your drop zone is part of a kanban item if it's one of those bottom ones from this item class right here if that's the case then you're going to want to append to the parents element of the drop zone all right so we'll say drop zone dot parents elements all right of course the parent of the drop zone refers to the actual you know item itself okay then we'll say colon drop zone otherwise we're going to be appending after the drop zone i may have said inserting into that's not right what i did mean is we're going to be inserting after the parent which basically just means after the kanban item itself all right so if i console.log the insert after right here i save this go back in the browser and i drop it oops i drop this let's drop this edit two videos into this middle one here it's going to be inserting after that record video right there all right if you want to you know i'll refresh if you want to drag this record video into in progress we're going to be inserting after the kanban drop zone so of course that refers to the first item in that in that column there so we have the insert after constant we can now very simply go down here and we'll say insert after then call the after method to simply insert the dropped item element into that particular section now if i save this and go back in the browser i can refresh click or move to not started and it drops there shut away as well as committed to local storage now the very last thing to do here is going to be to prevent a bug inside here we can say if the dropped item element dot contains the drop zone then we need to return so if you're trying to drag an item into its own drop zone then we're going to do nothing we do not want to update the api in that case so we can just exit out right there save this go back in the browser and we are complete with the kanban board we can drag and drop it's going to work there and everything is going to work like i showed you in the demonstration okay so that is all for today's video guys that's how to you know create a kanban board using html css and javascript my voice is really bad right now if you guys enjoyed today's video drop a like and subscribe i really appreciate it and that is all so i'll see you guys in the next video
Info
Channel: dcode
Views: 8,839
Rating: undefined out of 5
Keywords: html css javascript project, javascript project ideas, projects for learning javascript, web apps for learning javascript, learning html css and javascript, javascript classes tutorial, html drag and drop api, native drag and drop javascript, best javascript projects, best html css javascript projects for learning, javascript practice, projects to build javascript skills, how to get better at javascript, improve javascript skills with project
Id: ijQ6dCughW8
Channel Id: undefined
Length: 85min 39sec (5139 seconds)
Published: Mon Sep 20 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.