Event listeners

If you are using the Standard embed, Popup or Custom domain code injection, you can add a JavaScript event listener to get notified on specific events sent from the form.

<aside> <img src="/icons/info-alternate_blue.svg" alt="/icons/info-alternate_blue.svg" width="40px" />

If you’re using an embed or popup, please add the following snippets to your website on the page where the embed or popup will appear.

</aside>

Form loaded

Since the standard embed and the popup are lazy loaded, you will receive this event whenever the form is loaded i.e. shown to the respondent.

interface LoadedPayload {
	formId: string;
}

window.addEventListener('message', (e) => {
	if (e?.data?.includes('Tally.FormLoaded')) {
		const payload = JSON.parse(e.data).payload as LoadedPayload;
		// ...
	}
});

Form page view

This is specifically handy if you have a form with multiple pages so you get an event each time the respondent navigates to a page.

interface PageViewPayload {
	formId: string;
	page: number;
}

// For embeds/popups
window.addEventListener('message', (e) => {
	if (e?.data?.includes('Tally.FormPageView')) {
		const payload = JSON.parse(e.data).payload as PageViewPayload;
		// ...
	}
});

// For code injection via a custom domain
window.addEventListener('Tally.FormPageView', (e) => {
	const payload = e.detail as PageViewPayload;
	// ...
});

Form submission

This event is triggered when the form is submitted and it contains not only some metadata, but also the form data (respondent’s answers).

interface SubmissionPayload {
	id: string; // submission ID
	respondentId: string;
	formId: string;
	formName: string;
	createdAt: Date; // submission date
	fields: Array<{
		id: string;
		title: string;
		type: 'INPUT_TEXT' | 'INPUT_NUMBER' | 'INPUT_EMAIL' | 'INPUT_PHONE_NUMBER' | 'INPUT_LINK' | 'INPUT_DATE' | 'INPUT_TIME' | 'TEXTAREA' | 'MULTIPLE_CHOICE' | 'DROPDOWN' | 'CHECKBOXES' | 'LINEAR_SCALE' | 'FILE_UPLOAD' | 'HIDDEN_FIELDS' | 'CALCULATED_FIELDS' | 'RATING' | 'MULTI_SELECT' | 'MATRIX' | 'RANKING' | 'SIGNATURE' | 'PAYMENT';
		answer: { value: any; raw: any; };
	}>;
}

// For embeds/popups
window.addEventListener('message', (e) => {
	if (e?.data?.includes('Tally.FormSubmitted')) {
		const payload = JSON.parse(e.data).payload as SubmissionPayload;
		// ...
	}
});

// For code injection via a custom domain
window.addEventListener('Tally.FormSubmitted', (e) => {
	const payload = e.detail as SubmissionPayload;
	// ...
});

Popup closed