Jake
Jake

Reputation: 1186

How To have multiple buttons trigger one js function on the same page

How would I be able to use 2 different buttons to render the same product purchase modal in the same if statement?

I have a page where I only have one product but have 3 payment buttons (2 rendered in one case and 1 in another using an if/else statement).

The first button in the if section works and the one works in the else but the second button doesn't work in the if.

I have tried using .getElementsByClassName('purch-btn') and changing the button classes respectively.

I have also tried using .querySelectorAll('btn_buy, btn_buy_two') and assigning one of those ids to each of the buttons.

Neither of these work.

The Pack view:

<% if @pack.category_id == "sample-pack" %>

  <div class="col-md-4">
    <div class="wellington top-drop prod-pod">
      <button class="btn btn-success btn-block" id="btn_buy" type="button">Purchase This Library</button>
    </div>
  </div>

  <div class="col-md-12">
    <button class="btn btn-success btn-block top-drop" id="btn_buy_two" type="button">Purchase This Library</button>
  </div>

<% else %>

  <div class="col-md-8">
    <div class="wellington top-drop">
      <button class="packview-addcart btn btn-lg btn-success" id="btn_buy" type="button">Buy!</button>
    </div>
  </div>

<% end %>
<%= render 'purchase_modal' %>

The Purchase modal:

<script>
  var handler = StripeCheckout.configure({
    key: '<%= Rails.configuration.stripe[:publishable_key] %>',
    token: function(token, arg) {
      document.getElementById("stripeToken").value = token.id;
      document.getElementById("stripeEmail").value = token.email;
      document.getElementById("chargeForm").submit();
    }
  });
  document.getElementById('btn-buy').addEventListener('click', function(e) {
    handler.open({
      zipCode: 'true',
      // image: '<%= @pack.art_link %>',
      name: '<%= @pack.title %>',
      description: 'Total: $<%= @pack.price %> USD',
      amount: document.getElementById("amount").value
    });
    e.preventDefault();
  });

  // Close Checkout on page navigation:
  window.addEventListener('popstate', function() {
    handler.close();
  });
</script>

Upvotes: 1

Views: 1050

Answers (3)

valbuxvb
valbuxvb

Reputation: 89

One solution can be using document.querySelectorAll("#btn_buy, #btn_buy_two") This function will return an array containing the two elements you are looking for.

Since you want them to do the same thing when they are clicked you need .forEach(function(button){}) that will iterate thorough them.

This function will return one by one the buttons, and store them in the variable "button".

You can now act on them as they were a single element:

button.addEventListener('click', function(e) {
    handler.open({
        zipCode: 'true',
        // image: '<%= @pack.art_link %>',
        name: '<%= @pack.title %>',
        description: 'Total: $<%= @pack.price %> USD',
        amount: document.getElementById("amount").value
    });
    e.preventDefault();
});

I wrote a sample code snippet:

document.querySelectorAll('#btn1, #btn2').forEach(function(button) {
  button.addEventListener('click', function(e) {
    // ----- YOUR CODE -----
    console.log("some action")
  })
});
<button id="btn1">Button 1</button>
<button id="btn2">Button 2</button>

The two buttons perform the same action without having to write it twice.

(I changed the code to make it more accessible to other users having the same issue)

Upvotes: 0

Jake
Jake

Reputation: 1186

I ended up just having to use two purchase modals (one for each button).

In the if statement, I simply added a render <%= render 'purchase_modal_two' %> for the button with id="btn_buy_two" since there was already one for the first button (id="btn_buy") after it that will load for both the else and if.

The only difference in both modals where here:

purchase_modal:

document.getElementById('btn_buy').addEventListener('click', function(e) {

purchase_modal_two:

document.getElementById('btn_buy_two').addEventListener('click', function(e) {

I am still open to actual answers to this question, as this is kind of a workaround and would love to know if it's possible to do this with only one <script> section!

Upvotes: 0

thehuijb
thehuijb

Reputation: 239

like this

document.querySelectorAll('#btn_buy, #btn_buy_two').forEach(function(btn) { btn.addEventListener('click', function(e) {
    handler.open(...[YOUR CODE]...);
    e.preventDefault();
  })
});

Upvotes: 2

Related Questions