Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doesn't work on mobile? OnItemDrop never triggers. #147

Open
ChristopherLodge opened this issue Jun 30, 2022 · 4 comments
Open

Doesn't work on mobile? OnItemDrop never triggers. #147

ChristopherLodge opened this issue Jun 30, 2022 · 4 comments

Comments

@ChristopherLodge
Copy link

Tried on latest Edge, Chrome and Firefox. Dragdrop version 2.4.0 in a Blazor server project (NET 6). I have also confirmed this issue in Chrome in 'emulation' mode.

I have a number of dropzone elements configured as the below

<Dropzone Id=PlayerID Class="PlayerInventory d-flex justify-center align-center flex-wrap" Items="GameObject.Players.Find(a => a.PlayerID == selectedPlayer.PlayerID).Bags.Find(a => a.IDNum == bag.IDNum).contents" TItem="Item" OnItemDrop="@((i) => MoveItem(i, bag.IDNum))"> <<ItemComp context="@context" player="@GameObject.Players.Find(a => a.PlayerID == selectedPlayer.PlayerID)"></ItemComp> </Dropzone>
_Host.cshmtl has the following included:
`
<script src="https://cdn.jsdelivr.net/npm/mobile-drag-drop@2.3.0-rc.2/index.min.js"></script>

<script>
    // options are optional ;)
    MobileDragDrop.polyfill({
        // use this to make use of the scroll behaviour
       dragImageTranslateOverride: MobileDragDrop.scrollBehaviourDragImageTranslateOverride
    });
</script>`

When attempting to 'drag and drop' on the emulator window, I was about to discover an exception.

Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
at Function.from ()
at Object.createEventArgs (blazor.server.js:1:8200)
at P.dispatchGlobalEventToAllElements (blazor.server.js:1:13902)
at P.onGlobalEvent (blazor.server.js:1:13233)
at w (drag-utils.ts:144:38)
at t.Y (drag-operation-controller.ts:514:21)
at drag-operation-controller.ts:240:18

The code works as expected with no exceptions in a standard desktop browser.

If you want any further traces/information please let me know

@medmor
Copy link

medmor commented Jul 30, 2022

Hi
If you are still interested, I found a temporary solution to this problem.
I think that blazor.server.js expects two arrays in the dataTransfer object (files and items), and i dont know why?
here is a snippet from the source code (you can find the code here https://github.com/dotnet/aspnetcore/blob/8a05a97cbe08ee72486713f999856662f96f115c/src/Components/Web.JS/src/Rendering/Events/EventTypes.ts)

function parseDragEvent(event: DragEvent): DragEventArgs {
  return {
    ...parseMouseEvent(event),
    dataTransfer: event.dataTransfer ? {
      dropEffect: event.dataTransfer.dropEffect,
      effectAllowed: event.dataTransfer.effectAllowed,
      files: Array.from(event.dataTransfer.files).map(f => f.name), //here is the source of this error
      items: Array.from(event.dataTransfer.items).map(i => ({ kind: i.kind, type: i.type })),  //here is the source of this error
      types: event.dataTransfer.types,
    } : null,
  };
}

So what I did, is to simply I added those arrays to dataTransfer object when the event is dispatched.
I dont use mobile-drag-drop (the source code is very complicated for me)
I use instead dragdroptouch (https://github.com/Bernardo-Castilho/dragdroptouch).
Just copy the code of DragDropTouch.js, add a <script> link to this file, and add the needed arrays before the event is dispatched at line 419.

        DragDropTouch.prototype._dispatchEvent = function (e, type, target) {
            if (e && target) {
                var evt = document.createEvent('Event'), t = e.touches ? e.touches[0] : e;
                evt.initEvent(type, true, true);
                evt.button = 0;
                evt.which = evt.buttons = 1;
                this._copyProps(evt, e, DragDropTouch._kbdProps);
                this._copyProps(evt, t, DragDropTouch._ptProps);
                evt.dataTransfer = this._dataTransfer;
                evt.dataTransfer.files = []; //files
                evt.dataTransfer.items = []; //items
                target.dispatchEvent(evt);
                return evt.defaultPrevented;
            }
            return false;
        };

after that all is working as a charm for me.

@ChristopherLodge
Copy link
Author

ChristopherLodge commented Jul 31, 2022 via email

@mikjov93
Copy link

mikjov93 commented Aug 3, 2022

Hi, @ChristopherLodge Is this issue fixed now? What I will need to do to update in my app?

@ChristopherLodge
Copy link
Author

Hi Mikjov93 - apologies for the delay here.

The issue is worked around - rather than fixed. The developers of the polyfills need to make changes. I would suggest using: https://github.com/Bernardo-Castilho/dragdroptouch

Take a copy of the JS into your project, and add the lines of source Medmor mentioned above into the code.

For the Blazor-dragdrop project, I would suggest changing official guidance in the readme to use a working polyfill - as the provided one needs modifications in order to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants