Skip to content

Commit

Permalink
feat(DIST-891): Update event handler and add CUI docs and examples (#227
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Matej Lednicky authored Apr 26, 2021
1 parent ad1e944 commit aed1914
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 34 deletions.
15 changes: 9 additions & 6 deletions packages/demo-html/public/callbacks.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@
</head>
<body>
<script>
function onTypeformReady() {
alert('onReady')
function onTypeformReady(data) {
alert("onReady");
console.log("form ready", data);
}

function onTypeformSubmit() {
alert('onSubmit')
function onTypeformSubmit(data) {
alert("onSubmit");
console.log("form submitted", data);
}

function onTypeformQuestionChanged() {
alert('onQuestionChanged')
function onTypeformQuestionChanged(data) {
alert("onQuestionChanged");
console.log("form question changed", data);
}
</script>
<div
Expand Down
34 changes: 22 additions & 12 deletions packages/demo-html/public/chat.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,23 @@
<body>
<h1>this is an experimental feature</h1>

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

<div
id="wrapper"
data-tf-widget="moe6aa"
data-tf-medium="demo-test"
data-tf-transitive-search-params="foo,bar"
data-tf-hidden="foo=foo value,bar=bar value"
data-tf-opacity="50"
data-tf-chat
></div>
<div style="background: #ccc">
<div
id="wrapper"
data-tf-widget="moe6aa"
data-tf-medium="demo-test"
data-tf-transitive-search-params="foo,bar"
data-tf-hidden="foo=foo value,bar=bar value"
data-tf-opacity="50"
data-tf-chat
></div>
</div>

<p>
<button id="button">open popup</button>
(check dev tools console for callback methods)
</p>

<p>
Expand All @@ -51,6 +52,15 @@ <h1>this is an experimental feature</h1>
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;
</script>
Expand Down
43 changes: 41 additions & 2 deletions packages/embed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` |
Expand All @@ -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` |
Expand Down Expand Up @@ -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
<div id="wrapper"></div>
<script src="//embed.typeform.com/next/embed.js"></script>
<link rel="stylesheet" href="//embed.typeform.com/next/css/widget.css" />
<script>
window.tf.createWidget('<form-id>', {
container: document.getElementById("wrapper"),
onReady: () => {
console.log('form ready')
}
onQuestionChanged: (data) => {
console.log('question changed to ref:', data.ref)
}
onSubmit: (data) => {
console.log('forms submitted with id:', data.responseId)
// to retrieve the response use `data.responseId` (you have to do it server-side)
// more details: https://developer.typeform.com/responses/
}
})
</script>
```

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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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' })
Expand Down
20 changes: 7 additions & 13 deletions packages/embed/src/utils/create-iframe/get-form-event-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

0 comments on commit aed1914

Please sign in to comment.