Dashiell Rose Bark-Huss
Dashiell Rose Bark-Huss

Reputation: 2965

React Material UI- make a button open a file picker window

I have a styled Material UI button component. I want to make it so when I click the styled button I can select a file on my computer.

I thought this could be done by placing the <Button></Button> inside the <label> for a <input type="file"/> (file input) element. But this only seems to work with divs and not buttons. I can neither get the file picker to open for a regular button element nor a material UI Button component.

How can I make a material ui Button act as the label for the file input?

import React from 'react';

import { Button } from '@material-ui/core';
export default function InputButton() {
  return (
    <div>

    {/* Button does not open file picker window */}
      <div>
        <label>
          <input type="file" style={{ display: 'none' }} />
          <Button>upload file</Button>
        </label>
      </div>

    {/* div does open file picker window */}
      <div>
        <label>
          <input type="file" style={{ display: 'none' }} />
          <div>upload file</div>
        </label>
      </div>

    </div>
  );
}

Upvotes: 6

Views: 15994

Answers (2)

justin
justin

Reputation: 3607

If the label has an HTML for attribute (JSX htmlFor prop) matching the id of the input tag, and the button is rendered as a span, then you shouldn't need to use ref to simulate the click:

<>
                <input
                  style={{ display: 'none' }}
                  accept="image/*"
                  id={`preview-${inputId}`}
                  type="file"
                />
                <label htmlFor={`preview-${inputId}`}>
                  <Button
                    component="span"
                    size="small"
                    startIcon={<FileOpenIcon />}
                  >
                    Select
                  </Button>
                </label>
</>

Upvotes: 1

95faf8e76605e973
95faf8e76605e973

Reputation: 14191

Have an internal ref in your component that is bound to the input of type file. onClick of the MUI Button, reference the input and simulate a click on it

function InputButton() {

  const fileInput = React.useRef();

  return (
    <div>
      <Button 
        variant="contained" 
        color="primary" 
        onClick={()=>fileInput.current.click()}
      >
        upload file
      </Button>

      <input 
        ref={fileInput} 
        type="file" 
        style={{ display: 'none' }} 
      />
    </div>
  );
}

ReactDOM.render(<InputButton/>, document.getElementById("root"));
<body>
  <div id="root"></div>
  
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  <script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js"></script>

  <script type="text/babel">
    const { Button } = MaterialUI;
  </script>
</body>

Upvotes: 14

Related Questions