I need to manually trigger the onChange
event on an <input type="file">
element after the user clicks on a reset button. I have a complex form which contains over 20 inputs and allows for dynamically adding new inputs, the handling of which is tackled by a top-level function in my container component (not shown) which accepts the change event of each input and figures out how to alter my state.
On page load I make a call to an API and pre-populate the form with data. Depending on the content queried this can sometimes include a hero image. If an image exists I display it with a 'Click to remove/change' button. Clicking on this should trigger the onChange event on the input which trickles up the React tree and updates my 'content' state (in this case removing the data in the hero_image object).
I have tried setting the value to null but because the value is already null on page load it doesn't appear to fire the onChange event. I have also tried manually triggering the event in different ways. As you are not able to pre-populate the value of a file input in the same way you would do a text input for security reasons I am struggling to figure out the best way to tackle this problem.
export default class ImageUpload extends Component {
handleImageChange(e) {
console.log('change');
this.props.onChange(e);
}
removeImage = (e) => {
e.preventDefault();
// Setting the value to null doesn't trigger the onChange event
this.inputElement.value = null;
// Below is an attempt to manually trigger the onChange event using the input ref
const changeEvent = new Event('change');
this.inputElement.dispatchEvent(changeEvent);
}
render() {
const { name, label, value, children, error } = this.props;
return (
<div>
{label &&
<label htmlFor={name}>{label}</label>
}
{children}
<div className="image-upload-preview">
<Button onClick={e => this.removeImage(e)}>Click to remove/change</Button>
<img alt="" src={value.data.src} />
</div>
<button className="form-control image-upload-btn" onClick={this.fakeButtonClick}>
<IconWithText text="Click to add an image from your device (JPEG, PNG, GIF)" iconName="insert-image" iconSize="M" iconFill="dark" />
<input
id="eugh"
type="file"
name={name}
ref={(input) => { this.inputElement = input; }}
accept="image/jpeg, image/png, image/gif"
onChange={e => this.handleImageChange(e)}
onClick={e => e.stopPropagation()}
/>
</button>
</div>
);
}
}