Skip to main content

Element Events

Elements emit events that allow your application to respond to user interactions and state changes. This document explains how to effectively work with Element events.

Quick Reference

EventDescriptionCommon Use Cases
readyTriggered when the Element is mounted and readyInitialize UI state, show the form after Elements are ready
focusTriggered when the Element receives focusApply visual focus styles, show help text
blurTriggered when the Element loses focusValidate input, hide help text
changeTriggered when the Element's value changesUpdate UI based on input state, enable/disable submit buttons
keydownTriggered when a key is pressed while the Element has focusHandle special key actions (Enter to submit, etc.)

Handling Events

// Create a card element with inline event handlers
const cardElement = bt.createElement('card', {
targetId: 'my-card',
onReady: () => {
console.log('Card element is ready');
showForm(); // Show the form once Element is ready
},
onChange: (event) => {
// Update UI based on card input state
updateSubmitButton(event.complete);

if (event.error) {
showError(event.error.message);
} else {
clearError();
}
}
});

// Mount the element
cardElement.mount('#card-container');

// You can also add event listeners after creation
cardElement.on('focus', () => {
highlightCardField(); // Apply visual focus styles
showCardHelpText(); // Show help text when field is focused
});

cardElement.on('blur', () => {
resetCardFieldHighlight();
hideCardHelpText();
});

// Add keydown handler to submit form on Enter key
cardElement.on('keydown', (event) => {
if (event.key === 'Enter' && cardElement.getState().complete) {
document.getElementById('payment-form').requestSubmit();
}
});

// Remove event listeners when no longer needed
const changeHandler = (event) => {
// Handle change events
};

cardElement.on('change', changeHandler); // Add listener

Event Data Reference

Ready Event

The ready event is fired when the Element has been mounted and is ready for user interaction.

// Event data
{
type: 'ready'
}

Change Event

The change event is fired when the Element's value changes. The data varies by element type.

Base Change Event Properties (All Elements)

{
complete: false, // Whether the input is complete/valid
empty: true, // Whether the input is empty
errors: FieldError[], // Array of FieldErrors
maskSatisfied: false, // Whether the mask, if provided, is satisfied
type: "change"
valid: false, // Whether the current input is valid
}

Card Element Change Event Properties

{
cardBin: undefined, // First 6 to 8 digits of a credit or debit card number
cardBrand: 'visa', // Detected card brand (visa, mastercard, amex, etc.)
cardLast4: undefined, // Last 4 digits of a credit or debit card number
complete: true, // Whether all required card fields are complete
empty: true, // Whether the input is empty
errors: FieldError[], // Array of FieldErrors
maskSatisfied: false, // Whether the mask, if provided, is satisfied
valid: false // Whether the current input is valid
}

Card brands

Card Number Element Change Event Properties

{
cardBin: undefined, // First 6 to 8 digits of a credit or debit card number
cardBrand: 'visa', // Detected card brand (visa, mastercard, amex, etc.)
cardLast4: undefined, // Last 4 digits of a credit or debit card number
complete: true, // Whether all required card fields are complete
empty: true, // Whether the input is empty
errors: FieldError[], // Array of FieldErrors
maskSatisfied: false, // Whether the mask, if provided, is satisfied
valid: false, // Whether the current input is valid
}

Card brands

Expiration Date Element Change Event Properties

{
complete: true, // Whether all required card fields are complete
empty: true, // Whether the input is empty
errors: FieldError[], // Array of FieldErrors
maskSatisfied: false, // Whether the mask, if provided, is satisfied
valid: false, // Whether the current input is valid
}

Card Verification Code Element Change Event Properties

{
complete: true, // Whether all required card fields are complete
empty: true, // Whether the input is empty
errors: FieldError[], // Array of FieldErrors
maskSatisfied: false, // Whether the mask, if provided, is satisfied
valid: false, // Whether the current input is valid
}

Focus Events

{
targetId: string,
type: 'focus',
}

Blur Events

{
complete: true, // Whether all required card fields are complete
empty: true, // Whether the input is empty
errors: FieldError[], // Array of FieldErrors
maskSatisfied: false, // Whether the mask, if provided, is satisfied
targetId: string, // Elements targetId
type: "blur",
valid: false, // Whether the current input is valid
}

Keydown Event

The keydown event includes information about the key that was pressed. It is triggered when user hits a special key inside an element input.

{
altKey: false,
ctrlKey: false,
key: "Enter",
metaKey: false,
shiftKey: false,
targetId: string,
}

Errors

type FieldError = {
type: "incomplete" | "invalid",
targetId: string
}

Best Practices for Event Handling

Form Validation with Events

// Track the state of multiple elements
const formState = {
cardNumber: { complete: false },
cardExpiry: { complete: false },
cardCvc: { complete: false }
};

// Update form state when each element changes
cardNumberElement.on('change', (event) => {
formState.cardNumber = {
complete: event.complete,
valid: event.valid,
cardBrand: event.cardBrand
};
updateFormState();
});

cardExpiryElement.on('change', (event) => {
formState.cardExpiry = {
complete: event.complete,
valid: event.valid
};
updateFormState();
});

cardCvcElement.on('change', (event) => {
formState.cardCvc = {
complete: event.complete,
valid: event.valid
};
updateFormState();
});

// Update the UI based on overall form state
function updateFormState() {
const submitButton = document.getElementById('submit-button');
const isFormComplete =
formState.cardNumber.complete &&
formState.cardExpiry.complete &&
formState.cardCvc.complete;

submitButton.disabled = !isFormComplete;

// Show the card brand icon if detected
if (formState.cardNumber.cardBrand) {
showCardBrandIcon(formState.cardNumber.cardBrand);
}
}

Loading States with the Ready Event

// Show a loading state initially
const formContainer = document.getElementById('payment-form-container');
const loadingIndicator = document.getElementById('loading-indicator');

// Hide the form, show loading indicator
formContainer.style.display = 'none';
loadingIndicator.style.display = 'block';

// Track ready state of multiple elements
let elementsReady = {
cardNumber: false,
cardExpiry: false,
cardCvc: false
};

// Create and mount elements
const cardNumberElement = bt.createElement('cardNumber', {
targetId: 'card-number',
onReady: () => {
elementsReady.cardNumber = true;
checkAllElementsReady();
}
});

const cardExpiryElement = bt.createElement('cardExpirationDate', {
targetId: 'card-expiry',
onReady: () => {
elementsReady.cardExpiry = true;
checkAllElementsReady();
}
});

const cardCvcElement = bt.createElement('cardVerificationCode', {
targetId: 'card-cvc',
onReady: () => {
elementsReady.cardCvc = true;
checkAllElementsReady();
}
});

// Mount all elements
cardNumberElement.mount('#card-number-container');
cardExpiryElement.mount('#card-expiry-container');
cardCvcElement.mount('#card-cvc-container');

// Check if all elements are ready
function checkAllElementsReady() {
const allReady =
elementsReady.cardNumber &&
elementsReady.cardExpiry &&
elementsReady.cardCvc;

if (allReady) {
// Hide loading indicator, show the form
loadingIndicator.style.display = 'none';
formContainer.style.display = 'block';
}
}

Troubleshooting Event Issues

See the Troubleshooting Guide for help with event-related issues, including a complete debugging strategy.