Drag and Drop Tutorial with React DnD (Trello Clone)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys what's up in today's video I want to go over an interview question that I got recently for a web developer role and basically what it was was to recreate Trello now this is an example of Trello from their website and basically what it is is it's an organizational tool that allows you to create categories of content or items and then add items to those categories and update your team on you know how far you've gotten what you're doing let them post comments and share and just kind of have this like really nice and easy to use tool to create lists and then add specific information to those list items in addition to that you can drag items you can't do it here but you're able to and the final version of their product so my task was to so the interview question was just to recreate that right so we're gonna do is we're gonna recreate a really simple Trello dashboard that has four different categories for the status of tasks and what you're gonna be able to do is drag and drop them from place to place but only to their neighbor categories so for instance you can move done to in progress it has to go to in review first interview can only go to in progress or done it can't just jump all the way to open and then you're gonna be able to drag these items and also drop them as we already saw in addition to that when you click on the items it's gonna show a little simple modal window and some relevant information to that item ok so this is what we're gonna be building today it's gonna be pretty cool and we're gonna be using the react DND library now I know that there's already videos of this on YouTube but I actually looked through them and I thought they were really complicated it seemed like they took a really long time and some of the ways that they were doing the drag-and-drop was a little messy so I want to do it with this library first and then in the next video we're gonna go over how to do it natively and just JavaScript without a library so this is a react library and basically what it does is it wraps your components as you can see here and injects props into them so you can just think of it as it providing them some passed down context or something like that and wraps your components with some data and it gives you that extra functionality to drag drop and then collect the final state as you're moving or dragging your components around okay so that's a basically an overview what we're going to be doing why don't we go to my react D&D starter I'll put this link in the description and we're just going to clone this okay they're going to open this up in Visual Studio okay and the first thing you're gonna see is this is built off of my web pack starter repository so there's already a lot of stuff in here like all the style that we're gonna be using because I didn't I don't want us to do that on camera and then it's gonna have an app and then we're gonna have some pages for the home page we're gonna have a data directory that has all of the maca data that we're gonna use so that's right here you can see the statuses and you can also see the data and yeah so it's basically a setup really simply like my web pack Star Trek and go over that but it's basically a clone of create react at okay so now that we're ready to start going I think the first thing we're gonna want to do is create some components that our homepage is going to use so why don't we create a new folder called components and inside of this we're gonna do our easiest component first it's going to be called column and the only thing that this is gonna do is it's just going to be a wrapper component for all of the items or the categories like that in progress done and in review this is just going to be a wrapper for it where we can put content so we want to know two different props so we want to know that children and we also want to know whether the item is is over this column so if you're dragging over this column that's what we want to know and that's just going to be true or false so right here we're going to equal this two column class name and then we're gonna do children so basically this is gonna know whether an item is being dragged over on top of the column or not and the reason we have highlight region is because if you look back at our example it highlights yellow when you're dragging over it so that's all this component is gonna do for us okay so the next thing we want to do is probably the item so let's look at the item and this is gonna be the actual item right here that you drag over so as you can see we have the columns obviously this silver grayish block and then inside of it the white block is the item okay so this is where we're gonna actually use the the library so let's do import react when you get some things here we need to get the fragment we need to get you state and use rep we need to get use drag use drop from react DND you need to import the window and this is a file that we haven't created yet so just sit tight and then we also need to get something called the item tight and we haven't created that either so why don't we go into data and will create the types file and all this is going to be is it's just going to be a constant variable and this is going to be called item this is just the the type of the drag item so basically react D&D requires that you specify the type of the item so that it has a way of distinguishing what kind of draggable item you're working with at the time and we're only gonna have one but maybe in applications you'll have a few so that's why you declare a type for them okay and then I also forgot we need to install our dependencies so why don't we go ahead and do that real quick okay so we need to do npm install react D and D react D and D html5 back-end and then we need react to modal as well so we're going to use to create the window those first two dependencies are actually just listed right here so that's where I'm getting them and then we're also going to be using this modal library called reactive modal which is just this right here and you can look up that it's really simple to use it's basically just a a pop-up window okay so we're just waiting for this to load finish installing okay now before we finish the item there's a couple of things I want to do real quick so let's just create the header sorry I know we're jumping all over all over the place but trust me these are really easy components oh you really don't even need this if you don't want but it's just to kind of give the app a nice looking feel to it okay so this is just gonna be the header and all it's gonna do basically is just have Trello dashboard on it so we want to call this row and then we want to have a pink tag inside of it and this is just gonna be called the page header and it's just gonna say Trello dashboard now I have some emojis that I've been using I can't remember what website I got this from but I'm just gonna copy and paste it the website is actually called get emoji comm so you can find it here if you want to get um those icons whatever you want to use they're really nice you just basically click on it and copy and paste okay so we're just gonna do export default header so we have that and then we're going to go to our app and in order to use um react D&E we have to wrap our entire application or section of our app that we're using with the DND provider and basically what that is is if you've ever used to react context this is just a way to supply the state that we're gonna need in the props and passing the props down to all the different components so you can just think of this as a wrapper for our entire app that's gonna allow us to use that react D&D functionality this is just something that you have to do you also have to pass in a back-end to it you can use a separate back-end than the one that they provide but I'm just gonna get the one that they provide because I think that's easier and then we're gonna render our header here as well and I think that looks good so DD provider back-end okay perfect so we're gonna get out of that now we're going to go back to our item and we're gonna finish this up okay so why don't we create our item component and now the only thing that the item is gonna do is it's gonna be responsible for moving the item um within the container and then also on to UM the other columns I think we're gonna have to go through it I can't remember exactly let me look okay yeah so just like I said this is gonna be responsible for moving our item within the same column that we have or moving it between columns when you actually drop it into place on another call okay so the syntax that they use is they use this comma bracket so that we're only using one variable and the reason that they do that is just because they don't need whatever the first D structured variable is so they just put a comma because we're not gonna use that variable ever so we don't need it so we're gonna use the use drop hook that they provide us and it's gonna accept an item types this is what we were doing earlier we only have one item type so you could really just put whatever you want there so we're gonna do item monitor for when it hovers now this is a callback that it's gonna call and I'm just going to basically copy and paste the logic that they have for hovering on another column you guys can obviously write your own but I think this is probably the easiest way to do it so basically we want to know what the drag index is so as we click on a as we click on an item we're gonna assign an index to it and we want to get whatever that index is it's also going to let's see yeah so this index right here is gonna be whatever we're hovering over so whatever column we're hovering over it's gonna give us that index right there so drag index equals hover index we're just going to return because we don't want it so if it's hovering over the same item then we don't really need to do anything there so we're gonna do hovered rectangle equals ref dot current dot get bounding client rectangle and then we're gonna do get the middle why so they just hover rectangle that bottom hovered rectangle dot top and then we're gonna get our mouse position so ever our mouse is and wherever we're dragging it on the screen that's a function and then we're gonna get hover client Y okay and now we're gonna do some checks for whatever we need to return because we don't need to do anything so the drag index is less than the hover index and the hover client Y is less than the hover middle Y now we're just gonna return so we don't need to do anything there so that's just saying if yes let me try to explain this one more time that's just saying if the drag index so whatever item index we're working with we click on an item if it's less than the hover index so why don't we just show right here so if it's less than the hover index then we obviously don't need to move it but if it's more than we want to move it down so if it's half way over the card that it's hovering over then it's gonna pop down I hope that makes sense I I know that was a really bad explanation at the beginning okay so now if the drag index is over the hover index and the hover client y so let's just check for the opposite condition if you're traveling upwards so for in since if we have this and it's not you know halfway over the card on top then return put it back in the right place but if it's not let's put this over here if it's not put it on top okay so I'm gonna do move item so this is the callback that we're gonna supply and this is just going to allow us to actually change where the card is in the same column and we're going to do item dot index equals hugger index okay so that's looking pretty good now the next thing we're gonna do is we're gonna use the is dragging or we're gonna use the use drag hook so while we do this now the use drag hook looks a little different so it needs an item and the item is going to be an object that we create right here so we need the type we need to spread the actual item that we pass in here so all the data and then the index that we supply and then it's also going to use the collect call back so the collect call back basically gives you a bunch of props and data that react D&D supplies for you and one of the things is the monitor which is basically a copy of the screen um so like whenever you're moving your mouse and you're playing with the screen that's the monitor and it's going to tell us whether or not we're dragging the item or not so that's all we need to do right there and then we need one more variable first show and set show let's do you say false so this is going to be for opening the window and such when you click on an item it shows false and then we're gonna wrap drag and drop with the ref that we get so it's going to give us a an actual um like way for us to identify and locate the HTML item that were working with and you have to do that with um the user ref hook because as you know react doesn't work with an actual literal Dom it's a virtual Dom okay so we're gonna do ref with the ref our style we're gonna do opacity so if it's dragging then we want it to be invisible on the actual list and if it's not dragging then just make it visible class name is gonna be item on click equals on open div class name equals color bar and then the style is gonna be background color status doc color okay and then this is just gonna give us that little rectangular color block next thing we're gonna do is like the actual title of the item so this is gonna be a little darker and a little more pronounced so it's easier to read and we get that from the item dot content next thing we need to do is I think the status item that status now if you want this to look different you can obviously do it in whatever way you want this is just to kind of show it one way that we can do it and then we also just wanted to make it look like the react Trello the way that they have it on their website so I was just kind of trying to copy their style right here okay so then we have the window and this is just going to show that little popup menu we're gonna do on clothes show equals show okay and they're gonna do export default item okay and then I guess what we should do is we should just do the window real quick since we're already working with the item that you drag so why don't we create a new component window JSX and we can just quit get this done this is only 20 28 lines of code so it's really simple I wanted to put it in there so we're gonna import react we're gonna import modal from react modal do modal dot set app element and it just needs to get a ID for your the root of your app so in our case it's the ID is just app because we set it up my web pack starter sets it up exactly as the create react app does okay so we need some it's gonna give us three props right here we're gonna pass it the show weather to show the window what you do when you close the window and then the actual item and all of the data associated with that item so just to kind of show you what the data of each item looks like it's just this right here it's um we have an array of items and then we have an object that represents each item so it's got an ID an icon a status a title and a and some content okay so we're gonna do is we're gonna create our modal and this is gonna be is open that's gonna be equal to our show variable we're gonna do on request closed equals on close and this is just um their API and how it's set up so that's where I'm getting all those prop names from just following the documentation and then overlay class name so what is it going to what is the overlay gonna look like when we actually click on the item so you can see how it's darker right here that's just what that overlay class name is for okay and then we're gonna do div class name equals close button container okay so we're gonna have h1 style we're gonna do flex and this is just gonna take up 90% 90% of the row and then we're going to do h1 I have that oh I need to a little closing character alright they're gonna have a button for closing it this is just gonna be the X that you see in the top hand corner top hand right corner and then on click equals on clothes and the button is just gonna have an X right there okay and they're gonna have another wrapping do and this is gonna be h2 and then this is just gonna be for the other properties of the element or of the item object so we're just gonna display that so you can see how easy like this would be to extend if you wanted to add more to the objects and you know kind of figure out more information that you can display and either a fancier way in either a fancier way or just providing more functionality to this app that we that we have and if you if you want to do that like adding items and such you should definitely do that because it'll help you practice for any interviews that you might have in the future and then also just get a better understanding of how this is working as a whole okay so let me ask that and this needs to be a dollar sign okay then we need to do a closing carrot there okay and then delete that one okay and then this uh this fancy like piece of code it's not fancy but that like complicated piece of crap is on just to capitalize the status that's all that that's there for okay so it's looking good and we're gonna do export default window and I think the last thing we need to do now is just the drop wrapper and this one's actually really simple we already did all of the we did the hard one which was the item one okay so we're gonna do the drop wrapper and what this is gonna do is this is going to be um the parent wrapper that is that encloses the parent component that has the column as its children as a child and the items as children um so you can see that the highlight region right here this yellow block is the column and the drop wrapper is actually this this whole thing right here this whole silver block and the reason that we have that as the parent components because we need to have some indication some idea on whether knowing this column rank or the silver column is a droppable container so that the items can actually move between it as such okay so why don't we import the rest of our functionality so we need to use the drop hook again we're gonna do import item type from data slash types and for statuses from our [Music] our data folder okay so we're going to do the drop wrapper and this is gonna be on drop children and then status okay then we're gonna do const and then we're gonna de structure out some stuff here so it gives us an object as the first variable but we only need that first or that is drop property from the object so that's why ID structured it right there we're gonna use the used drop hook so again remember it accepts an item type you always have to supply that the item and the actual you know like so the draggable element and the droppable element they have to accept the same item type or it will always reject it so for instance if this item right here was of item type red and the droppable column was of item type zebra or something and they so they don't match in that case then it would just reject it every time like this it wouldn't let you drop it but since the item types are the same we can just drop it right here so that's what that accept property is for so now we can you can drop item monitor so this is just a a can drop book or call back sorry not not a call or not a hook a call back okay so we need to find the items index so we're gonna do two status is and then so the status icon so si dot status equals item not status so I just put si for status icon um cuz if we look at this right here it has an icon associated with it a status item is what I put si there for just in case your honor okay so we need to get the item index because basically when we drop when we drag our items over these drag these items over the columns the little cards I need to know what the item index is for the actual item so that we can see whether or not you're allowed to drop it or not because they have to be right next to each other um so that's what we're doing right here we're trying to see if the indexes of the columns are right next to each other if they're like one off or one less because that's how we're going to either reject the drop or accept so I hope that made sense - I'm like doing awful and explaining this right now but it honestly should be a pretty self-explanatory I think when you guys look at the code like I think you'll be able to understand it pretty clearly I might just take some extra time to look at it since I suck at explaining things so basically I created an array right here and if it includes the status index right here so if the item index is either 1 greater than or one less than or the already found item index so if it's equal to the column you can drop it if it's to the right of the column you can drop it and then if it's to the left of the column you can drop it but if it's not any of those so it's on the opposite side or it's to greater than or to less than then you can drop it so I just used include right there so we can either get a true or false statement okay so we have that now we need a drop callback so we're going to do drop monitor those are the two parameters we're gonna set right there and then we're gonna do on drop and the status okay and then I'm gonna do collect monitor and then this is just going to tell us whether it's over or not oops let's do that excuse me okay so we're going to return some HTML now it's going to be really simple so our reference is going to be the drop ref that we created at the beginning okay and then we're just gonna do react clone element and the reason we're doing this is because we're passing a bunch of children into this parent container this is basically just a all right to tell you whether or not you can drop stuff into this HTML that's within it and so we're gonna use reactant clone element there because we need to actually pass the props down into down into the children elements so that's why I used clone element and then I'm passing the is over prop okay so we have all of that you can see that we got the is over property from here from collect and it's just gonna equal a balloons the boolean's statement to tell us if we're dragging anything over and then we also got the ref from that second that second d-struct variable okay so now the very last thing and then we're gonna be able to run this and see if it works is setting up our home page to actually put everything together so let's do import item from components item import the drop wrapper components drop wrapper and then import column from the components and the column and then we're gonna import data and statuses from data okay and then we're just gonna delete that and we are gonna do Const items set items equals use state and we're just going to copy that from our data structure so this is just gonna give us an array of items that are objects okay so now we want to first set up what our on drop command is gonna do for our items in our state because what we're gonna do is we're gonna like move the indexes of these items um if we look at this right here so the ID we're gonna move the statuses in the icon are we're going to change these statuses and the icons as we um draw things into different containers that's how we're gonna update these variables okay so status is that find we're gonna do the status item so if the status equals the status that we popped in then or we need to find the status of the status that has passed in to us so we're gonna do prep state and then we're gonna do new items equals previous state dot filter so get the iso filter out the item that we're currently dropping that's what's gonna be passed back to us so filter that one out and then we're going to add it back into the array so we're gonna get the item we're gonna set the new status and then we're going to get the actual icon from that mapping that we did and then we're just going to return our new items we're just gonna use spread okay so basically what we do is we filter out the item that we're currently dropping and then we set the new status that we got right here and we set the new icon for the for the column I mean that's how that's how that works that's how I chose to chose to do I just get the item that matches the the column or the status icon that matches the column okay so on move it gives us remember the drag index and the hover index the drag indexes of the items and then the hover index is whatever item that it's on hovering over so items drag index so we're gonna do set items previous state and then we're just going to do the same thing that we did before so we're gonna filter out the item that it gives us so i ID x ID x does not equal the drag index so whatever item that we're currently working with that we're currently dragging let's take that out and then we're going to insert the new item that is sent to us in this in this callback and then we're going to return the new item so all we did is we filter it out and then we inserted ok sorry and I actually put this in the wrong place so why don't we copy and paste and move that down ok return ok I'm gonna do row I'm gonna do statuses that map I'm gonna do return okay so in here we're just gonna map through all of our statuses and what this is gonna do is this is gonna create the actual columns with the status names in our app or in those um sorry excuse me it's gonna create all of these different columns for the statuses so we have open in progress yada yada this is just a map function to iterate and create all of those so we don't have to do it um we don't have to type it out explicitly we can do it a little more dynamic so if you wanted to change you know the status columns here the categories are what have you you can do that to fit your needs okay so we have the h2 it's just gonna make it a header tag so it's a little darker obviously we want it to be darker okay so we're gonna pass the on drop call back here I'm never gonna pass the status so I can figure out everything you need to do in this drop wrapper and then we're gonna have the HTML content within here so we have the column so it gives us the highlight region and then we're gonna do um the actual items so we're only going to get this is where it's gonna make a lot of sense so we're only going to show the items in this column that equal the status of this column so we have filter and then we have map so and then IDX and we're going to create a item as well from whatever we get back from that filter call so the key is gonna be I dot ID because we assign a ID to all of our items in our data structure the item equals I the index equals the index that we get through from this map call and then move item is move item so that's that callback to actually move the item and then status equals s okay and I think that is all we need to do so why don't we save here let's clear this and then we can do NPM run dev all right looks like it compiled successfully that's good let's refresh this and of course it craps out on us I knew that was gonna happen homepage let's look at that oh that's because I did not D structure out you state so we need to get that now let's do this and countered it with the same key okay so that's not good so why don't we look at that real quick okay and what we have to do is we had this as status before but it needs to be s not status to get rid of that key issue so let's save let's refresh all right and let's see okay perfect look at that so it looks like everything is in place can we drag oh okay it looks like we might have messed up a little bit looks like you can't drag it appropriate so don't open this back up okay and another thing we need to fix is the background color I messed that up just need to capitalize that alright and then the last err we made was a spelling typo oh my god this took me so long to find okay so if you just copy and paste that rec reps out current I get bound and client rectangle and then the last spelling mistake right below it is you can see that we have Howe Baird needs to be hovered okay and that should thankfully be the last one so let's refresh and now you can move and drag it and drop it just like we wanted to in the demo okay that took so long to find those spelling mistakes oh my god okay so I hope this helps just a little bit with how you can do this and are really easy simple to simple to do away with react D&D library if you liked the video please a comment like subscribe all that good stuff if you didn't like it you absolutely hated it just let me know you know any feedback is welcome tell me I suck that all works too okay thank you and I'll see you guys in the next video
Info
Channel: RyanMichael Hirst
Views: 76,073
Rating: undefined out of 5
Keywords: Trello Clone, Trello Clone with React Drag-n-Drop, Drag and Drop React, Drag and Drop React.js, drag and drop tutorial react, drag and drop javascript, drag and drop tutorial, react dnd, react dnd tutorial, react.js trello, react trello, drag and drop javascript tutorial
Id: aK2PD_REk7A
Channel Id: undefined
Length: 40min 9sec (2409 seconds)
Published: Sun Apr 12 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.