This course is out of date and does not reflect our standards or industry best practices.

Check out a free preview of the full Electron Fundamentals, v2 course:
The "Dragging & Dropping Files" Lesson is part of the full, Electron Fundamentals, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Steve demonstrates how to add drag and drop features such that the user knows where they are permitted to drop files into the program to mimic native applications.

Get Unlimited Access Now

Transcript from the "Dragging & Dropping Files" Lesson

>> Steve Kinney: We can do another small nicety here. Which is, it would be very cool if we could take files from anywhere in the file system and drag and drop them into our editor, right? So let's try that on for size, let's see if we can implement drag and drop.

[00:00:20] Now, theoretically, drag and drop works, just not really in the way that you would want, all right? I could go grab any of these files, let's take not in the world dominate, we'll go grocery list. Drag and drop it right on in, oop, nothing in this case. If I go here, let's see if I can grab one of the HTML files.

[00:00:47] Used to be that it would just wipe out the entire UI and show you the page cuz it thinks it's a web browser. Doesn't happen like that anymore, but still, it'd be cool if we could actually show them some feedback about where they are able to drop it and where they're not able to drop it.

[00:01:01] So let's start with that, so first thing we're gonna do is basically make sure, and this is I think useful either way. To make sure that they can't drop it just in general and then we'll add the ability to drag and drop where they can drop. Almost all of this work will be in our renderer process, for now.

[00:01:25] And so go back over and we'll start with a few things. We'll say document, so this is for the overall document. Document add event listener for a drag start, so when I start dragging, I will just do event Event dot prevent default. We'll just copy that, so we'll stop it for a drag start.

[00:01:56] Drag over which is when they're dragging it over. It's like one of those things, nobody likes it when they explain something using exact words and then I found myself in a perilous position of having to do that and they leave and when they drop. At the very least, we now at least know what events that we're working with when we go to implement drag and drop, right?

[00:02:18] So when they start dragging over, as they are currently dragging over the application when they leave the drop zone, and when they actually drop the file. All right, there are some things that we need to get as far as information is concerned though. And so what we're going to do is create a bunch of helper functions, so that, I have a general policy on writing code.

[00:02:38] Which is, if you find yourself writing a very large function with a lot of like moving parts, breaking it out into smaller functions that you have to name will automatically clean up the code. Cuz you've had to give things names, which is better than putting gross comments everywhere.

[00:02:51] So let's give ourselves a few helpers, right? Because some of the APIs for drag and drop in the browser are gnarly and hard to keep track of. So if we give ourselves these helpers, we never have to think about it again. If you take a gnarly and wrap it in a decently named function, it's better.

[00:03:06] You can print that on a thing as an inspirational meme that you put in your office. So we'll do the getDraggedFile and you'll see why we're making these helpers as soon as I start doing it. We'll take the event and it'll be event.dataTransfer.items, we'll get the first one, cuz they can technically drag multiple items.

[00:03:32] The same reason we were grabbing the first thing from the array of file names, we're gonna grab the first file from multiple dragged files. Cool,
>> Steve Kinney: All right, that make sense, why do we need a function for that? Well, let's do get dropped file.
>> Steve Kinney: That's gonna be event.datatransfer.files zero, the chances of you ever remembering that in a day to day practice until its like bitten you once for several days, not saying that it's ever happened to me.

[00:04:07] It's happened to me, these will be a little more useful and then you don't have to think about it ever again. I'll do another one, file type is supported. When we did the open dialogue, we're like, hey, listen, only mark down files and text files, please don't give me images.

[00:04:24] All right, we need something very similar for that here, so we'll say file, and we'll return and we'll just say, hey, we're willing to take two types of files. And you can change this, add stuff if you want, text, plain, text slash markdown. So for whatever that file is, make sure it's in that array.

>> Steve Kinney: .type, all right, so we've got some helpers here, these in and of themselves don't do anything. They're just, when we start writing the larger logic, they call out exactly what's happening. So you're not like, what is this squirrely syntax that he's writing? We've got some well named helpers.

[00:05:10] All right so, we can tell the user that when they drop the file rather, that, hey, you gave me garbage and I'm angry at you. But it would be better if they knew before they dropped it. All right, if we can give them some visual indicator that shows, listen, this isn't going to work, right?

[00:05:33] You're trying to drop an image here, it's not gonna happen, I'm gonna tell you this now. So we'll do, on the drag over event, as they're dragging over our area, that will be when we can display that. And I have the CSS already written, so we're just basically gonna be adding and removing classes.

[00:05:48] So what we'll do is we'll say in the mark down view
>> Steve Kinney: We'll add event listener.
>> Steve Kinney: For drag over.
>> Steve Kinney: And we'll say that we'll get the file, which is this is where we use a get dragged file.
>> Steve Kinney: Cuz I'm gonna be really honest with you, If I didn't make these helpers and I tried to live code and remember the difference of which one uses items and which one uses files, that's gonna be embarrassing for me.

[00:06:20] It still might be embarrassing for me, we don't know yet. So we'll go ahead and we'll grab the event cuz these take the event and they find the items of the files. So we'll get the file that's currently being dragged. If the file type is supported,
>> Steve Kinney: We'll do a mark down view or add the class.

>> Steve Kinney: Drag over. If it's not supported,
>> Steve Kinney: We'll do a drag error, right? And these are just CSS classes that are already defined in the style sheet. So let's go ahead and refresh this, if I grab a mark down file, you can see, cool, we get this nice little visual indicator here showing that it's ready to rock.

[00:07:10] We never take it away so I can put this file back still happy and wonderful. Let's take a screenshot, so we got an image. That's very upsetting, right? We know that this is not going to work out well for us with this drop area. All right, when they finish dragging maybe we clean up after ourselves, it seems legitimate.

>> Steve Kinney: So we'll say, markdownView, addEventLIstener, dragLeave
>> Steve Kinney: And basically what we're gonna do is, listen, either one of those classes take them off.
>> Steve Kinney: markdownview.classlist.removedrag-over and remove drag-error. All right, so refresh it and we'll get a shot again.
>> Steve Kinney: We've got the good file.
>> Steve Kinney: All right, all right, it seems nice, this is why I became a front end engineer, right?

[00:08:26] Cuz clearly this stuff makes me happy, and then we'll get the bad one.
>> Steve Kinney: Cool, so we've got the visual indicators here about what's gonna work, and what's not gonna work.
>> Steve Kinney: And so now what happens if they actually drop the file? Right now if I drop the file nothing, right?

[00:08:47] I can drop it,
>> Steve Kinney: We still eventually need to clean up for a drop, for a dragleave, if I grab a file again now and leave with it, it'll clean up. But on a drop, nothing happens, so we gotta solve that.
>> Steve Kinney: So we still have some work to do here, but we've got drag.

[00:09:05] And now what happens is they actually drop the file. So we'll add one more event listener.
>> Steve Kinney: In this case, it's gonna be for the drop event.
>> Steve Kinney: This is where we have that other helper, the getDroppedFiles, or our get, so we'll say const file = getDroppedFile from the event.

[00:09:35] All right, they could have still ignored that giant red, angry looking div, cuz now you know why I'm not a designer. Now, you also know why both applications are built to have the same style sheet because I made one style sheet in like 2013 that I've been using for everything.

[00:09:52] If they didn't get the hint from that really red angry div that we still need to tell them somehow or some way that this is not going to work out. We certainly don't want to try to open the image file. So we'll do that file type is supported check again for the file.

[00:10:08] And,
>> Steve Kinney: If it's not gonna work we'll say alert. We should a nicer one but we'll do this one for now. That file type is not supported and no matter what, whether it works, whether it doesn't work, let's clean up those classes. You'll notice that I didn't write the, what happens if things are good yet, cuz I do need to change my code a little bit.

[00:10:42] All we have is get file from user, we don't have a way to just open the file. We've gotten the file from the user, they dragged it, they dropped it. Let's start off with just the console log for now, and then what we'll do is we'll export open file as well and we'll be able to call open file directly when they drop it which will update our user interface.

[00:11:05] You're all, earlier today, when you're all like why is he breaking it out? Now you know.
>> Steve Kinney: So, we'll just do
>> Steve Kinney: Before we get too far down the road, let's just make sure it works. Cuz this is not my first rodeo
>> Steve Kinney: All right so we'll grab a known good file, so we dropped it and here's the file, cool.

[00:11:38] So now what we need to do is we need to export open file from the main process. Use it in the renderer process to open the file.
>> Steve Kinney: Cool, all right so let's go back in to the main process here and really for the other ones, I called them exports dot whatever, cuz I was only exporting, I wasn't using them internally.

[00:12:06] Open file is being used by save mark down, and by get file from user. So I want to call it export, instead of open file everywhere, so I'm gonna use a fun JavaScript trick.
>> Steve Kinney: Right? What this'll do and prettier added the parentheses, but you can imagine they're not there.

[00:12:26] Which is, first they'll take the function and assign it to exports at open file and it will then assign that to open file. So I get to have my cake and eat it, too. I get to use open file internally to this file and I still get to export it as well.

[00:12:40] All right, so we renderer now, we should have main process dot open file, and this one, we'll do file dot path, right? Cuz the file object is a native dom type, and so we wanna get the path of it so we can give that to node to read it from the file system as if we had picked it from a dialogue menu.

[00:13:03] All right, we changed the main process, so we have to quit and open.
>> Steve Kinney: All right, moment of truth. Hey, drag and drop, right? So now we can drop anything from the file system, drop it in. It'll get passed over to the main process, the main process will use Node's FS library to read the file and send it back to the renderer process, all right?

[00:13:26] So we're communicating back and forth between these two processes, and be able to figure it all out.