react-spectrum icon indicating copy to clipboard operation
react-spectrum copied to clipboard

Add "form" attribute to buttons of type="submit"

Open undavide opened this issue 3 years ago • 8 comments

🙋 Feature Request

It would be nice to have a "form" attribute for React Spectrum Buttons, when they are of type="submit".

🔦 Context

See the following example coming from the React Spectrum examples page:

<DialogTrigger>
  <ActionButton>Register</ActionButton>
  {(close) => (
    <Dialog>
      <Heading>
        <Flex alignItems="center" gap="size-100">
          <Book size="S" />
          <Text>Register for newsletter</Text>
        </Flex>
      </Heading>
      <Header>
        <Link>
          <a href="//example.com" target="_blank">
            What is this?
          </a>
        </Link>
      </Header>
      <Divider />
      <Content>
        <Form>
          <TextField label="First Name" placeholder="John" autoFocus />
          <TextField label="Last Name" placeholder="Smith" />
          <TextField label="Street Address" placeholder="123 Any Street" />
          <TextField label="City" placeholder="San Francisco" />
        </Form>
      </Content>
      <Footer>
        <Checkbox>
          I want to receive updates for exclusive offers in my area.
        </Checkbox>
      </Footer>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>
          Cancel
        </Button>
        <Button variant="cta" onPress={close}>
          Register
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>

image

The dialog is nicely designed, and the content is kept separate in the <Heading>, <Content>, and <Footer>.

Problem is that the ButtonGroup, which very likely contains a submit button in such Dialogs, belongs to the Footer, i.e. it's not contained within the <Form> component – hence it can't act as a Button of type="submit".

In HTML it's possible to add a form attribute to a submit Button, so that it can work regardless to its positioning. E.g.

<form id="aForm">
  <!-- stuff -->
</form>
<button type="submit" form="aForm">Submit</button>

A similar possibility for <Form> and React Buttons would be nice to have.

Thanks!

undavide avatar Jan 12 '21 11:01 undavide

@undavide Allowing the form attribute on a button seems pretty reasonable, lemme double check with the team just in case.

LFDanLu avatar Jan 13 '21 18:01 LFDanLu

I'm guessing this is related to wanting the enter key to trigger the submit button's action? I'm having a hard time imagining wanting to submit a form in a dialog via the browser which would trigger a full page reload.

If so, it seems related to #855

devongovett avatar Jan 27 '21 19:01 devongovett

Uhm, actually no, my feat request was specifically only about being able to use a submit button when the button itself can't be inside the <form>

undavide avatar Jan 28 '21 07:01 undavide

i think there are some other libraries out there regarding forms that usually really on a submit button being present in the form to handle submit

razvanip avatar Jan 29 '21 12:01 razvanip

Since the <Button> component in Spectrum is an implementation of the native <button> element, shouldn't it support all the native attributes?
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-form


I have a similar use case where I was trying to put a form inside the content area of a dialog, and then include a submit button in the footer of the dialog, because wrapping the input and submit buttons in the same <Form> component was breaking the dialog layout.

Notional example of dialog with form fields in content section and submit button in footer

dmbaughman avatar Jul 11 '22 21:07 dmbaughman

I think Button should also have name, value, formmethod and formaction attributes. They are all very useful when working with forms. And in frameworks like remix-run forms are used to trigger any actions (they do not trigger full reloads like it was mentioned earlier). In some cases this approach makes it simpler to implement a basic experience even if JavaScript fails for some reason.

tchak avatar Feb 04 '23 14:02 tchak

I'm struggling with the same Issue. My very ugly workaround right now is to add

  useEffect(() => {
    ref.current?.UNSAFE_getDOMNode().setAttribute("form", "new-field-form");
  }, [ref]);

Spooky-0 avatar May 05 '23 20:05 Spooky-0