Skip to content

original DragEvent not passed to gridstack dropped event (no access to dataTransfer property) #1817

Closed

Description

@zgilewski

In griddstack 'dragged' event, we dont have access to original DragEvent, which making impossible to access dataTransfer property of DragEvent.

Gridstack version 4.0.1

We expecting that in 'dragged' event we can access original DragEvent from which we can access dataTransfer property, which will allow us to update widget content basing on data taken from dataTransfer property.
Actually its not possible.

Activity

  1. adumesny commented on Jul 21, 2021

    @adumesny
    Member

    can this be passed and be the same API for H5 and Jquery ? (raw event or something as they are different). Please make a code suggestion if you can, or donate for me to take a look... thanks.

  2. zgilewski commented on Jul 22, 2021

    @zgilewski
    Author

    Problem is with H5. For Jquery it looks ok.
    In case of H5 issue is in line

    this._gsEventHandler['dropped']({type: 'dropped'}, origNode && origNode.grid ? origNode : undefined, node);

    where to gridstack dropped event handler you passing new Event object which contains ONLY type property.
    But it should contains all info from original drag event, as in other case we loosing all informations.

    So simple solution is to replace this line:
    line 280: this._gsEventHandler['dropped']({type: 'dropped'}, origNode && origNode.grid ? origNode : undefined, node);
    to this line:
    line 280: this._gsEventHandler['dropped']({...event, type: 'dropped'}, origNode && origNode.grid ? origNode : undefined, node);

    Example of usage after this change:

    1. Create any html element and setup DDElement for it:
    const test = document.createElement('div');
    test.className = 'xxx';
    const testContent = document.createElement('div');
    testContent.className = 'xxxContent';
    testContent.innerText = 'ANY WIDGET';
    test.appendChild(testContent);`
    
    const _ddElement = DDElement.init(test);
    _ddElement.setupDraggable({
        handle: '.xxx',
        revert: 'invalid',
        scroll: true,
        appendTo: 'body',
        helper: 'clone',
        start: (event: DragEvent) => {
            if (event.dataTransfer) {
                event.dataTransfer.setData('text/plain', 'BINGO');
            }
        },
    });
    1. for your gridstack add dropped event handler:
    grid.on('dropped', this.gridStackDropped.bind(this));
    
    gridStackDropped(event: Event, previousWidget: GridStackNode, newWidget: GridStackNode): void {
        const dragEvent = event as DragEvent;
        if (dragEvent.dataTransfer) {
            console.log('gridstack dropped: ', dragEvent.dataTransfer.getData('text/plain'));
        }
    }

    Then you will see that now we are able to read info from dataTransfer property.
    Hope this will help you.

  3. adumesny commented on Jul 23, 2021

    @adumesny
    Member

    (fixed your code formatting) Hey thanks for the code fix. mind making a changelist with the fixes and ideally a way to test/verify this (you can change one of the demo or unit testing (still have not figure out how to enable the browser gestures ones).

    The downside is that 2. won't be the same for JQ version since you are assuming an event type, AND the fact it will break if/when I convert the H5 code to use plain mousedown/touch events as draggable has many issues and doesn't work on mobile either...

  4. zgilewski commented on Jul 23, 2021

    @zgilewski
    Author

    I showed you example in case of using H5 as we are using this version and not using jquery.
    If somebody else using jquery version then yes, they will need to create their own dropped handler.

    If you want you could create you own let say GridstackEvent interface, where you can put type, dataTransfer and anything else required for gridstack event handlers.

    Like for example:

    interface GridstackEvent {
      type: string;
      dataTransfer?: DataTransfer;
      ...
      ...
    }
    
    

    Then in line 280 of gridstack-dd.ts you can pass whats needed.

    Then dropped handler implementation will look like for example:

    gridStackDropped(event: GridstackEvent, previousWidget: GridStackNode, newWidget: GridStackNode): void {
        if (event.dataTransfer) {
            console.log('gridstack dropped: ', event.dataTransfer.getData('text/plain'));
        }
    }
    
  5. onepartsam commented on Sep 2, 2021

    @onepartsam
    Contributor

    Hi @adumesny, I am a colleague of @zgilewski, just following up on this issue.

    Is the code fix suggested by @zgilewski sufficient for a PR? If it is, we can proceed with creating the PR for your review.

  6. adumesny commented on Sep 3, 2021

    @adumesny
    Member

    @onepartsam @zgilewski the code change is trivial of course - a PR would be nice so you get the credit, but I was hoping for a running example showing the usage as well (either modify a current example, or create a new one) if this is generally useful. thanks

  7. adumesny commented on Sep 13, 2021

    @adumesny
    Member

    in new release. thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions