Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Commit

Permalink
Feat(useForm): add id and class for the excludeFields option
Browse files Browse the repository at this point in the history
  • Loading branch information
wellyshen committed Mar 1, 2021
1 parent 07808a6 commit b3554f2
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-garlics-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-cool-form": patch
---

Feat(useForm): add `id` and `class` for the `excludeFields` option
24 changes: 23 additions & 1 deletion docs/api-reference/use-form.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,32 @@ Default field values of the form. In most case (especially working with TypeScri

`string[]`

Tell React Cool Form to exclude field(s) by passing in the `name` of the field. You can also exclude a field via the pre-defined `data-rcf-exclude` attribute. Check the [Exclude Fields](../getting-started/integration-an-existing-form#exclude-fields) to learn more.
Tell React Cool Form to exclude field(s) by passing in the `name`/`id`/`class` of the field. You can also exclude a field via the pre-defined `data-rcf-exclude` attribute.

- The `excludeFields` and `data-rcf-exclude` won't affect the functionality of the [useControlled](./use-controlled).

```js
import { useForm } from "react-cool-form";

const App = () => {
const { form } = useForm({
excludeFields: ["foo", "#bar", ".baz"],
});

return (
<form ref={form}>
<input name="foo" />
<input id="bar" />
<input className="baz" />
{/* Excluding via the pre-defined data attribute */}
<input data-rcf-exclude />
</form>
);
};
```

👉🏻 Check the [Exclude Fields](../getting-started/integration-an-existing-form#exclude-fields) to learn more.

### shouldRemoveField

`boolean`
Expand Down
4 changes: 3 additions & 1 deletion docs/getting-started/3rd-party-ui-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const App = () => {
const { form } = useForm({
id: "form-1", // The ID is used by the "useControlled" hook
defaultValues: { framework: "" }, // (Strongly advise) Provide a default value for the controlled field
excludeFields: ["#framework"], // Exclude the internal input element of React-Select by ID
onSubmit: (values) => console.log("onSubmit: ", values),
});

Expand All @@ -120,6 +121,7 @@ const App = () => {
as={Select}
formId="form-1" // Provide the corresponding ID of the "useForm" hook
name="framework"
inputId="framework" // Used for excluding the internal input element of React-Select
options={options}
parse={(option) => option.value}
format={(value) => options.find((option) => option.value === value)}
Expand Down Expand Up @@ -166,7 +168,7 @@ const App = () => {
const { form, select } = useForm({
id: "form-1", // The ID is used by the "useFormState" and "useFormMethods" hooks
defaultValues: { username: "" },
// excludeFields: ["username"], // You can also exclude the field by this option
// excludeFields: ["username"], // You can also exclude the field here
validate: ({ username }) => {
const errors = {};
if (!username.length) errors.username = "Required";
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/integration-an-existing-form.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ import { useForm } from "react-cool-form";
const App = () => {
const { from } = useForm({
defaultValues: { username: "", email: "" },
// excludeFields: ["more"], // You can also exclude the fields by this option
// excludeFields: ["more"], // You can also exclude the field here by passing in name/id/class
onSubmit: (values) => console.log("onSubmit: ", values),
});
const [toggle, setToggle] = useState(false);
Expand Down
23 changes: 20 additions & 3 deletions src/useForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ describe("useForm", () => {
renderHelper({ children: <input data-testid="foo" /> });
fireEvent.input(getByTestId("foo"));
expect(console.warn).toHaveBeenCalledTimes(2);
expect(console.warn).toHaveBeenCalledWith(
expect(console.warn).toHaveBeenNthCalledWith(
1,
'💡 react-cool-form > field: Missing the "name" attribute. Do you want to exclude the field? See: https://react-cool-form.netlify.app/docs/api-reference/use-form/#excludefields'
);
expect(console.warn).toHaveBeenNthCalledWith(
2,
'💡 react-cool-form > field: Missing the "name" attribute.'
);
});
Expand Down Expand Up @@ -1123,13 +1128,25 @@ describe("useForm", () => {
it("should exclude a field via excludeFields option", async () => {
renderHelper({
defaultValues,
excludeFields: ["foo"],
excludeFields: ["foo", "#bar", ".baz"],
onSubmit,
children: <input data-testid="foo" name="foo" />,
children: (
<>
<input data-testid="foo" name="foo" />
<input data-testid="bar" name="bar" id="bar" />
<input data-testid="baz" name="baz" className="baz" />
</>
),
});
const foo = getByTestId("foo") as HTMLInputElement;
const bar = getByTestId("bar") as HTMLInputElement;
const baz = getByTestId("baz") as HTMLInputElement;
expect(foo.value).toBe("");
expect(bar.value).toBe("");
expect(baz.value).toBe("");
fireEvent.input(foo, e);
fireEvent.input(bar, e);
fireEvent.input(baz, e);
fireEvent.submit(getByTestId("form"));
await waitFor(() => expect(onSubmit).toHaveBeenCalledWith(defaultValues));
});
Expand Down
19 changes: 16 additions & 3 deletions src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,31 @@ export default <V extends FormValues = FormValues>({
const {
type,
name,
id: fieldId,
classList,
dataset: { rcfExclude },
} = field;

if (/button|image|submit|reset/.test(type)) return false;
const classes = Array.from(classList);
const { current: exclude } = excludeFieldsRef;

if (
/button|image|submit|reset/.test(type) ||
(fieldId && exclude[`#${fieldId}`]) ||
classes.find((n) => exclude[`.${n}`])
)
return false;

if (rcfExclude !== "true" && !name) {
warn('💡 react-cool-form > field: Missing the "name" attribute.');
warn(
'💡 react-cool-form > field: Missing the "name" attribute. Do you want to exclude the field? See: https://react-cool-form.netlify.app/docs/api-reference/use-form/#excludefields'
);
return false;
}

return (
controllersRef.current[name] ||
(rcfExclude !== "true" && !excludeFieldsRef.current[name])
(rcfExclude !== "true" && !exclude[name])
);
})
.reduce((acc: Map<any>, cur) => {
Expand Down

0 comments on commit b3554f2

Please sign in to comment.