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

Add <form> compatibility #1214

Merged
merged 12 commits into from
Mar 9, 2022
Merged

Add <form> compatibility #1214

merged 12 commits into from
Mar 9, 2022

Conversation

RobinMalfait
Copy link
Member

@RobinMalfait RobinMalfait commented Mar 9, 2022

This PR will add <form> compatibility.

We have a few form element related components:

  • Combobox
  • Listbox
  • RadioGroup
  • Switch

The issue is that you manually have to wire these components to form input if
you want them to be included when you submit your form.

This PR will make that a bit easier for you. On the component listed above, you
can now add a name prop, once you do that a hidden input field will be
rendered with the selected value.


If your data (for example the value of your Listbox.Option) is an object, then we will make sure to properly encode it. Here is an example:

// Assuming we have a `name` of `person`
let value = ['Alice', 'Bob', 'Charlie']

Results in:

<input type="hidden" name="person[]" value="Alice" />
<input type="hidden" name="person[]" value="Bob" />
<input type="hidden" name="person[]" value="Charlie" />

Note: the additional [] in the name attribute.

A more complex object (even deeply nested) can be encoded like this:

// Assuming we have a `name` of `person`
let value = {
  id: 1,
  name: {
    first: 'Jane',
    last: 'Doe'
  }
}

Results in:

<input type="hidden" name="person[id]" value="1" />
<input type="hidden" name="person[name][first]" value="Jane" />
<input type="hidden" name="person[name][last]" value="Doe" />

If we are working with more complex data structures then we have to
encode those data structures into a syntax that the HTML can understand.

This means that we have to use `<input type="hidden" name="..." value="...">` syntax.

To convert a simple array we can use the following syntax:
```js
// Assuming we have a `name` of `person`
let input = ['Alice', 'Bob', 'Charlie']
```

Results in:
```html
<input type="hidden" name="person[]" value="Alice" />
<input type="hidden" name="person[]" value="Bob" />
<input type="hidden" name="person[]" value="Charlie" />
```

Note: the additional `[]` in the name attribute.

---

A more complex object (even deeply nested) can be encoded like this:
```js
// Assuming we have a `name` of `person`
let input = {
  id: 1,
  name: {
    first: 'Jane',
    last: 'Doe'
  }
}
```

Results in:
```html
<input type="hidden" name="person[id]" value="1" />
<input type="hidden" name="person[name][first]" value="Jane" />
<input type="hidden" name="person[name][last]" value="Doe" />
```
@vercel
Copy link

vercel bot commented Mar 9, 2022

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployments, click below or on the icon next to each commit.

headlessui-vue – ./packages/playground-vue

🔍 Inspect: https://vercel.com/tailwindlabs/headlessui-vue/EyfCz9ANczaHPLSquEXTaogHPDjx
✅ Preview: https://headlessui-vue-git-form-compatibility-tailwindlabs.vercel.app

headlessui-react – ./packages/playground-react

🔍 Inspect: https://vercel.com/tailwindlabs/headlessui-react/EMcsk8GYFtyTm3FVQSawN5xDERAY
✅ Preview: https://headlessui-react-git-form-compatibility-tailwindlabs.vercel.app

@justinechang39
Copy link

nice! 👌

@cliffordfajardo
Copy link

cliffordfajardo commented Jul 16, 2022

Hey @RobinMalfait,
I'm currently using the Ant Design react library which has partial <form> compatibility
I saw this PR and think this PR might serve as inspiration for working towards full <form> compatibility in Ant Design React component library.

I ran into 2 challenges when I was converting an existing React app to Remix, which does fully embrace <form>'s:

The only work around I have for this challenge is to: keep a select value in a state, then use the state as the value of a hidden input.

Out of curiosity, what prompted the headless-ui team to look into <form> compatability?
Were you all also working with Remix or another fullstack javascript framework which leverage's <forms>?

@RobinMalfait - do you have any recommendations/considerations tips for other react component library creators as far as how to approach this? I plan on knowledge sharing with the Ant design core team about this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants