I want to restrict allowed files extension and need to know what files user is dragging, but console throws warning: NativeDragSources.js:61 Browser doesn't allow reading "files" until the drop event.
So what is the best way of checking file extension or dragging files count before dropping it on drop target?
Are you looking for not allowing drag on the Source OR to show not allowed on the Target based on a type ?
false
from canDrag
in Source.types
on Target @theTechie No, I'm loking for a way of reading file extension that I'm currently dragging.
All of the source and target methods get monitor
as the second argument. (including canDrop
)
You can use monitor.getItem()
to get the currently dragged items.
Reference:
canDrop(props, monitor): Optional. Use it to specify whether the drop target is able to accept the item. If you want to always allow it, just omit this method. Specifying it is handy if you'd like to disable dropping based on some predicate over props or monitor.getItem(). Note: You may not call monitor.canDrop() inside this method.
you can use the monitor
It doesn't work for files
That's strange.
I believe you are dragging and dropping files from filesystem onto a Target ?
I have done a similar thing and it seems to be working for me. If you can share some code, we can probably see what's wrong.
Could you please show how you read file extension in canDrop method?
as i already mentioned above, monitor.getItem().files
inside canDrop
should give you an array of native File
objects
Read my fist comment, when you read files in canDrop it throws error like I mentioned. Do you have working example of reading files in canDrop or you just refer to the documentation? Error says that i can't read files until drop event NativeDragSources.js:61 Browser doesn't allow reading "files" until the drop event
It's possible we are using two different versions and this restriction has been added later. I am using 2.1.4.
Ok, I will test the latest version and let you know if it works
I'm getting this, too, when trying to filter files in canDrop
by MIME type. As soon as I call monitor.getItem().files
it throws the above warning (Chrome 56.0.2924.87, react-dnd 2.2.4, react-dnd-html5-backend 2.2.4).
According to MDN my case, at least, could be accomplished using a property on event.dataTransfer
, but as far as I can see, react-dnd doesn't expost that object or its information anywhere.
@theTechie
It's possible we are using two different versions and this restriction has been added later. I am using 2.1.4.
No, I use the same version. Also updated to the latest possible version (2.2.4) and getting the same error:
canDrop method looks like this:
canDrop: function (props, monitor) {
let files = monitor.getItem().files;
console.log('Files: ', files);
return true;
}
How can it work on your side? Do you have working example?
I will share a working example shortly.
On Mon, 6 Mar 2017 at 4:12 PM, Andrey Karavaychik notifications@github.com
wrote:
@theTechie https://github.com/theTechie
It's possible we are using two different versions and this restriction has
been added later. I am using 2.1.4.No, I use the same version. Also updated to the latest possible version
(2.2.4) and getting the same error:[image: image]
https://cloud.githubusercontent.com/assets/710513/23606619/8acabe7a-0272-11e7-8db1-b1c88870cf92.pngcanDrop method looks like this:
canDrop: function (props, monitor) {
let files = monitor.getItem().files;
console.log('Files: ', files);
return true;
}How can it work on your side? Do you have working example?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/react-dnd/react-dnd/issues/584#issuecomment-284361793,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AA_31panjV9Uo11jF63f2Pkx4FBKiV6Aks5ri-MtgaJpZM4K5hkG
.>
Regards,
Gagan
@andrewQwer - really sorry!
i had a wrong memory of what i had implemented and it doesn't use monitor.getItem().files
in canDrop
, all i am doing is restricting the number of files which can be dropped by maintaining the file count once it's dropped.
sorry for misleading!
PS: i am looking into ways we can achieve this, will let you know if i am able to.
I don't think this will ever be possible. Looks like reading info on dragged items is restricted intentionally for security purpose.
Would it be possible to expose some information about the files via the event.dataTransfer
object (e.g. types
)? I realize that may not satisfy all use cases, but it would help at least some.
This might be something to be added to the HTML5 backend, but it does seem possible to determine if a file fits an accepted set of mime types before the file/folder is dropped. Specifcally, react-dropzone does this when you hover the item over the dropzone, as can be seen in this example.
Any solution for this issue yet?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Not stale
I'm also looking for a way to allow dropping specific files, e.g.: images, video, like react-dropzone. Does anyone have a solution?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
I have the issue too. It seems to be quite hardcoded in the "NativeDragSource.ts".
It creates a DragSource, however, for accessing the values it just adds a console-warning mentioning that the browser wouldn´t allow it.
However, the browser DOES allow it, it is just in protected mode and does not allow changing it or accessing the DATA ( of the files, but the items can with the files´ properties should be able to be enumerated. (like DropZone does).
Will try something and come back to you
@LeopoldLerch @darthtrevino I still cannot access to files
list before I drop. I want to check the mime type of the file on hover and change the color of the border depending on if it's a valid format of the file. I am using canDrop
method for useDrop
hook. And it returns an array of files just when I drop. When I hover over drop zone I have an empty array
Thing is, the events, that the browser delivers, are as they are, we can´t change them. The browser gives access to the data only on dragstart. After that, all subsequent events are in protected mode, which means, you can´t access the data.
if you use the onHover method of useDrop, you will get empty metadata, as the browser does not allow you to access it on "dragenter". Even if you store the object in dragstart (or the collect-function), the browser will in the background clear the properties, as you do have a reference to the object, not a copy of it.
The only way to work around that, is to use the "collect" function. Here you can access the "items" or "files" of the item (depending on the browser you use, IE11 will never allow you to access them before ondrop).
however, you have to do all by yourself: validating and remembering it in eg. a useRef. For example
collect: monitor => {
const item: DataTransfer = monitor.getItem();
const isOver = monitor.isOver();
let _canDrop: VerificationResult = null;
if (item) {
if (item.items) {
if (item.items.length > 0) {
draggedFilesValid.current = allFilesAccepted(
fromList<DataTransferItem>(item.items),
accept,
multiple,
maxSize,
minSize
)
? VerificationResult.Valid
: VerificationResult.Invalid;
}
}
} else {
draggedFilesValid.current = null;
}
if (isOver && item && item.files) {
_canDrop = VerificationResult.Unknown;
if (draggedFilesValid.current != null) {
_canDrop = disabled
? VerificationResult.Invalid
: draggedFilesValid.current;
}
}
return {
isDragActive: item != null,
canDrop: _canDrop
};
}
@LeopoldLerch
Thank you for the explanation! I will try this kind of workaround
Most helpful comment
Would it be possible to expose some information about the files via the
event.dataTransfer
object (e.g.types
)? I realize that may not satisfy all use cases, but it would help at least some.