Skip to content

DT-15112: Secure Fields Sample: Jump to next field #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion floating-label.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
<nav style="text-align: center; background: #213d62; padding: 10px; margin-bottom: 40px;">
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="index.html">Basic Example</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="inline-example.html">Inline Example</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="floating-label.html">Floating Label Example</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="inline-example-autotab.html">Inline Example with autojump to next field</a>
<a style="color: #06bd6e; margin: 0 10px; text-decoration: none;" href="floating-label.html">Floating Label Example</a>
</nav>
<form style="max-width: 400px; margin: 0 auto;">
<div style="max-width: 400px">
Expand Down
3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
</head>
<body style="margin: 0;">
<nav style="text-align: center; background: #213d62; padding: 10px; margin-bottom: 40px;">
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="index.html">Basic Example</a>
<a style="color: #06bd6e; margin: 0 10px; text-decoration: none;" href="index.html">Basic Example</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="inline-example.html">Inline Example</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="inline-example-autotab.html">Inline Example with autojump to next field</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="floating-label.html">Floating Label Example</a>
</nav>
<form style="max-width: 400px; margin: 0 auto;">
Expand Down
218 changes: 218 additions & 0 deletions inline-example-autotab.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>PCI Proxy Web Tokenization</title>
<script src="https://pay.sandbox.datatrans.com/upp/payment/js/secure-fields-2.0.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="assets/css/stylesheet.css">
<link rel="stylesheet" type="text/css" href="assets/css/inline.css">
</head>
<body style="margin: 0;">
<nav style="text-align: center; background: #213d62; padding: 10px; margin-bottom: 40px;">
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="index.html">Basic Example</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="inline-example.html">Inline Example</a>
<a style="color: #06bd6e; margin: 0 10px; text-decoration: none;" href="inline-example-autotab.html">Inline Example with autojump to next field</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="floating-label.html">Floating Label Example</a>
</nav>
<form style="max-width: 390px; margin: 0 auto;">
<div id="payment-container" class="inline-wrapper">
<!-- Card Number markup -->
<div id="card-number-container" class="secure-field secure-field__input secure-field__base secure-field__has-actions secure-field__has-actions-left secure-field__has-card-icon">
<div class="secure-field--input-container" style="height: 40px">
<div class="secure-field--actions">
<span class="secure-field--action secure-field--action__card-icon">
<span class="secure-field--action-card-wrap">
<img class="secure-field--card-icon secure-field--card-icon__empty" src="assets/img/card-empty.svg">
<img class="secure-field--card-icon secure-field--card-icon__error" src="assets/img/card-error.svg">
<img class="secure-field--card-icon secure-field--card-icon__recognized-card" src="assets/img/card-recognized.svg">
<img class="secure-field--card-icon secure-field--cvv-icon secure-field--card-icon__empty" src="assets/img/cvc-empty.svg">
</span>
</span>
</div>
<div class="secure-field--input" id="card-number"></div>
</div>
</div>
<div>
<input id="expiry" name="expiry" placeholder="MM/YY" type="tel" maxlength="7" />
</div>
<!-- CVV markup -->
<div id="cvv-container" class="secure-field secure-field__input secure-field__base">
<div class="secure-field--input-container" style="height: 40px">
<div class="secure-field--input" id="cvv-number"></div>
</div>
</div>
</div>
<div style="max-width: 200px; margin-top: 20px">
<button type="button" id="form-submit">
Submit
</button>
<pre id="form-result" style="margin-top: 20px; font-size: 1rem"></pre>
</div>
</form>
<script>
// Expiry date
function setInputFilter(textbox, inputFilter) {
['input', 'keydown', 'keyup', 'mousedown', 'mouseup', 'select', 'contextmenu', 'drop'].forEach(function (type) {
textbox.addEventListener(type, function (e) {
if (/^\d+$/.test(e.key)) {
this.value = formatExpriy(this.value);
}

if (inputFilter(this.value)) {
this.oldValue = this.value;
this.oldSelectionStart = this.selectionStart;
this.oldSelectionEnd = this.selectionEnd;
} else if (this.hasOwnProperty('oldValue')) {
this.value = this.oldValue;
this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
} else {
this.value = '';
}

if (this.oldSelectionEnd === 7 && type === 'keyup' && e.key.match(/^[0-9]$/)) {
secureFields.focus('cvv');
}
});
});
}

setInputFilter(document.getElementById("expiry"), function(value) { return /^\d{0,2}[\/]?\d{0,2}/.test(value); });

function formatExpriy (val) {
var p1 = parseInt(val[0], 10),
p2 = parseInt(val[1], 10);

return /^\d$/.test(val) && "0" !== val && "1" !== val
? "0" + val + " / "
: /^\d\d$/.test(val)
? p2 > 2 && 0 !== p1 ? "0" + p1 + " / " + p2 : "" + val + " / "
: val
}
</script>
<script>
// Credit Card and CVV
var secureFields = new SecureFields();

secureFields.initTokenize(
'1100007006',
{
cardNumber: {
placeholderElementId: 'card-number',
inputType: 'tel'
},
cvv: {
placeholderElementId: 'cvv-number',
inputType: 'tel'
}
},
{
// options...
}
);

secureFields.on('ready', function () {
// Set styles manually as they're inside an iframe and out of the scope of the parent's stylesheets
secureFields.setStyle('cardNumber', 'font: 16px/18px system-ui, sans-serif; border-radius: 0; border:0; -webkit-appearance: none; padding: 0');
secureFields.setStyle('cvv','font: 16px/18px system-ui, sans-serif; border-radius: 0; border:0; -webkit-appearance: none; padding: 0');
secureFields.focus('cardNumber');
secureFields.setPlaceholder("cardNumber", "4242 4242 4242 4242");
secureFields.setPlaceholder("cvv", "123");
});

var cardContainer = document.getElementById('card-number-container');
var cvvContainer = document.getElementById('cvv-container');
var paymentContainer = document.getElementById('payment-container');

// Set focus to input fields when clicking containers
cardContainer.addEventListener('click', function () {
secureFields.focus('cardNumber');
});
cvvContainer.addEventListener('click', function () {
secureFields.focus('cvv');
});

// Set class names when fields change
secureFields.on('change', function (data) {
console.log(data.event.type)
var cardImage = cardContainer.querySelector('.secure-field--card-icon__recognized-card');
paymentContainer.classList.remove('secure-field__has-focus-cvv');
paymentContainer.classList.remove('secure-field__has-focus-cardNumber');
paymentContainer.classList.remove('field__has-error');
cardContainer.classList.remove('secure-field__has-error');
cvvContainer.classList.remove('secure-field__has-error');

paymentContainer.classList.add(`secure-field__has-focus-${data.event.field}`);

if (!data.fields.cardNumber.paymentMethod) {
cardImage.src = 'assets/img/card-empty.svg';
cardContainer.classList.remove('secure-field__is-recognized');
} else {
cardImage.src = 'assets/img/brands/' + data.fields.cardNumber.paymentMethod + '.svg';
cardContainer.classList.add('secure-field__is-recognized');
}

if (data.event.type === 'keyUp' && data.event.field === 'cardNumber' && data.event.eventData.isNumber && data.fields.cardNumber.valid) {
document.getElementById('expiry').focus();
}
})

// Set class names on validate
secureFields.on('validate', function (data) {
paymentContainer.classList.remove('field__has-error');

if (data.fields.cardNumber.valid) {
cardContainer.classList.remove('secure-field__has-error');
} else {
cardContainer.classList.remove('secure-field__is-recognized');
cardContainer.classList.add('secure-field__has-error');
paymentContainer.classList.add('field__has-error');
}

if (data.fields.cvv.valid) {
cvvContainer.classList.remove('secure-field__has-error');
} else {
cvvContainer.classList.add('secure-field__has-error');
paymentContainer.classList.add('field__has-error');
}
});

document.getElementById('form-submit').addEventListener('click', function () {
// validate your expiry field here
if (document.getElementById('expiry').value !== '') {
secureFields.submit();
} else {
paymentContainer.classList.add('field__has-error');
}
});

secureFields.on('success', function (data) {
if (data.transactionId) {
var result = document.getElementById('form-result');
result.innerText = 'Data submitted successfully (transactionId: ' + data.transactionId + ')';
result.style.display = 'block';
}
});
</script>
<style>
/* The following styles are NOT required */
html, body {
font-family: Arial, Helvetica, sans-serif;
}

label {
font-weight: bold;
font-size: 0.9rem;
line-height: 1.5rem;
}

button {
border: none;
background-color: #06bd6e;
color: white;
padding: 7px 12px;
font-size: 1rem;
cursor: pointer;
}
</style>
</body>
3 changes: 2 additions & 1 deletion inline-example.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
<body style="margin: 0;">
<nav style="text-align: center; background: #213d62; padding: 10px; margin-bottom: 40px;">
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="index.html">Basic Example</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="inline-example.html">Inline Example</a>
<a style="color: #06bd6e; margin: 0 10px; text-decoration: none;" href="inline-example.html">Inline Example</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="inline-example-autotab.html">Inline Example with autojump to next field</a>
<a style="color: #fff; margin: 0 10px; text-decoration: none;" href="floating-label.html">Floating Label Example</a>
</nav>
<form style="max-width: 390px; margin: 0 auto;">
Expand Down
8 changes: 2 additions & 6 deletions react-example/.gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
node_modules
example/lib
example/src/SecureField.css
example/src/SecureField.js
example/src/SecureFieldIcon.js
example/src/SecureFields.js
example/package-lock.json
dist
.cache
3 changes: 2 additions & 1 deletion react-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ Install all dependencies

### `npm start`
A working bundle will be created
Open the new lib/app.html in your browser
Server running at http://localhost:1234

9 changes: 0 additions & 9 deletions react-example/example/.babelrc

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
/>
<meta name="theme-color" content="#000000" />
<title>PCI Proxy Web Tokenization</title>
<script src="main.js" type="text/javascript" charset="utf-8" async defer></script>
<script src="./index.js" type="text/javascript" charset="utf-8" async defer></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="app"></div>
<style>
/* The following styles are NOT required */
html, body {
Expand Down
29 changes: 29 additions & 0 deletions react-example/example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react'
import ReactDOM from 'react-dom'

import SecureFields from '../src'

const App = <>
<h1 style={{ fontFamily: '"Volte-Medium", "Helvetica Neue", Helvetica, Arial', color: '#213d62' }}>Datatrans SecureFields</h1>
<h2 style={{ fontFamily: '"Volte-Medium", "Helvetica Neue", Helvetica, Arial', color: '#213d62' }}>with React</h2>

<SecureFields config={{
merchantID: '1100007006',
fields:{
cardNumber: {
placeholderElementId: 'card-number',
inputType: 'tel'
},
cvv: {
placeholderElementId: 'cvv-number',
inputType: 'tel'
}
},
options: {}
}} />
</>

ReactDOM.render(
App,
document.getElementById('app')
);
20 changes: 0 additions & 20 deletions react-example/example/src/index.js

This file was deleted.

31 changes: 0 additions & 31 deletions react-example/example/webpack.config.js

This file was deleted.

Loading