From 7320a1714cc0bd2e0dff1569c3c53503df41bbd0 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Wed, 18 Jan 2023 11:40:28 +0100 Subject: [PATCH 1/3] Instead of selecting the controller, send an event handled by stripe-cards Using a query selector to find controller in order to call method could be dangerous as the DOM can change. Using an event should be more robust. --- .../payment/_stripe_sca.html.haml | 2 +- .../controllers/paymentmethod_controller.js | 17 ++++++----------- .../controllers/stripe_cards_controller.js | 5 +++++ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/views/split_checkout/payment/_stripe_sca.html.haml b/app/views/split_checkout/payment/_stripe_sca.html.haml index ba451ff37d..24448c7346 100644 --- a/app/views/split_checkout/payment/_stripe_sca.html.haml +++ b/app/views/split_checkout/payment/_stripe_sca.html.haml @@ -1,4 +1,4 @@ -%div{"data-controller": "stripe-cards"} +%div{"data-controller": "stripe-cards", "data-paymentid": "#{payment_method.id}" } - if @saved_credit_cards.any? .checkout-input %label diff --git a/app/webpacker/controllers/paymentmethod_controller.js b/app/webpacker/controllers/paymentmethod_controller.js index b7a1b27e8d..00e607f333 100644 --- a/app/webpacker/controllers/paymentmethod_controller.js +++ b/app/webpacker/controllers/paymentmethod_controller.js @@ -12,17 +12,12 @@ export default class extends Controller { selectPaymentMethod(event) { this.setPaymentMethod(event.target.dataset.paymentmethodId); - - const stripeCardSelector = - this.application.getControllerForElementAndIdentifier( - document - .querySelector( - `[data-paymentmethod-id="${event.target.dataset.paymentmethodId}"]` - ) - .querySelector('[data-controller="stripe-cards"]'), - "stripe-cards" - ); - stripeCardSelector?.initSelectedCard(); + // Send an event to the right (ie. the one with the same paymentmethodId) + // StripeCardsController to initialize the form elements with the selected card + const customEvent = new CustomEvent("stripecards:initSelectedCard", { + detail: event.target.dataset.paymentmethodId, + }); + document.dispatchEvent(customEvent); } setPaymentMethod(paymentMethodContainerId) { diff --git a/app/webpacker/controllers/stripe_cards_controller.js b/app/webpacker/controllers/stripe_cards_controller.js index 98c657867b..2b36f58bfa 100644 --- a/app/webpacker/controllers/stripe_cards_controller.js +++ b/app/webpacker/controllers/stripe_cards_controller.js @@ -7,6 +7,11 @@ export default class extends Controller { connect() { this.initSelectedCard(); + document.addEventListener("stripecards:initSelectedCard", (e) => { + if (e.detail == `paymentmethod${this.element.dataset.paymentid}`) { + this.initSelectedCard(); + } + }); } initSelectedCard() { From 251ab2ac9aa962944961a7e96a51b3b7a02efa1a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Mon, 23 Jan 2023 17:45:26 +0100 Subject: [PATCH 2/3] Payment method id attribute don't need to start with `paymentmethod` --- app/views/split_checkout/_payment.html.haml | 4 ++-- app/webpacker/controllers/stripe_cards_controller.js | 2 +- .../stimulus/paymentmethod_controller_test.js | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/views/split_checkout/_payment.html.haml b/app/views/split_checkout/_payment.html.haml index 69d55d6a0b..1e363d6875 100644 --- a/app/views/split_checkout/_payment.html.haml +++ b/app/views/split_checkout/_payment.html.haml @@ -12,12 +12,12 @@ name: "order[payments_attributes][][payment_method_id]", checked: (payment_method.id == selected_payment_method), "data-action": "paymentmethod#selectPaymentMethod", - "data-paymentmethod-id": "paymentmethod#{payment_method.id}", + "data-paymentmethod-id": "#{payment_method.id}", "data-paymentmethod-target": "input" = f.label :payment_method_id, "#{payment_method.name}", for: "payment_method_#{payment_method.id}" %em=payment_or_shipping_price(payment_method, @order) - .paymentmethod-container{"data-paymentmethod-id": "paymentmethod#{payment_method.id}", style: "display: #{payment_method.id == selected_payment_method ? "block" : "none"}"} + .paymentmethod-container{"data-paymentmethod-id": "#{payment_method.id}", style: "display: #{payment_method.id == selected_payment_method ? "block" : "none"}"} - if payment_method.description && !payment_method.description.empty? .paymentmethod-description.panel #{payment_method.description} diff --git a/app/webpacker/controllers/stripe_cards_controller.js b/app/webpacker/controllers/stripe_cards_controller.js index 2b36f58bfa..acffbabe57 100644 --- a/app/webpacker/controllers/stripe_cards_controller.js +++ b/app/webpacker/controllers/stripe_cards_controller.js @@ -8,7 +8,7 @@ export default class extends Controller { connect() { this.initSelectedCard(); document.addEventListener("stripecards:initSelectedCard", (e) => { - if (e.detail == `paymentmethod${this.element.dataset.paymentid}`) { + if (e.detail == this.element.dataset.paymentid) { this.initSelectedCard(); } }); diff --git a/spec/javascripts/stimulus/paymentmethod_controller_test.js b/spec/javascripts/stimulus/paymentmethod_controller_test.js index 483a159a80..f366df573a 100644 --- a/spec/javascripts/stimulus/paymentmethod_controller_test.js +++ b/spec/javascripts/stimulus/paymentmethod_controller_test.js @@ -14,23 +14,23 @@ describe("PaymentmethodController", () => { describe("#selectPaymentMethod", () => { beforeEach(() => { document.body.innerHTML = `
- - - + + + -
+
-
+
-
+