Mamata Hegde
Mamata Hegde

Reputation: 1709

How to manually trigger click event in ReactJS?

How can I manually trigger a click event in ReactJS? When a user clicks on element1, I want to automatically trigger a click on the input tag.

<div className="div-margins logoContainer">
  <div id="element1" className="content" onClick={this.uploadLogoIcon}>
    <div className="logoBlank" />
  </div>
  <input accept="image/*" type="file" className="hide"/>
</div>

Upvotes: 168

Views: 360269

Answers (15)

John Weisz
John Weisz

Reputation: 31924

Update

Since the original answer, React has mostly transitioned to functional components and hooks. The basic principles remain the same, however, only the syntax changes.

First you need to get a reference to your DOM element using the useRef hook:

const inputRef = React.useRef(null);
...
<input ref={inputRef} />

Then you just call click() on that DOM element from an event handler:

inputRef.current?.click() // or .focus() for text fields

Note: inputRef.current will point to an actual DOM element, same as what you would get using document.getElementById or similar, so the same methods and properties are available.

Full example:

function MyComponent() {
  const inputRef = React.useRef(null);
  const handleClick = React.useCallback(() => inputRef.current?.click(), []);

  return (
    <div onClick={handleClick}>
      <input ref={inputRef} />
    </div>
  );
}

Original Answer (class component)

You could use the ref prop to acquire a reference to the underlying HTMLInputElement object through a callback, store the reference as a class property, then use that reference to later trigger a click from your event handlers using the HTMLElement.click method.

In your render method:

<input ref={input => this.inputElement = input} ... />

In your event handler:

this.inputElement.click(); // or .focus() for text fields

Full example:

class MyComponent extends React.Component {
  render() {
    return (
      <div onClick={this.handleClick}>
        <input ref={input => this.inputElement = input} />
      </div>
    );
  }

  handleClick = (e) => {
    this.inputElement.click();
  }
}

Note the ES6 arrow function that provides the correct lexical scope for this in the callback. Also note, that the object you acquire this way is an object akin to what you would acquire using document.getElementById, i.e. the actual DOM-node.

Upvotes: 173

Jeff Lowery
Jeff Lowery

Reputation: 2597

Radio buttons are a little trickier; you only want to click on first render:

const MyComponent = () => {
   const v1 = useRef(null);
   
    const body =  <div>
       {Object.keys(versions).map((k, i) => (
           <div key={k}>
               <label>
                   <input
                       type="radio"
                       name="viz"
                       value={k}
                       onClick={handler}
                       style={{ width: "1em" }}
                       ref={i === 0 ? v1 : null}
                    ></input>
                        {k}
                </label>
            </div>
        ))}
        </div>
    );

    useEffect(() => {
        v1.current?.click();
    }, []);
    return body;
}

Upvotes: 0

S.Saderi
S.Saderi

Reputation: 5523

Here is the Hooks solution:

import React, {useRef} from 'react';

const MyComponent = () => {
    const myRefname= useRef<HTMLInputElement>(null);
    const handleClick = () => {
        myRefname.current.focus();
     }

    return (
        <div onClick={handleClick}>
            <input ref={myRefname}/>
        </div>
    );
}

Upvotes: 46

Saeed Nasiri
Saeed Nasiri

Reputation: 11

for typescript you could use this code to avoid getting type error

import React, { useRef } from 'react';

const MyComponent = () => {
    const fileRef = useRef<HTMLInputElement>(null);

    const handleClick = () => {
      fileRef.current?.focus();
    }

    return (
        <div>
            <button onClick={handleClick}>
                Trigger click inside input
            </button>
            <input ref={fileRef} />
        </div>
    );
}

Upvotes: 1

Hadi Abou Hamzeh
Hadi Abou Hamzeh

Reputation: 144

this.buttonRef.current.click();

Upvotes: 8

Matt E
Matt E

Reputation: 25

  let timer;
  let isDoubleClick = false;

  const handleClick = () => {
    if(!isDoubleClick) {
      isDoubleClick = true;
      timer = setTimeout(() => {
        isDoubleClick = false;
        props.onClick();
      }, 200);
    } else {
      clearTimeout(timer);
      props.onDoubleClick();
    }
  }

return <div onClick={handleClick}></div>

Upvotes: 1

Jack Bridger
Jack Bridger

Reputation: 165

Riffing on Aaron Hakala's answer with useRef inspired by this answer https://stackoverflow.com/a/54316368/3893510

const myRef = useRef(null);

  const clickElement = (ref) => {
    ref.current.dispatchEvent(
      new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true,
        buttons: 1,
      }),
    );
  };

And your JSX:

<button onClick={() => clickElement(myRef)}>Click<button/>
<input ref={myRef}>

Upvotes: 6

Aaron Hakala
Aaron Hakala

Reputation: 302

Using React Hooks and the useRef hook.

import React, { useRef } from 'react';

const MyComponent = () => {
    const myInput = useRef(null);

    const clickElement = () => {
        // To simulate a user focusing an input you should use the
        // built in .focus() method.
        myInput.current?.focus();

        // To simulate a click on a button you can use the .click()
        // method.
        // myInput.current?.click();
    }

    return (
        <div>
            <button onClick={clickElement}>
                Trigger click inside input
            </button>
            <input ref={myInput} />
        </div>
    );
}

Upvotes: 5

arslan
arslan

Reputation: 1144

  imagePicker(){
        this.refs.fileUploader.click();
        this.setState({
            imagePicker: true
        })
    }
  <div onClick={this.imagePicker.bind(this)} >
  <input type='file'  style={{display: 'none'}}  ref="fileUploader" onChange={this.imageOnChange} /> 
  </div>

This work for me

Upvotes: 0

mXaln
mXaln

Reputation: 125

If it doesn't work in the latest version of reactjs, try using innerRef

class MyComponent extends React.Component {


  render() {
    return (
      <div onClick={this.handleClick}>
        <input innerRef={input => this.inputElement = input} />
      </div>
    );
  }

  handleClick = (e) => {
    this.inputElement.click();
  }
}

Upvotes: 0

Immutable Brick
Immutable Brick

Reputation: 820

In a functional component this principle also works, it's just a slightly different syntax and way of thinking.

const UploadsWindow = () => {
  // will hold a reference for our real input file
  let inputFile = '';

  // function to trigger our input file click
  const uploadClick = e => {
    e.preventDefault();
    inputFile.click();
    return false;
  };

  return (
    <>
      <input
        type="file"
        name="fileUpload"
        ref={input => {
          // assigns a reference so we can trigger it later
          inputFile = input;
        }}
        multiple
      />

      <a href="#" className="btn" onClick={uploadClick}>
        Add or Drag Attachments Here
      </a>
    </>
  )

}

Upvotes: 9

Alex Oleksiiuk
Alex Oleksiiuk

Reputation: 338

Try this and let me know if it does not work on your end:

<input type="checkbox" name='agree' ref={input => this.inputElement = input}/>
<div onClick={() => this.inputElement.click()}>Click</div>

Clicking on the div should simulate a click on the input element

Upvotes: 2

taggartJ
taggartJ

Reputation: 287

How about just plain old js ? example:

autoClick = () => {
 if (something === something) {
    var link = document.getElementById('dashboard-link');
    link.click();
  }
};
  ......      
var clickIt = this.autoClick();            
return (
  <div>
     <Link id="dashboard-link" to={'/dashboard'}>Dashboard</Link>
  </div>
);

Upvotes: -3

Sir Codes Alot
Sir Codes Alot

Reputation: 1169

Got the following to work May 2018 with ES6 React Docs as a reference: https://reactjs.org/docs/refs-and-the-dom.html

import React, { Component } from "react";
class AddImage extends Component {
  constructor(props) {
    super(props);
    this.fileUpload = React.createRef();
    this.showFileUpload = this.showFileUpload.bind(this);
  }
  showFileUpload() {
    this.fileUpload.current.click();
  }
  render() {
    return (
      <div className="AddImage">
        <input
          type="file"
          id="my_file"
          style={{ display: "none" }}
          ref={this.fileUpload}
        />
        <input
          type="image"
          src="http://www.graphicssimplified.com/wp-content/uploads/2015/04/upload-cloud.png"
          width="30px"
          onClick={this.showFileUpload}
        />
      </div>
    );
  }
}
export default AddImage;

Upvotes: 32

Pranesh Ravi
Pranesh Ravi

Reputation: 19113

You can use ref callback which will return the node. Call click() on that node to do a programmatic click.

Getting the div node

clickDiv(el) {
  el.click()
}

Setting a ref to the div node

<div 
  id="element1"
  className="content"
  ref={this.clickDiv}
  onClick={this.uploadLogoIcon}
>

Check the fiddle

https://jsfiddle.net/pranesh_ravi/5skk51ap/1/

Hope it helps!

Upvotes: 10

Related Questions