Reputation: 1709
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
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 usingdocument.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
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
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
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
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
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
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
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
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
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
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
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
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
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