To have structured data in a form, you can use the same key on multiple inputs. For example, if you want to post an array of categories, you can use checkboxes with the same name attribute:
tsx Copy
< Form method= "post" >
< p> Select the categories for this video : < / p>
< label>
< input type= "checkbox" name= "category" value= "comedy" / > { " " }
Comedy
< / label>
< label>
< input type= "checkbox" name= "category" value= "music" / > { " " }
Music
< / label>
< label>
< input type= "checkbox" name= "category" value= "howto" / > { " " }
How- To
< / label>
< / Form>
In your action, you can access the checkbox values using formData.getAll()
:
tsx Copy
export async function action ( { request } : ActionArgs) {
const formData = await request. formData ( ) ;
const categories = formData. getAll ( "category" ) ;
}
This approach covers most cases for submitting structured data in forms. If you want to submit nested structures as well, you can use non-standard form-field naming conventions and the query-string
package from npm:
tsx Copy
< >
< input name= "category[]" value= "comedy" / >
< input name= "category[]" value= "comedy" / >
< input name= "user[name]" value= "Ryan" / >
< / >
In your action, you can parse the form data using request.text()
and query-string
:
tsx Copy
import queryString from "query-string" ;
export async function action ( { request } : ActionArgs) {
const formQueryString = await request. text ( ) ;
const obj = queryString. parse ( formQueryString) ;
}
If you want to send structured data as JSON, you can store the JSON in a hidden field:
tsx Copy
< input
type= "hidden"
name= "json"
value= { JSON . stringify ( obj) }
/ >
And then parse it in the action:
tsx Copy
export async function action ( { request } : ActionArgs) {
const formData = await request. formData ( ) ;
const obj = JSON . parse ( formData. get ( "json" ) ) ;
}
Overall, using the same input name and formData.getAll()
is often sufficient for submitting structured data in forms.