RiotAct
RiotAct

Reputation: 773

Dynamic number of AJAX forms on same page

I have a payment method page that allows users to delete cards or to set a card as default. I noticed today that when I click a card to delete, it actually deletes another card. I am using AJAX to handle the forms and am not sure the best way to keep these separate as they are dynamic and each user will have random numbers of payment methods.

Here is an example of my HTML/PHP:

<table>
  <tr>
    <th>Method</th>
    <th>Expires</th>
    <th>Actions</th>
  </tr>
  <?php foreach($cards->data as $card) { ?>
    <tr>
      <td>Card Info</td>
      <td>Expiration</td>
      <td>
        <form class="sg-inline-form" method="post" action="">
          <input type="hidden" name="sg_customer_id" value="customerID">
          <input type="hidden" name="sg_card_id" value="cardID">
          <a href="#" class="set-default">Set As Default</a>
          <a href="#" class="delete-card">Delete</a>
        </form>
      </td>
    </tr>
  <?php } ?>
</table>

Here is my AJAX function:

// Delete Card
$('.delete-card').click(function() {
  $('.ajax-loading').show();
  var customer = $('input[name=sg_customer_id]').val();
  var card = $('input[name=sg_card_id]').val();
  $.ajax({
    url: sg_obj.ajaxurl,
      data: {
        'action': 'sg_delete_payment_source',
        'customer' : customer,
        'card' : card
      },
      success:function(data) {
        // This outputs the result of the ajax request
        $('.ajax-loading').hide();
        $('#ajax-messages').addClass('alert alert-success').html('The payment source has been deleted. <a href=".">Refresh Page</a>');
        },
        error: function(errorThrown){
          $('.ajax-loading').hide();
          $('#ajax-messages').addClass('alert alert-danger').html('An error occurred.');
        }
      });  
    });

From there the handler works fine, but I need to be able to get the right form for the initial response.

Upvotes: 0

Views: 32

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371049

In your top handler, refer to this to refer to the clicked .delete-card <a> element, and then you can refer to its parent() to get to the <form> you want:

$('.delete-card').click(function() {
  const $form = $(this).parent();
  const customer = $form.find('input[name=sg_customer_id]').val();
  const card = $form.find('input[name=sg_card_id]').val();
  console.log('Sending ajax request for ' + customer + ', ' + card);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <th>Method</th>
    <th>Expires</th>
    <th>Actions</th>
  </tr>
  <tr>
    <td>Card Info</td>
    <td>Expiration</td>
    <td>
      <form class="sg-inline-form" method="post" action="">
        <input type="hidden" name="sg_customer_id" value="customerID1">
        <input type="hidden" name="sg_card_id" value="cardID1">
        <a href="#" class="set-default">Set As Default</a>
        <a href="#" class="delete-card">Delete</a>
      </form>
    </td>
  </tr>
    <tr>
    <td>Card Info</td>
    <td>Expiration</td>
    <td>
      <form class="sg-inline-form" method="post" action="">
        <input type="hidden" name="sg_customer_id" value="customerID2">
        <input type="hidden" name="sg_card_id" value="cardID2">
        <a href="#" class="set-default">Set As Default</a>
        <a href="#" class="delete-card">Delete</a>
      </form>
    </td>
  </tr>
</table>

Upvotes: 1

Related Questions