Skip to content

Instantly share code, notes, and snippets.

@tkhyn
Forked from jdanyow/app.html
Last active July 23, 2017 03:34
Show Gist options
  • Save tkhyn/624564b49a1e3aa4bb0fd3a82f262240 to your computer and use it in GitHub Desktop.
Save tkhyn/624564b49a1e3aa4bb0fd3a82f262240 to your computer and use it in GitHub Desktop.
Aurelia + Recaptcha
<template>
<require from="./recaptcha"></require>
<form submit.delegate="submit()" ref="form">
<button recaptcha.bind="recaptcha">Submit</button>
</form>
</template>
export class App {
recaptcha;
submit() {
if (this.recaptcha) {
alert('form submitted');
} else {
alert('invalid captcha');
}
}
click() {
this.form.dispatchEvent(new CustomEvent('submit', {bubbles: true}));
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
import {inject} from 'aurelia-dependency-injection';
import {customAttribute} from 'aurelia-templating';
import {bindingMode} from 'aurelia-binding';
import {TaskQueue} from 'aurelia-task-queue';
const SITE_KEY = "6Le1wRoUAAAAAOoT3p5Yp2GO7NCwnB65ejhtgAJa";
// The name of the global function the recaptcha API will call when
// it's ready.
const recaptchaCallbackName = 'setRecaptchaReady';
// An "API ready" promise that will be resolved when the reCAPTCHA API
// is ready.
const ready = new Promise(
resolve => window[recaptchaCallbackName] = resolve
);
// Inject an async script element to load the reCAPTCHA API.
// Notice the callback name is passed as an argument on the query string
// as well as the "render" option which tells the API we don't want the
// reCAPTCHAs automatically rendered, we will render them explicitly.
let script = document.createElement('script');
script.src = `https://www.google.com/recaptcha/api.js?onload=${recaptchaCallbackName}&render=explicit`;
script.async = true;
script.defer = true;
document.head.appendChild(script);
// we need to explicitly set 2-way here, as the default is oneWay
@customAttribute('recaptcha', bindingMode.twoWay)
@inject(Element, TaskQueue)
export class RecaptchaCustomAttribute {
form;
constructor(element, taskQueue) {
this.element = element;
this.taskQueue = taskQueue;
}
bind(bindingContext, overrideContext) {
this.form = bindingContext.form;
}
attached() {
ready.then(() => grecaptcha.render(this.element, {
sitekey: SITE_KEY,
theme: 'dark',
callback: (response) => this.callback(response)
}))
}
callback(response) {
this.value = response;
// this updates the binding's value, as the submit callback is
// likely to rely on the captcha response
this.taskQueue.flushMicroTaskQueue();
this.form.dispatchEvent(new CustomEvent('submit', {bubbles: true}));
grecaptcha.reset();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment