Skip to main content

Elements Methods & Events

Basis Theory Elements offers several methods and events to listen to changes to your components and interact with the underlying data.

Methods

Once you have created and mounted an element instance, you can invoke the methods below:

<div id="my-card"></div>

<script>
var cardElement = BasisTheory.createElement("card");
cardElement.mount("#my-card");

cardElement.focus();
</script>
NameResulting TypeEligible ElementsDescription
clearvoidAllClears the element input(s) value.
focusvoidAllFocuses on the element input.
blurvoidAllBlurs the element input.
monthnumbercardExpirationDateData-parsing method that resolves to the month value of the input date, where "January" = 1.
yearnumbercardExpirationDateData-parsing method that resolves to the four-digit year value of the input date.
setValuevoidAllAccepts a synthetic reference from a retrieved token and safely sets it as the input value.

Events

You can communicate with Elements by listening to events. When you subscribe to an event, you'll get back a Subscription that you can unsubscribe if/when it fits your workflow.

// Make sure to replace 'event-type' with an actual event type.
var subscription = cardElement.on("event-type", (event) => {
// handle event
});

subscription.unsubscribe(); // stops listening to the event type

On Ready

This event is triggered when the element has rendered and user is able to start interacting with it.

cardElement.on("ready", () => {
// handle ready event
});

On Change

This event is triggered whenever element's value(s) change. For example, if the user types data that doesn't change the state of a field between valid/invalid or empty/filled, you shouldn't expect the event to trigger.

cardElement.on("change", (changeEvent) => {
if (changeEvent.complete) {
// enable submit button
} else {
// disable submit button
// present validation message
}
});
ParameterRequiredTypeDescription
eventtrue"change"The event type to listen to.
handlertruefunctionCallback function to be called when the event is fired. Takes in a ChangeEvent.

ChangeEvent

ChangeEvents are emitted depending on the validation strategy set for each element; by default, validations run onBlur. You can change this behavior by setting the boolean flag validateOnChange to true.

When running validations onChange, elements emit events whenever an error occurs or if the input's value changes. Default validation (onBlur) triggers an event every time one of the values below changes:

{
"complete": false,
"valid": false,
"maskSatisfid": false,
"empty": false,
"errors": [
{...},
{...}
],
"cardBrand": "american-express",
"cardLast4": "8431",
"cardBin": "341212"
}
AttributeTypeEligible ElementsDescription
completebooleanAllWhether the input valid and maskSatisfied properties are true.
validbooleanAllWhether the input is valid according to validation for each element. Defaults to true if no validation is defined for the element.
maskSatisfiedbooleanAllWhether the input satisfies the mask length requirements. Defaults to true if no mask is provided.
emptybooleanAllWhether the element is empty. Multi-input Elements will be empty only if all inputs are.
errorsarrayAllArray of FieldError.
cardBrandstringcard
cardNumber
(Optional) The credit card brand (e.g. 'american-express', 'visa', 'unknown'). The value defaults to 'unknown' until a card brand is recognized.
cardLast4stringcard
cardNumber
(Optional) The credit card's last 4 digits. The value is not provided until a complete card number is entered.
cardBinstringcard
cardNumber
(Optional) The credit card number's first 6 digits when the input is considered complete.

If you need an eight digit BINs please email us at info@basistheory.com.

Metadata

Instead of subscribing to events, the same properties can be accessed at any time from the metadata property on all elements.

Additionally, the card related event change events can be accessed from the cardMetadata property only on Card and CardNumber elements.

AttributeEligible ElementsAttributes
metadataAllcomplete, valid, maskSatisfied, empty
cardMetadatacard
cardNumber
cardLast4, cardBin, cardBrand

FieldError

{
"targetId": "cardNumber",
"type": "invalid"
}
AttributeTypeDescription
targetIdstringInput ID that triggered the error. Values vary per element type.
type"invalid" or "incomplete"Type of the error.

On Focus

Triggered when an element input is focused.

