13

I'm using React and Ant Design.

I have a popover with a button. When the user clicks the button, it shows the modal with an input field.

Problem

When I click the Show Modal Button auto focus is not working and also popover is not hiding

I tried with HTML5 autoFocus

<textarea autoFocus></textarea>

But it did not work, here the code: stackblitz

tanguy_k
  • 11,307
  • 6
  • 54
  • 58
Maria Jeysingh Anbu
  • 3,164
  • 3
  • 34
  • 55

4 Answers4

19

Add autoFocus={false} to your modal to reject the modal's focus management.

<Modal ... autoFocus={false}>

<textarea autoFocus={true}>
Rosy Shrestha
  • 1,359
  • 10
  • 10
  • After opening a modal I'm loading a tinymce editor inside modal. When any of the tinymce modal is opened on top of the bootstrap modal none of the tinymce modal input controls are getting focused. Tried setting autoFocus to false on Modal but still no use. Any other solution – Ravi MCA Jan 19 '21 at 17:05
  • 1
    This worked like a charm, Can you please specify what is the difference of having `autofocus` attribute vs using `useRef` in react? since to make `useRef` work in a dynamically rendered component like React Modal, it takes some work, instead using autofocus it achieved the needed result with no hassle, thanks in advance – Hasintha Abeykoon Aug 16 '21 at 08:49
6

What worked for me is setting input's focus after the modal finishes transitioning in.

Using useRef hook, my code was like

...
<Modal ... onEntered={() => textarea.current.focus()} >
    <textarea  ... ref={textarea} />
</Modal>

Link to Modal API https://react-bootstrap.github.io/components/modal/#modal-props

bertdida
  • 4,988
  • 2
  • 16
  • 22
  • 1
    Thank you! So simple and so hard to find! – Coco May 12 '21 at 21:41
  • `autoFocus` attribute is supposed to work with react-bootstrap, unfortunately it doesn't if animation is enabled: https://github.com/react-bootstrap/react-bootstrap/issues/5102 – tanguy_k Mar 19 '22 at 00:21
5

When you show Modal, you can use ref of your textarea to manually set focus.

 showModal=()=> {
    this.setState({
        visible: true,
        popOverVisible: false
    },()=>{
      setTimeout(()=>{this.testInput && this.testInput.focus()}, 1);
    });
 }

In Your Modal,

<Modal ...>
  ...
  <textarea 
   type='text'
   ref={(textarea) => { this.testInput = textarea; }} ></textarea>
  ...
</Modal>

To hide you Popover, you can use visible prop of PopOver and set state accordingly.

 showPopOver = () => {
    this.setState({
      popOverVisible: true
    })
 }
 ...
 <Popover ...
   visible={this.state.popOverVisible}>
   <span type="primary" onClick={this.showPopOver}>Click me (Popover Button)</span>
 </Popover>

Hope this helps.

Working demo

For multiple PopOvers : Demo

Dev
  • 3,922
  • 3
  • 24
  • 44
  • Thanks @Dev. It is not working when there are two popover buttons. at the same time both popover button are showing – Maria Jeysingh Anbu Mar 01 '18 at 10:03
  • How many Popovers you are going to have? If you are going to reuse them, I would suggest change visibility of popovers by appropriately setting the state. Let me update the answer – Dev Mar 01 '18 at 10:29
  • @MariaJeysinghAnbu, Updated the answer. Hope this helps – Dev Mar 01 '18 at 10:40
  • It worked for me, but I don't understand the logic. Do you have a link to documentation of this ref attribute and second argument of setState? – Diego Ortiz Sep 05 '19 at 12:21
  • it didn't work for me. Just a waste of time. console.log(this.testInput); // undefined – CHRIS LEE Nov 23 '20 at 19:22
  • This also be working(I haven't tried it), but the answer by @Rosy Shrestha worked & it was simple as putting a HTML attribute to the input element inside of the modal, Can you clarify the difference between React's `useRef` hook & this https://stackoverflow.com/a/53648011/12204242 answer? Does it have any issues in the context of React? – Hasintha Abeykoon Aug 16 '21 at 08:52
3

Just add autoFocus = {false} on modal and autoFocus = {true} on input.

<Modal autoFocus={false}>
  <Form>
    <ModalHeader>Type Your Input</ModalHeader>
    <ModalBody>
      <Input autoFocus={true} />
      <Button>Submit</Button>
    </ModalBody>
  </Form>
</Modal>

Ref: https://simplernerd.com/js-reactstrap-modal-autofocus/