Some tips to make the most of hosted-fields integration: How to custom your form according to the card type ? How faking the
Because the input fields are hosted on another page, displayed in an iframe, it is not possible to use the classic "for" attribute for labels. however it is possible to simulate this property in this way:
-
Add a onclick event on the labels
htmlCopy
<p>
<label id="card-label" onclick="focusIframe('hosted-fields-frame-card');">Card number</label>
<!-- Card number container -->
</p>
<p>
<label id="card-label" onclick="focusIframe('hosted-fields-frame-expiry');">Expiry</label>
<!-- Card expiry container -->
</p>
<p>
<label id="card-label" onclick="focusIframe('hosted-fields-frame-cryptogram');">Cryptogram</label>
<!-- Card cryptogram container -->
</p>Tip
This onclick event can be added on the containers themself to avoid unclickable dead zones around iframes.
-
Add this little piece of JavaScript
jsCopy
function focusIframe(id)
{
var iframe = document.getElementById(id);
iframe.contentWindow.focus();
return true;
}
Custom your form according to the card type
-
Create a function to apply a class depending of the card type
jsCopy
function formCustom(cardType)
{
// Customize your form as you wish, for example by adding a pictogram of the type of card used
var picto= document.getElementById("cardPictogram");
picto.className = cardType;
}Reminder
the available values for cardType are as follows:
- american_express
- bancontact
- maestro
- mastercard
- visa
-
Call this fonction for the input event of the card input field
jsCopy
var hfields = be2bill.hostedFields({
key: {
id: "Your API Key",
value: "Your API Key value"
},
fields: {
'card': {
id: 'card-container',
onInput: function(event) {
if(event.cardType) {
formCustom(event['cardType']);
}
}
} -
Manage your classes in your CSS
cssCopy
#cardPictogram.mastercard {
background-image: url("mastercard-logo.svg");
}
...
Imitate Material Design floating label effect
As seen previously, the input fields being hosted on an external page, outside the DOM, it is inconceivable to consider animating their placeholder attributes.
So you have to fake it, making labels look like placeholders.
-
To get started, you have to display floating labels over the input fields:
htmlCopy
<p>
<label id="card-label" onclick="focusIframe('hosted-fields-frame-card');">Card number</label>
<span class="input-container" id="card-container" onclick="focusIframe('hosted-fields-frame-card');"></span>
</p>
<p>
<label id="card-label" onclick="focusIframe('hosted-fields-frame-expiry');">Expiry</label>
<span class="input-container" id="expiry-container" onclick="focusIframe('hosted-fields-frame-expiry');"></span>
</p>
<p>
<label id="card-label" onclick="focusIframe('hosted-fields-frame-cryptogram');">Cryptogram</label>
<span class="input-container" id="cryptogram-container" onclick="focusIframe('hosted-fields-frame-cryptogram');"></span>
</p>cssCopyform p {
/* The position of each paragraph will be used as a reference to
* set the absolute position of the child elements <label> */
position: relative;
height: 40px;
}
label {
/* Gives an absolute position based on the parent elements <p> */
z-index: 1;
position: absolute;
padding: 10px 7px;
left: 0;
bottom: 0;
/* Labels must be superimposed on the input fields */
display: block;
width: 100%;
height: 40px;
box-sizing: border-box;
/* Simulates a placeholder style */
fonts-style: italic;
color: #bbb;
/* Simulates an on hover input text cursor */
cursor: text;
/* Smooth transition effect */
transition: all 250ms ease-in-out;
} -
One might be tempted to start the labels animation only when clicking on them, but the user could use the TAB key to focus to target the iframes.
So add onclick and onkeydown listeners to make sure you don't miss any command to target a hosted field:
jsCopy// Detects the use of any key, especially the TAB key, to focus on a hosted field.
document.onkeydown = function(){
formDynamics();
};
// Detects the use of the mouse
document.onclick = function(){
formDynamics();
}; -
In case a listener is triggered, hold on 100 ms before checking if a container class has changed, and indicates a focus on a hosted field.
If so, add classes on all the labels to trigger their animations:
jsCopyfunction formDynamics() {
var cardField = document.getElementById("card-container");
var cardLabel = document.getElementById("card-label");
var expiryField = document.getElementById("expiry-container");
var expiryLabel = document.getElementById("expiry-label");
var cryptogramField = document.getElementById("cryptogram-container");
var cryptogramLabel = document.getElementById("cryptogram-label");
// Hold on 100ms before checking for the presence of a "focus" class on the hosted-fields containers
setTimeout(function() {
// If the focus is confirmed on any hosted-field...
if( cardField.className.indexOf("hosted-fields-focus-state") > -1
|| expiryField.className.indexOf("hosted-fields-focus-state") > -1
|| cryptogramField.className.indexOf("hosted-fields-focus-state") > -1
) {
// ...Then add classes on the labels to trigger their animations
cardLabel.classList.add("up");
expiryLabel.classList.add("up");
cryptogramLabel.classList.add("up");
}
}, 100);
} -
Manage the CSS animations:
cssCopy
label.up {
padding: 0;
bottom: 42px;
height: 20px;
fonts-size: 75%;
}
Animation of an input field with incorrect data
Just manage the .hosted-fields-invalid-state
CSS class:
.hosted-fields-invalid-state {
border: 2px solid red;
animation-name: wriggle;
animation-duration: 75ms;
animation-iteration-count: 2;
animation-direction: normal;
animation-timing-function: linear;
}
And create a shaking animation:
@keyframes wriggle {
from { transform: translateY(-3px); }
to { transform: translateY(0); }
}
Practical example
Warning
This is a "sandbox environment" payment form: no actual bank movements will occur.
However, I cannot guarantee the confidentiality of the banking data entered on a Codepen interface, so DO NOT use real bank card data, please use instead one of these test cards:
- VISA: 4111 1111 1111 1111
- MasterCard: 5111 1111 1111 1118
With any expiry date, and any 3 digits cryptogram.