From aed19145792bdc58fbcef5310a28b4cad3d0363d Mon Sep 17 00:00:00 2001 From: Matej Lednicky Date: Mon, 26 Apr 2021 10:25:16 +0200 Subject: [PATCH] feat(DIST-891): Update event handler and add CUI docs and examples (#227) --- packages/demo-html/public/callbacks.html | 15 ++++--- packages/demo-html/public/chat.html | 34 +++++++++------ packages/embed/README.md | 43 ++++++++++++++++++- .../utils/create-iframe/create-iframe.spec.ts | 2 +- .../create-iframe/get-form-event-handler.ts | 20 +++------ 5 files changed, 80 insertions(+), 34 deletions(-) diff --git a/packages/demo-html/public/callbacks.html b/packages/demo-html/public/callbacks.html index 4fde67be..c00520e0 100644 --- a/packages/demo-html/public/callbacks.html +++ b/packages/demo-html/public/callbacks.html @@ -13,16 +13,19 @@

this is an experimental feature

-

- you can use embed lib to embed the form with chat UI, however not all features are yet supported (eg. callbacks) -

+

you can use embed lib to embed the form with chat UI

-
+
+
+

+ (check dev tools console for callback methods)

@@ -51,6 +52,15 @@

this is an experimental feature

chat: true, width: 400, height: 600, + onReady: (data) => { + console.log("chat ready", data); + }, + onSubmit: (data) => { + console.log("chat submitted", data); + }, + onQuestionChanged: (data) => { + console.log("chat question changed", data); + }, }); document.getElementById("button").onclick = toggle; diff --git a/packages/embed/README.md b/packages/embed/README.md index d28a7ea8..ee89b7d1 100644 --- a/packages/embed/README.md +++ b/packages/embed/README.md @@ -68,6 +68,7 @@ Or from admin panel URL: | name | type | description | default | | ---------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | | container | HTMLElement | specify element to place the embed into, only for widget, required | current element when embedding as HTML, otherwise `undefined` | +| chat | boolean | embed the typeform as [Chat UI](https://help.typeform.com/hc/en-us/articles/360034224732-Turn-your-typeform-into-a-chat) | `false` | | size | number | size of the popup in percentage | `100` (100% size, fullscreen popup) | | width | number | width of the popup in pixels (instead of `size`, also specify `height`) | `undefined` | | height | number | height of the popup in pixels (instead of `size`, also specify `width`) | `undefined` | @@ -76,8 +77,8 @@ Or from admin panel URL: | medium | string | name of the plugin built on top of the SDK | `"embed-sdk"` | | mediumVersion | string | version of the plugin built on top of the SDK | `"next"` | | transitiveSearchParams | string[] | search parameters to be forwarded from host page to form | `undefined` | -| hideFooter | boolean | hide form progress bar and navigation buttons | `false` | -| hideHeaders | boolean | hide header that appears when you have a question group, or a long question | `false` | +| hideFooter | boolean | hide form progress bar and navigation buttons (does not apply to Chat UI) | `false` | +| hideHeaders | boolean | hide header that appears when you have a question group, or a long question (does not apply to Chat UI) | `false` | | opacity | number | form background opacity, number from 0 (fully transparent) 100 (fully opaque) | `100` | | disableAutoFocus | boolean | disable form auto focus when loaded | `false` | | open | string | open embed based on user action (see below) | `undefined` | @@ -115,6 +116,44 @@ Properties `open` and `openValue` apply only to embed types that are opened by u For details see [behavioral demo](../demo-html/public/behavioral-html). +### Callbacks + +You can listen to form events by providing callback methods: + +```html +
+ + + +``` + +Callback method receive payload object from the form: + +- onReady + - empty object +- onQuestionChanged + - `ref` (string) identifies currenttly displayed question +- onReady + - `responseId` (string) identifies the response, can be retrieved via [Responses API](https://developer.typeform.com/responses/) + - `response_id` (string) same as above (for backward comaptibility with old embed SDK) + +See [callbacks example in demo package](../../packages/demo-html/public/callbacks.html). + ### Examples You can find examples for specific use-cases in our demos: diff --git a/packages/embed/src/utils/create-iframe/create-iframe.spec.ts b/packages/embed/src/utils/create-iframe/create-iframe.spec.ts index fc5b1406..75ada74d 100644 --- a/packages/embed/src/utils/create-iframe/create-iframe.spec.ts +++ b/packages/embed/src/utils/create-iframe/create-iframe.spec.ts @@ -60,7 +60,7 @@ describe('create-iframe', () => { }) it('should call form-submit handler', async () => { - window.postMessage({ type: 'form-submit', response_id: 'test-response-id', embedId: 'random-id' }, '*') + window.postMessage({ type: 'form-submit', responseId: 'test-response-id', embedId: 'random-id' }, '*') await new Promise((resolve) => setTimeout(resolve)) expect(options.onSubmit).toBeCalledWith({ responseId: 'test-response-id' }) diff --git a/packages/embed/src/utils/create-iframe/get-form-event-handler.ts b/packages/embed/src/utils/create-iframe/get-form-event-handler.ts index cc54fbbd..6dc9ced6 100644 --- a/packages/embed/src/utils/create-iframe/get-form-event-handler.ts +++ b/packages/embed/src/utils/create-iframe/get-form-event-handler.ts @@ -9,25 +9,19 @@ export const getFormQuestionChangedHandler = (embedId: string, options: Actionab } export const getFormSubmitHandler = (embedId: string, options: ActionableOptions) => { - const getEventPayload = (ev: any) => ({ responseId: ev?.data?.response_id }) - - return getFormEventHandler('form-submit', embedId, options.onSubmit, getEventPayload) + return getFormEventHandler('form-submit', embedId, options.onSubmit) } -export function getFormEventHandler( - eventType: string, - embedId: string, - callback?: (ev: any) => void, - transformEventPayload: (ev: any) => any = () => undefined -) { +export function getFormEventHandler(eventType: string, expectedEmbedId: string, callback?: (ev: any) => void) { return (event: any) => { - if (event.data.type !== eventType) { + const { type, embedId, ...data } = event.data + if (type !== eventType) { return } - if (event.data.embedId !== embedId) { + if (embedId !== expectedEmbedId) { return } - const transformedEvent = transformEventPayload(event) - callback?.(transformedEvent) + + callback?.(data) } }