0

In Material UI Documentation, they showed how to create an "Upload" button by hiding the input file and then adding the Button component inside the label. (see: https://material-ui.com/demos/buttons/)

Now, I want a different button, so I'm working with ButtonBase but it's not working - file select pop-up doesn't show. I'm not sure if I'm missing anything, maybe I'm missing some parameter to pass it?

<input
    accept="image/*"
    className="d-none"
    id="image-upload"
    type="file"
  />
  <label htmlFor="image-upload"
    className="d-block" >
    <Button component="span">
      Upload
    </Button> {/* working */}
    <ButtonBase>
      test
    </ButtonBase>  {/* not working*/}
 </label>

ButtonBase API: https://material-ui.com/api/button-base/

2 Answers 2

4

First, what version are you running? Material-UI is a very fast project so you need to make sure you're checking the documentation for whatever version you are at.

I favor using explicit events (ref in this case) and this works for me under 3.1.0

<input 
  ref={'file-upload'}
  type='file'
/>
<ButtonBase
  onClick={e => {
    this.refs['file-upload'].click()
  }}
>
  <div style={{
    color: 'red',
    backgroundColor: 'yellow',
    border: '1px solid green',
  }}
  >
    Upload!
  </div>
</ButtonBase>
<hr />
<Button
  type='file'
  onClick={e => {
    this.refs['file-upload'].click()
  }}
>
  File Upload Material
</Button>

I use something similar to this in one of my projects and I just hide the <input type='file' /> element.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! Let me give it a try, but i notice that you added an onClick function? Do you know why does the Button Component works even without it?
@AbigailA. I do not as I'm not quite sure how it is rendering, but I suspect that it is directly rendering a <button> tag rather than rendering nothing like the ButtonBase component does. You can always inspect the element to see what's happening behind the scenes. I bet a <ButtonBase><button /></ButtonBase> would have the same effect.
3

the same can be implement with hooks

export default function myForm(props) { 
 const inputEl = React.useRef(null);
  const onButtonClick = () => {
    console.log("inside")
    // `current` points to the mounted file input element
    inputEl.current.click();
  };

  return (
    <React.Fragment>
        Upload Photos
          <br/>
          <input
        accept="image/*"
        className={classes.input}
        id="outlined-button-file"
        multiple
        type="file"
        ref={inputEl}
      />
      <label htmlFor="outlined-button-file">

        <ButtonBases
        onClick={()=>onButtonClick()}
        />
      </label>
    </React.Fragment>
)}

Don't forget to call onClick inside ButtonBasses component.

export default function ButtonBases(props) {
  const classes = useStyles();

  return (
    <div className={classes.root}>
       <ButtonBase
          ...
          onClick={props.onClick}
        >
          ....
        </ButtonBase>
      ))}
    </div>
  );
} 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.