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

Client-side submit is not serializing button names and values #158

Open
danielweinmann opened this issue Feb 20, 2023 · 4 comments
Open
Labels
bug Something isn't working

Comments

@danielweinmann
Copy link
Contributor

Let's say I have the following form:

<Form schema={schema}>
  {({ Field, Errors, Button }) => (
    <>
      <Field name="foo" />
      <Errors />
      <Button name="intent" value="update" type="submit" />
    </>
  )}
</Form>

If I try to submit it with JS disabled, the field intent is serialized and submitted with value update. However, if JS is enabled, it is not.

I did some testing, and is seems the problem lies at this line. We should investigate it and make sure all inputs are always serialized and submitted when the form is valid, regardless of:

  • Whether they are part of the schema or not.
  • Whether are coming from a button, input, or any other tag.

Original issue on domain-functions repo. Thanks for reporting this, @netdesignr! 💪🏼

@danielweinmann
Copy link
Contributor Author

@netdesignr, we published a fix on v1.5.3.

However, it will only work out-of-the-box if you use the same Button component from your form's children.

Before the fix, we had an onSubmit event handler at the form level that would preventDefault to do client-side validation. That handler would call Remix's submit (from useSubmit() or useFetcher().submit) with the event target. But, since we were handling it at the form level, it would not include the clicked button.

To make this behavior work, we had to add an onClick event handler to Button that will do the same but with the button as the target. That will make Remix serialize the button name and value.

If you don't want to use the same Button component from your form's children, you can still achieve the same effect by manually adding the handler to the button. Let me know if you'd like instructions on that, and I'll provide them :)

@netdesignr
Copy link

@danielweinmann I will try it out today. Thank you!

@netdesignr
Copy link

@danielweinmann to confirm that this bug fix release did fix the issue. Thank you!

@brettdh
Copy link

brettdh commented Mar 2, 2024

@danielweinmann Either this has regressed sometime in the past year, or I am holding the thing wrong 😕

I have a component like this:

export function SettingsForm({ ...props }: SettingsFormProps) {
  const title = "Edit settings"
  return (
    <div>
      <div className="flex space-x-2 items-center">
        <h1 className="text-3xl">{title}</h1>
      </div>
      <Form
        inputTypes={{
          secret: "password",
        }}
        className="w-96"
        schema={configSchema}
        {...props}
      >
        {({ Field, Button, Errors }) => (
          <>
            <Field name="name" />
            <Field name="secret" />
            <Field name="url" />
            <Errors />
            <div className="flex space-x-2 items-center mt-3">
              <Button type="submit" name="_action" value="save" />
              <Button
                type="submit"
                name="_action"
                value="delete"
                className="bg-red-500 hover:bg-red-700"
              >
                Delete
              </Button>
            </div>
          </>
        )}
      </Form>
    </div>
  )
}

where Form is the result of remix-forms createForm. The value of (await request.clone().formData()).get("_action") in the action function is null, and looking at the Chrome network tab, the data sent to the server does not include _action.

At first, I was using a custom Button component (only for default styles), but the issue persists with or without that component. I also previously had an onSubmit on the Form, but the issue happens with or without that as well.

I'd be interested to know what the manual testing on #159 was, so I can make sure I'm using this feature as intended. Also, I don't think I'm doing anything that would require the manual step alluded to here:

If you don't want to use the same Button component from your form's children, you can still achieve the same effect by manually adding the handler to the button. Let me know if you'd like instructions on that, and I'll provide them :)

but if I am, I'd love to know what it is and what's required. 🙂 Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants