xiaohutai / bolt-isuseful

[Bolt Extension] Add a simple "Is this page useful?" to pages
https://market.bolt.cm/view/twokings/is-useful
1 stars 1 forks source link

Refactor to non-jQuery JavaScript #6

Open xiaohutai opened 6 years ago

xiaohutai commented 6 years ago

In BoltForms v4.2.1, some changes have been made with AJAX submissions. No more JQuery it seems.

AJAX

This solution works for AJAX + non-ReCaptcha forms [but doesn't work nice when errors are present, so that's why keep the forms simple as possible):

var forms = document.querySelectorAll(".is-useful-wrapper > .expand > .boltform > form");
Array.prototype.forEach.call(forms, function(el) {
    el.addEventListener("submit", function(event) {
        var wrapper = el
            .parentElement // .boltform
            .parentElement // .expand
            .parentElement // .is-useful-wrapper
        ;
        wrapper.innerHTML = "<span class='is-useful-success'>" + wrapper.getAttribute("data-thanks") + "</span>";
    });
});
xiaohutai commented 6 years ago

AJAX + ReCaptcha

function invisibleRecaptchaOnLoad() {
  function createHiddenElement(name, value) {
    var input = document.createElement("input");
    input.setAttribute("type", "hidden");
    input.setAttribute("name", name);
    input.setAttribute("value", value);
    return input;
  }

  var els = document.getElementsByClassName('g-recaptcha-button');
  for (var i = 0; i < els.length; ++i) {
    var buttonElement = els[i];
    grecaptcha.render(buttonElement, {
      sitekey: buttonElement.getAttribute('data-sitekey'),
      size: 'invisible',
      callback: function (token) {
        if (token) {
          var form = buttonElement.closest('form');
          form.appendChild(createHiddenElement('g-recaptcha-response', token));

          var XHR = new XMLHttpRequest();
          var data = new FormData(form);
          XHR.addEventListener("load", function () {
            var wrapper = form
              .parentElement // .boltform
              .parentElement // .expand
              .parentElement // .is-useful-wrapper
            ;
            wrapper.innerHTML = "<span class='is-useful-success'>" + wrapper.getAttribute("data-thanks") + "</span>";
          });
          XHR.addEventListener("error", function () {
            boltFormError(form, this);
          });
          XHR.open("POST", form.action);
          XHR.send(data);
        }
      }
    });
  }
}

and invisibleRecaptchaOnLoad must be in the global scope.

xiaohutai commented 6 years ago

AJAX + ReCaptcha + other non-AJAX forms

function invisibleRecaptchaOnLoad() {
  function createHiddenElement(name, value) {
    var input = document.createElement("input");
    input.setAttribute("type", "hidden");
    input.setAttribute("name", name);
    input.setAttribute("value", value);
    return input;
  }

  var els = document.getElementsByClassName('g-recaptcha-button');
  for (var i = 0; i < els.length; ++i) {
    var buttonElement = els[i];
    grecaptcha.render(buttonElement, {
      sitekey: buttonElement.getAttribute('data-sitekey'),
      size: 'invisible',
      callback: function (token) {
        if (token) {
          var form = buttonElement.closest('form');
          form.appendChild(createHiddenElement('g-recaptcha-response', token));

          if (form.action.indexOf('async') !== -1 ) {
              // -- ajax forms
              var XHR = new XMLHttpRequest();
              var data = new FormData(form);
              XHR.addEventListener("load", function () {
                var wrapper = form
                  .parentElement // .boltform
                  .parentElement // .expand
                  .parentElement // .is-useful-wrapper
                ;
                wrapper.innerHTML = "<span class='is-useful-success'>" + wrapper.getAttribute("data-thanks") + "</span>";
              });
              XHR.addEventListener("error", function () {
                boltFormError(form, this);
              });
              XHR.open("POST", form.action);
              XHR.send(data);
          } else {
            // -- normal forms
            form.submit();
          }
        }
      }
    });
  }
}