Focus on div without click in React to enable keyboard navigation on a module












1















I am coding an image gallery from scratch in React, when clicking on an image, a modal pops up (separate component from my gallery component). I want to navigate between the pictures with left and right arrow, not just with the added arrows on the screen (onclick) but at the moment it only focuses on the modal when I click on it once, then I can navigate with the keyboard too (onKeyDown).



I have added tabIndex="0" to my div, but I still need to click on the div once to focus on it.



<div tabIndex="0" onKeyDown={(event) => this.onKeyNavigation(event, ImageUrl, currentIndex, ImageUrls)}>




onKeyNavigation = (event, ImageUrl, currentIndex, ImageUrls) => {

if ((event.keyCode) === 39) {
this.props.loadNext(ImageUrl, currentIndex, ImageUrls)
}
else if ((event.keyCode) === 37) {
this.props.loadPrevious(ImageUrl, currentIndex, ImageUrls)
}
else if ((event.keyCode) === 27) {
this.props.onClose()
}
}









share|improve this question



























    1















    I am coding an image gallery from scratch in React, when clicking on an image, a modal pops up (separate component from my gallery component). I want to navigate between the pictures with left and right arrow, not just with the added arrows on the screen (onclick) but at the moment it only focuses on the modal when I click on it once, then I can navigate with the keyboard too (onKeyDown).



    I have added tabIndex="0" to my div, but I still need to click on the div once to focus on it.



    <div tabIndex="0" onKeyDown={(event) => this.onKeyNavigation(event, ImageUrl, currentIndex, ImageUrls)}>




    onKeyNavigation = (event, ImageUrl, currentIndex, ImageUrls) => {

    if ((event.keyCode) === 39) {
    this.props.loadNext(ImageUrl, currentIndex, ImageUrls)
    }
    else if ((event.keyCode) === 37) {
    this.props.loadPrevious(ImageUrl, currentIndex, ImageUrls)
    }
    else if ((event.keyCode) === 27) {
    this.props.onClose()
    }
    }









    share|improve this question

























      1












      1








      1








      I am coding an image gallery from scratch in React, when clicking on an image, a modal pops up (separate component from my gallery component). I want to navigate between the pictures with left and right arrow, not just with the added arrows on the screen (onclick) but at the moment it only focuses on the modal when I click on it once, then I can navigate with the keyboard too (onKeyDown).



      I have added tabIndex="0" to my div, but I still need to click on the div once to focus on it.



      <div tabIndex="0" onKeyDown={(event) => this.onKeyNavigation(event, ImageUrl, currentIndex, ImageUrls)}>




      onKeyNavigation = (event, ImageUrl, currentIndex, ImageUrls) => {

      if ((event.keyCode) === 39) {
      this.props.loadNext(ImageUrl, currentIndex, ImageUrls)
      }
      else if ((event.keyCode) === 37) {
      this.props.loadPrevious(ImageUrl, currentIndex, ImageUrls)
      }
      else if ((event.keyCode) === 27) {
      this.props.onClose()
      }
      }









      share|improve this question














      I am coding an image gallery from scratch in React, when clicking on an image, a modal pops up (separate component from my gallery component). I want to navigate between the pictures with left and right arrow, not just with the added arrows on the screen (onclick) but at the moment it only focuses on the modal when I click on it once, then I can navigate with the keyboard too (onKeyDown).



      I have added tabIndex="0" to my div, but I still need to click on the div once to focus on it.



      <div tabIndex="0" onKeyDown={(event) => this.onKeyNavigation(event, ImageUrl, currentIndex, ImageUrls)}>




      onKeyNavigation = (event, ImageUrl, currentIndex, ImageUrls) => {

      if ((event.keyCode) === 39) {
      this.props.loadNext(ImageUrl, currentIndex, ImageUrls)
      }
      else if ((event.keyCode) === 37) {
      this.props.loadPrevious(ImageUrl, currentIndex, ImageUrls)
      }
      else if ((event.keyCode) === 27) {
      this.props.onClose()
      }
      }






      reactjs focus






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 13 '18 at 18:09









      Gabriella CsernusGabriella Csernus

      5210




      5210
























          2 Answers
          2






          active

          oldest

          votes


















          0














          You'll need to fire a focus() event on the <div> you want to have focus after it has rendered.



          The easiest way to do this is to use React's built-in lifecycle methods. First, create a ref for the element you want to have focus (in this case, the div listening for keyDown events). Then, you can call focus() on that node in your component's componentDidMount() method:



          class ImageGallery extends React.Component {
          construtor(){
          super();

          // Create the ref in the constructor
          this.focusRef = React.createRef();
          }

          /* your other methods here */

          componentDidMount(){
          // Focus on the rendered div using the DOM focus() method
          this.focusRef.focus();
          }

          render(){
          // Set the ref in your render() method
          return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
          }
          }





          share|improve this answer
























          • I get an error on the componentDidMount method. this.focusRef.focus is not a function

            – Gabriella Csernus
            Nov 13 '18 at 21:22











          • You'll need to investigate to make sure the ref is getting set properly. Different versions of React handle this differently; you may need to set it as a function on the element (i.e. ref={div => this.focusRef = div} but the main idea still holds - you need to set focus on the element after render, and you can use the DOM node method focus() to do that.

            – dcastrodale
            Nov 14 '18 at 10:38













          • I have React 16.6.1. I have gone through the documentation here: [link] reactjs.org/blog/2018/03/29/react-v-16-3.html I have also tried it with componentDidMount() { this.inputRef.current.focus(); } I cannot seem to figure it out how to set the ref properly.

            – Gabriella Csernus
            Nov 14 '18 at 13:19



















          0














          So the solution was:



          componentDidUpdate(){
          this.focusRef.current.focus();
          }






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287098%2ffocus-on-div-without-click-in-react-to-enable-keyboard-navigation-on-a-module%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            You'll need to fire a focus() event on the <div> you want to have focus after it has rendered.



            The easiest way to do this is to use React's built-in lifecycle methods. First, create a ref for the element you want to have focus (in this case, the div listening for keyDown events). Then, you can call focus() on that node in your component's componentDidMount() method:



            class ImageGallery extends React.Component {
            construtor(){
            super();

            // Create the ref in the constructor
            this.focusRef = React.createRef();
            }

            /* your other methods here */

            componentDidMount(){
            // Focus on the rendered div using the DOM focus() method
            this.focusRef.focus();
            }

            render(){
            // Set the ref in your render() method
            return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
            }
            }





            share|improve this answer
























            • I get an error on the componentDidMount method. this.focusRef.focus is not a function

              – Gabriella Csernus
              Nov 13 '18 at 21:22











            • You'll need to investigate to make sure the ref is getting set properly. Different versions of React handle this differently; you may need to set it as a function on the element (i.e. ref={div => this.focusRef = div} but the main idea still holds - you need to set focus on the element after render, and you can use the DOM node method focus() to do that.

              – dcastrodale
              Nov 14 '18 at 10:38













            • I have React 16.6.1. I have gone through the documentation here: [link] reactjs.org/blog/2018/03/29/react-v-16-3.html I have also tried it with componentDidMount() { this.inputRef.current.focus(); } I cannot seem to figure it out how to set the ref properly.

              – Gabriella Csernus
              Nov 14 '18 at 13:19
















            0














            You'll need to fire a focus() event on the <div> you want to have focus after it has rendered.



            The easiest way to do this is to use React's built-in lifecycle methods. First, create a ref for the element you want to have focus (in this case, the div listening for keyDown events). Then, you can call focus() on that node in your component's componentDidMount() method:



            class ImageGallery extends React.Component {
            construtor(){
            super();

            // Create the ref in the constructor
            this.focusRef = React.createRef();
            }

            /* your other methods here */

            componentDidMount(){
            // Focus on the rendered div using the DOM focus() method
            this.focusRef.focus();
            }

            render(){
            // Set the ref in your render() method
            return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
            }
            }





            share|improve this answer
























            • I get an error on the componentDidMount method. this.focusRef.focus is not a function

              – Gabriella Csernus
              Nov 13 '18 at 21:22











            • You'll need to investigate to make sure the ref is getting set properly. Different versions of React handle this differently; you may need to set it as a function on the element (i.e. ref={div => this.focusRef = div} but the main idea still holds - you need to set focus on the element after render, and you can use the DOM node method focus() to do that.

              – dcastrodale
              Nov 14 '18 at 10:38













            • I have React 16.6.1. I have gone through the documentation here: [link] reactjs.org/blog/2018/03/29/react-v-16-3.html I have also tried it with componentDidMount() { this.inputRef.current.focus(); } I cannot seem to figure it out how to set the ref properly.

              – Gabriella Csernus
              Nov 14 '18 at 13:19














            0












            0








            0







            You'll need to fire a focus() event on the <div> you want to have focus after it has rendered.



            The easiest way to do this is to use React's built-in lifecycle methods. First, create a ref for the element you want to have focus (in this case, the div listening for keyDown events). Then, you can call focus() on that node in your component's componentDidMount() method:



            class ImageGallery extends React.Component {
            construtor(){
            super();

            // Create the ref in the constructor
            this.focusRef = React.createRef();
            }

            /* your other methods here */

            componentDidMount(){
            // Focus on the rendered div using the DOM focus() method
            this.focusRef.focus();
            }

            render(){
            // Set the ref in your render() method
            return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
            }
            }





            share|improve this answer













            You'll need to fire a focus() event on the <div> you want to have focus after it has rendered.



            The easiest way to do this is to use React's built-in lifecycle methods. First, create a ref for the element you want to have focus (in this case, the div listening for keyDown events). Then, you can call focus() on that node in your component's componentDidMount() method:



            class ImageGallery extends React.Component {
            construtor(){
            super();

            // Create the ref in the constructor
            this.focusRef = React.createRef();
            }

            /* your other methods here */

            componentDidMount(){
            // Focus on the rendered div using the DOM focus() method
            this.focusRef.focus();
            }

            render(){
            // Set the ref in your render() method
            return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
            }
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 13 '18 at 18:31









            dcastrodaledcastrodale

            5714




            5714













            • I get an error on the componentDidMount method. this.focusRef.focus is not a function

              – Gabriella Csernus
              Nov 13 '18 at 21:22











            • You'll need to investigate to make sure the ref is getting set properly. Different versions of React handle this differently; you may need to set it as a function on the element (i.e. ref={div => this.focusRef = div} but the main idea still holds - you need to set focus on the element after render, and you can use the DOM node method focus() to do that.

              – dcastrodale
              Nov 14 '18 at 10:38













            • I have React 16.6.1. I have gone through the documentation here: [link] reactjs.org/blog/2018/03/29/react-v-16-3.html I have also tried it with componentDidMount() { this.inputRef.current.focus(); } I cannot seem to figure it out how to set the ref properly.

              – Gabriella Csernus
              Nov 14 '18 at 13:19



















            • I get an error on the componentDidMount method. this.focusRef.focus is not a function

              – Gabriella Csernus
              Nov 13 '18 at 21:22











            • You'll need to investigate to make sure the ref is getting set properly. Different versions of React handle this differently; you may need to set it as a function on the element (i.e. ref={div => this.focusRef = div} but the main idea still holds - you need to set focus on the element after render, and you can use the DOM node method focus() to do that.

              – dcastrodale
              Nov 14 '18 at 10:38













            • I have React 16.6.1. I have gone through the documentation here: [link] reactjs.org/blog/2018/03/29/react-v-16-3.html I have also tried it with componentDidMount() { this.inputRef.current.focus(); } I cannot seem to figure it out how to set the ref properly.

              – Gabriella Csernus
              Nov 14 '18 at 13:19

















            I get an error on the componentDidMount method. this.focusRef.focus is not a function

            – Gabriella Csernus
            Nov 13 '18 at 21:22





            I get an error on the componentDidMount method. this.focusRef.focus is not a function

            – Gabriella Csernus
            Nov 13 '18 at 21:22













            You'll need to investigate to make sure the ref is getting set properly. Different versions of React handle this differently; you may need to set it as a function on the element (i.e. ref={div => this.focusRef = div} but the main idea still holds - you need to set focus on the element after render, and you can use the DOM node method focus() to do that.

            – dcastrodale
            Nov 14 '18 at 10:38







            You'll need to investigate to make sure the ref is getting set properly. Different versions of React handle this differently; you may need to set it as a function on the element (i.e. ref={div => this.focusRef = div} but the main idea still holds - you need to set focus on the element after render, and you can use the DOM node method focus() to do that.

            – dcastrodale
            Nov 14 '18 at 10:38















            I have React 16.6.1. I have gone through the documentation here: [link] reactjs.org/blog/2018/03/29/react-v-16-3.html I have also tried it with componentDidMount() { this.inputRef.current.focus(); } I cannot seem to figure it out how to set the ref properly.

            – Gabriella Csernus
            Nov 14 '18 at 13:19





            I have React 16.6.1. I have gone through the documentation here: [link] reactjs.org/blog/2018/03/29/react-v-16-3.html I have also tried it with componentDidMount() { this.inputRef.current.focus(); } I cannot seem to figure it out how to set the ref properly.

            – Gabriella Csernus
            Nov 14 '18 at 13:19













            0














            So the solution was:



            componentDidUpdate(){
            this.focusRef.current.focus();
            }






            share|improve this answer




























              0














              So the solution was:



              componentDidUpdate(){
              this.focusRef.current.focus();
              }






              share|improve this answer


























                0












                0








                0







                So the solution was:



                componentDidUpdate(){
                this.focusRef.current.focus();
                }






                share|improve this answer













                So the solution was:



                componentDidUpdate(){
                this.focusRef.current.focus();
                }







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 15 '18 at 14:42









                Gabriella CsernusGabriella Csernus

                5210




                5210






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287098%2ffocus-on-div-without-click-in-react-to-enable-keyboard-navigation-on-a-module%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Florida Star v. B. J. F.

                    Danny Elfman

                    Lugert, Oklahoma