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

Support multiple reCaptcha on a one page #20

Merged
merged 2 commits into from Nov 8, 2017
Jump to file or symbol
Failed to load files and symbols.
+92 −12
Diff settings

Always

Just for now

@@ -108,6 +108,30 @@ or simply
<?= \himiklab\yii2\recaptcha\ReCaptcha::widget(['name' => 'reCaptcha']) ?>
```
Multiple reCaptcha on a one page
-----
Each the reCaptcha instance must have unique id
```php
<?= $form1->field($modelForm1, 'reCaptcha')
->widget(\himiklab\yii2\recaptcha\ReCaptcha::className(), [
'widgetOptions' => [
'id' => 're-captcha-form1',
]
]) ?>
<?= $form2->field($modelForm2, 'reCaptcha')
->widget(\himiklab\yii2\recaptcha\ReCaptcha::className(), [
'widgetOptions' => [
'id' => 're-captcha-form2',
]
]) ?>
```
If you use one model in a few forms (ex. feedback form) must use unique ids.
Notes
-----
Exclude a reCaptcha field from ajax validation. It creates problem.
Resources
---------
* [Google reCAPTCHA](https://developers.google.com/recaptcha)
View
@@ -10,6 +10,7 @@
use Yii;
use yii\base\InvalidConfigException;
use yii\helpers\Html;
use yii\helpers\Inflector;
use yii\widgets\InputWidget;
/**
@@ -81,6 +82,12 @@ class ReCaptcha extends InputWidget
/** @var array Additional html widget options, such as `class`. */
public $widgetOptions = [];
public function init()
{
$view = $this->view;
$view->registerJs($this->render('onload'), $view::POS_BEGIN);
}
public function run()
{
if (empty($this->siteKey)) {
@@ -93,14 +100,24 @@ public function run()
}
}
$arguments = http_build_query([
'hl' => $this->getLanguageSuffix(),
'render' => 'explicit',
'onload' => 'recaptchaOnloadCallback',
]);
$view = $this->view;
$view->registerJsFile(
self::JS_API_URL . '?hl=' . $this->getLanguageSuffix(),
['position' => $view::POS_HEAD, 'async' => true, 'defer' => true]
self::JS_API_URL . '?' . $arguments,
['position' => $view::POS_END, 'async' => true, 'defer' => true]
);
$this->customFieldPrepare();
echo Html::tag('div', '', $this->buildDivOptions());
}
protected function buildDivOptions()
{
$divOptions = [
'class' => 'g-recaptcha',
'data-sitekey' => $this->siteKey
@@ -124,13 +141,29 @@ public function run()
$divOptions['data-tabindex'] = $this->tabindex;
}
if (isset($this->widgetOptions['class'])) {
$divOptions['class'] = "{$divOptions['class']} {$this->widgetOptions['class']}";
}
// The id attribute required for explicit reCaptcha initialization
$divOptions['id'] = $this->getReCaptchaId();
$divOptions = $divOptions + $this->widgetOptions;
echo Html::tag('div', '', $divOptions);
return $divOptions;
}
protected function getReCaptchaId()
{
if (isset($this->widgetOptions['id'])) {
return $this->widgetOptions['id'];
}
if ($this->hasModel()) {
return $this->model->formName() . '-recaptcha';
} else {
return $this->name . '-recaptcha';
}
}
protected function getLanguageSuffix()
@@ -154,18 +187,21 @@ protected function customFieldPrepare()
$view = $this->view;
if ($this->hasModel()) {
$inputName = Html::getInputName($this->model, $this->attribute);
$inputId = Html::getInputId($this->model, $this->attribute);
} else {
$inputName = $this->name;
$inputId = 'recaptcha-' . $this->name;
}
if (empty($this->jsCallback)) {
$jsCode = "var recaptchaCallback = function(response){jQuery('#{$inputId}').val(response);};";
} else {
$jsCode = "var recaptchaCallback = function(response){jQuery('#{$inputId}').val(response); {$this->jsCallback}(response);};";
}
$this->jsCallback = 'recaptchaCallback';
$inputId = $this->getReCaptchaId() . '-input';
$verifyCallbackName = lcfirst(Inflector::id2camel($inputId)) . 'Callback';
$jsCode = $this->render('verify', [
'verifyCallbackName' => $verifyCallbackName,
'jsCallback' => $this->jsCallback,
'inputId' => $inputId,
]);
$this->jsCallback = $verifyCallbackName;
if (empty($this->jsExpiredCallback)) {
$jsExpCode = "var recaptchaExpiredCallback = function(){jQuery('#{$inputId}').val('');};";
@@ -176,6 +212,7 @@ protected function customFieldPrepare()
$view->registerJs($jsCode, $view::POS_BEGIN);
$view->registerJs($jsExpCode, $view::POS_BEGIN);
echo Html::input('hidden', $inputName, null, ['id' => $inputId]);
}
}
View
@@ -0,0 +1,13 @@
var recaptchaOnloadCallback = function() {
jQuery(".g-recaptcha").each(function(index) {
var reCaptcha = jQuery(this);
grecaptcha.render(reCaptcha.attr("id"), {
'sitekey': reCaptcha.attr("data-sitekey"),
'callback': eval(reCaptcha.attr("data-callback")),
'theme': reCaptcha.attr("data-theme"),
'type': reCaptcha.attr("data-type"),
'size': reCaptcha.attr("data-size"),
'tabindex': reCaptcha.attr("data-tabindex"),
});
});
};
View
@@ -0,0 +1,6 @@
var <?= $verifyCallbackName ?> = function(response) {
jQuery('#<?= $inputId ?>').val(response);
<?php if ($jsCallback) { ?>
<?= $jsCallback ?>(response);
<?php } ?>
};
ProTip! Use n and p to navigate between commits in a pull request.