<!DOCTYPE html>
<html>
<head>
<base href="." />
<title>Angular playground</title>
<link rel="stylesheet" href="style.css" />
<script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js/dist/zone.js"></script>
<script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
<script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
<script src="config.js"></script>
<script>
console.clear();
System.import('app')
.catch(console.error.bind(console));
</script>
</head>
<body>
<my-app>loading...</my-app>
</body>
</html>
/* Styles go here */
### Angular Starter Plunker - Typescript
System.config({
transpiler: 'typescript',
typescriptOptions: {
emitDecoratorMetadata: true
},
paths: {
'npm:': 'https://unpkg.com/'
},
map: {
'app': './src',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
'@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
'@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
'@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
'@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
'@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
'@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
'rxjs': 'npm:rxjs',
'typescript': 'npm:typescript@2.0.2/lib/typescript.js',
'ng-recaptcha': 'npm:ng-recaptcha@latest',
},
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
'ng-recaptcha': {
main: './index.js',
},
rxjs: {
defaultExtension: 'js'
}
}
});
//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';
platformBrowserDynamic().bootstrapModule(AppModule)
//our root app component
import {Component, NgModule, Injectable, Inject, ViewChild, NgZone} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {FormsModule, FormGroup, FormControl, ReactiveFormsModule, Validators} from '@angular/forms';
import {Observable} from 'rxjs/Observable';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {RecaptchaModule, RECAPTCHA_SETTINGS, RecaptchaLoaderService} from 'ng-recaptcha';
import {RecaptchaFormsModule} from 'ng-recaptcha/forms';
import {RecaptchaReloadWrapper, RecaptchaDynamicLanguageLoaderService} from './dynamic-language-loader.service';
export declare var grecaptcha: any;
@Component({
selector: 'my-app',
template: `
<div>
<h2><a href="https://github.com/DethAriel/ng-recaptcha"><code>ng-recaptcha</code></a> demo plunk</h2>
<h3>Dynamic language</h3>
<p>
Select a language:
<select [(ngModel)]="lang" name="language">
<option value="">Auto</option>
<option value="fr">French</option>
<option value="ru">Russian</option>
<option value="en">English</option>
</select>
</p>
<h3>Normal mode</h3>
<div *ngIf="loaderReady">
<re-captcha></re-captcha>
</div>
<h3>Invisible CAPTCHA</h3>
<div *ngIf="loaderReady">
<re-captcha
size="invisible"
#invisible
(resolved)="response = $event"
></re-captcha>
</div>
<button (click)="invisible.execute()">Execute</button>
<button (click)="invisible.reset()">Reset</button>
<h4>Invisible captcha response</h4>
<pre>{{ response || '[empty]' }}</pre>
<h3>Declarative Forms</h3>
<form #declarativeForm="ngForm">
<div *ngIf="loaderReady">
<re-captcha
[(ngModel)]="declarativeFormCaptchaValue"
name="captcha"
required
></re-captcha>
</div>
<button [disabled]="!declarativeForm.valid">Submit</button>
</form>
<h3>Reactive Forms</h3>
<form [formGroup]="reactiveForm">
<div *ngIf="loaderReady">
<re-captcha
formControlName="recaptchaReactive"
></re-captcha>
</div>
<button [disabled]="reactiveForm.invalid">Submit</button>
</form>
</div>
`,
})
export class App {
public declarativeFormCaptchaValue: string;
public reactiveForm;
public loaderReady = false;
constructor(
@Inject(RecaptchaLoaderService)private loader: RecaptchaDynamicLanguageLoaderService,
private zone: NgZone,
) {
this._lang = this.loader.language;
}
public ngOnInit() {
this.loader.ready.subscribe(v => {
setTimeout(() => this.zone.run(() => this.loaderReady = !!v), 0);
});
this.reactiveForm = new FormGroup({
recaptchaReactive: new FormControl(null, Validators.required)
});
}
public get lang() {
return this._lang;
}
public set lang(value: string) {
this._lang = value;
this.loader.updateLanguage(value);
}
}
@NgModule({
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
RecaptchaModule.forRoot(),
RecaptchaFormsModule,
],
declarations: [ App ],
bootstrap: [ App ],
providers: [
{
provide: RECAPTCHA_SETTINGS,
useValue: {
siteKey: '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI',
} as RecaptchaSettings,
},
{
provide: RecaptchaLoaderService,
useClass: RecaptchaDynamicLanguageLoaderService,
},
],
})
export class AppModule {}
//our root app component
import {Component, NgModule, Injectable, Inject, NgZone} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {Observable} from 'rxjs/Observable';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {RecaptchaModule, RecaptchaLoaderService} from 'ng-recaptcha';
@Injectable()
export class RecaptchaDynamicLanguageLoaderService {
public ready: Observable<any>;
public language = '';
private static ready: BehaviorSubject<any>;
constructor() {
this.init();
this.ready = RecaptchaDynamicLanguageLoaderService.ready.asObservable();
}
public updateLanguage(newLang: string): void {
this.language = newLang;
RecaptchaDynamicLanguageLoaderService.ready.next(null);
this.init();
}
private init() {
if (RecaptchaDynamicLanguageLoaderService.ready) {
if (RecaptchaDynamicLanguageLoaderService.ready.getValue()) {
return;
}
} else {
RecaptchaDynamicLanguageLoaderService.ready = new BehaviorSubject<any>(null);
window.ng2recaptchaloaded = () => {
RecaptchaDynamicLanguageLoaderService.ready.next(grecaptcha);
};
}
const script = document.createElement('script') as HTMLScriptElement;
script.innerHTML = '';
const langParam = this.language ? '&hl=' + this.language : '';
script.src = `https://www.google.com/recaptcha/api.js?render=explicit&onload=ng2recaptchaloaded${langParam}`;
script.async = true;
script.defer = true;
document.head.appendChild(script);
}
}