Skip to content

Commit 21976bc

Browse files
erunionepicfaace
authored andcommitted
Key changes on additionalProperties items no longer suffer data loss. (rjsf-team#1401)
* Key changes on additionalProperties items no longer suffer data loss. Resolves rjsf-team#1382 * Adding a unit test.
1 parent 90f50c3 commit 21976bc

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

src/components/fields/ObjectField.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class ObjectField extends Component {
7070
};
7171

7272
state = {
73+
wasPropertyKeyModified: false,
7374
additionalProperties: {},
7475
};
7576

@@ -128,6 +129,7 @@ class ObjectField extends Component {
128129
if (oldValue === value) {
129130
return;
130131
}
132+
131133
value = this.getAvailableKey(value, this.props.formData);
132134
const newFormData = { ...this.props.formData };
133135
const newKeys = { [oldValue]: value };
@@ -136,6 +138,9 @@ class ObjectField extends Component {
136138
return { [newKey]: newFormData[key] };
137139
});
138140
const renamedObj = Object.assign({}, ...keyValues);
141+
142+
this.setState({ wasPropertyKeyModified: true });
143+
139144
this.props.onChange(
140145
renamedObj,
141146
errorSchema &&
@@ -191,10 +196,19 @@ class ObjectField extends Component {
191196
onFocus,
192197
registry = getDefaultRegistry(),
193198
} = this.props;
199+
194200
const { definitions, fields, formContext } = registry;
195201
const { SchemaField, TitleField, DescriptionField } = fields;
196202
const schema = retrieveSchema(this.props.schema, definitions, formData);
197-
const title = schema.title === undefined ? name : schema.title;
203+
204+
// If this schema has a title defined, but the user has set a new key/label, retain their input.
205+
let title;
206+
if (this.state.wasPropertyKeyModified) {
207+
title = name;
208+
} else {
209+
title = schema.title === undefined ? name : schema.title;
210+
}
211+
198212
const description = uiSchema["ui:description"] || schema.description;
199213
let orderedProperties;
200214
try {
@@ -242,6 +256,7 @@ class ObjectField extends Component {
242256
idSchema={idSchema[name]}
243257
idPrefix={idPrefix}
244258
formData={(formData || {})[name]}
259+
wasPropertyKeyModified={this.state.wasPropertyKeyModified}
245260
onKeyChange={this.onKeyChange(name)}
246261
onChange={this.onPropertyChange(
247262
name,

src/components/fields/SchemaField.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ function SchemaFieldRender(props) {
235235
onDropPropertyClick,
236236
required,
237237
registry = getDefaultRegistry(),
238+
wasPropertyKeyModified = false,
238239
} = props;
239240
const { definitions, fields, formContext } = registry;
240241
const FieldTemplate =
@@ -296,8 +297,15 @@ function SchemaFieldRender(props) {
296297

297298
const { type } = schema;
298299
const id = idSchema.$id;
299-
const label =
300-
uiSchema["ui:title"] || props.schema.title || schema.title || name;
300+
301+
// If this schema has a title defined, but the user has set a new key/label, retain their input.
302+
let label;
303+
if (wasPropertyKeyModified) {
304+
label = name;
305+
} else {
306+
label = uiSchema["ui:title"] || props.schema.title || schema.title || name;
307+
}
308+
301309
const description =
302310
uiSchema["ui:description"] ||
303311
props.schema.description ||

test/ObjectField_test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,26 @@ describe("ObjectField", () => {
552552
expect(comp.state.formData.newFirst).eql(1);
553553
});
554554

555+
it("should retain user-input data if key-value pair has a title present in the schema", () => {
556+
const { comp, node } = createFormComponent({
557+
schema: {
558+
type: "object",
559+
additionalProperties: {
560+
title: "Custom title",
561+
type: "string",
562+
},
563+
},
564+
formData: { "Custom title": 1 },
565+
});
566+
567+
const textNode = node.querySelector("#root_Custom\\ title-key");
568+
Simulate.blur(textNode, {
569+
target: { value: "Renamed custom title" },
570+
});
571+
572+
expect(comp.state.formData["Renamed custom title"]).eql(1);
573+
});
574+
555575
it("should keep order of renamed key-value pairs while renaming key", () => {
556576
const { comp, node } = createFormComponent({
557577
schema,

0 commit comments

Comments
 (0)