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

Problems with inputs and textareas inside of draggable component #178

Closed
playpauseandstop opened this issue Jun 2, 2015 · 24 comments
Closed
Labels

Comments

@playpauseandstop
Copy link

I investigate some problems when placing <input> and <textarea> elements inside of draggable component,

  1. cmd+A or Ctrl+A shortcuts doesn't work for input or textarea (but selecting text with Shift + Arrows still works)
  2. Attempt to select input or textarea content with touchpad/mouse starts dragging parent element

My draggable component looks like,

draggable component

@dperetti
Copy link

dperetti commented Jun 2, 2015

This is caused by the registration of the selectstart event, which is apparently only needed for IE compatibility.
If like me you don't need IE compatibility, here was my quick fix that may work for you :
dperetti@06f74ef

@gaearon
Copy link
Member

gaearon commented Jun 2, 2015

Thanks for reporting! I'm glad to accept a PR fixing this.

I have two requirements:

  • It needs to still have that IE fix.
  • Please verify whether preventDefault() is needed for the other browsers. I think it prevents the text selection of whatever you tried to drag. If it indeed helps prevent unwanted selection in other browsers, you might want to surround e.preventDefault() with some check a la e.target.tagName !== 'input' (but a smarter one).

@gaearon gaearon added the bug label Jun 3, 2015
@ostinru
Copy link

ostinru commented Jun 10, 2015

Same bug with <div contentEditable={isEditing} />.
Also I can't edit it. Ctrl+A and Shift + Arrows doesn't work.

@gaearon
Copy link
Member

gaearon commented Jun 10, 2015

In the next three weeks I'm going to be busy and I don't have the time for fixing this.
As I said I'm happy to accept a PR with a fix as described in #178 (comment).

@stevenhauser
Copy link

Was looking into this. If I comment out the entire handleSelectStart function's body, everything works as expected. Tested this in IE11 and seems to be good there, too.

@gaearon do you know if there's a specific use case or setup for why the event needs to be handled at all? IE10? Different setup from textarea/input in a draggable node? I don't get text selection issues, and I wonder if CSS user-select works around this over preventDefault if necessary.

@gaearon
Copy link
Member

gaearon commented Jul 14, 2015

The original issue was #128.
If you can prepare a PR that fixes the problem, but also keeps #128 working, that would be a huge help.

@stevenhauser
Copy link

Will see if I can look into it. Need to figure out a way to set up a simple test case for IE9.

@gaearon
Copy link
Member

gaearon commented Jul 14, 2015

I think sortable-simple example failed on IE9 before #128 was fixed.

@stevenhauser
Copy link

@gaearon Yeah that was a good example to use, thanks. A few notes:

  1. No other browsers (tested latest Chrome, Safari, FF, and IE 11) seem to care about this. The event doesn't need to be handled whatsoever.
  2. IE9 only appears to only need the e.target.dragDrop() call. Disabling the text selection can be done by creating a handle that covers the entire draggable, wrapping the draggable node in connectDragPreview and the handle in connectDragSource. While this may sound nasty, AFAIK you're not officially supporting IE9 so is that a reasonable workaround, especially when other problems are likely to arise in that browser?
  3. Point number two is also useful anyway in the case that you have a text input within the draggable. Users can't select text by dragging their mice if connectDragSource is applied the the whole node (it ends up dragging the node instead of selecting text), however applying to an invisible handle that is the size of the whole node works very nicely.

Unsure how you want to handle this. Without resorting to UA checking, I don't know that there's a great way to deal with this and it seems to me like it's adding functionality to support an unofficially supported browser that's breaking good browsers which may end up digging a maintenance hole. But that's all my opinion. Regardless, there's a workaround to this issue that also solves other issues.

@danielbuechele
Copy link

Removing the event listener for selectstart makes contentEditable work in Chrome, but still it's not working in Safari.

@gaearon
Copy link
Member

gaearon commented Sep 17, 2015

Fixed by 0a36033.

Removing the event listener for selectstart makes contentEditable work in Chrome, but still it's not working in Safari.

This is HTML5 drag and drop API issue in Safari. Nothing we can do about it.

@gaearon
Copy link
Member

gaearon commented Sep 17, 2015

The fix for this issue was released in react-dnd@1.1.8.
Please verify that it works.

@playpauseandstop
Copy link
Author

Confirmed that Ctrl/Cmd-A works in <input> inside a draggable component.

@sstefoss
Copy link

Attempt to select input or textarea content with touchpad/mouse starts dragging parent element

I see this is not fixed, create a new issue?

@trevorsmith
Copy link
Contributor

Elements with contentEditable set inside a draggable parent container wouldn't allow me to select text or interact with them in any way. After some digging, I found this bug report: https://bugs.chromium.org/p/chromium/issues/detail?id=170139

It appears Chrome has since fixed the issue. Safari's behavior can be fixed in the meantime with CSS:

.contenteditable-element {
  user-select: text;
}

facebook-github-bot pushed a commit to facebookarchive/draft-js that referenced this issue Sep 29, 2017
Summary:
**Summary**

