Skip to content

Commit 2558f02

Browse files
feat: add support to live sync form on inline editing
1 parent c572486 commit 2558f02

3 files changed

Lines changed: 97 additions & 68 deletions

File tree

src/visualBuilder/generators/generateOverlay.tsx

Lines changed: 72 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -117,76 +117,83 @@ export function hideFocusOverlay(elements: HideOverlayParams): void {
117117
childNode.removeAttribute("style");
118118
}
119119
});
120+
sendFieldEvent({
121+
visualBuilderContainer,
122+
eventType: VisualBuilderPostMessageEvents.UPDATE_FIELD,
123+
});
120124

121-
if (
122-
VisualBuilder.VisualBuilderGlobalState.value
123-
.previousSelectedEditableDOM
124-
) {
125-
const pseudoEditableElement = visualBuilderContainer?.querySelector(
126-
"div.visual-builder__pseudo-editable-element"
127-
);
128-
129-
if (
130-
VisualBuilder.VisualBuilderGlobalState.value.previousSelectedEditableDOM.hasAttribute(
131-
"contenteditable"
132-
) ||
133-
pseudoEditableElement
134-
) {
135-
const actualEditedElement =
136-
pseudoEditableElement ||
137-
(VisualBuilder.VisualBuilderGlobalState.value
138-
.previousSelectedEditableDOM as HTMLElement);
139-
140-
let data =
141-
"innerText" in actualEditedElement
142-
? actualEditedElement.innerText
143-
: actualEditedElement.textContent;
144-
145-
const fieldMetadata = extractDetailsFromCslp(
146-
VisualBuilder.VisualBuilderGlobalState.value.previousSelectedEditableDOM.getAttribute(
147-
"data-cslp"
148-
) as string
125+
cleanIndividualFieldResidual({
126+
overlayWrapper: visualBuilderOverlayWrapper,
127+
visualBuilderContainer: visualBuilderContainer,
128+
focusedToolbar: focusedToolbar,
129+
resizeObserver: resizeObserver,
130+
});
131+
}
132+
}
133+
interface ISendFieldEventParams {
134+
visualBuilderContainer: HTMLElement | null;
135+
eventType: VisualBuilderPostMessageEvents.UPDATE_FIELD | VisualBuilderPostMessageEvents.SYNC_FIELD
136+
}
137+
export function sendFieldEvent(options: ISendFieldEventParams): void {
138+
const {
139+
visualBuilderContainer,
140+
eventType
141+
} = options;
142+
const previousSelectedEditableDOM = VisualBuilder.VisualBuilderGlobalState.value.previousSelectedEditableDOM;
143+
const pseudoEditableElement = visualBuilderContainer?.querySelector(
144+
"div.visual-builder__pseudo-editable-element"
145+
);
146+
if (
147+
previousSelectedEditableDOM &&
148+
(
149+
previousSelectedEditableDOM.hasAttribute("contenteditable") ||
150+
pseudoEditableElement
151+
)
152+
) {
153+
const actualEditedElement =
154+
pseudoEditableElement ||
155+
(previousSelectedEditableDOM as HTMLElement);
156+
157+
let data =
158+
"innerText" in actualEditedElement
159+
? actualEditedElement.innerText
160+
: actualEditedElement.textContent;
161+
162+
const fieldMetadata = extractDetailsFromCslp(
163+
previousSelectedEditableDOM.getAttribute(
164+
"data-cslp"
165+
) as string
166+
);
167+
168+
FieldSchemaMap.getFieldSchema(
169+
fieldMetadata.content_type_uid,
170+
fieldMetadata.fieldPath
171+
)
172+
.then((fieldSchema) => {
173+
if (fieldSchema && eventType === VisualBuilderPostMessageEvents.UPDATE_FIELD) {
174+
const fieldType = getFieldType(fieldSchema);
175+
if (
176+
fieldType &&
177+
fieldType === FieldDataType.MULTILINE
178+
) {
179+
data =
180+
getMultilinePlaintext(actualEditedElement);
181+
(actualEditedElement as HTMLElement).innerText =
182+
data as string;
183+
}
184+
}
185+
})
186+
.finally(() => {
187+
visualBuilderPostMessage?.send(
188+
eventType,
189+
{
190+
data,
191+
fieldMetadata,
192+
}
149193
);
150-
151-
FieldSchemaMap.getFieldSchema(
152-
fieldMetadata.content_type_uid,
153-
fieldMetadata.fieldPath
154-
)
155-
.then((fieldSchema) => {
156-
if (fieldSchema) {
157-
const fieldType = getFieldType(fieldSchema);
158-
if (
159-
fieldType &&
160-
fieldType === FieldDataType.MULTILINE
161-
) {
162-
data =
163-
getMultilinePlaintext(actualEditedElement);
164-
(actualEditedElement as HTMLElement).innerText =
165-
data as string;
166-
}
167-
}
168-
})
169-
.finally(() => {
170-
visualBuilderPostMessage?.send(
171-
VisualBuilderPostMessageEvents.UPDATE_FIELD,
172-
{
173-
data,
174-
fieldMetadata,
175-
}
176-
);
177-
});
178-
}
179-
180-
cleanIndividualFieldResidual({
181-
overlayWrapper: visualBuilderOverlayWrapper,
182-
visualBuilderContainer: visualBuilderContainer,
183-
focusedToolbar: focusedToolbar,
184-
resizeObserver: resizeObserver,
185194
});
186-
}
187195
}
188196
}
189-
190197
interface HideOverlayParams
191198
extends Pick<
192199
EventListenerHandlerParams,

src/visualBuilder/utils/handleFieldMouseDown.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
1+
import { throttle } from "lodash-es";
2+
import { sendFieldEvent } from "../generators/generateOverlay";
13
import {
4+
ALLOWED_INLINE_EDITABLE_FIELD,
25
VISUAL_BUILDER_FIELD_TYPE_ATTRIBUTE_KEY,
36
numericInputRegex,
47
} from "./constants";
58
import { FieldDataType } from "./types/index.types";
9+
import { VisualBuilderPostMessageEvents } from "./types/postMessage.types";
610

711
export function handleFieldInput(e: Event): void {
812
const event = e as InputEvent;
9-
10-
if (event.type === "input") {
11-
// do something
13+
const targetElement = event.target as HTMLElement;
14+
const fieldType = targetElement.getAttribute(
15+
VISUAL_BUILDER_FIELD_TYPE_ATTRIBUTE_KEY
16+
) as FieldDataType | null;
17+
if (event.type === "input" && ALLOWED_INLINE_EDITABLE_FIELD.includes(fieldType as FieldDataType)) {
18+
throttledFieldSync();
1219
}
1320
}
21+
const throttledFieldSync = throttle(() => {
22+
try {
23+
const visualBuilderContainer = document.querySelector(
24+
".visual-builder__container"
25+
) as HTMLElement;
26+
if(!visualBuilderContainer) return;
27+
sendFieldEvent({
28+
visualBuilderContainer,
29+
eventType: VisualBuilderPostMessageEvents.SYNC_FIELD,
30+
})
31+
} catch (error) {
32+
console.error("Error in throttledFieldSync", error)
33+
}
34+
}, 300);
1435

1536
export function handleFieldKeyDown(e: Event): void {
1637
const event = e as KeyboardEvent;

src/visualBuilder/utils/types/postMessage.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export enum VisualBuilderPostMessageEvents {
22
INIT = "init",
33
ADD_INSTANCE = "add-instance",
44
UPDATE_FIELD = "update-field",
5+
SYNC_FIELD = 'sync-field',
56
OPEN_ASSET_MODAL = "open-asset-modal",
67
OPEN_REFERENCE_MODAL = "open-reference-modal",
78
OPEN_QUICK_FORM = "open-quick-form",

0 commit comments

Comments
 (0)