Skip to content

Commit b4ea936

Browse files
committed
fix(live-component): fix array valued checkboxes change event handling
1 parent cec9422 commit b4ea936

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

src/LiveComponent/assets/dist/live_controller.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ class ValueStore {
368368
return this.pendingProps[normalizedName];
369369
}
370370
if (this.props[normalizedName] !== undefined) {
371+
if (Array.isArray(this.props[normalizedName])) {
372+
return [...this.props[normalizedName]];
373+
}
371374
return this.props[normalizedName];
372375
}
373376
return getDeepData(this.props, normalizedName);

src/LiveComponent/assets/src/Component/ValueStore.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ export default class {
5050
}
5151

5252
if (this.props[normalizedName] !== undefined) {
53+
if (Array.isArray(this.props[normalizedName])) {
54+
return [...this.props[normalizedName]];
55+
}
5356
return this.props[normalizedName];
5457
}
5558

src/LiveComponent/assets/test/controller/model.test.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,38 @@ describe('LiveController data-model Tests', () => {
335335
expect(test.component.valueStore.getOriginalProps()).toEqual({form: {check: ['foo', 'bar']}});
336336
});
337337

338+
it('sends correct data for array valued checkbox fields with non-form object', async () => {
339+
const test = await createTest({ check: [] }, (data: any) => `
340+
<div ${initComponent(data)}>
341+
<form data-model="*">
342+
<label>
343+
Checkbox 1: <input type="checkbox" name="check[]" value="foo" ${data.check.indexOf('foo') > -1 ? 'checked' : ''} />
344+
</label>
345+
346+
<label>
347+
Checkbox 2: <input type="checkbox" name="check[]" value="bar" ${data.check.indexOf('bar') > -1 ? 'checked' : ''} />
348+
</label>
349+
</form>
350+
351+
Checkbox 2 is ${data.check.indexOf('bar') > -1 ? 'checked' : 'unchecked' }
352+
</div>
353+
`);
354+
355+
const check1Element = getByLabelText(test.element, 'Checkbox 1:');
356+
const check2Element = getByLabelText(test.element, 'Checkbox 2:');
357+
358+
// only 1 Ajax call will be made thanks to debouncing
359+
test.expectsAjaxCall()
360+
.expectUpdatedData({ 'check': ['foo', 'bar'] });
361+
362+
await userEvent.click(check1Element);
363+
await userEvent.click(check2Element);
364+
365+
await waitFor(() => expect(test.element).toHaveTextContent('Checkbox 2 is checked'));
366+
367+
expect(test.component.valueStore.getOriginalProps()).toEqual({check: ['foo', 'bar']});
368+
});
369+
338370
it('sends correct data for array valued checkbox fields with initial data', async () => {
339371
const test = await createTest({ form: { check: ['foo']} }, (data: any) => `
340372
<div ${initComponent(data)}>
@@ -367,6 +399,36 @@ describe('LiveController data-model Tests', () => {
367399
expect(test.component.valueStore.getOriginalProps()).toEqual({form: {check: ['bar']}});
368400
});
369401

402+
it('sends correct data for array valued checkbox fields with non-form object and with initial data', async () => {
403+
const test = await createTest({ check: ['foo'] }, (data: any) => `
404+
<div ${initComponent(data)}>
405+
<label>
406+
Checkbox 1: <input type="checkbox" data-model="check[]" value="foo" ${data.check.indexOf('foo') > -1 ? 'checked' : ''} />
407+
</label>
408+
409+
<label>
410+
Checkbox 2: <input type="checkbox" data-model="check[]" value="bar" ${data.check.indexOf('bar') > -1 ? 'checked' : ''} />
411+
</label>
412+
413+
Checkbox 1 is ${data.check.indexOf('foo') > -1 ? 'checked' : 'unchecked' }
414+
</div>
415+
`);
416+
417+
const check1Element = getByLabelText(test.element, 'Checkbox 1:');
418+
const check2Element = getByLabelText(test.element, 'Checkbox 2:');
419+
420+
// only 1 Ajax call will be made thanks to debouncing
421+
test.expectsAjaxCall()
422+
.expectUpdatedData({ 'check': ['bar'] });
423+
424+
await userEvent.click(check1Element);
425+
await userEvent.click(check2Element);
426+
427+
await waitFor(() => expect(test.element).toHaveTextContent('Checkbox 1 is unchecked'));
428+
429+
expect(test.component.valueStore.getOriginalProps()).toEqual({check: ['bar']});
430+
});
431+
370432
it('sends correct data for select multiple field', async () => {
371433
const test = await createTest({ form: { select: []} }, (data: any) => `
372434
<div ${initComponent(data)}>

0 commit comments

Comments
 (0)