10/UI/DataTable-Ordering touch screen drag and drop 44136
https://mantis.ilias.de/view.php?id=44136
Issue
Drag and drop of ordering table doesn't work at all on touchscreens and in Webkit/Safari desktop.
Changes
- added a whole list of event listeners reproducing drag and drop on mobile
- mobile doesn't scroll when reaching the edges of the screen, added detection and scroll behavior manually.
- modifying the browser default desktop drag and drop behaviour so that Webkit/Safari is working. It still adds its own twist when drag and drop is stopping with a flyback animation that is not fitting, but I didn't look further into it for now.
- added settle animation to make UI jump more pleasant
- stopped row hovering during drag because it miscommunicates the drag position
- @yvseiler provided me with some helpful best practices of how the drag and drop could be even more user friendly:
- add a ghostly double at the position where the item is dragged from
- visualized position where the item would be dropped as a gap in the table
- added a drag image to the finger position on touch, desktop behavior is mostly default browser behavior with minor tweaks so Safari cooperates.
Desktop
Mobile
Outlook / Discussion
Settle animation on desktop
I know we aren't big into UI animations, but I think in this case the little settle at the end of the drag on desktop can really help to make the UX feel just a little bit lighter and less disorienting. I would like to add this for mobile as well, if that is okay with you all.
I am not too happy with the setTimeout solution. Does anyone know a more elegant way? I suspect that a smarter solution could be done, but that could quickly grow to something that shouldn't be burried in a single UI component... maybe a small reusable animation state handler that grabs animation timing and keyframes from CSS variables and can catch edge cases like interruptions gracefully.
For now, the worst that can happen is that the animation is not triggered because the animation class was never removed if you start another drag before setTimeout could ran.
Mobile design has yet to be merged
The design for the mobile view is currently WIP in this PR: #9015
Hi @thibsy and @Amstutz,
I have looked into this and would kindly ask you to move this on. Frankly, I do not like the code very much, it looks like the typical JS event code that also tries to accomodate various environments. Unprincipled, kind of ugly. On the other hand, I'm positive that it indeed does what it should do and I also don't really see a way for valuable improvements. Might be my lack of imagination, though.
Please have a look...
@catenglaender please reassign me when this is ready for another round :).
Thank you all very much for your input. :+1: :blush:
Yes, long term, I hope we can write a universal, re-usable drag and drop tool that has an keyboard accessible drag mode. The way how H5P manages to do this even for visual puzzles is quite impressive... eventually we will not get around this when refactoring the test questions. For now, I think the table offers an acceptable compromise with the order input field (plus some mouse users might even prefer it when working with large tables).
On small screens, the Ordering Table is not displayed as vertically stacked entries as in the gif above.
This was solved in a separate PR which was just about the visual nature of the ordering table on mobile. It has since been merged and I rebased this PR, so it should now look better.
DataTransfer
I just loaded the data object with plain text content and the HTML Element of the row for now. When you pull the drag image from the browser into another app it now pastes the text from the row... fun!
TLDR: Just loaded DataTranfer with text for external apps. Drop behavior with replacing DOM elements had to stay the same.
My attempts with then dropping that HTML Element via getData into its placeholder place in the table failed spectacularly though. Something about getData and being able to modify the DOM lines up weirdly and converting a html string back into an HTML Element also feels quite cumbersome and wasteful when we have the originRow right there. That's why I still don't use the DataTransfer object to actually transfer the row in the table. Shifting/replacing DOM elements on dragend (not drop... that one is for data transfer/manipulation not visual updates) still seems to be best practice.
It seems like DataTransfer's full power is transmitting an item in data form from one context to another (e.g. from one table to another, or a table to a folder). In that case best practice seems to be to DataTransfer a json object which can be sent, understood and processed from all dropzones constructing/rendering UI components from that json data if necessary.
And another caveat: The touch events have nothing comparable... so in that case one would have to construct helper data objects, send and catch them between the different contexts manually
flyback animation that is not fitting
Flyback animation is now canceled whenever the cursor is still hovering over a row or the placeholder... outside of the table or the browser window both Safari and Firefox still do that animation. There are methods with disabling default behavior on the whole document... but that seemed a bit risky to me.
setTimeout()
Now actually listening to the animationend of the CSS animation. Much better solution, I think.
Constants
Added
Draggable attribute in html template
Done
example 3: On small screens
Couldn't reproduce... should be fine after rebase.
Please take another look, @thibsy! Thank you for your patient guidance!
I made the two changes. Should be ready to merge now :)
sorry @catenglaender, this was not on my radar because you were still assignee. I assume this is still ready for merge, however, you need to resolve conflicts one last time before we can do so.
@catenglaender please let us (UI coordinators) merge pull-requests in the future.
Oops, my apologies. Will do!