We are both using react-sortable-hoc and react-dropzone and they work fine if on separate pages. However, react-sortable-hoc do not work properly when react-dropzone is used on the same page because I noticed that react-dropzone also gets triggered by the drag event from the react-sortable-hoc. (E.g. I can no longer drag an item in between other items.)
I tried adding e.preventDefault() and e.stopPropagation() on react-sortable-hoc's onSortStart event but react-dropzone is still being triggered.
What other approach can we try to make them play nice together / not allow the other to be affected?
If the problem is caused when dropping (not when starting the drag): react-dropzone takes over the whole window regarding file drops, to prevent the browser from navigating away from the current page to the dropped file if the user misses the drop zone (a common annoyance).
More specifically, dragover and drop handlers are registered on the document:
document.addEventListener('dragover', onDocumentDragOver, false)
document.addEventListener('drop', onDocumentDrop, false)
If that's the problem you should be able to circumvent this by setting the react-dropzone option preventDropOnDocument to false (default is true).
Alternatively, you could try the react-dropzone option noDragEventsBubbling, but I think this would handle the opposite problem (triggering events on react-sortable-hoc when dropping files)
I created a Sandbox and tried to reproduce your code which is using both react-dropzone and react-sortable-hoc at the same component. And it works well and has no problem.
https://codesandbox.io/s/nifty-ganguly-khswc?file=/src/App.js:1156-1485
Related
I have a very specific scenario in my hands to solve. I'm using FastClick to overcome the old
~300ms delay on clicks on mobile.
The project is an old Cordova app, and FastClick basically listens to touch events to
programmatically create click events. But the issue comes with Vuetify Click Outside directive,
which exist to close multiple menus and components through the app, this directive chooses to
ignore click events that are not trusted (event.isTrusted) so basically my components don't close
when user clicks.
I have tried to transpile Vuetify locally as the last resort, which I'm struggling with.
Next is the link to the Vuetify Source Code on the version I'm using (2.1.18).
https://github.com/vuetifyjs/vuetify/blob/v2.2.18/packages/vuetify/src/directives/click-outside/index.ts#L35-L37
// Vuetify Source Code
// If click was triggered programmaticaly (domEl.click()) then
// it shouldn't be treated as click-outside
// Chrome/Firefox support isTrusted property
// IE/Edge support pointerType property (empty if not triggered
// by pointing device)
if (('isTrusted' in e && !e.isTrusted) ||
('pointerType' in e && !e.pointerType)
) return
If someone could tell me how to overwrite this behavior or any kind of solution, it would help me a lot.
I've a simple list made of mat-card. I would like to highlight the mat-card when dragging a file over and do something on the file drop, but I have two main issues:
Sometimes, when dragging too fast, the status of the mat-card is not correctly updated. so in some cases I have multiple cards highligthed.
The e.preventDefault() on drop event does nothing. The file is open in the browser, which is not the expected behaviour.
I tried so many things, even manually add/remove event listeners, but nothing worked. Hope someone will help :)
Here you can find a demo made in stackblitz so it can be easier to debug:
https://stackblitz.com/edit/angular-material-with-angular-v5-d2uted
Update:
Using Angular v5 and Angular Material 2
After some poking around, the dragover event needs to be prevented as well as the drop event in order to stop the browser from opening the file. To fix the class being applied multiple times, I fixed this by using ngClass instead of the ngIf and it seems to work more consistently. Check out this stackblitz for a demo.
For the first issue, this is because of Angular lifecycle that isn't fast enough. Either you stop using Angular's context to update your elements, or you find another way of notifying the user that he is above the application.
For the second issue, add an host listener to the window:dragover event to prevent the default :
#HostListener('window:dragover', ['$event'])
windowDragOver(event: Event) {
event.preventDefault();
}
Stackblitz
I have an issue with interact.js 1.2.4 and iPad Retina iOS 8.1 Mobile Safari, which I need to resolve somehow. The problem occurs in a sorting component nested inside a large sequential learning web-application, where the user solves a succession of tasks. The interact.js plugin is used for adding drag/drop behavior so the user can sort elements in the correct order. The site is live, but the issue I'm about to describe is now persistent and reproducible, so it needs to be solved quick.
Here's the setup. We've initialised a number of draggable elements with
interact('.drag').draggable(...);
and we've registered onstart, onmove and onend listeners, which are handled manually with callback functions.
In most cases, the drag drop behavior acts as planned. But when using the sorting component in certain parts of the application sequence, the actionName of an interaction is inexplicably "gesture" instead of "drag", which makes the validateAction (interact.js) function return null instead of a valid action. This in turn causes the pointerDown (interact.js) handler to never get fired, so the drag motion is never initiated, and the element stays put forever, making it impossible to progress further in the sequence. The behavior only occurs on iPad.
If I run the site in an iPad simulator and inspect the element with Safari's developer tools crosshair functionality, something changes the element, and the next interaction's actionName suddenly becomes "drag", so the component starts to work as intended and the user can proceed in the sequence.
Do you have any idea as to:
What causes the website to relay a "gesture" action instead of a "drag" action?
What excactly happens when I use the inspection crosshair? Why does it change behavior?
How do I solve this issue?
You can see the component code here, but it's part of a major Backbone solution, so this is all I can include.
Thanks in advance.
We still don't know the cause, but seemingly there is a bug in iOS, which causes the application to fire 5 pointer events at once. Thus, the plugin registers the event as a gesture, and the drag drop functionality fails. The plugin creator gave this suggestion, which fixed the issue:
interact(document).on('down', function (event) {
var interaction = event.interaction;
var canGesture = interaction.target && interaction.target.options.gesture.enabled;
var maxAllowedPointers = canGesture? 2 : 1;
while (interaction.pointers.length > maxAllowedPointers) {
interaction.removePointer(interaction.pointers[0]);
}
})
I'm using Fine Uploader as a jQuery plugin in UI mode and I have a drop down list of file types such as image, video, pdf, etc. I'm dynamically changing the allowedExtensions and acceptFiles when the drop down list changes by removing the Fine Uploader generated div and then recreating it like this:
$('.qq-uploader').remove();
$('#jquery-wrapped-fine-uploader').fineUploader({/* options go here... */});
The dynamic validation works great this way, but I am doing some custom things in the complete callback event such as displaying thumbnails. When the file is uploaded, it fires the complete event for every time the dropdown list had changed prior to the first upload.
My workaround for now is storing the uploaded file name in an array and skipping over the custom complete logic if it already exists in the array.
I don't understand why the complete callback event is firing multiple times since I'm only uploading one file. Is there an explanation for this and/or a way to prevent duplicate callbacks from firing?
There are a couple ways to achieve your goal here:
Remove the Fine Uploader container element from the DOM before re-initializing Fine Uploader. In your fiddle, you were removing an internal element used by Fine Uploader. This will never work. You need to destroy the instance, and the only way to do this when using the jQuery plug-in is to destroy the DOM element that houses the plug-in instance. After you remove the container element, you can then re-add it and re-init Fine Uploader.
Make use of the multiple upload buttons feature. Essentially, you would create an alternate upload button for each file type with appropriate validation settings and change the one that is displayed when the user changes the value of the <select>.
I'm adding one more line to Ray Nicholus's answer.
$('#jquery-wrapped-fine-uploader').off()
You also have an option to remove event handlers that were attached to $('#jquery-wrapped-fine-uploader')
We're currently using the Chosen Dropdown Plugin which is rather awesome, apart from one minor issue. When we're using a single dropdown, if you tab into the 'chosen' control, the actual dropdown portion is not shown. However, when applying the plugin to a multiple 'select', it does appear.
Having been through the documentation and GitHub issues, there seems to be a lot of mentions regarding tab ordering and focusing, but nothing that seemingly deals with this rather simple requirement; Display the dropdown when receiving focus when tabbing.
So assuming that this functionality is not part of the plugin, is there an alternative such as capturing the focus of the anchor tag?
$('.chzn-single').focus(function(e){
alert('I should be focused!')
});
So far, I haven't been successful and was wondering whether any others have experienced this issue. You can check out this jsfiddle that demonstrates the problem
You should keep track of focus event for the search input thats inside chosen conainer, not the anchor element, then trigger mousedown event for the chosen container - that's the event that it listens to when opening a dropdown
You need to use delegated events approach to bind event handler to elements added dynamically (for jquery 1.7.1 and earlier you may just use 'live' method)
You also need to check if the container is active currently, to avoid recursive calls (when chosen dropdown gets opened - search input will be focused again)
$('body').on('focus', '.chzn-container-single input', function() {
if (!$(this).closest('.chzn-container').hasClass('chzn-container-active'))
$(this).closest('.chzn-container').trigger('mousedown');
//or use this instead
//$('#select').trigger('liszt:open');
});
Here's working jsfiddle
Instead of $(this).closest('.chzn-container').trigger('mousedown');
you may also trigger plugin's internal event: $('#select').trigger('liszt:open');