MDL-69166 pg_paypal: Display PayPal buttons in a modal
authorShamim Rezaie <shamim@moodle.com>
Fri, 10 Jan 2020 18:34:47 +0000 (05:34 +1100)
committerShamim Rezaie <shamim@moodle.com>
Tue, 27 Oct 2020 03:37:28 +0000 (14:37 +1100)
payment/amd/build/gateways_modal.min.js
payment/amd/build/gateways_modal.min.js.map
payment/amd/src/gateways_modal.js
payment/gateway/paypal/amd/build/gateways_modal.min.js
payment/gateway/paypal/amd/build/gateways_modal.min.js.map
payment/gateway/paypal/amd/build/selectors.min.js [deleted file]
payment/gateway/paypal/amd/build/selectors.min.js.map [deleted file]
payment/gateway/paypal/amd/src/gateways_modal.js
payment/gateway/paypal/amd/src/selectors.js [deleted file]

index f69ff04..0c03f71 100644 (file)
Binary files a/payment/amd/build/gateways_modal.min.js and b/payment/amd/build/gateways_modal.min.js differ
index a2b8d63..d457464 100644 (file)
Binary files a/payment/amd/build/gateways_modal.min.js.map and b/payment/amd/build/gateways_modal.min.js.map differ
index 0424017..39251ca 100644 (file)
@@ -97,7 +97,6 @@ const show = (rootNode, {
 
                         if (gateway) {
                             processPayment(
-                                root,
                                 gateway,
                                 rootNode.dataset.amount,
                                 rootNode.dataset.currency,
@@ -122,7 +121,6 @@ const show = (rootNode, {
 /**
  * Process payment using the selected gateway.
  *
- * @param {HTMLElement} rootElement The root element of the main modal
  * @param {string} gateway The gateway to be used for payment
  * @param {number} amount Amount of payment
  * @param {string} currency The currency in the three-character ISO-4217 format
@@ -131,8 +129,8 @@ const show = (rootNode, {
  * @param {string} description Description of the payment
  * @returns {Promise<void>}
  */
-const processPayment = async(rootElement, gateway, amount, currency, component, componentid, description) => {
+const processPayment = async(gateway, amount, currency, component, componentid, description) => {
     const paymentMethod = await import(`pg_${gateway}/gateways_modal`);
 
-    paymentMethod.process(rootElement, amount, currency, component, componentid, description);
+    paymentMethod.process(amount, currency, component, componentid, description);
 };
index 8511ad8..b60eba1 100644 (file)
Binary files a/payment/gateway/paypal/amd/build/gateways_modal.min.js and b/payment/gateway/paypal/amd/build/gateways_modal.min.js differ
index 4cba6e8..3d793bc 100644 (file)
Binary files a/payment/gateway/paypal/amd/build/gateways_modal.min.js.map and b/payment/gateway/paypal/amd/build/gateways_modal.min.js.map differ
diff --git a/payment/gateway/paypal/amd/build/selectors.min.js b/payment/gateway/paypal/amd/build/selectors.min.js
deleted file mode 100644 (file)
index 4779204..0000000
Binary files a/payment/gateway/paypal/amd/build/selectors.min.js and /dev/null differ
diff --git a/payment/gateway/paypal/amd/build/selectors.min.js.map b/payment/gateway/paypal/amd/build/selectors.min.js.map
deleted file mode 100644 (file)
index 41f80eb..0000000
Binary files a/payment/gateway/paypal/amd/build/selectors.min.js.map and /dev/null differ
index 4878736..a86daf8 100644 (file)
 
 import * as Repository from './repository';
 import Templates from 'core/templates';
-import Selectors from './selectors';
 import Truncate from 'core/truncate';
 import Ajax from 'core/ajax';
 import Notification from 'core/notification';
+import ModalFactory from 'core/modal_factory';
 
 /**
- * Renders a placeholder in the modal.
+ * Creates and shows a modal that contains a placeholder.
  *
- * @param rootElement
- * @returns {Promise<void>}
+ * @returns {Promise<Modal>}
  */
-const showPlaceholder = async(rootElement) => {
-    const {html, js} = await Templates.renderForPromise('pg_paypal/paypal_button_placeholder', {});
-    Templates.replaceNodeContents(rootElement.querySelector(Selectors.regions.gatewaysContainer), html, js);
+const showPlaceholder = async() => {
+    const modal = await ModalFactory.create({
+        type: ModalFactory.types.CANCEL,
+        body: await Templates.render('pg_paypal/paypal_button_placeholder', {})
+    });
+    modal.show();
+    return modal;
 };
 
-export const process = async(rootElement, amount, currency, component, componentid, description) => {
+/**
+ * Process the payment.
+ *
+ * @param {double} amount Amount of payment
+ * @param {string} currency The currency in the three-character ISO-4217 format
+ * @param {string} component Name of the component that the componentid belongs to
+ * @param {number} componentid An internal identifier that is used by the component
+ * @param {string} description Description of the payment
+ * @returns {Promise<void>}
+ */
+export const process = async(amount, currency, component, componentid, description) => {
 
     const [
-        ,
+        modal,
         paypalConfig,
     ] = await Promise.all([
-        showPlaceholder(rootElement),
+        showPlaceholder(),
         Repository.getConfigForJs(),
     ]);
 
     const paypalScript = `https://www.paypal.com/sdk/js?client-id=${paypalConfig.clientid}&currency=${currency}&intent=authorize`;
 
     callExternalFunction(paypalScript, () => {
-        rootElement.querySelector(Selectors.buttons.save).style.display = 'none';
-        rootElement.querySelector(Selectors.regions.gatewaysContainer).innerHTML = '';
+        modal.setBody('<form></form>'); // This is a hack. Instead of emptying the body, we put an empty form there so the modal
+                                        // is not closed when user clicks outside of modal.
         paypal.Buttons({ // eslint-disable-line
             createOrder: function(data, actions) {
                 // This function sets up the details of the transaction, including the amount and line item details.
@@ -95,14 +108,20 @@ export const process = async(rootElement, amount, currency, component, component
                     });
                 });
             }
-        }).render(Selectors.regions.gatewaysContainer);
+        }).render(modal.getBody()[0]);
     });
 };
 
-const callExternalFunction = (jsFile, callback) => {
-    // Check to see if this file has already been loaded. If so just go straight to the callback.
+/**
+ * Calls a function from an external javascript file.
+ *
+ * @param {string} jsFile URL of the external JavaScript file
+ * @param {function} func The function to call
+ */
+const callExternalFunction = (jsFile, func) => {
+    // Check to see if this file has already been loaded. If so just go straight to the func.
     if (callExternalFunction.currentlyloaded.includes(jsFile)) {
-        callback();
+        func();
         return;
     }
 
@@ -112,12 +131,12 @@ const callExternalFunction = (jsFile, callback) => {
         script.onreadystatechange = function() {
             if (this.readyState == 'complete' || this.readyState == 'loaded') {
                 this.onreadystatechange = null;
-                callback();
+                func();
             }
         };
     } else {
         script.onload = function() {
-            callback();
+            func();
         };
     }
 
@@ -127,4 +146,10 @@ const callExternalFunction = (jsFile, callback) => {
     callExternalFunction.currentlyloaded.push(jsFile);
 };
 
+/**
+ * Holds the list of external JavaScript files.
+ *
+ * @static
+ * @type {Array}
+ */
 callExternalFunction.currentlyloaded = [];
diff --git a/payment/gateway/paypal/amd/src/selectors.js b/payment/gateway/paypal/amd/src/selectors.js
deleted file mode 100644 (file)
index 1515be7..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Define all of the selectors we will be using on the gateways modal.
- *
- * @module     pg_paypal/selectors
- * @package    pg_paypal
- * @copyright  2019 Shamim Rezaie <shamim@moodle.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-export default {
-    regions: {
-        gatewaysContainer: '[data-region="gateways-container"]',
-    },
-    buttons: {
-        save: '[data-action="save"]',
-    },
-};