There is an excellent article explain how to handle form submission in a Gatsby Js project hosted on netlify. However it's only about text values submission, how about the form includes some file inputs?
Any one can shed some light here?
There is an excellent article explain how to handle form submission in a Gatsby Js project hosted on netlify. However it's only about text values submission, how about the form includes some file inputs?
Any one can shed some light here?
Thanks for @coreyward's help. That I figured out the problem here is how to use javascript fetch API to post a form data. So the solution here is quite straightforward:
const encode = (data) => {
const formData = new FormData()
Object.keys(data)
.map(key => {
if (key === 'files') {
for (const file of data[key]) {
formData.append(key, file, file.name)
}
} else {
formData.append(key, data[key])
}
})
return formData
}
await window.fetch('/', {
method: 'POST',
body: encode({ 'form-name': 'loan', ...this.state, userId: netlifyIdentity.currentUser().id }),
})
You can notice that the only tricky part is rewrite the encode function of the official sample article from uri encoding to form data encoding.
Netlify supports file uploads in their form handler without any special configuration: https://www.netlify.com/docs/form-handling/#file-uploads
Netlify Forms can receive files uploaded via form submissions. To do this, add an input with
type="file"to any form. When a form is submitted, a link to each uploaded file will be included in the form submission details. These are viewable in the Netlify app, in email notifications, and via our API.
As an alternative solution, you can use Getform.io to setup file upload forms in a Gatsby.js project.
In this article they show an example with Axios:
import axios from 'axios';
import React, { useState } from "react"
import 'bootstrap/dist/css/bootstrap.min.css';
const GETFORM_FORM_ENDPOINT = "YOUR-FORM-ENDPOINT";
function Form() {
const [formStatus, setFormStatus] = useState(false);
const [query, setQuery] = useState({
name: "",
email: "",
});
const handleFileChange = () => (e) => {
setQuery((prevState) => ({
...prevState,
files: e.target.files[0]
}));
};
const handleChange = () => (e) => {
const name = e.target.name;
const value = e.target.value;
setQuery((prevState) => ({
...prevState,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
Object.entries(query).forEach(([key, value]) => {
formData.append(key, value);
});
axios
.post(
GETFORM_FORM_ENDPOINT,
formData,
{headers: {Accept: "application/json"}}
)
.then(function (response) {
setFormStatus(true);
setQuery({
name: "",
email: "",
});
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
return (
<div class="container-md">
<h2>Gatsby File Upload Form using Getform.io</h2>
<form
acceptCharset="UTF-8"
method="POST"
enctype="multipart/form-data"
id="gatsbyForm"
onSubmit={handleSubmit}
>
<div className="form-group mb-2">
<label for="exampleInputEmail1">Email address</label>
<input
type="email"
className="form-control"
placeholder="Enter your email"
required
name="email"
value={query.email}
onChange={handleChange()}
/>
</div>
<div className="form-group mb-2">
<label for="exampleInputName">Name</label>
<input
type="text"
className="form-control"
placeholder="Enter your name"
required
name="name"
value={query.name}
onChange={handleChange()}
/>
</div>
<hr/>
<div className="form-group mt-3">
<label className="mr-2">Upload your Resume:</label>
<input name="file" type="file" onChange={handleFileChange()}/>
</div>
<hr/>
{formStatus ? (
<div className="text-success mb-2">
Your message has been sent.
</div>
) : (
""
)}
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
);
}
export default Form
PS: They let you submit a single file up to 5MB in their free plan.