DraftEditors that lived inside draggable parents were useless in Safari. Now they work.
Solution found here: react-dnd/react-dnd#178 (comment)

**Test Plan**

Use the fiddle in #1326 with the updated version.
For a quick n dirty, just add this to the stylesheet:
`div[contenteditable="true"] { user-select: text;}`
Closes #1356

Differential Revision: D5901625

fbshipit-source-id: 7d3797286e4040575b9b5503c776bff1e29b67a9
@rahul1995
Copy link

@trevorsmith This is still not fixing the Firefox's behaviour. Do you know any workaround for Firefox?

@megawebmaster
Copy link

@rahul1995 - I just found out a solution: just store a ref to the draggable DOM node and when user focuses input/textarea set draggable attribute to false:

const Test = () => {
  const ref = useRef(null);
  const [focused, setFocused] = useState(false);
  const [_, drag] = useDrag({ item: { type: 'test' } });

  useEffect(() => {
    if (ref.current) {
      ref.current.setAttribute('draggable', !focused);
    }
  }, [focused]);

  return drag(
    <textarea ref={ref} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)}></textarea>
  );
};

This should do the trick for Firefox 😉

midas19910709 added a commit to midas19910709/draft-js that referenced this issue Mar 30, 2022
Summary:
**Summary**

DraftEditors that lived inside draggable parents were useless in Safari. Now they work.
Solution found here: react-dnd/react-dnd#178 (comment)

**Test Plan**

Use the fiddle in #1326 with the updated version.
For a quick n dirty, just add this to the stylesheet:
`div[contenteditable="true"] { user-select: text;}`
Closes facebookarchive/draft-js#1356

Differential Revision: D5901625

fbshipit-source-id: 7d3797286e4040575b9b5503c776bff1e29b67a9
@scottydev
Copy link

scottydev commented Aug 16, 2022

@rahul1995 - I just found out a solution: just store a ref to the draggable DOM node and when user focuses input/textarea set draggable attribute to false:

const Test = () => {
  const ref = useRef(null);
  const [focused, setFocused] = useState(false);
  const [_, drag] = useDrag({ item: { type: 'test' } });

  useEffect(() => {
    if (ref.current) {
      ref.current.setAttribute('draggable', !focused);
    }
  }, [focused]);

  return drag(
    <textarea ref={ref} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)}></textarea>
  );
};

This should do the trick for Firefox 😉

Have you considered making a PR? This is a fairly big issue on Strapi when entering data and happens on Chrome too.

strapi/strapi#12432

@megawebmaster
Copy link

To be honest I didn't, because I didn't know where to start - if anyone can point me in the right direction I'm happy to work on the issue 👍

@scottydev
Copy link

All good, digging in more I saw that your fix has to be applied outside the scope of the react-dnd core. Was trying to apply it to this ref, but the Strapi contrib process was not working correctly on my M1 machine 😅

There may be a way to use the logic you propose on nested elements and have it bubble up to the draggable ref so we fix it at the React-dnd level for all to make benefit, but we'd have to dig in more to see how that would work.

@sean-mcclure
Copy link

This is a vanilla JS issue, not a React issue. Programmatically focusing the input element when its clicked on fixes the issue.

@megawebmaster
Copy link

@sean-mcclure - so you think a solution like this should work?

const Test = () => {
  const [_, drag] = useDrag({ item: { type: 'test' } });

  return drag(
    <textarea onClick={(e) => e.target.focus()}></textarea>
  );
};

Why is this a vanilla JS issue and is it reported anywhere in Gecko (Firefox) or Blink (Chromium based browsers)?

@trainoasis
Copy link

trainoasis commented Feb 2, 2023

A year later almost, but I for some reason found a now soon-to-be-deprecated repo react-sortable-hoc way more intuitive to work with. Have more troubles setting the new repo up for some reason 🤔 Am I the only one ? Are we exchanging flexibility for the ease of use?

alicayan008 pushed a commit to alicayan008/draft-js that referenced this issue Jul 4, 2023
Summary:
**Summary**

DraftEditors that lived inside draggable parents were useless in Safari. Now they work.
Solution found here: react-dnd/react-dnd#178 (comment)

**Test Plan**

Use the fiddle in #1326 with the updated version.
For a quick n dirty, just add this to the stylesheet:
`div[contenteditable="true"] { user-select: text;}`
Closes facebookarchive/draft-js#1356

Differential Revision: D5901625

fbshipit-source-id: 7d3797286e4040575b9b5503c776bff1e29b67a9
@rbehal
Copy link

rbehal commented Dec 7, 2023

This is not documented very well, but if you add the class name nodrag this works to not allow dragging by the text input field, meaning you can select and highlight text with your cursor.

No other solutions solved my issue.

      <>
        <Input
          disabled={isDisabled}
          value={value}
          onChange={handleChange}
          className={'nodrag'}
          placeholder={placeholder}
          multiline
          error={error_message}
        />
      </>

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

No branches or pull requests