Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with new Google reCAPTCHA in IE when inside modal or dialog

reCAPTCHA works perfectly well in Chrome.

However, (only when reCAPTCHA iframe is inside a dialog box or a modal) in IE the placeholder won't go away.

Whatever the user writes is considered part of the placeholder (I think) and the "verify" button won't be enabled to be clicked.

The picture explains this:

The same code works perfectly well in all browsers when I take the recaptcha div outside the modal

<html lang="en">
<head>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
    <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
    <script type="text/javascript">
    var onloadCallback = function() {
        grecaptcha.render('html_element', {
          'sitekey' : '6Lc7PAATAAAAAE7JwcA7tNEDIrczjCCUvi3GiK4L'
      });
    };
    </script>
</head>
<body>
    <div class="container">
        <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
          Launch modal
      </button>
      <!-- Modal -->
      <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
          <div class="modal-dialog">
            <div class="modal-content">
                <form action="?" method="POST">
                  <div id="html_element"></div>
                  <br>
                  <input type="submit" value="Submit">
              </form>
          </div>
      </div>
  </div>
</div>
</body>
</html>
like image 258
Mutaz Ghuni Avatar asked Jan 11 '15 11:01

Mutaz Ghuni


1 Answers

The problem is generated by the the modal component of Bootstrap.

When the modal is about to appear this function is called:

Modal.prototype.enforceFocus = function () {
    $(document)
    .off('focusin.bs.modal') // guard against infinite focus loop
    .on('focusin.bs.modal', $.proxy(function (e) {
        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
            this.$element.trigger('focus')
        }
    }, this))
}

The function adds a "focusin" event to the document to be sure that the focus is still inside the modal; if the focus goes to another element outside the modal then the latter immediately obtain it back.
Therefore, when you click inside the recaptcha form the focus' conflict causes the Internet Explorer bug.

Anyway, one possible solution is to override that method and disable the focus-back behaviour when a recaptcha component obtain the focus, but this is quite difficult to do because there is no control over the recaptcha html (how can you know if e.target is an element of recaptcha?).

My solution is to completely disable this behavior, to do this just override the enforceFocus function with an empty function:

$.fn.modal.Constructor.prototype.enforceFocus = function () { };

A more elegant solution would be apreciated. :)

like image 139
Digibusiness Avatar answered Nov 08 '22 15:11

Digibusiness