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).
On version 0.7.5.
@nschaubeck Does the button on the doc site work for you?
@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.
I'm having this problem as well. @nschaubeck Did you ever find a solution?
@e-monson I was actually not able to find a solution.
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>
@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}/>
);
}
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.
Why close this when there is not a native solution
hi @Wofiel how do you suggest using this technique without refs in a stateless component
@excalliburbd You can use id and Jquery, that should work
@Birssan dom manipulation in react? is that okay?
I would not recommand it usually, but I think to trigger a click event that should be ok in this case
@Wofiel As can be done with version 15 react?
@Wofiel with this solution console.log(e.target.value)
one receive
C:\fakepath\imagefilename.png
Best solutions is
e.target.files[0]
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>
@Thomas101 Thanks! I've just encountered this issue and your solution seems to work.
Awesome :)
@Thomas101 Thanks for the tip. This solved my problem as well. The actual
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>
@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!
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.
@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?
The latest Chrome version.
I agree with @andreyluiz , the shows as well, but with a style={{display: 'none'}}
, it works like a charm !
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>
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)
@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>
Most helpful comment
If anyone else comes across this issue I found that you can set
containerElement
on theRaisedButton
to be something more suited to having an input element as a child. For example a label ;-)