-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #124 from recurly/co-badge
Add Dual/Co-Badged example
- Loading branch information
Showing
2 changed files
with
172 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<title>Recurly.js Example: Co-Badged Support</title> | ||
<script src="https://js.recurly.com/v4/recurly.js"></script> | ||
<script src="/config"></script> | ||
<link href="https://js.recurly.com/v4/recurly.css" rel="stylesheet" /> | ||
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" /> | ||
<link href="/style.css" rel="stylesheet" /> | ||
</head> | ||
<body> | ||
<main> | ||
<section> | ||
<h1 class="logo"> | ||
<span class="price">$10</span> | ||
<span class="term">monthly</span> | ||
</h1> | ||
</section> | ||
|
||
<section id="errors" class="errors"></section> | ||
|
||
<section> | ||
<form method="post" action="/api/subscriptions/new"> | ||
|
||
<div> | ||
<label for="first_name">First Name</label> | ||
<input type="text" data-recurly="first_name" id="first_name" name="first-name"> | ||
</div> | ||
|
||
<div> | ||
<label for="last_name">Last Name</label> | ||
<input type="text" data-recurly="last_name" id="last_name" name="last-name"> | ||
</div> | ||
|
||
<div id="card-element-container"> | ||
<div data-my-js-ref="recurly-element-card"></div> | ||
</div> | ||
|
||
<button id="subscribe">Subscribe</button> | ||
|
||
<input type="hidden" data-recurly="token" name="recurly-token"> | ||
</form> | ||
</section> | ||
</main> | ||
|
||
<script> | ||
recurly.configure(window.recurlyConfig.publicKey); | ||
// Create a CardElement | ||
const elements = recurly.Elements(); | ||
const cardElement = elements.CardElement({ | ||
style: { | ||
fontFamily: 'Open Sans', | ||
fontSize: '1rem', | ||
fontWeight: 'bold', | ||
fontColor: '#2c0730' | ||
} | ||
}); | ||
cardElement.attach('[data-my-js-ref="recurly-element-card"]'); | ||
// Listen for changes to the coBadge card details | ||
cardElement.on('coBadge', handleCoBadge) | ||
|
||
function handleCoBadge(coBadgeResults) { | ||
// coBadgeResults is an object with the following properties: | ||
// coBadgeSupport: boolean | ||
// supportedBrands: array of strings (e.g. ['visa', 'cartes_bancaires']) | ||
let coBadgeBrands = coBadgeResults.supportedBrands; | ||
let targetEle = document.querySelector('#card-element-container'); | ||
let coBadgeContainer = document.querySelector('#co-badge-container'); | ||
|
||
if (!coBadgeContainer) { | ||
if (!coBadgeResults.coBadgeSupport) { return; } | ||
// create the coBadge div if it does not exist and the card has coBadge support | ||
createCoBadge(coBadgeBrands, targetEle); | ||
} else { | ||
// remove the coBadge div if the card does not have coBadge support | ||
if (!coBadgeResults.coBadgeSupport) { coBadgeContainer.remove(); return; } | ||
// update the coBadge div if the card has coBadge support | ||
updateCardBrandOptions(coBadgeBrands); | ||
} | ||
} | ||
|
||
function createCoBadge(coBadgeBrands, target) { | ||
// create an input for selecting the customer's card brand that is populated with the card's coBadge options | ||
const coBadgeContainer = document.createElement('div'); | ||
coBadgeContainer.id = 'co-badge-container'; | ||
const coBadgeRadio = document.createElement('div'); | ||
coBadgeRadio.id = 'co-badge-radio'; | ||
coBadgeBrands.forEach((brand, idx) => { | ||
let brandInput = document.createElement('input'); | ||
brandInput.type = 'radio'; | ||
brandInput.value = brand; | ||
brandInput.className = 'co-badge-input'; | ||
brandInput.id = `co-badge-input-${idx}`; | ||
brandInput.name = 'co-badge'; | ||
brandInput.setAttribute('data-recurly', 'card_network_preference'); | ||
|
||
let brandLabel = document.createElement('label'); | ||
brandLabel.textContent = formatBrand(brand); | ||
brandLabel.id = `co-badge-label-${idx}`; | ||
brandLabel.className = 'co-badge-label'; | ||
|
||
coBadgeRadio.appendChild(brandInput); | ||
coBadgeRadio.appendChild(brandLabel); | ||
}); | ||
coBadgeContainer.appendChild(coBadgeRadio); | ||
target.after(coBadgeContainer); | ||
}; | ||
|
||
function updateCardBrandOptions(coBadgeBrands) { | ||
coBadgeBrands.forEach((brand, idx) => { | ||
let brandInput = document.querySelector(`#co-badge-input-${idx}`); | ||
brandInput.value = brand; | ||
|
||
let brandLabel = document.querySelector(`#co-badge-label-${idx}`); | ||
brandLabel.setAttribute('for', brand); | ||
brandLabel.textContent = formatBrand(brand); | ||
}); | ||
}; | ||
|
||
function formatBrand(brand) { | ||
return brand.replace(/_/g, ' '); | ||
}; | ||
|
||
// When a customer hits their 'enter' key while using the card element | ||
cardElement.on('submit', function (event) { | ||
document.querySelector('form').submit(); | ||
}); | ||
|
||
// On form submit, we stop submission to go get the token | ||
document.querySelector('form').addEventListener('submit', function (event) { | ||
console.log('form submit'); | ||
// Prevent the form from submitting while we retrieve the token from Recurly | ||
event.preventDefault(); | ||
|
||
// Reset the errors display | ||
document.querySelector('#errors').textContent = ''; | ||
document.querySelectorAll('input').forEach(input => input.classList.remove('error')); | ||
|
||
// Disable the submit button | ||
document.querySelector('button').disabled = true; | ||
|
||
const form = this; | ||
|
||
// Now we call recurly.token with the form. It goes to Recurly servers | ||
// to tokenize the credit card information, then injects the token into the | ||
// data-recurly="token" field above | ||
recurly.token(elements, form, function (err, token) { | ||
// send any errors to the error function below | ||
if (err) error(err); | ||
|
||
// Otherwise we continue with the form submission | ||
else form.submit(); | ||
|
||
}); | ||
}); | ||
|
||
// A simple error handling function to expose errors to the customer | ||
function error (err) { | ||
document.querySelector('#errors').textContent = 'The following fields appear to be invalid: ' + err.fields.join(', '); | ||
document.querySelector('button').disabled = false; | ||
err.fields.forEach(field => { | ||
document.querySelector(`[data-recurly=${field}]`).classList.add('error'); | ||
}); | ||
} | ||
|
||
// runs some simple animations for the page | ||
document.querySelector('body').classList.add('show'); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters