Skip to main content

Elements Method & 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

{
"complete": false,
"empty": false,
"errors": [
{...},
{...}
],
"cardBrand": "american-express",
"cardLast4": "8431"
}
AttributeTypeEligible ElementsDescription
completebooleanAllIf the element value is well-formed and is ready to be submitted.
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.

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 an 'expiring' application
})
.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 an 'expiring' application
})
.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 an 'expiring' application
})
.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 an 'expiring' application
})
.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 an 'expiring' application
})
.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.