Repository: mozilla-services/react-jsonschema-form
Pull request #1172 (2019-02-06 19:18:31)

Return original submit event as second param
### Reasons for making this change
See https://github.com/mozilla-services/react-jsonschema-form/issues/1167






Patch:
diff --git a/.gitignore b/.gitignore
index 22092001c..b37f604b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,120 @@
-npm-debug.log
-node_modules
+# Created by https://www.gitignore.io/api/osx,node,linux,windows
+# Edit at https://www.gitignore.io/?templates=osx,node,linux,windows
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# Dependency directories
+node_modules/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+
+### OSX ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.gitignore.io/api/osx,node,linux,windows
+
+# Package specific files
+
 build
 _build
 site
diff --git a/docs/index.md b/docs/index.md
index e1550ef85..0887052f5 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -107,10 +107,10 @@ render((
 
 #### Form submission
 
-You can pass a function as the `onSubmit` prop of your `Form` component to listen to when the form is submitted and its data are valid. It will be passed a result object having a `formData` attribute, which is the valid form data you're usually after:
+You can pass a function as the `onSubmit` prop of your `Form` component to listen to when the form is submitted and its data are valid. It will be passed a result object having a `formData` attribute, which is the valid form data you're usually after. The original event will also be passed as a second parameter:
 
 ```js
-const onSubmit = ({formData}) => console.log("Data submitted: ",  formData);
+const onSubmit = ({formData}, e) => console.log("Data submitted: ",  formData);
 
 render((
   <Form schema={schema}
diff --git a/playground/app.js b/playground/app.js
index 2a8dffdb6..f8c972517 100644
--- a/playground/app.js
+++ b/playground/app.js
@@ -476,9 +476,10 @@ class App extends Component {
               uiSchema={uiSchema}
               formData={formData}
               onChange={this.onFormDataChange}
-              onSubmit={({ formData }) =>
-                console.log("submitted formData", formData)
-              }
+              onSubmit={({ formData }, e) => {
+                console.log("submitted formData", formData);
+                console.log("submit event", e);
+              }}
               fields={{ geo: GeoPosition }}
               validate={validate}
               onBlur={(id, value) =>
diff --git a/src/components/Form.js b/src/components/Form.js
index 87b96c0e0..182f56af3 100644
--- a/src/components/Form.js
+++ b/src/components/Form.js
@@ -151,6 +151,7 @@ export default class Form extends Component {
 
   onSubmit = event => {
     event.preventDefault();
+    event.persist();
 
     if (!this.props.noValidate) {
       const { errors, errorSchema } = this.validate(this.state.formData);
@@ -168,7 +169,7 @@ export default class Form extends Component {
 
     this.setState({ errors: [], errorSchema: {} }, () => {
       if (this.props.onSubmit) {
-        this.props.onSubmit({ ...this.state, status: "submitted" });
+        this.props.onSubmit({ ...this.state, status: "submitted" }, event);
       }
     });
   };
diff --git a/src/utils.js b/src/utils.js
index 8c69cccae..ad92ee494 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -67,6 +67,11 @@ export function getDefaultRegistry() {
 
 export function getSchemaType(schema) {
   let { type } = schema;
+
+  if (!type && schema.const) {
+    return guessType(schema.const);
+  }
+
   if (!type && schema.enum) {
     type = "string";
   }


Test patch:
diff --git a/test/Form_test.js b/test/Form_test.js
index 23b6ea816..3933f570d 100644
--- a/test/Form_test.js
+++ b/test/Form_test.js
@@ -774,15 +774,15 @@ describe("Form", () => {
         foo: "bar",
       };
       const onSubmit = sandbox.spy();
+      const event = { type: "submit" };
       const { comp, node } = createFormComponent({
         schema,
         formData,
         onSubmit,
       });
 
-      Simulate.submit(node);
-
-      sinon.assert.calledWithMatch(onSubmit, comp.state);
+      Simulate.submit(node, event);
+      sinon.assert.calledWithMatch(onSubmit, comp.state, event);
     });
 
     it("should not call provided submit handler on validation errors", () => {
diff --git a/test/const_test.js b/test/const_test.js
new file mode 100644
index 000000000..d47e012bd
--- /dev/null
+++ b/test/const_test.js
@@ -0,0 +1,60 @@
+import { expect } from "chai";
+
+import { createFormComponent, createSandbox } from "./test_utils";
+
+describe("const", () => {
+  let sandbox;
+
+  beforeEach(() => {
+    sandbox = createSandbox();
+  });
+
+  afterEach(() => {
+    sandbox.restore();
+  });
+
+  it("should render a schema that uses const with a string value", () => {
+    const schema = {
+      type: "object",
+      properties: {
+        foo: { const: "bar" },
+      },
+    };
+
+    const { node } = createFormComponent({
+      schema,
+    });
+
+    expect(node.querySelector("input#root_foo")).not.eql(null);
+  });
+
+  it("should render a schema that uses const with a number value", () => {
+    const schema = {
+      type: "object",
+      properties: {
+        foo: { const: 123 },
+      },
+    };
+
+    const { node } = createFormComponent({
+      schema,
+    });
+
+    expect(node.querySelector("input#root_foo")).not.eql(null);
+  });
+
+  it("should render a schema that uses const with a boolean value", () => {
+    const schema = {
+      type: "object",
+      properties: {
+        foo: { const: true },
+      },
+    };
+
+    const { node } = createFormComponent({
+      schema,
+    });
+
+    expect(node.querySelector("input#root_foo[type='checkbox']")).not.eql(null);
+  });
+});
diff --git a/test/utils_test.js b/test/utils_test.js
index 7ba1be760..cb32727c0 100644
--- a/test/utils_test.js
+++ b/test/utils_test.js
@@ -5,6 +5,7 @@ import {
   dataURItoBlob,
   deepEquals,
   getDefaultFormState,
+  getSchemaType,
   isFilesArray,
   isConstant,
   toConstant,
@@ -1369,4 +1370,51 @@ describe("utils", () => {
       expect(guessType({})).eql("object");
     });
   });
+
+  describe("getSchemaType()", () => {
+    const cases = [
+      {
+        schema: { type: "string" },
+        expected: "string",
+      },
+      {
+        schema: { type: "number" },
+        expected: "number",
+      },
+      {
+        schema: { type: "integer" },
+        expected: "integer",
+      },
+      {
+        schema: { type: "object" },
+        expected: "object",
+      },
+      {
+        schema: { type: "array" },
+        expected: "array",
+      },
+      {
+        schema: { type: "boolean" },
+        expected: "boolean",
+      },
+      {
+        schema: { type: "null" },
+        expected: "null",
+      },
+      {
+        schema: { const: "foo" },
+        expected: "string",
+      },
+      {
+        schema: { const: 1 },
+        expected: "number",
+      },
+    ];
+
+    it("should correctly guess the type of a schema", () => {
+      for (const test of cases) {
+        expect(getSchemaType(test.schema)).eql(test.expected);
+      }
+    });
+  });
 });