Skip to content

Commit e242869

Browse files
Fix checkbox DOM sync (#50991)
# Fix checkbox DOM sync Unbreaks checkboxes with custom value attributes. ## Description There was a trivial logic error in the DOM syncing code, causing the `value` attribute on checkboxes to get wrongly overwritten in a certain case (if there was a custom value attribute and `checked` was unchanged). Fixes #50995 ## Customer Impact In some cases, checkbox values would get corrupted after an enhanced navigation. This would break form functionality. The specific scenario was "checkboxes with a custom value attribute, when an enhanced nav leaves the `checked` state unchanged". ## Regression? - [ ] Yes - [x] No [If yes, specify the version the behavior has regressed from] ## Risk - [ ] High - [ ] Medium - [x] Low Very low because it's a tiny code edit, and only affects a very specific scenario, and the old logic was (in retrospect) definitely incorrect. ## Verification - [x] Manual (required) - [x] Automated ## Packaging changes reviewed? - [ ] Yes - [ ] No - [x] N/A
1 parent 07963de commit e242869

File tree

4 files changed

+22
-4
lines changed

4 files changed

+22
-4
lines changed

src/Components/Web.JS/dist/Release/blazor.server.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/dist/Release/blazor.web.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Rendering/DomMerging/DomSync.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,10 @@ function ensureEditableValueSynchronized(destination: Element, value: any) {
354354
} else if (destination instanceof HTMLSelectElement && destination.selectedIndex !== value) {
355355
destination.selectedIndex = value as number;
356356
} else if (destination instanceof HTMLInputElement) {
357-
if (destination.type === 'checkbox' && destination.checked !== value) {
358-
destination.checked = value as boolean;
357+
if (destination.type === 'checkbox') {
358+
if (destination.checked !== value) {
359+
destination.checked = value as boolean;
360+
}
359361
} else if (destination.value !== value) {
360362
destination.value = value as string;
361363
}

src/Components/Web.JS/test/DomSync.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,22 @@ describe('DomSync', () => {
469469
expect(selectElem.selectedIndex).toBe(2);
470470
});
471471

472+
test('should handle checkboxes with value attribute', () => {
473+
// Checkboxes require even more special-case handling because their 'value' attribute
474+
// has to be handled as a regular attribute, and 'checked' must be handled similarly
475+
// to 'value' on other inputs
476+
477+
const destination = makeExistingContent(`<input type='checkbox' value='first' checked />`);
478+
const newContent = makeNewContent(`<input type='checkbox' value='second' checked />`);
479+
480+
const checkboxElem = destination.startExclusive.nextSibling as HTMLInputElement;
481+
482+
// Act/Assert
483+
synchronizeDomContent(destination, newContent);
484+
expect(checkboxElem.checked).toBeTruthy();
485+
expect(checkboxElem.value).toBe('second');
486+
});
487+
472488
test('should treat doctype nodes as unchanged', () => {
473489
// Can't update a doctype after the document is created, nor is there a use case for doing so
474490
// We just have to skip them, as it would be an error to try removing or inserting them

0 commit comments

Comments
 (0)