M

ALX DESIGN

HOME / UX /

Dalenys' hosted-fields method tricks

Some tips to make the most of hosted-fields integration: How to custom your form according to the card type ? How faking the

Faking a <label> "for" attribute

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:

  1. Add a onclick event on the labels
    <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.

  2. Add this little piece of JavaScript
    function focusIframe(id)
    {
        var iframe = document.getElementById(id);
        iframe.contentWindow.focus();
        return true;
    }

Custom your form according to the card type

  1. Create a function to apply a class depending of the card type
    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
  2. Call this fonction for the input event of the card input field
    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']);
    				}
    			}
    		},
  3. Manage your classes in your CSS
    #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.

  1. To get started, you have to display floating labels over the input fields:
    <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>
    form 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 */
    	font-style: italic;
    	color: #bbb;
    	
    	/* Simulates an on hover input text cursor */
    	cursor: text; 
    	
    	/* Smooth transition effect */
    	transition: all 250ms ease-in-out;
    }
  2. 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:

    // 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();
    };
  3. 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:

    function 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);
    }
  4. Manage the CSS animations:
    label.up {
    	padding: 0;
    	bottom: 42px;
    	height: 20px;
    	font-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.

BACK TO HOME

Leave a comment ?