Reputation: 1741
I'm trying to implement a file upload, but using SUIR <Input>
, button, label, etc.
This is strictly about the use of the elements in render.
Using regular html <label>
and <input>
elements this process works as expected.
<Form.Field>
<label>File input & upload for dataschemas & datasources</label>
<input type="file" onChange={this.fileChange} />
<Button type="submit">Upload</Button>
</Form.Field>
Now I'm trying to use SUIR <Input>
element, as well as some props with the <Button>
element for styling.
<Form.Field>
<label>File input & upload </label>
<Input type="file" onChange={this.fileChange}>
<Button
content="Choose File"
labelPosition="left"
icon="file"
/>
</Input>
<Button type="submit">Upload</Button>
</Form.Field>
You can visit the codesandbox here to get a better visual idea of what I'm talking about.
When I click Choose File
in the SUIR implementation example it does not prompt the user to chose a file from their system, whereas the regular html <input>
does. I'm not sure how to get <Input type="file ...>
in semantic to behave the same way.
Upvotes: 17
Views: 23624
Reputation: 85
Using only the react-semantic-ui's Input props. Following @GProst and @DJ2 answers, you can do something like:
<Input
action={{
icon: 'upload',
className: 'file-button-provider-icon', //<-- your css
onClick: () => document.querySelector('#file-input-button').click()
}}
input={{
id: 'file-input-button',
hidden: true,
}}
onChange={fileChange}
type='file'
/>
Upvotes: 0
Reputation: 1124
This is my solution:
function mainPage(){
const [newFile, SetNewFile] = useState([]);
const fileChange = (event) => {
SetNewFile( event.target.files[0] );
};
const onFormSubmit = () =>{
// Do something
}
return(
<Form onSubmit={onFormSubmit}>
<Form.Field>
<Button as="label" htmlFor="file" type="button">
Some button stuff
</Button>
<input type="file" id="file" hidden onChange={fileChange} />
</Form.Field>
<Button type="submit">Upload</Button>
</Form>)
}
Upvotes: 2
Reputation: 6558
You can setup file upload form with react as below.
And also you can get the filename and the reference of the file as demonstrated in this example,
I have included the front end upload logic with axios
and the backend code if you are using express, node
stack
class Thingy extends React.Component {
uploadFile = event => {
// filename
console.log('filename ' + event.target.value);
//file
console.log('file ' + event.target.files[0]);
// if you are using axios then you can use below code
//const formData = new FormData();
// formData.append('file', event.target.files[0])
// axios.put(
// 'url',
// formData,
// { headers: { 'content-type': 'multipart/form-data' } }
// ).then(data => {
// console.log('file uploaded')
// console.log(data)
// }).catch(e => {
// console.log('error')
// console.log(e)
// })
// in express , node, backend code would be
//import formidable from 'formidable'
//(req, res) => {
// let form = new formidable.IncomingForm();
// form.parse(req, (err, fields, files) => {
// you can get the file from files.file.path
// })
// }
}
render() {
console.log("rendered");
return (
<div>
<input type="file" id="file" name="filename" onChange={this.uploadFile} />
</div>
);
}
}
// Render it
ReactDOM.render(
<Thingy/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Upvotes: 6
Reputation: 1741
The answer by GProst works perfectly well. In another case you might not want to create a ref
to achieve this file input button.
The solution below uses the htmlFor
prop and passes that id
to the <input>
.
Not using ref eliminates extra JS, and unnecessary communication between button and input.
<Button as="label" htmlFor="file" type="button">
Some button stuff
</Button>
<input type="file" id="file" style={{ display: "hidden" }} onChange={this.onChange} />
Upvotes: 12
Reputation: 10227
SUIR doesn't provide a FileInput button solution out of the box. But you can easily create your own implementation of such button. For instance, usually this is done by using a hidden
file input and a button which triggers the hidden input click when user clicks on it:
<Button
content="Choose File"
labelPosition="left"
icon="file"
onClick={() => this.fileInputRef.current.click()}
/>
<input
ref={this.fileInputRef}
type="file"
hidden
onChange={this.fileChange}
/>
Where this.fileInputRef
is a React ref created by React.createRef()
method.
You can check this codesandbox example with the above solution.
Upvotes: 31