cardElement.on("focus", (focusEvent) => {});
ParameterRequiredTypeDescription
eventtrue"focus"The event type to listen to.
handlertruefunctionCallback function to be called when the event is fired. Takes in a FocusEvent.

FocusEvent

{
"targetId": "cardNumber"
}
AttributeTypeDescription
targetIdstringInput ID that triggered the event. Values vary per element type.

On Blur

Triggered when an element input focus is lost.

cardElement.on("blur", (blurEvent) => {});
ParameterRequiredTypeDescription
eventtrue"blur"The event type to listen to.
handlertruefunctionCallback function to be called when the event is fired. Takes in a BlurEvent.

BlurEvent

{
"targetId": "cardNumber"
}
AttributeTypeDescription
targetIdstringInput ID that triggered the event. Values vary per element type.

On Keydown

Triggered when user hits a special key inside an element input.

cardElement.on("keydown", (keydownEvent) => {});
ParameterRequiredTypeDescription
eventtrue"keydown"The event type to listen to.
handlertruefunctionCallback function to be called when the event is fired. Takes in a KeydownEvent.

KeydownEvent

{
"targetId": "cardNumber",
"key": "Enter",
"ctrlKey": false,
"altKey": false,
"shiftKey": false,
"metaKey": false
}
AttributeTypeDescription
targetIdstringInput targetId that triggered the event. Values vary per element type.
keyEscape or EnterKey pressed by the user.
ctrlKeybooleanFlag indicating control key was pressed when the event occurred.
altKeybooleanFlag indicating alt key was pressed when the event occurred.
shiftKeybooleanFlag indicating shift key was pressed when the event occurred.
metaKeybooleanFlag indicating meta key was pressed when the event occurred.

Tokenization

Elements' values can be securely tokenized using tokens.create and tokenize services. To do that, simply pass the Element instance (or one of its data parsing methods) in the payload.

You can fetch this same data later with Get a Token API

Create generic token
BasisTheory.tokens
.create({
type: "token",
data: {
sensitiveData: sensitiveDataElement,
nonSensitiveData: "plainText", // see warning on plain text data
otherData: {
someInteger: 20,
someBoolean: false,
},
someOtherData: ["plainText1", "plainText2"],
},
metadata: {
nonSensitiveField: "nonSensitiveValue",
},
})
.then((token) => {
console.log(token.id); // token to store
console.log(JSON.stringify(token)); // full response
});
Create card token
BasisTheory.tokens
.create({
type: "card",
data: cardElement,
})
.then((token) => {
console.log(token.id); // token to store
console.log(JSON.stringify(token.data)); // redacted card data
});
Create bank token
BasisTheory.tokens
.create({
type: "bank",
data: {
routingNumber: routingNumberElement,
accountNumber: accountNumberElement,
},
})
.then((token) => {
console.log(token.id); // token to store
console.log(JSON.stringify(token.data)); // redacted bank data
});
Tokenize data
BasisTheory.tokenize({
card1: {
type: "card",
data: cardElement,
},
card2: {
type: "card",
data: {
number: cardNumberElement,
expiration_month: cardExpirationDateElement.month(),
expiration_year: cardExpirationDateElement.year(),
cvc: cardVerificationCodeElement,
},
},
sensitiveData: sensitiveDataElement,
nonSensitiveData: "plainText", // see warning on plain text data
otherData: {
someInteger: 20,
someBoolean: false,
},
someOtherData: ["plainText1", "plainText2"],
}).then((tokens) => {
console.log(tokens.card1.id, tokens.card2.id, tokens.sensitiveData); // token to store
console.log(JSON.stringify(tokens)); // full response
});

The actual input data never leaves the element (iframe) other than to hit our secure API endpoints.

When submitting plainText values, data will be HTML encoded before storage for security reasons.

Errors

Elements services could throw an error based on client-side validations or if the server rejects the request.

Handling services errors
import {
BasisTheoryApiError,
BasisTheoryValidationError,
} from "@basis-theory/basis-theory-js/common";

