-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
added additional support #458
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,5 @@ build | |
dist | ||
lib | ||
|
||
/*.iml | ||
.idea | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
module.exports = { | ||
schema: { | ||
"title": "A registration form", | ||
"description": "A simple form example.", | ||
"$schema": "http://json-schema.org/draft-04/schema#", | ||
"type": "object", | ||
"properties": { | ||
"name": { | ||
"type": "string" | ||
}, | ||
"devMap": { | ||
"type": "object", | ||
"additionalProperties": { | ||
"type": "integer" | ||
} | ||
} | ||
} | ||
}, | ||
uiSchema: {}, | ||
formData: { | ||
"name": "test", | ||
"devMap": { | ||
"key": 2, | ||
"value": 12 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this example is quite confusing. How about an example where the keys are really arbitrary, for example site names or URLs? I guess we'd still want the values to be numeric, so maybe it could be a map of site -> estimated user count or something? |
||
} | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,10 +21,7 @@ function objectKeysHaveChanged(formData, state) { | |
return true; | ||
} | ||
// deep check on sorted keys | ||
if (!deepEquals(newKeys.sort(), oldKeys.sort())) { | ||
return true; | ||
} | ||
return false; | ||
return !deepEquals(newKeys.sort(), oldKeys.sort()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please do not commit stylistic changes as part of this PR, it makes it harder to review. |
||
} | ||
|
||
class ObjectField extends Component { | ||
|
@@ -36,7 +33,7 @@ class ObjectField extends Component { | |
required: false, | ||
disabled: false, | ||
readonly: false, | ||
} | ||
}; | ||
|
||
constructor(props) { | ||
super(props); | ||
|
@@ -84,67 +81,124 @@ class ObjectField extends Component { | |
}; | ||
|
||
render() { | ||
const { | ||
uiSchema, | ||
errorSchema, | ||
idSchema, | ||
name, | ||
required, | ||
disabled, | ||
readonly, | ||
onBlur | ||
} = this.props; | ||
const {definitions, fields, formContext} = this.props.registry; | ||
const {SchemaField, TitleField, DescriptionField} = fields; | ||
const {name} = this.props; | ||
const {definitions} = this.props.registry; | ||
const schema = retrieveSchema(this.props.schema, definitions); | ||
const title = (schema.title === undefined) ? name : schema.title; | ||
if ("additionalProperties" in schema){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Space before |
||
return this.renderAdditionalProperties(schema, title); | ||
} | ||
|
||
return this.renderProperties(schema, title); | ||
} | ||
|
||
renderProperties(schema, title){ | ||
const { | ||
uiSchema, | ||
errorSchema, | ||
idSchema, | ||
name, | ||
required, | ||
disabled, | ||
readonly, | ||
onBlur | ||
} = this.props; | ||
const {fields, formContext} = this.props.registry; | ||
const {SchemaField, TitleField, DescriptionField} = fields; | ||
|
||
let orderedProperties; | ||
try { | ||
const properties = Object.keys(schema.properties); | ||
orderedProperties = orderProperties(properties, uiSchema["ui:order"]); | ||
} catch (err) { | ||
return ( | ||
<div> | ||
<p className="config-error" style={{color: "red"}}> | ||
Invalid {name || "root"} object field configuration: | ||
<em>{err.message}</em>. | ||
</p> | ||
<pre>{JSON.stringify(schema)}</pre> | ||
</div> | ||
); | ||
<div> | ||
<p className="config-error" style={{color: "red"}}> | ||
Invalid {name || "root"} object field configuration: | ||
<em>{err.message}</em>. | ||
</p> | ||
<pre>{JSON.stringify(schema)}</pre> | ||
</div> | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please do not change indentation, here as well as elsewhere, as it no longer matches the style of the rest of the code, and the changes themselves are hard to review. I see that you unindented the code that |
||
} | ||
return ( | ||
<fieldset> | ||
{title ? <TitleField | ||
id={`${idSchema.$id}__title`} | ||
title={title} | ||
required={required} | ||
formContext={formContext}/> : null} | ||
{schema.description ? | ||
<DescriptionField | ||
id={`${idSchema.$id}__description`} | ||
description={schema.description} | ||
formContext={formContext}/> : null} | ||
{ | ||
orderedProperties.map((name, index) => { | ||
return ( | ||
<SchemaField key={index} | ||
name={name} | ||
required={this.isRequired(name)} | ||
schema={schema.properties[name]} | ||
uiSchema={uiSchema[name]} | ||
errorSchema={errorSchema[name]} | ||
idSchema={idSchema[name]} | ||
formData={this.state[name]} | ||
onChange={this.onPropertyChange(name)} | ||
onBlur={onBlur} | ||
registry={this.props.registry} | ||
disabled={disabled} | ||
readonly={readonly}/> | ||
); | ||
}) | ||
}</fieldset> | ||
); | ||
<fieldset> | ||
{title ? <TitleField | ||
id={`${idSchema.$id}__title`} | ||
title={title} | ||
required={required} | ||
formContext={formContext}/> : null} | ||
{schema.description ? | ||
<DescriptionField | ||
id={`${idSchema.$id}__description`} | ||
description={schema.description} | ||
formContext={formContext}/> : null} | ||
{orderedProperties.map((name, index) => { | ||
return ( | ||
<SchemaField key={index} | ||
name={name} | ||
required={this.isRequired(name)} | ||
schema={schema.properties[name]} | ||
uiSchema={uiSchema[name]} | ||
errorSchema={errorSchema[name]} | ||
idSchema={idSchema[name]} | ||
formData={this.state[name]} | ||
onChange={this.onPropertyChange(name)} | ||
onBlur={onBlur} | ||
registry={this.props.registry} | ||
disabled={disabled} | ||
readonly={readonly}/> | ||
); | ||
})} | ||
</fieldset> | ||
); | ||
} | ||
|
||
renderAdditionalProperties(schema, title){ | ||
const { | ||
uiSchema, | ||
errorSchema, | ||
idSchema, | ||
required, | ||
disabled, | ||
readonly, | ||
onBlur | ||
} = this.props; | ||
const {fields, formContext} = this.props.registry; | ||
const {SchemaField, TitleField, DescriptionField} = fields; | ||
|
||
return ( | ||
<fieldset> | ||
{title ? <TitleField | ||
id={`${idSchema.$id}__title`} | ||
title={title} | ||
required={required} | ||
formContext={formContext}/> : null} | ||
{schema.description ? | ||
<DescriptionField | ||
id={`${idSchema.$id}__description`} | ||
description={schema.description} | ||
formContext={formContext}/> : null} | ||
{Object.keys(this.state).map((name, index) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of the ways that this is different from the existing method, I don't understand why we no longer respect |
||
const childIdSchema = {"$id": `${idSchema.$id}__${name}`}; | ||
return ( | ||
<SchemaField key={index} | ||
name={name} | ||
required={this.isRequired(name)} | ||
schema={schema.additionalProperties} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm pretty sure this doesn't correctly support a schema that has both |
||
uiSchema={uiSchema[name]} | ||
errorSchema={errorSchema[name]} | ||
idSchema={childIdSchema} | ||
formData={this.state[name]} | ||
onChange={this.onPropertyChange(name)} | ||
onBlur={onBlur} | ||
registry={this.props.registry} | ||
disabled={disabled} | ||
readonly={readonly}/> | ||
); | ||
})} | ||
</fieldset> | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think it's necessary to copy and paste this entire function. There are more commonalities than differences in the two implementations, which means most parts are unchanged. Trying to review this is challenging because I have to read a whole new method rather than an enhanced version of the existing method. |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import merge from "lodash.merge"; | ||
import React from "react"; | ||
import "setimmediate"; | ||
|
||
|
||
const widgetMap = { | ||
boolean: { | ||
checkbox: "CheckboxWidget", | ||
|
@@ -112,7 +112,7 @@ function computeDefaults(schema, parentDefaults, definitions={}) { | |
if (isObject(defaults) && isObject(schema.default)) { | ||
// For object defaults, only override parent defaults that are defined in | ||
// schema.default. | ||
defaults = mergeObjects(defaults, schema.default); | ||
defaults = merge(defaults, schema.default); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Switching from the existing |
||
} else if ("default" in schema) { | ||
// Use schema defaults for this node. | ||
defaults = schema.default; | ||
|
@@ -129,6 +129,10 @@ function computeDefaults(schema, parentDefaults, definitions={}) { | |
} | ||
// We need to recur for object schema inner default values. | ||
if (schema.type === "object") { | ||
if (!schema.properties){ | ||
return defaults; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this change about? |
||
|
||
return Object.keys(schema.properties).reduce((acc, key) => { | ||
// Compute the defaults for this node, with the parent defaults we might | ||
// have from a previous run: defaults[key]. | ||
|
@@ -150,7 +154,7 @@ export function getDefaultFormState(_schema, formData, definitions={}) { | |
return defaults; | ||
} | ||
if (isObject(formData)) { // Override schema defaults with form data. | ||
return mergeObjects(defaults, formData); | ||
return merge(defaults, formData); | ||
} | ||
return formData || defaults; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't commit these to the project's
.gitignore
. If you find them helpful, you might add them to your$HOME/.config/git/ignore
(per the gitignore man page).