Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FlatButton] File input not working with button. #647

Closed
actionnick opened this issue May 15, 2015 · 28 comments
Closed

[FlatButton] File input not working with button. #647

actionnick opened this issue May 15, 2015 · 28 comments
Labels
component: button This is the name of the generic UI component, not the React module!

Comments

@actionnick
Copy link

With this...

<FlatButton primary={true} label="Choose an Image">
  <input type="file" id="imageButton"></input>
</FlatButton>

I end up with a button that doesn't actually render a file input field in the dom (clicking on the button does not open up the file dialog).

@actionnick
Copy link
Author

On version 0.7.5.

@hai-cea
Copy link
Member

hai-cea commented May 15, 2015

@nschaubeck Does the button on the doc site work for you?

@actionnick
Copy link
Author

@hai-cea Yes it does. It seemed like there wasn't even an <input> element in DOM, like the button element wasn't rendering it's children.

@e-monson
Copy link

e-monson commented Jun 5, 2015

I'm having this problem as well. @nschaubeck Did you ever find a solution?

@actionnick
Copy link
Author

@e-monson I was actually not able to find a solution.

@hai-cea hai-cea changed the title File input not working with button. [FlatButton] File input not working with button. Jun 19, 2015
@nikhildaga
Copy link

this works!
let styles = {
exampleImageInput: {
cursor: 'pointer',
position: 'absolute',
top: '0',
bottom: '0',
right: '0',
left: '0',
width: '100%',
opacity: '0'
}
}

      <FlatButton label="Choose an Image" primary={true}>
        <input id="imageButton" style={styles.exampleImageInput} type="file"></input>
      </FlatButton>

@Wofiel
Copy link

Wofiel commented Sep 7, 2015

@nikhildaga That only works on Chrome as placing input fields into buttons is not part of the W3C spec.

A different solution is to make the button just fire the click event of a hidden input field.

handleChange: function(e){
  console.log(e.target.value)
},
_openFileDialog: function(){
  var fileUploadDom = React.findDOMNode(this.refs.fileUpload);
  fileUploadDom.click();
},
render: function() {
  return (
    <FlatButton
      label="Upload file"
      onClick={this._openFileDialog}/>
    <input
      ref="fileUpload"
      type="file" 
      style={{"display" : "none"}}
      onChange={this._handleChange}/>
  );
}

@seb-vial
Copy link

I see this issue is still not fixed correctly...
The solution proposed in the doc only works in Chrome as @Wofiel said. (still the case in beta 15-0.2)

Wouldn't it better to be able to set like a htmlFor to the <FlatButton> (or <RaisedButton>), set an Id to the input file and that's all ? You wouldn't need to trigger the click manually...
I tried wrapping the button in the label, unfortunately, that doesn't work :(

Right now @Wofiel seems to be the best solution.

@mewsu
Copy link

mewsu commented May 12, 2016

Why close this when there is not a native solution

@excalliburbd
Copy link

hi @Wofiel how do you suggest using this technique without refs in a stateless component

@seb-vial
Copy link

@excalliburbd You can use id and Jquery, that should work

@excalliburbd
Copy link

@Birssan dom manipulation in react? is that okay?

@seb-vial
Copy link

I would not recommand it usually, but I think to trigger a click event that should be ok in this case

@juandav
Copy link

juandav commented Aug 8, 2016

@Wofiel As can be done with version 15 react?

@code-by
Copy link

code-by commented Sep 5, 2016

@Wofiel with this solution console.log(e.target.value) one receive
C:\fakepath\imagefilename.png
Best solutions is
e.target.files[0]

@Thomas101
Copy link

If anyone else comes across this issue I found that you can set containerElement on the RaisedButton to be something more suited to having an input element as a child. For example a label ;-)

<RaisedButton
  containerElement='label' // <-- Just add me!
  label='My Label'>
    <input type="file" />
</RaisedButton>

@w3nda
Copy link

w3nda commented Sep 6, 2016

@Thomas101 Thanks! I've just encountered this issue and your solution seems to work.
Awesome :)

@trialTrail
Copy link

@Thomas101 Thanks for the tip. This solved my problem as well. The actual <span key="labelElement"... was a deadzone for my click event. Your solution fixed this!

@andreyluiz
Copy link

andreyluiz commented Apr 11, 2017

Just complementing @Thomas101 answer, when I declare the components like his example, my RaisedButton is rendered with a file input inside. To prevent this, just set the file input style to display: none. :)

<RaisedButton
  containerElement='label' // <-- Just add me!
  label='My Label'>
    <input type="file" style={{ display: 'none' }} />
</RaisedButton>

@mbrookes
Copy link
Member

mbrookes commented Apr 11, 2017

@andreyluiz under what circumstances does this not work:

<RaisedButton label='My Label'>
    <input type="file" />
</RaisedButton>

I haven't been able to find an issue wit the docs site example, but clearly many others have this issue!

@andreyluiz
Copy link

Is it suposed to the file input to not show with the code you provided?

That's weird. In my case it renders an file input inside the material-ui button.

@mbrookes
Copy link
Member

mbrookes commented Apr 13, 2017

@andreyluiz Yes, with the docs site example (http://www.material-ui.com/#/components/raised-button) there's no visible <input>. What browser & version are you testing with?

@andreyluiz
Copy link

The latest Chrome version.

@bachrc
Copy link

bachrc commented Jun 23, 2017

I agree with @andreyluiz , the shows as well, but with a style={{display: 'none'}}, it works like a charm !

@sonaye
Copy link

sonaye commented Aug 29, 2017

tl;dr

<RaisedButton
  containerElement="label"
  icon={<Icons.FileUpload />} // material-ui-icons
  labelColor="white"
  primary
  style={{ minWidth: 40, width: 40 }}>
  <input
    onChange={e => this.upload(e.target.files[0])}
    style={{ display: 'none' }}
    type="file"
  />
</RaisedButton>

@Aditya94A
Copy link

Aditya94A commented Nov 20, 2017

The above solution doesn't seem to work any more. I'm using the new v1 beta branch and the following doesn't work for me

                        <Button dense
                                containerElement="label"
                                label="label">
                            <input
                                onChange={e => this.upload(e.target.files[0])}
                                style={{display: 'none'}}
                                type="file"
                            />
                        </Button>

I get the following error in the console:

Warning: React does not recognize the `containerElement` prop on a DOM element.
If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `containerelement` instead.
If you accidentally passed it from a parent component, remove it from the DOM element.

Anybody know a workaround? Anyways shouldn't such a common use case be natively supported? (in a non-hacky way)

@itelo
Copy link
Contributor

itelo commented Dec 4, 2017

@AdityaAnand1 the following code should work

<Button
            raised
            component="label" <---- use component instead of containerElement
            color="primary"
            className={buttonClassname}
            disabled={this.state.loading}
            onClick={this.handleButtonClick}
          >
            {'Upload'}
            <FileUpload className={classes.rightIcon} />
            <input
              onChange={e => console.log(e.target.files[0])}
              style={{ display: 'none' }}
              type="file"
            />
</Button>

@ajhool ajhool mentioned this issue Jul 14, 2019
2 tasks
@zannager zannager added the component: button This is the name of the generic UI component, not the React module! label Dec 21, 2022
@sanjaraybekov
Copy link

https://stackoverflow.com/a/54043619. it is simple

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: button This is the name of the generic UI component, not the React module!
Projects
None yet
Development

No branches or pull requests