BasisTheory.tokenize({
card1: {
type: "card",
data: cardElement1,
},
card2: {
type: "card",
data: cardElement2,
},
ssn: textElement,
}).catch((error) => {
if (error instanceof BasisTheoryValidationError) {
// check error details
} else if (error instanceof BasisTheoryApiError) {
// check error data or status
}
});

BasisTheoryValidationError

{
details: {
card1: {
number: {
type: 'invalid'
},
cvc: {
type: 'incomplete'
}
},
card2: {
}
},
validation: [] // deprecated
}
AttributeTypeDescription
namestringError name, always 'BasisTheoryValidationError'.
detailsobjectMaps payload properties to their respective element's validation problems.

BasisTheoryApiError

{
data: {
// API response body
},
status: 400
}
AttributeTypeDescription
namestringError name, always 'BasisTheoryApiError'.
dataobjectResponse body sent from the server.
statusnumberResponse HTTP status.

Error name property may be used instead of checking its instance type.

Detokenization

Elements' values can be securely revealed using the tokens.retrieve service and the Elements' setValue method. When retrieve is called from a Basis Theory instance configured with elements: true, the API request is made from inside a Basis Theory hosted iframe and the returned data remains within it.

Retrieve 'string' token data and set value into TextElement
const textElement = BasisTheory.createElement("text", {
targetId: "text-element",
});

BasisTheory.tokens
.retrieve("ca9f3fd7-3906-4087-83aa-9a6129221297", {
apiKey: "key_N88mVGsp3sCXkykyN2EFED", // api key is required and should belong to a session
})
.then((token) => {
textElement.setValue(token.data);
});
Retrieve card token and set value into CardElement
const cardElement = BasisTheory.createElement("card");

BasisTheory.tokens
.retrieve("ca9f3fd7-3906-4087-83aa-9a6129221297", {
apiKey: "key_N88mVGsp3sCXkykyN2EFED", // api key is required and should belong to a session
})
.then((token) => {
cardElement.setValue(token.data);
});

// or

BasisTheory.tokens
.retrieve("ca9f3fd7-3906-4087-83aa-9a6129221297", {
apiKey: "key_N88mVGsp3sCXkykyN2EFED", // api key is required and should belong to a session
})
.then((token) => {
cardElement.setValue({
number: token.data.number, // expects string
expiration_month: token.data.expiration_month, // expects number
expiration_year: token.data.expiration_year, // expects number
});
});
Retrieve card token and set value into split card elements
const cardNumberElement = BasisTheory.createElement("cardNumber", {
targetId: "card-number",
});
const cardExpirationDateElement = BasisTheory.createElement(
"cardExpirationDate",
{ targetId: "card-expiration-date" }
);

BasisTheory.tokens
.retrieve("ca9f3fd7-3906-4087-83aa-9a6129221297", {
apiKey: "key_N88mVGsp3sCXkykyN2EFED", // api key is required and should belong to a session
})
.then((token) => {
cardNumberElement.setValue(token.data.number);
cardExpirationDateElement.setValue({
month: token.data.expiration_month,
year: token.data.expiration_year,
});
});

The data attribute in the token returned by the retrieve method is not the actual data, but a a synthetic representation of the sensitive detokenized data.

Token attributes such as metadata are directly accessible from the retrieve response as they are considered non-sensitive.

Errors

Elements services will throw an error if the server rejects the request.

Handling service errors
import { BasisTheoryApiError } from "@basis-theory/basis-theory-js/common";

BasisTheory.tokens
.retrieve("ca9f3fd7-3906-4087-83aa-9a6129221297", {
apiKey: "key_N88mVGsp3sCXkykyN2EFED", // api key is required and should belong to a session
})
.catch((error) => {
if (error instanceof BasisTheoryApiError) {
// check error details
}
});

BasisTheoryApiError

{
data: {
// API response body
},
status: 400
}
AttributeTypeDescription
namestringError name, always 'BasisTheoryApiError'.
dataobjectResponse body sent from the server.
statusnumberResponse HTTP status.

Error name property may be used instead of checking its instance type.