4

I've read Cancel event on input type="file", but this doesn't work when input tag is hidden, the focus doesn't go to input tag.

I'm looking to re-render the button when OS file-picker closes - a. either after selecting any file, b. without selecting file and clicking on cancel button

Attaching useState/useForceUpdate/useReducer on Button.onClick or input.onChange|onClick event works when user actually selects file, but "not" when user clicks on cancel button without selecting file (or when user clicks on Esc key using keyboard).

input.onFocus doesn't get trigger. Is there a way to re-render button when user is done with file-picker closes without file selection (cancel/Esc key)?

const [, forceUpdate] = React.useReducer((x) => x + 1, 0);

return (
    <>
        <input
            type="file"
            ref={uploadRef}
            id={`${toolbarButtonId}`}
            accept={acceptParams}
            onChange={onClickEvent}
            onClick={onClick}
            hidden
            onFocus={forceUpdate}
        />
        <Button
            ariaLabel={ariaLabel}
            ariaDescription={ariaDescription}
            disabled={disabled}
            iconName={iconName}
            id={toolbarButtonId}
            position={position}
            onClick={fileUploadRefLink}
            {...props}
        />
    </>
);
unknown_boundaries
  • 1,482
  • 3
  • 25
  • 47
  • https://www.google.com/amp/s/www.geeksforgeeks.org/how-to-detect-when-cancel-is-clicked-on-file-input-using-javascript/amp/ – Harshit Agarwal Jun 16 '21 at 08:48
  • onfocus event is not triggered when input is hidden – unknown_boundaries Jun 16 '21 at 08:51
  • Please add codesandbox with minimum code which doesn't work – Observer Jun 22 '21 at 13:30
  • Would a flow like this answer suggest work? To use visible button to trigger a function which clicks the input, still giving you an onChange event on the input to work with: https://stackoverflow.com/questions/52025558/how-to-trigger-onchange-on-input-type-file-by-another-button-click-in-reac – Anders Elmgren Jun 25 '21 at 20:01

1 Answers1

3

You could add a focus event on the window to watch when it get focused back after the user closes the file input dialog.

let button = document.querySelector("button");
let input = document.querySelector("input");

let renderCount = 0;
    
let pageRefocused =  () => {
  button.textContent = `User closed the dialog ${++renderCount} times`;
  window.removeEventListener("focus", pageRefocused);
};

button.addEventListener("click", () => {
  input.click();
  // we watch the window after opening the file input dialog
  window.addEventListener("focus",pageRefocused); 
});
input {
  visibility:hidden;
}
<button>Upload a file</button><input type="file">
mwryl
  • 664
  • 7
  • 16
  • Just out of curiosity, will `.click()` work on Safari? I remember doing something similar a while ago and Safari not really liking "fake" clicks. – Sheraff Jun 26 '21 at 08:21
  • I don't have a Mac to test, but it did work on my iPad so – mwryl Jun 26 '21 at 09:29