Skip to content

Commit d1f36bd

Browse files
authored
Merge pull request #7248 from marmelab/fix-cbgi
Fix prevent `CheckboxGroupInput` from changing selected values type
2 parents fd8ef16 + e5f4246 commit d1f36bd

File tree

2 files changed

+76
-6
lines changed

2 files changed

+76
-6
lines changed

packages/ra-ui-materialui/src/input/CheckboxGroupInput.spec.tsx

+60
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,66 @@ describe('<CheckboxGroupInput />', () => {
217217
expect(queryByText('Can I help you?')).not.toBeNull();
218218
});
219219

220+
it('should not parse selected values types to numbers if all choices types are non numbers', () => {
221+
const handleSubmit = jest.fn();
222+
const { getByLabelText } = render(
223+
<Form
224+
onSubmit={handleSubmit}
225+
initialValues={{ notifications: ['31', '42'] }}
226+
render={({ handleSubmit }) => (
227+
<form onSubmit={handleSubmit}>
228+
<CheckboxGroupInput
229+
source="notifications"
230+
choices={[
231+
{ id: '12', name: 'Ray Hakt' },
232+
{ id: '31', name: 'Ann Gullar' },
233+
{ id: '42', name: 'Sean Phonee' },
234+
]}
235+
/>
236+
<button type="submit" aria-label="Save" />
237+
</form>
238+
)}
239+
/>
240+
);
241+
const input = getByLabelText('Ray Hakt') as HTMLInputElement;
242+
fireEvent.click(input);
243+
244+
fireEvent.click(getByLabelText('Save'));
245+
expect(handleSubmit.mock.calls[0][0]).toEqual({
246+
notifications: ['31', '42', '12'],
247+
});
248+
});
249+
250+
it('should parse selected values types to numbers if some choices are numbers', () => {
251+
const handleSubmit = jest.fn();
252+
const { getByLabelText } = render(
253+
<Form
254+
onSubmit={handleSubmit}
255+
initialValues={{ notifications: [31, 42] }}
256+
render={({ handleSubmit }) => (
257+
<form onSubmit={handleSubmit}>
258+
<CheckboxGroupInput
259+
source="notifications"
260+
choices={[
261+
{ id: 12, name: 'Ray Hakt' },
262+
{ id: 31, name: 'Ann Gullar' },
263+
{ id: 42, name: 'Sean Phonee' },
264+
]}
265+
/>
266+
<button type="submit" aria-label="Save" />
267+
</form>
268+
)}
269+
/>
270+
);
271+
const input = getByLabelText('Ray Hakt') as HTMLInputElement;
272+
fireEvent.click(input);
273+
274+
fireEvent.click(getByLabelText('Save'));
275+
expect(handleSubmit.mock.calls[0][0]).toEqual({
276+
notifications: [31, 42, 12],
277+
});
278+
});
279+
220280
describe('error message', () => {
221281
it('should not be displayed if field is pristine', () => {
222282
const { container } = render(

packages/ra-ui-materialui/src/input/CheckboxGroupInput.tsx

+16-6
Original file line numberDiff line numberDiff line change
@@ -138,21 +138,31 @@ const CheckboxGroupInput: FunctionComponent<CheckboxGroupInputProps> = props =>
138138
const handleCheck = useCallback(
139139
(event, isChecked) => {
140140
let newValue;
141-
try {
142-
// try to convert string value to number, e.g. '123'
143-
newValue = JSON.parse(event.target.value);
144-
} catch (e) {
145-
// impossible to convert value, e.g. 'abc'
141+
142+
if (
143+
choices.every(
144+
item => typeof get(item, optionValue) === 'number'
145+
)
146+
) {
147+
try {
148+
// try to convert string value to number, e.g. '123'
149+
newValue = JSON.parse(event.target.value);
150+
} catch (e) {
151+
// impossible to convert value, e.g. 'abc'
152+
newValue = event.target.value;
153+
}
154+
} else {
146155
newValue = event.target.value;
147156
}
157+
148158
if (isChecked) {
149159
finalFormOnChange([...(value || []), ...[newValue]]);
150160
} else {
151161
finalFormOnChange(value.filter(v => v != newValue)); // eslint-disable-line eqeqeq
152162
}
153163
finalFormOnBlur(); // HACK: See https://github.com/final-form/react-final-form/issues/365#issuecomment-515045503
154164
},
155-
[finalFormOnChange, finalFormOnBlur, value]
165+
[choices, finalFormOnBlur, optionValue, finalFormOnChange, value]
156166
);
157167

158168
if (loading) {

0 commit comments

Comments
 (0)