- Issue created by @mayur-sose
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
Interesting find! Not sure yet if this is a client-side or server-side bug. But since the server side renders the preview for the component tree it receives, I suspect it's the client side. If it's the server side, then I suspect it's in the auto-save functionality.
- ๐ฎ๐ณIndia BhumikaVarshney Delhi
Hi
I tried to reporduce the issue but not able to reporcude the same.
I edited the button and followed the steps added above.
But in preview i can see the same text which we added.
please refer the screenshots - ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
Definitely a bug! ๐ Thanks! ๐
This is either a bug on the back-end (internal HTTP API or Auto-save), in the client-side handling of Auto-save, or in the Redux-integrated field widgets. Can you please attach the request body that was sent to generate that form when it was broken? ๐
Below is the request payload (when it was broken) :
{ "componentInstanceUuid": "ebfd85b0-1622-4a67-aa18-4847301ce5a5", "componentType": "sdc.experience_builder.my-hero", "model": { "source": { "heading": { "expression": "โน๏ธstringโvalue", "sourceType": "static:field_item:string", "value": "There goes my hero" }, "subheading": { "expression": "โน๏ธstringโvalue", "sourceType": "static:field_item:string", "value": "Watch him as he goes!" }, "cta1": { "expression": "โน๏ธstringโvalue", "sourceType": "static:field_item:string", "value": "View" }, "cta1href": { "expression": "โน๏ธlinkโuri", "sourceType": "static:field_item:link", "value": "https://example.com", "sourceTypeSettings": { "instance": { "title": 0 } } }, "cta2": { "expression": "โน๏ธstringโvalue", "sourceType": "static:field_item:string", "value": "Click" } }, "resolved": { "heading": "There goes my hero", "subheading": "Watch him as he goes!", "cta1": "View", "cta1href": "https://example.com", "cta2": "Click" } } }
- ๐ซ๐ฎFinland lauriii Finland
I was able to reproduce this! This is critical because of data loss.
- ๐ฌ๐งUnited Kingdom jessebaker
When editing the Hero component that is bundled with XB
1. Update the values of some of the fields
2. Observe that the preview is updated with those changes
3. Focus into and then focus out of the "CTA 1 link" (autocomplete) field
4. Observe that, while the form values remain updated, the preview reverts back to before the changes made in step 1.If you view the network request that occurs on blur you can see that the data sent as PATCH to the server contains the starting values of the form, not the updated ones.
- First commit to issue fork.
- Merge request !997#3519734: Blur on the auto-complete field sends stale data to update the preview. โ (Open) created by omkar-pd
- ๐ฎ๐ณIndia omkar-pd
Adding
attributes.onChange
in dependency array fixes the issue.While this causes the effect to run multiple times as
onChange
reference update, but I think it's necessary to ensure event handlers always have access to the current state. - ๐ฎ๐ณIndia omkar-pd
Or we could use useRef to fix the issue
diff --git a/ui/src/components/form/components/TextFieldAutocomplete.tsx b/ui/src/components/form/components/TextFieldAutocomplete.tsx index 762e9b47..6ff8adee 100644 --- a/ui/src/components/form/components/TextFieldAutocomplete.tsx +++ b/ui/src/components/form/components/TextFieldAutocomplete.tsx @@ -1,6 +1,6 @@ import clsx from 'clsx'; import { TextField as RadixThemesTextField } from '@radix-ui/themes'; -import { forwardRef, useEffect, useImperativeHandle } from 'react'; +import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react'; import type { MutableRefObject } from 'react'; import type { Attributes } from '@/types/DrupalAttribute'; import styles from './TextField.module.css'; @@ -40,6 +40,12 @@ const TextFieldAutocomplete = forwardRef( attributes['data-xb-no-update'] = ''; const inputRef = ref as MutableRefObject<HTMLInputElement>; + const onChangeRef = useRef(attributes.onChange); + + // Update ref when onChange changes + useEffect(() => { + onChangeRef.current = attributes.onChange; + }, [attributes.onChange]); // Create a version of the ref that will appease Typescript. useImperativeHandle(ref, () => inputRef.current as HTMLInputElement); @@ -55,7 +61,7 @@ const TextFieldAutocomplete = forwardRef( inputRef.current.removeAttribute('data-xb-no-update'); setTimeout(() => { // Call the onChange listener so the Redux store is updated. - if (attributes?.onChange) { + if (onChangeRef.current) { const event = new Event('change'); inputRef.current.value = e.detail.target.value; @@ -63,8 +69,8 @@ const TextFieldAutocomplete = forwardRef( writable: false, value: inputRef.current, }); - if (typeof attributes?.onChange === 'function') { - attributes.onChange(event); + if (typeof onChangeRef.current === 'function') { + onChangeRef.current(event); } } }); @@ -100,14 +106,14 @@ const TextFieldAutocomplete = forwardRef( // If the input is blurred, remove the attribute that prevents real // time preview updates. inputRef.current.removeAttribute('data-xb-no-update'); - if (attributes?.onChange) { + if (onChangeRef.current) { const event = new Event('change'); Object.defineProperty(event, 'target', { writable: false, value: inputRef.current, }); - if (typeof attributes?.onChange === 'function') { - attributes.onChange(event); + if (typeof onChangeRef.current === 'function') { + onChangeRef.current(event); } } };
- ๐บ๐ธUnited States bnjmnm Ann Arbor, MI
Or we could use useRef to fix the issue
Good idea. Lets do that to minimize
useEffect
, even if it means a bit of extra logic. - Merge request !1005#3519734 ref approach with test to fix autocomplete blur problems โ (Merged) created by bnjmnm
- ๐บ๐ธUnited States bnjmnm Ann Arbor, MI
bnjmnm โ changed the visibility of the branch 3519734-blur-on-the to hidden.
-
bnjmnm โ
committed f98dd275 on 0.x
Issue #3519734 by bnjmnm, omkar-pd, mayur-sose, jessebaker: Blur on the...
-
bnjmnm โ
committed f98dd275 on 0.x
- ๐ฆ๐บAustralia larowlan ๐ฆ๐บ๐.au GMT+10
bnjmnm โ credited larowlan โ .
- ๐บ๐ธUnited States bnjmnm Ann Arbor, MI
With @larowlan approval this can be merged.