Repository: mozilla-services/react-jsonschema-form (js)

Issue:
`formContext` not passed to the multiselect and the file array
I wrote a fix here: https://github.com/olzraiti/react-jsonschema-form/tree/fixFormContextFilesAndMultiSelect

I'm delaying making a pull request until #437 is merged.

Pull request description:
Pass formContext properly to ArrayTemplateField, files array and multiselect array
### Reasons for making this change

`formContext` should be passed to every component that renders something. Fixes #441 

### Checklist

* [ ] **I'm updating documentation**
  - [ ] I've checked the rendering of the Markdown text I've added
  - [ ] If I'm adding a new section, I've updated the Table of Content
* [x] **I'm adding or updating code**
  - [x] I've added and/or updated tests
  - [x] I've updated docs if needed
* [ ] **I'm adding a new feature**
  - [ ] I've updated the playground with an example use of the feature


Patch:
diff --git a/README.md b/README.md
index 84c41a994..d68c0fedc 100644
--- a/README.md
+++ b/README.md
@@ -776,6 +776,7 @@ The following props are passed to each `ArrayFieldTemplate`:
 - `required`: A boolean value stating if the array is required.
 - `schema`: The schema object for this array.
 - `title`: A string value containing the title for the array.
+- `formContext`: The `formContext` object that you passed to Form.
 
 The following props are part of each element in `items`:
 
diff --git a/src/components/fields/ArrayField.js b/src/components/fields/ArrayField.js
index d610ef081..b9d4e54b1 100644
--- a/src/components/fields/ArrayField.js
+++ b/src/components/fields/ArrayField.js
@@ -283,6 +283,7 @@ class ArrayField extends Component {
       readonly,
       autofocus,
       registry,
+      formContext,
       onBlur
     } = this.props;
     const title = (schema.title === undefined) ? name : schema.title;
@@ -320,7 +321,8 @@ class ArrayField extends Component {
       required,
       schema,
       title,
-      TitleField
+      TitleField,
+      formContext
     };
 
     // Check if a custom render function was passed in
@@ -331,7 +333,7 @@ class ArrayField extends Component {
   renderMultiSelect() {
     const {schema, idSchema, uiSchema, disabled, readonly, autofocus, onBlur} = this.props;
     const {items} = this.state;
-    const {widgets, definitions} = this.props.registry;
+    const {widgets, definitions, formContext} = this.props.registry;
     const itemsSchema = retrieveSchema(schema.items, definitions);
     const enumOptions = optionsList(itemsSchema);
     const {widget="select", ...options} = {...getUiOptions(uiSchema), enumOptions};
@@ -347,6 +349,7 @@ class ArrayField extends Component {
         value={items}
         disabled={disabled}
         readonly={readonly}
+        formContext={formContext}
         autofocus={autofocus}/>
     );
   }
@@ -355,7 +358,7 @@ class ArrayField extends Component {
     const {schema, uiSchema, idSchema, name, disabled, readonly, autofocus, onBlur} = this.props;
     const title = schema.title || name;
     const {items} = this.state;
-    const {widgets} = this.props.registry;
+    const {widgets, formContext} = this.props.registry;
     const {widget="files", ...options} = getUiOptions(uiSchema);
     const Widget = getWidget(schema, widget, widgets);
     return (
@@ -370,6 +373,7 @@ class ArrayField extends Component {
         value={items}
         disabled={disabled}
         readonly={readonly}
+        formContext={formContext}
         autofocus={autofocus}/>
     );
   }


Test patch:
diff --git a/test/FormContext_test.js b/test/FormContext_test.js
index 10608ada3..c285ea78d 100644
--- a/test/FormContext_test.js
+++ b/test/FormContext_test.js
@@ -66,7 +66,6 @@ describe("FormContext", () => {
     const {node} = createFormComponent({
       schema: {
         type: "object",
-        title: "A title",
         properties: {
           prop: {
             type:  "string"
@@ -81,6 +80,26 @@ describe("FormContext", () => {
       .to.exist;
   });
 
+  it("should be passed to ArrayTemplateField", () => {
+    function CustomArrayTemplateField({formContext}) {
+      return <div id={formContext.foo}/>;
+    }
+
+    const {node} = createFormComponent({
+      schema: {
+        type: "array",
+        items: {
+          type:  "string"
+        }
+      },
+      ArrayFieldTemplate: CustomArrayTemplateField,
+      formContext
+    });
+
+    expect(node.querySelector("#" + formContext.foo))
+      .to.exist;
+  });
+
   it("should be passed to custom TitleField", () => {
     const fields = {TitleField: CustomComponent};
 
@@ -114,4 +133,43 @@ describe("FormContext", () => {
     expect(node.querySelector("#" + formContext.foo))
       .to.exist;
   });
+
+
+  it("should be passed to multiselect", () => {
+    const widgets = {SelectWidget: CustomComponent};
+    const {node} = createFormComponent({
+      schema: {
+        type: "array",
+        items: {
+          type: "string",
+          enum: ["foo"],
+          enumNames: ["bar"]
+        },
+        uniqueItems: true
+      },
+      widgets,
+      formContext
+    });
+
+    expect(node.querySelector("#" + formContext.foo))
+      .to.exist;
+  });
+
+  it("should be passed to files array", () => {
+    const widgets = {FileWidget: CustomComponent};
+    const {node} = createFormComponent({
+      schema: {
+        type: "array",
+        items: {
+          type: "string",
+          format: "data-url"
+        }
+      },
+      widgets,
+      formContext
+    });
+
+    expect(node.querySelector("#" + formContext.foo))
+      .to.exist;
+  });
 });