Repository: grommet/grommet (JavaScript)

Issue:
FormField validation only receives first argument
Hi Grommet devs,

In the docs for FormField validate attribute it states

> If a function is provided, it will be called with two arguments, the value for this field and the entire value object

However from testing it is only called with the first argument (the value for the field), and not the second argument. Having the whole form data as the second argument is needed for more complex validations like password confirmation fields.

Codepen example here: https://codesandbox.io/s/4j9jzlnz3w

```tsx
<Form onSubmit={e => e.preventDefault()}>
      <FormField
        label="Name"
        name="name"
        validate={(fieldData, formData) => {
          console.log("validating form field");
          console.log("fieldData", fieldData);
          console.log("formData", formData); // 'formData' is undefined
        }}
      />
      <FormField label="Email" name="email" />
      <Button
        type="submit"
        primary
        label="Submit"
      />
    </Form>
```

The implementation shows that no second argument is being passed https://github.com/grommet/grommet/blob/master/src/js/components/FormField/FormField.js#L21

thanks,

Pete


Discussion:
@ericsoderberghp do we want to fix it in documentation to allow one argument value? or should we enhance the second argument as well?
@ShimiSun updating the implementation would make the validation feature a lot more useful. If fields can only be validated independently users will be forced to migrate away from the built-in validation as soon as they have to, for example, validate that a password confirmation field matches the password field. 



Patch:
diff --git a/src/js/components/FormField/FormField.js b/src/js/components/FormField/FormField.js
index 8995d67a14f..25920578551 100644
--- a/src/js/components/FormField/FormField.js
+++ b/src/js/components/FormField/FormField.js
@@ -12,13 +12,13 @@ import { TextInput } from '../TextInput';
 import { withFocus } from '../hocs';
 import { FormContext } from '../Form/FormContext';
 
-const validateField = (required, validate, messages) => data => {
+const validateField = (required, validate, messages) => (value, data) => {
   let error;
   if (required && (data === undefined || data === '')) {
     error = messages.required;
   } else if (validate) {
     if (typeof validate === 'function') {
-      error = validate(data);
+      error = validate(value, data);
     } else if (validate.regexp) {
       if (!validate.regexp.test(data)) {
         error = validate.message || messages.invalid;


Test patch:
diff --git a/src/js/components/Form/__tests__/Form-test.js b/src/js/components/Form/__tests__/Form-test.js
index a5964ab888d..5d57f60b01e 100644
--- a/src/js/components/Form/__tests__/Form-test.js
+++ b/src/js/components/Form/__tests__/Form-test.js
@@ -48,23 +48,30 @@ describe('Form', () => {
             validate={validate}
             placeholder="test input"
           />
+          <FormField name="test2" placeholder="test-2 input" />
           <Button type="submit" primary label="Submit" />
         </Form>
       </Grommet>,
     );
     expect(container.firstChild).toMatchSnapshot();
-    fireEvent.click(getByText('Submit'));
     fireEvent.change(getByPlaceholderText('test input'), {
       target: { value: 'v' },
     });
-    expect(validate).toBeCalledWith('v');
+    fireEvent.click(getByText('Submit'));
+    expect(validate).toBeCalledWith('v', { test: 'v' });
     fireEvent.change(getByPlaceholderText('test input'), {
       target: { value: 'value' },
     });
-    expect(validate).toBeCalledWith('value');
+    fireEvent.change(getByPlaceholderText('test-2 input'), {
+      target: { value: 'value-2' },
+    });
     fireEvent.click(getByText('Submit'));
+    expect(validate).toBeCalledWith('value', {
+      test: 'value',
+      test2: 'value-2',
+    });
     expect(onSubmit).toBeCalledWith(
-      expect.objectContaining({ value: { test: 'value' } }),
+      expect.objectContaining({ value: { test: 'value', test2: 'value-2' } }),
     );
   });
 });
diff --git a/src/js/components/Form/__tests__/__snapshots__/Form-test.js.snap b/src/js/components/Form/__tests__/__snapshots__/Form-test.js.snap
index a1a55e22c37..779f00a99fc 100644
--- a/src/js/components/Form/__tests__/__snapshots__/Form-test.js.snap
+++ b/src/js/components/Form/__tests__/__snapshots__/Form-test.js.snap
@@ -191,6 +191,25 @@ exports[`Form update 1`] = `
         </div>
       </div>
     </div>
+    <div
+      class="c1"
+    >
+      <div
+        class="c2"
+      >
+        <div
+          class="c3"
+        >
+          <input
+            autocomplete="off"
+            class="c4"
+            name="test2"
+            placeholder="test-2 input"
+            value=""
+          />
+        </div>
+      </div>
+    </div>
     <button
       class="c5"
       type="submit"