skip to Main Content

Beginner here. I have an HTMl table with buttons and I want a button to toggle open a form with the values from that row. Problem is, if I have multiple rows in my table, it opens multiple forms for each row with the values pre-filled. How can I make it so that it only opens a single form for that row only?

my HTML and js , shortened for clarity

I have already gone from IDs to classes, but still it wouldn’t work.

$(".btn-edit-address").click(function() {
  $('.form-edit-address').toggle('fast');
});

function closeEditAddressForm() {
  $('.form-edit-address').toggle('fast');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="table-responsive my-5">
  <table id="table-address-book" class="display table table-striped table-hover">
    <thead>
      <tr style="text-align: center;">
        <th style="width: 150px;">insert headers here</th>
        <th style="width: 150px;">Actions</th>
      </tr>
    </thead>
    <tbody>
      {% for address in addressInfo %}
      <tr class="row-address-book" style="text-align: center; vertical-align: middle;">
        <td>
          insert table data here
        </td>
        <td>
          <div class="d-flex align-items-center justify-content-center" style="display: inline; vertical-align: baseline;">
            <button class="btn btn-sm mx-1 btn-black" type="button" hidden="">
                            <i class="fa fa-chevron-down"></i>
                        </button>
            <button class="btn-edit-address btn btn-sm mx-1" type="button" style="color: rgb(24, 115, 184);">
                            <i class="fa fa-edit"></i>
                        </button>
            <form action="{{ url_for('homepage.deleteBuyerAddress', addressBookID=address.0 ) }}" class="form-delete-address" method="POST">
              <button class="btn-delete-address btn btn-sm mx-1" type="submit" style="color: red;">
                                <i class="fa fa-times"></i>
                            </button>
            </form>
          </div>
        </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
</div>

{% for address in addressInfo %}
<form action="#" method="POST" class="form-edit-address" style="display: none; margin-top: 50px;">
  <div class="input-group mb-3">
    input groups here
  </div>

  <div class="d-flex align-items-center justify-content-center">
    <button class="btn btn-primary me-2" type="submit" style="margin-top: 25px;">
        Edit address
        </button>
    <button class="btn btn-warning ms-2" type="button" style="margin-top: 25px;" onclick="closeEditAddressForm()">
        Cancel
        </button>
  </div>
</form>
{% endfor %}

2

Answers


  1. With your current structure, it seems that you’ll need a way to associate each table row (or button) with its corresponding form. It looks like each row has the same numeric index as its form (i.e. row#1 corresponds to form#1, row#2 to form#2, etc.), so you might consider using jQuery’s index() and eq(). You could also assign each table row (or button) a data attribute that matches the data attribute or unique ID of its corresponding form.

    Here’s an example using index() and eq():

    // define all forms
    let $forms = jQuery('.form');
    
    jQuery('.cell').on('click', function() {
    
      // define this row's numeric index in the table
      let indx = jQuery(this).parent('tr').index();
    
      // hide all forms
      $forms.hide(200);
    
      // show the form that corresponds with the table row
      $forms.eq(indx).show(200);
    
    });
    table {
      margin-bottom: 30px;
    }
    
    .cell {
      cursor: pointer;
    }
    
    .form {
      display: none;
      color:green;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    
    <table>
      <tbody>
        <tr>
          <td class="cell">One</td>
        </tr>
        <tr>
          <td class="cell">Two</td>
        </tr>
        <tr>
          <td class="cell">Three</td>
        </tr>
      </tbody>
    </table>
    
    <form class="form">
      One!
    </form>
    <form class="form">
      Two!
    </form>
    <form class="form">
      Three!
    </form>

    Here’s an example using data attributes and IDs:

    // define all forms
    let $forms = jQuery('.form');
    
    jQuery('.cell').on('click', function() {
    
      // get the data attribute from the clicked table cell
      let id = jQuery(this).data('id');
    
      // hide all forms
      $forms.hide(200);
    
      // show the form with the ID matching that of the clicked table cell
      jQuery('#form-' + id).show(200);
    
    });
    table {
      margin-bottom: 30px;
    }
    
    .cell {
      cursor: pointer;
    }
    
    .form {
      display: none;
      color: green;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    
    <table>
      <tbody>
        <tr>
          <td class="cell" data-id="1">One</td>
        </tr>
        <tr>
          <td class="cell" data-id="2">Two</td>
        </tr>
        <tr>
          <td class="cell" data-id="3">Three</td>
        </tr>
      </tbody>
    </table>
    
    <form class="form" id="form-1">
      One!
    </form>
    <form class="form" id="form-2">
      Two!
    </form>
    <form class="form" id="form-3">
      Three!
    </form>
    Login or Signup to reply.
  2. You can delegate and have only one form

    Store the ID in the row as a data attribute and use that to tell the server what ID you are targeting

    $(".row-address-book .btn").on("click", function() {
      const $tgt = $(this).closest('.btn'); // did we click a button?
      if ($tgt.length === 0) return; // no, leave
      const $row = $tgt.closest('tr');
      const $form = $('.form-edit-address');
      $form.find('[name=id]').val($row.data('id')); // add the ID to the form
      const $formButton = $form.find('[type=submit]');
      $input = $('div.input-group');
      const html = $row.find('.address').clone().html();
      $input.html(html); // copy contents
      if ($tgt.is('.btn-edit-address')) {
        $input.find('input').each(function() {
          $(this).removeAttr('readonly')
          $formButton.text('Submit')
        });
      } else if ($tgt.is('.btn-delete-address')) {
        $formButton.text('Delete')
        $form.attr('action', '{{homepage.deleteBuyerAddress}}');
      }
      $form.show('fast');
    });
    $('.closeEdit').on('click', function() {
      $(this).closest('form').hide()
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css" />
    <div class="table-responsive my-5">
      <table id="table-address-book" class="display table table-striped table-hover">
        <thead>
          <tr style="text-align: center;">
            <th style="width: 150px;">insert headers here</th>
            <th style="width: 150px;">Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr class="row-address-book" style="text-align: center; vertical-align: middle;" data-id="idforrow1">
            <td class="address">
              <input type="text" name="add1" value="row 1 addressline1" readonly /><br />
              <input type="text" name="add1" value="row 1 addressline2" readonly /><br />
              <input type="text" name="add1" value="row 1 addressline3" readonly /><br />
            </td>
            <td>
              <div class="d-flex align-items-center justify-content-center" style="display: inline; vertical-align: baseline;">
                <button class="btn btn-sm mx-1 btn-black" type="button" hidden="">
                    <i class="fa fa-chevron-down"></i>
                  </button>
                <button class="btn-edit-address btn btn-sm mx-1" type="button" style="color: rgb(24, 115, 184);">
                    <i class="fa fa-edit"></i>
                  </button>
                <button class="btn-delete-address btn btn-sm mx-1" type="button" style="color: red;">
                    <i class="fa fa-times"></i>
                  </button>
              </div>
            </td>
          </tr>
          <tr class="row-address-book" style="text-align: center; vertical-align: middle;" data-id="idforrow1">
            <td class="address">
              <input type="text" name="add2" value="row 2 addressline1" readonly /><br />
              <input type="text" name="add2" value="row 2 addressline2" readonly /><br />
              <input type="text" name="add2" value="row 2 addressline3" readonly /><br />
            </td>
            <td>
              <div class="d-flex align-items-center justify-content-center" style="display: inline; vertical-align: baseline;">
                <button class="btn btn-sm mx-1 btn-black" type="button" hidden="">
                    <i class="fa fa-chevron-down"></i>
                  </button>
                <button class="btn-edit-address btn btn-sm mx-1" type="button" style="color: rgb(24, 115, 184);">
                    <i class="fa fa-edit"></i>
                  </button>
                <button class="btn-delete-address btn btn-sm mx-1" type="button" style="color: red;">
                    <i class="fa fa-times"></i>
                  </button>
              </div>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    
    
    <form action="#" method="POST" class="form-edit-address" style="display: none; margin-top: 50px;">
      <input type="hidden" name="id" value="" />
      <div class="input-group mb-3">
        input groups here
      </div>
    
      <div class="d-flex align-items-center justify-content-center">
        <button class="btn btn-primary me-2" type="submit" style="margin-top: 25px;">
          Save address
        </button>
        <button class="btn btn-warning ms-2 closeEdit" type="button" style="margin-top: 25px;">
          Cancel
        </button>
      </div>
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search