Magento – How to add recaptcha v2 for multiple forms on single page

contact-usmagento2.2.6newsletterrecaptcha

I am trying to configure re captcha for contact us form and newsletter form.

Both these form are on one page.

Now I have to configure common recaptcha for these two form and when on submit captcha should work for both forms.

I have tried to configure programmatically for both form but it is not working me. According to me captcha gives conflicts on form submission

I have following code for news letter form:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>
     <script>
       function onSubmit(token) {
         document.getElementById("newsletter-validate-detail").submit();
       }
    </script>

and

<button class="g-recaptcha action subscribe primary" data-sitekey="SITE_KEY" data-callback='onSubmit' title="<?php /* @escapeNotVerified */ echo __('Subscribe') ?>" type="submit">
   <span><?php /* @escapeNotVerified */ echo __('Subscribe') ?></span>
</button>

for the contact-us form:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>
         <script>
           function onSubmit(token) {
             document.getElementById("contact-form").submit();
           }
        </script>

and

<button class="g-recaptcha action submit" data-sitekey="SITE_KEY" data-callback='onSubmit' title="<?php /* @escapeNotVerified */ echo __('Subscribe') ?>" type="submit">
   <span><?php /* @escapeNotVerified */ echo __('Submit') ?></span>
</button>

is it possible to add recaptcha for multiple forms on same page programmatically?

Best Answer

You could use this extension https://github.com/magento/magespecialist_ReCaptcha

And my pull request to have multiple ReCaptcha on a page

Some customization to get it work on newsletter on footer. Basically you'd need to add configuration and render it to footer where you newsletter form was.

system.xml

<field id="enabled_newsletter" translate="label" type="select" sortOrder="250" showInDefault="1"
       showInWebsite="1" showInStore="0" canRestore="1">
    <label>Use in Newsletter Form</label>
    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
    <depends>
        <field id="enabled">1</field>
    </depends>
</field>

The model Config.php

    const XML_PATH_ENABLED_FRONTEND_NEWSLETTER = 'msp_securitysuite_recaptcha/frontend/enabled_newsletter';

And a function

/**
 * Return true if enabled on frontend newsletter form
 * @return bool
 */
public function isEnabledFrontendNewsletter()
{
    if (!$this->isEnabledFrontend()) {
        return false;
    }

    return (bool) $this->scopeConfig->getValue(static::XML_PATH_ENABLED_FRONTEND_NEWSLETTER);
}

The helper Data.php

public function isEnabledFrontendNewsletter() {
    return $this->config->isEnabledFrontendNewsletter();
}

The model LayoutSettings.php

/**
 * Return captcha config for frontend
 * @return array
 */
public function getCaptchaSettings()
{
    return [
        'siteKey' => $this->config->getPublicKey(),
        'size' => $this->config->getFrontendSize(),
        'badge' => $this->config->getFrontendPosition(),
        'theme' => $this->config->getFrontendTheme(),
        'lang' => $this->config->getLanguageCode(),
        'enabled' => [
            'login' => $this->config->isEnabledFrontendLogin(),
            'create' => $this->config->isEnabledFrontendCreate(),
            'forgot' => $this->config->isEnabledFrontendForgot(),
            'contact' => $this->config->isEnabledFrontendContact(),
            'newsletter' => $this->config->isEnabledFrontendNewsletter()
        ]
    ];
}

Create a new template footer/captcha.phtml

<?php
/** @var $block MSP\ReCaptcha\Block\Frontend\ReCaptcha */
?>
<?php if($block->isEnabledFrontend()) :?>
    <div class="field-recaptcha" id="msp-recaptcha-container" data-bind="scope:'msp-recaptcha-newsletter'">
        <!-- ko template: getTemplate() --><!-- /ko -->
    </div>

    <script type="text/x-magento-init">
    {
        "#msp-recaptcha-container": {
            "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getNewsletterFooterJsLayout();?>
        }
    }
    </script>
<?php endif;?>

Assume you have your footer newsletter form, call the block of recaptcha under your form

<form class="form subscribe"
      novalidate
      action="<?php echo $block->getFormActionUrl() ?>"
      method="post"
      id="newsletter-validate-detail-footer" data-role="newsletter-detail-footer">
    <div class="newsletter-wrapper">
        <div class="field newsletter">
            <label class="label" for="newsletter"><span><?php echo __('Sign Up for Our Newsletter:') ?></span></label>
            <div class="control">
                <input name="email" type="email" id="newsletter"
                       placeholder="<?php echo __('Your email') ?>"
                       data-validate="{required:true, 'validate-email':true}"
                       onfocus="this.placeholder = ''"
                       onblur="this.placeholder = '<?php echo __('Your email') ?>'" />
                <div class="checknews">
                    <i class="ctrue fa fa-check" aria-hidden="true" style="display:none"></i>
                    <i class="cfalse fa fa-times" aria-hidden="true" style="display:none"></i>
                </div>
            </div>
        </div>
        <div class="actions">
            <button class="action subscribe primary" title="<?php echo __('Ok') ?>" type="submit">
                <span><?php echo __('Ok') ?></span>
            </button>
        </div>
    </div>

    <?php if ($this->helper('MSP\ReCaptcha\Helper\Data')->isEnabledFrontendNewsletter()): ?>
        <?php echo $block->getLayout()->createBlock('MSP\ReCaptcha\Block\Frontend\ReCaptcha')
            ->setTemplate('MSP_ReCaptcha::footer/captcha.phtml')->toHtml(); ?>
    <?php endif; ?>

</form>

From Block/Frontend/Recaptcha.php add new function

public function getNewsletterFooterJsLayout(){
    $layout = $this->decoder->decode(parent::getJsLayout());
    $layout['components']['msp-recaptcha-newsletter']['settings'] = $this->layoutSettings->getCaptchaSettings();
    $layout['components']['msp-recaptcha-newsletter']['component'] = 'MSP_ReCaptcha/js/reCaptcha';
    $layout['components']['msp-recaptcha-newsletter']['zone'] = 'newsletter';
    $layout['components']['msp-recaptcha-newsletter']['reCaptchaId'] = 'msp-recaptcha-newsletter-footer';

    return $this->encoder->encode($layout);
}
Related Topic