‫So let's now come to the end of this project,
‫and that involves the possibility to drag and drop
‫a project which we have in one of the boxes,
‫for example, in the active projects box
‫into the other box.
‫So, to basically switch the project from being
‫an active project to being a finished project.
‫So, it's also not just about the visual update
‫it's not just about dragging and dropping it
‫and updating the UI, it's also about adjusting
‫the data behind the scenes in our state management class
‫the project state where we manage a list
‫of projects in the end, keep in mind
‫that every project does have a status property
‫and we'll need to update that as well.
‫So, two things we need to implement: drag and drop
‫and then all of this behind the scenes state
‫and data update.
‫Now let's start with drag and drop,
‫and for that we will basically implement drag and drop
‫as we would do it in vanilla java script
‫which you, for example, can learn about
‫in my complete java script guide.
‫Basically, it's all about implementing a bunch
‫of event listeners and of course you will see
‫how it works in this module in the next lectures,
‫but we'll implement it in typescript style,
‫so we'll enhance it by using some typescript features.
‫So, let's get started and how do I want to enhance it
‫with typescript features?
‫Well I want to reuse interfaces here.
‫Drag and drop interfaces,
‫but not just to define the structure
‫of some objects as we previously used interfaces
‫but instead to really setup a contract
‫which certain classes can sign
‫to force these classes to,
‫to basically implement certain methods
‫that help us with drag and drop.
‫To be precise I'm thinking about two interfaces,
‫and of course, using these interfaces will be optional
‫but this will allow us to, well,
‫basically provide some code that forces a class
‫to implement everything it needs
‫to be draggable or to be a valid drop target
‫which if we were building a bigger application
‫could help us write cleaner code
‫and more understandable code, especially
‫when working in a team.
‫So, which interfaces am I talking about?
‫I want to have one interface,
‫which I'll name draggable,
‫and I'll have a second interface
‫which I'll name drag target.
‫My idea here is that we can add
‫the draggable interface to any class
‫that renders and element which can be draggable.
‫In our example, that would be the project item class.
‫The project item class is responsible
‫for rendering, well, these project items
‫and these should be the draggable pieces,
‫and the boxes, active projects and finished projects,
‫so here our project list class should be drag targets.
‫Now, what do these interfaces force to be implemented
‫or to be added to the classes then?
‫Let's start with draggable.
‫Here, we basically need two event listeners
‫and therefore two handlers for these events.
‫A drag start handler, which will be a method
‫and a drag end handler,
‫because when implementing drag and drop
‫the thing which you want to drag
‫will require some listener that listens
‫to the start of that drag event
‫and also, potentially a listener
‫that listens to the end of the drag event
‫so that can do any kind of updates there
‫which you want to do.
‫Now, the drag start event handler
‫will get an event object which we
‫will have called drag event, that's a built in type,
‫types with options libs, because of our TS conflict setup
‫and the libs we're adding there
‫and it will not return anything
‫it will be a method which executes
‫but which then just does something,
‫configures the drag event for example,
‫but does not return.
‫Now the drag end handler gets a similar event,
‫it also gets a drag event and it all returns nothing.
‫Now, of course you will see how we apply those
‫in just a few seconds, so bare with me.
‫Now, what about the drag target?
‫Well, for the target, so the box
‫onto which we can drag something
‫there are three event handlers I want to implement.
‫A drag over handler,
‫a drop handler,
‫and a drag leave handler.
‫Now, what do these things do?
‫Now, you need to implement a drag over handler
‫when implementing drag and drop in java script
‫to basically signal the browser in java script
‫that the thing you're dragging something over
‫is a valid drag target.
‫If you don't do the right in the drag over handler,
‫dropping will not be possible.
‫You need the drop handler then
‫to react to the actual drop that happens,
‫so if the drag over handler will permit the drop
‫with the drop handler will handle the drop
‫and then here we can update our data
‫and UI for example and the drag leave handler
‫can be useful if we're, for example,
‫giving some visual feedback to the user
‫when he or she drags something over the box
‫for example, we change the background color
‫well if no drop happens and instead it's canceled
‫or the user moves the element away we can use
‫the drag leave handler to revert our visual update.
‫Now, all three handlers all receive a drag event
‫and don't return anything,
‫so let's update them appropriately like this.
‫And also for this last handler here.
‫And now we configured some interfaces
‫which on their own don't do much,
‫but now we can use them and I want to start
‫with the project item.
‫So let's find our project item class for this
‫here's the component, here's the project item,
‫and now you might remember that an interface
‫cannot just be used to define a custom object type
‫but that you can use it as a contract on a class.
‫You can call implements, or add implements here
‫after your class name
‫and after potential extensions you are doing
‫and then implement the interface.
‫In this case, the draggable interface.
‫Now, when you do so, and I just formatted this
‫to bring it in a new line to make it easier to read.
‫When you do so, you get an error now
‫that that the class here incorrectly implements
‫the interface because that draggable interface forces us
‫to add two methods, if you remember.
‫So, let's add them here.
‫Maybe we'll load a constructor.
‫Let's add a drag start handler
‫which gets an event of type drag event
‫and let's also add our drag end handler
‫which receives our drag event.
‫And now we have these two methods added.
‫Now, that alone does not enable drag and drop.
‫It just helps us write draggable components
‫or draggable classes in a uniform way,
‫so if we add more and more classes
‫which should be draggable, we always will have these methods
‫which simply makes it easier to reason about our code
‫and to work our code, especially when working
‫in a team, because everyone knows where to put
‫in work for the drag start event.
‫Now what this does not do, of course, is listen
‫to a drag start event.
‫That's something we can do in the configure method
‫which you already have though.
‫We can reach out to our rendered element
‫and add an event listener to it
‫and there, that would be the drag start event.
‫The drag start event is one event,
‫one default browser dom event you can listen to
‫and the even handler we want to trigger,
‫of course, is the drag
‫start handler, at which we can point here.
‫Now, we also want to be sure that
‫inside of the drag start handler
‫that this keyword refers to our class
‫and as you learn with event listeners
‫that would by default would not be the case,
‫so we could use bind here and bind this
‫that would be valid, but we have a better way actually.
‫We added out auto bind decorator
‫so I'm just going to add this here
‫to the drag start handler.
‫Now, we can also listen to the drag end event here
‫and point at the drag end handler.
‫You can also add auto bind there
‫if you plan on using the vis keyword here
‫for the moment I will just log drag end
‫in here so that we see that is triggered
‫because here I actually have nothing specific I want to do
‫with it and therefore I will also blank this parameter
‫and basically tell typescript that I'm not using it.
‫Here in drag start, we will use event
‫and for the moment, I'll just log the event,
‫when this event occurs.
‫Now, that alone won't do the trick though.
‫If you save everything
‫and you add some project here,
‫you'll see that you can't re-drag it, right?
‫If you try to drag it, that will not work
‫because you'll also need to change something
‫in your HTML file.
‫On this list item, which is getting rendered
‫for every project, which is the thing you want to drag,
‫you have to add the draggable attribute
‫and set this to true.
‫That is important.
‫This tells the browser that this will be draggable.
‫With that, if you saved it, and you re-add a project here,
‫you see now, this indeed is draggable,
‫it now is stuck to my mouse
‫and now we can really move it around here just fine.
‫You'll also see on the right that a drag event fired
‫when I started dragging and if I let go, you'll see
‫the drag end event also fires.
‫So our listeners are connected
‫and we can drag, now we can work on the drop target
‫so on the box where this should be draggable to,
‫to then add the project to that box.
‫One this I will also do real quick
‫is in the apps.css file, on the list items,
‫so on projects LI, I will add a background color
‫of white simply so that we can see this a bit better.
‫So here, project LI, I added the white
‫so that when we do drag around the project here,
‫we do have the white background here
‫so this makes it a bit easier to see.
‫Doesn't change our next step though.
‫We want to make his dropabble.